MySQL Performance: Improved Adaptive Flushing in 5.6-labs
I’d start this blog post with "I’ve had a dream"..
)
Seriously,
it was my dream from a long time that "official" MySQL code comes with a
more improved Adaptive Flushing solution in InnoDB.. – and now, with
5.6-labs release, this dream becomes a reality
)
The story
with Adaptive Flushing is so long.. Started by Yasufumi after his
brilliant analyze of the flushing problem in InnoDB, then integrated in
XtraDB as Adaptive Checkpoint, then came in alternative way as Adaptive
Flushing in "official" InnoDB code, then yet more improved within
Percona Server, etc. etc. etc.. (my last
post about was one year ago, and it was already a call to action
rather a general discussion about performance improvements
)
However,
it took a time to get similar improvement within an "official" InnoDB
code, but not because people are lazy or not open to changes, but just
because the already implemented solution within InnoDB was simply "good
enough" in many cases
) specially with appearing of the page_cleaner
thread in 5.6.. The only weak point it has is that it’s unable to keep
load spikes (but in this point no one of existing solutions is good,
even in XtraDB), and it may take a long time before to "adapt" to a
given workload..
Let’s get a look on the following graph:
Explanations:
- this a light dbSTRESS RW workload with 32 concurrent user sessions
-
MySQL 5.5 and 5.6 are both having a similar drops in TPS level (left
part of graph) - these drops are due Checkpoint Age reaching max REDO log space
-
so urgent burst flushing (furious flushing) is involved to create a
room of free space within REDO, otherwise the whole transactional
processing is remaining frozen.. -
however, over a time such drops are less and less important, so some
users may probably even live with it.. -
but on the right part of the graph you may see 5.6-labs solution in
action, and there is no more any drops at all (except the initial one
which is related to adaptive hash index initialization) -
as well, 5.6-labs is keeping a quite significant marge in Checkpoint
Age in case there will some spikes happen in the load with increased
activity (where 5.5 will almost have TPS drops every time..)
To be sure we’re not reinventing the wheel, we even ported most
interesting solutions to the 5.6 prototype trunk, and I’ve tested all of
them on the more hard RW workload:
From
the left to right:
- 5.6-native
- 5.6 + "estimate" from Percona
- 5.6 + "keep avg" from Percona
- 5.6-labs
-
Percona 5.5 (this one I’ve tested just to be sure nothing was wrong
with a logic in a ported code)
As you may see directly from these graphs that our solution (implemented
now in 5.6-labs) looked more attractive from the beginning.. And I’m very
happy to be able to contribute to it, as several of my previously
expressed ideas were accepted to be a part of this solution too
)
So,
what was changed in the improved Adaptive Flushing (AF) in MySQL 5.6-labs:
-
first of all the logic is moved to the REDO log space occupancy rather
tracking estimation of pages to flush as before -
more REDO space is filled, and more aggressively becomes InnoDB is
flushing - less REDO is filled – more relaxed is flushing..
-
the relation between REDO occupancy and flushing power level is
progressive and non-linear.. -
all the time we’re also considering the average REDO filling speed and
average amount of flushed pages -
these averages are helping to guide the AF decisions to better adapt
dirty pages flushing according database activity.. -
then only point which is remaining yet open is a case when pages
flushing is unable to follow REDO writes simply because of weak I/O
layer.. – we already have a solution here too, but it’s not yet part
of 5.6-labs
From the user/DBA point of view the AF configuration as looking as simple
as following:
-
the IO capacity setting is still remaining (and used for most
maintenance tasks within InnoDB – you should consider it now as kind
of AVG I/O write activity you’re expecting to see from your database
server in general, specially useful if your MySQL server is running
with many other applications on the same machine (or other MySQL
instances as well)).. -
the "Max" IO capacity is introduced to say how high InnoDB
is allowed to go in flushing to be able to follow REDO log activity -
the Low Watermark is introduced to say since what percentage of
REDO log space filling the AF processing should be activated –
depending on your workload it may vary.. (default is 10%) -
all configuration variables are dynamic and can be changed at any
moment
So, once you’ve set your limits – InnoDB then will try to do the best with
what it has
And all AF internals are available for
monitoring via METRICS table:
-
buffer_flush_adaptive_total_pages — getting delta of this
value divided by the time interval giving you the current speed of
pages flushing due AF -
buffer_flush_avg_page_rate — the average pages flushing rate
seen and considered within AF, and if everything is going well with
your I/O level, this value should less or more follow the previous one
-
buffer_flush_n_to_flush_requested — the amount of pages
requested for flushing by AF (and which may be quite different from
both previous counters because the avg REDO filling speed is also
coming in the game, and may limit a real flushing by pages age).. -
buffer_flush_lsn_avg_rate — LSN avg rate seen by AF
(corresponding to the REDO logs feeling speed and used as age
limitation barrier when flushing is involved — so we may then flush
as many pages as requested or less, because of this age rate).. – when
on the I/O level everything is going well, this value should less or
more follow your REDO MB/sec write speed, and grow in case of lagging
to increase the current age barrier for flushing..
There are also some other counters, but let’s skip them to keep stuff
simple
Now, replaying the same RW workload presented before on
MySQL 5.6-labs with:
- innodb_io_capacity = 2000
- innodb_max_io_capacity = 4000
will give us the following:

So,
- AF is requesting to flush 2000 pages according its estimation
-
but in reality flushing 1000 pages/sec is quite enough to keep
Checkpoint Age on a reasonable level - 70K QPS is reached..
But what will be changed since there will be some activity spikes?..
I’ll
mix now this workload with Sysbench OLTP_RW – additional 16/32 users
sessions will come and leave the database activity with their RW
transactions:
Observations:
- Checkpoint Age is jumping up during spikes in activity..
-
within a current I/O configuration InnoDB is unable to flush faster
than 1500 pages/sec.. - which is resulting in QPS drops during these spikes..
-
What can we do to help here?..
-
we may improve the I/O level performance (sure will help!
)
-
or expect that is the spikes are not too long in time, with a
bigger REDO logs there will be more room to resist to them..
-
we may improve the I/O level performance (sure will help!
So, now replaying the same test case, but now with using 8GB REDO logs
total space:
Observations:
-
having a bigger REDO space automatically reduced the flushing rate
during "quiet periods" (from 1500 to 500 pages/sec) - and we’re reaching 1500 pages/sec flushing only during spikes now..
-
the marge on the REDO log space is big enough to keep Checkpoint Ages
jumps under critical level -
which is resulting in a total absence of QPS drops
Or the same workload on a served with less powerful CPUs, but more
powerful storage level:
Observations:
- QPS level is lower due lower CPU speed
-
but dirty pages flushing level is way faster when requested, easily
reaching 3000 pages/sec -
so we’re not observing any QPS drops on activity spikes as Checkpoint
Ages levels were never critical..
Looking on these results we may be only happy, because none of ones was
possible to achieve with MySQL 5.5 and previously in 5.6 (both will keep
Checkpoint Age too close to the critical limit, so any activity spike will
bring a TPS drop)..
After these "complex" tests, let’s get a
look on a "simple" Sysbench OLTP_RW between 5.5 and 5.6-labs:
As
you can see, as soon as you have to flush due reaching critical Checkpoint
Age levels – as soon you’ll have TPS drops too.. It’s what we’re observing
in 5.5 and before in 5.6 – but I hope time is changed since 5.6-labs
)
The
solution is not yet final, but at least very promising and pretty easy to
tune
but more testing will give us more ideas about how the final code
should look like.. – so don’t hesitate to test it on your own systems and
your own workloads!!
)
As the final word, I’d like to thank
Inaam from InnoDB team for his patience in implementation and adoption of
all the ideas we have around into a single and truly integrated within
InnoDB code solution!.. Kudos Inaam!
)
I’d say, and you may just
trust me, since 5.6-labs benchmarking MySQL will become much more
interesting!
)
Rgds,
-Dimitri
PlanetMySQL Voting:
Vote UP /
Vote DOWN
Read more at: http://planet.mysql.com/
