Innodb_io_capacity research on IO stability _ MySQL

Source: Internet
Author: User
Tags perl script
Innodb_io_capacity some research on IO stability bitsCN.com

Background: I/O loads on an online server recently discovered the following phenomena:

The 24-hour IO_UTIL curve seems calm and has fewer burrs.

However, when the image is enlarged to half an hour, it is found that IO_UTIL indicates that the disk usage fluctuates regularly. for details, see:

This article will start from this phenomenon and explore the reasons for such regular fluctuations.

Step 1: view the real-time IO load on the server

Use iostat-x 1 to view the I/O usage once every second. We can see that UTIL fluctuates regularly (once every 10 seconds ).

And the main load source is write requests (when the load is high, wsec/s also increases)

Because the server is exclusively occupied by MySQL, it is easier to attribute the cause to the data flushing of MySQL (log/data ).

It is easy to guess that it is the 10_seconds loop in MySQL src_master_thread.

To ensure the consistency of diagnostic ideas, repeat the operation at that time.

root@db-mysql-tg03b.nh:/root>iostat -x 1 vgca0 |grep vgca0
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %utilvgca0 0.00 0.00 12.96 371.75 1562.56 24314.49 67.26 0.37 0.28 0.28 10.62vgca0 0.00 0.00 2.00 2.00 40.00 138.00 44.50 0.00 1.00 1.00 0.40vgca0 0.00 0.00 1.00 2.00 32.00 170.00 67.33 0.00 1.00 1.00 0.30vgca0 0.00 0.00 3.00 2.00 96.00 130.00 45.20 0.00 0.80 0.80 0.40vgca0 0.00 0.00 4.00 2.00 128.00 178.00 51.00 0.00 0.67 0.67 0.40vgca0 0.00 0.00 1.00 5.00 32.00 170.00 33.67 0.00 0.83 0.83 0.50vgca0 0.00 0.00 0.00 1868.00 0.00 101510.00 54.34 1.28 0.16 0.16 30.20vgca0 0.00 0.00 7.00 2.00 200.00 130.00 36.67 0.10 12.78 12.78 11.50vgca0 0.00 0.00 1.98 1.98 39.60 160.40 50.50 0.00 1.00 1.00 0.40vgca0 0.00 0.00 6.00 2.00 168.00 170.00 42.25 0.00 0.88 0.88 0.70vgca0 0.00 0.00 4.00 26.00 104.00 5026.00 171.00 0.02 0.73 0.73 2.20vgca0 0.00 0.00 10.00 2.00 296.00 164.00 38.33 0.04 3.92 3.92 4.70vgca0 0.00 0.00 1.00 2.00 8.00 138.00 48.67 0.00 1.00 1.00 0.30vgca0 0.00 0.00 2.00 2.00 40.00 162.00 50.50 0.00 1.00 1.00 0.40vgca0 0.00 0.00 3.00 2.00 72.00 170.00 48.40 0.00 0.80 0.80 0.40vgca0 0.00 0.00 2.00 6.00 40.00 172.00 26.50 0.00 0.50 0.50 0.40vgca0 0.00 0.00 2.00 601.00 40.00 32942.00 54.70 0.39 0.17 0.17 10.40vgca0 0.00 0.00 2.00 1179.00 16.00 63932.00 54.15 0.82 0.17 0.17 19.90vgca0 0.00 0.00 3.96 1.98 126.73 144.55 45.67 0.00 1.50 1.50 0.89vgca0 0.00 0.00 3.00 2.00 96.00 170.00 53.20 0.00 1.00 1.00 0.50vgca0 0.00 0.00 4.00 3.00 104.00 162.00 38.00 0.00 0.86 0.86 0.60vgca0 0.00 0.00 1.00 2.00 8.00 138.00 48.67 0.00 0.33 0.33 0.10vgca0 0.00 0.00 6.00 2.00 168.00 178.00 43.25 0.00 1.12 1.12 0.90vgca0 0.00 0.00 5.00 2.00 136.00 138.00 39.14 0.00 0.86 0.86 0.60vgca0 0.00 0.00 4.00 2.00 104.00 170.00 45.67 0.00 0.83 0.83 0.50vgca0 0.00 0.00 2.00 2.00 40.00 162.00 50.50 0.00 1.00 1.00 0.40vgca0 0.00 0.00 1.00 5.00 8.00 187.00 32.50 0.00 0.50 0.50 0.30vgca0 0.00 0.00 7.00 1815.00 104.00 98762.00 54.26 1.31 0.25 0.25 45.50vgca0 0.00 0.00 5.00 2.00 136.00 178.00 44.86 0.00 0.86 0.86 0.60

Step 2: determine the MySQL write IO Source

Currently, we only know that MySQL data is flushed, so we do not know whether it is caused by redo-log or data page flush.

The statistics of write in innodb is still relatively limited. Therefore, a perl script similar to top is roughly written to monitor these parameters.

The script is as follows. if you are interested, read it.

use strict;use warnings;use utf8;use DBI;my $CONFIG_SERVER_IP  ='127.0.0.1';my $CONFIG_SERVER_DB='test';my $CONFIG_SERVER_PORT='3306';my $CONFIG_SERVER_USER='user';my $CONFIG_SERVER_PASS='password';my $conf_dbh = DBI->connect("DBI:mysql:$CONFIG_SERVER_DB;host=$CONFIG_SERVER_IP;port=$CONFIG_SERVER_PORT", $CONFIG_SERVER_USER, $CONFIG_SERVER_PASS,{RaiseError => 1}) || die "Could not connect to database: $DBI::errstr";my %last_value_hash;print "data_write/tdata_written/tdblwr_pages_written/tdblwr_writes/tlog_write_req/tos_log_fsync/tos_log_written/tpages_written/n";while(1){    my $conf_sth = $conf_dbh->prepare("show global status like '%innodb%'") || die "Prepare error";    $conf_sth->execute();    while(my $row=$conf_sth->fetchrow_hashref){        my $name=$row->{Variable_name};        my $value=$row->{Value};        if( $name eq 'Innodb_data_writes' || $name eq 'Innodb_data_written'         || $name eq 'Innodb_dblwr_pages_written' || $name eq 'Innodb_dblwr_writes'         || $name eq 'Innodb_log_write_requests' || $name eq 'Innodb_os_log_fsyncs'         || $name eq 'Innodb_os_log_written' || $name eq 'Innodb_pages_written'){            $last_value_hash{$name}=0 if( !defined($last_value_hash{$name}) );            my $value_step=$value-$last_value_hash{$name};            $last_value_hash{$name}=$value;            print "$value_step/t";        }    }    print "/n";    sleep 1;}
Innodb write monitor

The following figure shows the parameter fluctuations:

We can see that innodb_data_writes/innodb_data_written/innodb_dblwr_pages_written/innodb_pages_written both fluctuate once every 10 seconds like IO_UTIL.

Combined with the large value of wsec/s in iostat, it can be basically determined that the culprit of high IO load is the flush of data page, rather than the flush of redo log.

data_write    data_written    dblwr_pages_written    dblwr_writes    log_write_req    os_log_fsync    os_log_written    pages_written1    79360    0    0    169    1    79360    01    72192    0    0    127    1    72192    01    67072    0    0    139    1    67072    01    69120    0    0    149    1    69120    01    74752    0    0    128    1    74752    01    61952    0    0    134    1    61952    01    71168    0    0    131    1    71168    01    62976    0    0    126    1    62976    01    71168    0    0    109    1    71168    01388    44870144    1367    14    125    6    75776    13671    66048    0    0    158    1    66048    01    73728    0    0    144    1    73728    01    69632    0    0    126    1    69632    01    75776    0    0    172    1    75776    01    88576    0    0    151    1    88576    01    67584    0    0    134    1    67584    01    80384    0    0    155    1    80384    01    86528    0    0    191    1    86528    01    72704    0    0    135    1    72704    01525    49385984    1504    13    154    5    102400    15041    74752    0    0    158    1    74752    0

Step 3: When does Innodb flush dirty data page?

Since the data flushing of innodb is just a little bit unfamiliar, there are also different opinions on the Flushing policies on the internet. it seems that I cannot go into depth after diagnosis.

In fact, the truth is quietly lying there: reading the source code.

The code path for Innodb disk writing is clear and easy to read. The main code is stored in storage/innodb_plugin/Buf/Buf0flu. c.

The code is too long to be pasted here. it mainly describes the calling relationship.

Buf_flush_batch calls buf_flush_try_neighbors (attempts to write the neighbor page)

Buf_flush_try_neighbots calls buf_flush_page (fl a single page)

Buf_flush_page calls buf_flush_write_block_low (actually fl a single page)

Buf_flush_write_block_low call buf_flush_post_to_doublewrite_buf (put the page in the double write buffer and prepare to be written)

Buf_flush_post_to_doublewrite_buf call fil_io (file IO encapsulation)

Fil_io calls OS _aio (aio related operations)

OS _aio calls OS _file_write (actual file write operations)

Buf_flush_batch has only two flushing modes: BUF_FLUSH_LIST and BUF_FLUSH_LRU:

BUF_FLUSH_LIST: it is called in the 1_second/10 second loop of the innodb master thread. There are many trigger conditions (which will be analyzed below)

BUF_FLUSH_LRU: called when the Buffer Pool has no idle page and there is not enough clean page in the old list. Some free pages can be blank after dirty pages are written for BP.

From the trigger frequency, we can see that the call to buf_flush_batch (BUF_FLUSH_LIST) in the 10 second loop is the culprit of the high I/O load once every 10 seconds.

Let's look at the flush logic in a 10-second loop:

The parameter is used to determine whether the IO of the previous loop is idle. if it is idle, the buf_flush_batch (BUF_FLUSH_LIST,PCT_IO (100));

If the proportion of dirty pages exceeds 70, buf_flush_batch (BUF_FLUSH_LIST,PCT_IO (100));

Otherwise, buf_flush_batch (BUF_FLUSH_LIST,PCT_IO (10));

We can see that the SSD responds very quickly to random write requests, resulting in almost no IO accumulation. In this way, innodb mistakenly believes that I/O is idle, and decides to fully write.

PCT_IO (N) = innodb_io_capacity * N %. unit: page. Therefore, innodb refreshes at least 10000 pages every 10 seconds or clears all dirty pages.

Step 4: further analyze and find the solution

After innodb_adaptive_flushing and innodb_adaptive_flushing_method are adjusted multiple times, the phenomenon is not changed.

This is also easy to explain: the reason for the large volume of write Flushing is that innodb considers IO to be relatively idle in a 10-second loop, so it is best to perform full write based on innodb_io_capacity; adaptive only occurs in a one-second loop.

Therefore, adjusting adaptive parameters does not solve the problem.

From the analysis in step 3, we can draw a clear conclusion that the problem can be solved to a large extent after innodb_io_capacity is reduced.

After we adjust innodb_io_capacity from 10000 to 200 and add the following configuration:

Innodb_adaptive_flush = OFF;

Innodb_adaptive_checkpoint = keep_average

We can see that the data written write volume of mysql is greatly reduced and kept stable (see, after, the result of parameter adjustment)

At the same time, from the perspective of flash card hardware writing volume, it also reduces a lot (see)

References:

Http://www.mysqlperformanceblog.com/2011/03/31/innodb-flushing-a-lot-of-memory-and-slow-disk/

Https://www.google.com/reader/view/#stream/feed%2Fhttp%3A%2F%2Fwww.xaprb.com%2Fblog%2Ffeed%2F

Http://www.mysqlperformanceblog.com/2012/09/10/adaptive-flushing-in-mysql-5-6-cont/

Http://dimitrik.free.fr/blog/archives/04-01-2012_04-30-2012.html#143

Https://www.google.com/reader/view/#stream/feed%2Fhttp%3A%2F%2Fplanet.mysql.com%2Frss20.xml

BitsCN.com

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.