« December 2015 | Main | October 2015 »
Friday, 27 November, 2015
MySQL Performance: Improved Connect/sec Rate in MySQL 5.7
This article is continuing the MySQL 5.7 Performance story, started from 1.6M
QPS on MySQL 5.7 details post , then 1M
QPS on mixed OLTP_RO with MySQL 5.7 article, and detailed story
about why
the Point-Selects performance is so critical (and why the 1M result
published by MariaDB is not fair)..
The current story will be
about Connect/sec (connect/disconnect) performance improvement in
MySQL 5.7 - such kind of metric is very critical for any application
which cannot use persistent connections all the time (and many web apps
are in such a case). Well, I'd say MySQL from the beginning was
extremely good for its lightweight connections, and made in the past the
base of success for many web solutions.. However, time is going, and
we're no more with 4cores as "commodity hardware" (this is rather a
smart-watch today ;-)) - so, there was a need to speed-up this Connect
rate to match higher workloads. This was already greatly done in MySQL
5.6, and finally yet more improved in MySQL 5.7 - you may read all
details about directly from our developers - I'll just present here
a short summary about where we're today..
So far, first of all,
how to test the Connect/sec performance of your MySQL server instance? -
the most simple way here is just to use a standard Sysbench kit, load
10M rows into sysbench database (1 table or several tables, no matter --
the main show-stopper here is the Connect code itself), and then run the
following :
#!/bin/bash # ---------------------------------------------------------------- # Connect/sec test # ---------------------------------------------------------------- for Users in 8 16 32 64 128 256 512 1024 do LD_PRELOAD=/usr/lib64/libjemalloc.so.1 sysbench --num-threads=$Users \ --test=oltp --oltp-table-size=10000000 \ --db-ps-mode=disable --oltp-dist-type=uniform --oltp-table-name=sbtest_10M \ --max-requests=0 --max-time=300 --mysql-socket=/tmp/mysql.sock \ --mysql-user=dim --mysql-password=dim --mysql-db=sysbench \ --mysql-table-engine=INNODB --db-driver=mysql \ --oltp-point-selects=1 --oltp-simple-ranges=0 --oltp-sum-ranges=0 \ --oltp-order-ranges=0 --oltp-distinct-ranges=0 --oltp-skip-trx=on \ --oltp-read-only=on --oltp-reconnect-mode=query --oltp-connect-delay=0 run sleep 30 done # ----------------------------------------------------------------
means on every point-select query your client session will re-connect, and the final QPS result will give you the max Connect/sec rate your MySQL instance is able to reach for a given amount of concurrent users.
And here are the results obtained from older to newer generations Intel-based Linux servers :
12cores-HT @2.9Ghz :

32cores-HT @2.3Ghz :

40cores-HT @2.3Ghz :

72cores-HT @2.5Ghz :

Instead of SUMMARY :
- Connect/sec performance is mainly depending on the MySQL "connect/disconnect" code itself + CPU chip speed
- it's hard to speak about "scalability" here as the max possible Connect/sec rate limit is reached pretty quickly and depending on IP stack performance as well..
- tuning "thread_cache_size" to something bigger than zero is helping here, but not too much..
- MySQL 5.7 showing the best performance here regardless the HW platform, and reaching over 100K Connect/sec on the latest Intel CPU chip
- there is a clear better-and-better tendency in MySQL 5.5 => 5.6 => 5.7 results
- and we still can do yet more better with MySQL 5.8 ! (question of time and resources - so, please, send us your feedback/ votes/ wishes if you want to see it ;-))
MySQL 5.7 rocks! ;-))
Rgds,
-Dimitri
Wednesday, 11 November, 2015
MySQL Performance: What is odd with 1M QPS claimed by MariaDB 10.1 ?..
This article is continuing the MySQL 5.7 Performance story, started from 1.6M
QPS details post, and followed by 1M
QPS OLTP_RO article. However, the current story will not be mostly
about MySQL 5.7, but also about announced on the same time MariaDB 10.1
GA ;-)
So far, MySQL Team was proud to show 1.6M
QPS on Point-Select (SQL) queries, and MariaDB 10.1 GA announce was
also claiming an
ability to reach 1M QPS, also on Point-Selects, but on POWER8 HW.
And I may be only happy for MariaDB team for their progress on POWER
systems, except just one small detail related to how their 1M QPS result
was obtained..
But first of all, what are these Point-Selects and
what is so special with this workload ?..
- point-select is representing a single SQL query reading a row by its primary key (PK)
- a workload based on such queries is very similar to any generic key-value store solution, but via SQL
- usually a point-select is extremely fast and doing a round-trip from end-to-end in database engine
- so any internals overhead in engine code, any contentions, any scalability limits are seen very quickly..
- historically such kind of workload did not scale very well on MySQL/InnoDB tandem..
- on MySQL Server side there was a huge amount of internal locks around every SQL query execution
- while on the InnoDB side there was a huge general overhead related to transactions management + related locks..
- the first step ahead was made here in MySQL 5.6
- but the real changes came only with MySQL 5.7 ;-)
So, our 1.6M QPS on Point-Selects with MySQL 5.7 we were able to reach under the most heavy conditions :
- each Sysbench "client" thread is executing a single point-select query per iteration
- no transactions clauses used, no grouping..
- single query round-trip is driving the response time latency
- a fair simulation of a key-value store by SQL access
and the Sysbench execution command line is looking then as the following:
LD_PRELOAD=/usr/lib64/libjemalloc.so /BMK/sysbench --num-threads=$1 \ --test=oltp --oltp-table-size=1000000 \ --oltp-dist-type=uniform --oltp-table-name=sbtest_1M_$n \ --max-requests=0 --max-time=$2 --mysql-socket=/SSD_raid0/mysql.sock \ --mysql-user=dim --mysql-password=dim --mysql-db=sysbench \ --mysql-table-engine=INNODB --db-driver=mysql \ --oltp-point-selects=1 --oltp-simple-ranges=0 --oltp-sum-ranges=0 \ --oltp-order-ranges=0 --oltp-distinct-ranges=0 --oltp-skip-trx=on \ --oltp-read-only=on run > /tmp/test_$n.log &
Now, about 1M QPS result published on MariaDB 10.1 :
- if you'll look in details published in their article, instead of --oltp-point-selects=1 the --oltp-point-selects=1000 was used
- and these 1K point-selects then grouped and executed within a single transaction!.. (--oltp-skip-trx=off is used (default))
Adapting these test conditions to my Sysbench command line this will then give the following :
LD_PRELOAD=/usr/lib64/libjemalloc.so /BMK/sysbench --num-threads=$1 \ --test=oltp --oltp-table-size=1000000 \ --oltp-dist-type=uniform --oltp-table-name=sbtest_1M_$n \ --max-requests=0 --max-time=$2 --mysql-socket=/SSD_raid0/mysql.sock \ --mysql-user=dim --mysql-password=dim --mysql-db=sysbench \ --mysql-table-engine=INNODB --db-driver=mysql \ --oltp-point-selects=1000 --oltp-simple-ranges=0 --oltp-sum-ranges=0 \ --oltp-order-ranges=0 --oltp-distinct-ranges=0 --oltp-skip-trx=off \ --oltp-read-only=on run > /tmp/test_$n.log &
How does this change the initial workload test case ?
- in one word : completely ;-)
- by grouping 1000 queries within a single transaction we're lowering a lot the whole related transaction locks..
- and as the result, an overall QPS numbers are growing! ;-)
- but did you see many real cases when a single MySQL session is grouping 1000 SELECT queries within a single transaction ?..
- I may still imagine a need to run several SELECTs within a single transaction to guarantee a read consistency...
- but such kind of queries are usually not short ones, so not really good to show a high QPS ;-)
- but well, even they are really short as point-selects.. -- what kind of application will run them by 1000 in a single shot ?..
- such kind of a "workaround" we proposed yet to our users when started to ship MySQL 5.6, but always mentioned that this is as a workaround, not a final solution (as this could help when you're really have many fast SELECTs and you can really group then within a single transaction without breaking your apps logic).. -- but as soon as potential amount of SELECTs to group is small, the transaction overhead is quickly eating your gain..
- so, the real solution here is - MySQL 5.7 ;-)
Let me show now all this by example, using the test scenario as proposed by MariaDB and just vary the amount of point-selects executed within a single transaction. Let's start with 50 point-selects (which is already too much as to me, but well) :
50 point-selects in transaction :

Observations :
- MySQL 5.7 is still reaching its 1.6M QPS as well
- MariaDB 10.1 is reaching over 1.4M QPS (so, not only on Power while running within a "workaround" test conditions)..
Then the following are the results with 25, 10, and 5 point-selects executed within the same transaction :
25 point-selects in transaction :

10 point-selects in transaction :

5 point-selects in transaction :

Observations :
- as you can see, less queries executed within the same single transaction - lower QPS is reached..
- so, MySQL 5.7 is going from 1.6M QPS to 1.2M QPS
- while MariaDB 10.1 is going from 1.4M QPS to just 600K QPS..
On the last test, with 5 point-selects within a transaction the lower QPS is also impacted by round-trips of BEGIN and COMMIT statements around transaction.. What the result will be if I'll not use transactions?
5 point-selects without transaction :

Observations :
- as you can see, MySQL 5.7 is going back to its 1.6M QPS
- while MariaDB 10.1 is going yet more down to just slightly higher than 400K QPS only..
To get a better understanding of the transaction statements impact let's get a look on the following graph comparing MySQL 5.7 in the last test with 5 point-selects within transaction (left side) -vs- 5 point-selects without transaction (right side) :

Observations :
- as you can see in overall amount of Queries/sec the left side is even higher! (BEGIN and COMMIT are also counted as queries by MySQL stats)
- and as we're wasting CPU cycles to process BEGIN and COMMIT - we're doing less SELECTs as the result..
- while on the right side (without transactions) the whole CPU time is spent for SELECTs, and we're reaching 1.6M QPS then ;-)
Now :
- it's up to you to consider whenever MariaDB 10.1 is really reaching 1M QPS, or 400K QPS only ;-))
- however, what is important for me here after all : you can really reach 1.6M QPS with MySQL 5.7 whatever the test conditions are used here ;-))
Then, to avoid any kind of speculations about new Intel chips as the reason of excellent MySQL 5.7 scalability results, let me just remind you about the results obtained on the old severs (32cores-HT and 40cores-HT), running the old Intel CPUs (similar 4CPU sockets each, but just 8cores-HT and 10cores-HT per CPU socket, both are running at 2300Mhz frequency). The following are the results obtained on the same Sysbench RO Point-Select workload :
- single point-select per iteration, no transactions
- 8 tables of 1M rows are used in the first test
- 1 table of 10M rows is used in the second test
32cores-HT :


40cores-HT :


72cores-HT :


Observations :
- as you can see there is a huge gap between MySQL 5.7 and any other engine on 32, 40 and 72cores-HT HW..
- the gap on 72cores-HT HW is way bigger only because MySQL 5.7 is continuing to scale and reaching a yet more higher result, while all other engines are already reached their limits and cannot go anymore further..
- NOTE : only MySQL 5.7 is showing near the same QPS results on both 8-tables and 1-table workloads
INSTEAD OF SUMMARY :
-
From where is coming such a great scalability gain in MySQL 5.7 ?
- first of all it's a continuous improvement process started yet since MySQL 5.6 with kernel_mutex split + RO transactions on InnoDB side, and many various internal contentions improvements on the MySQL Server side
- then, on MySQL 5.7 InnoDB side : a whole transactions management redesign, improved lock management, redesigned index locking, etc...
- MySQL 5.7 Server side : resolved contentions around MDL, THR_lock, LOCK_grant, LOCK_plugin, and all other "next-level" locks fixes.. -- in fact for today there is no more any known/visible internal contentions in MySQL 5.7 except coming from InnoDB ;-)
- so far, all the credit is to our great MySQL Engineering Team! (all the listed stuff above is related to fundamental changes invented and implemented by our Engineering, taking us months and years of heavy work)..
-
and, of course, huge thanks to MySQL Community for all feedback we
have about ;-)
-
When MariaDB will be able to scale as far as MySQL 5.7 ?
- when it'll move to InnoDB SE from MySQL 5.7
-
and when on its Server side the lock contention in the "lock free"
table definition cache code will be fixed ;-)
-
When Percona Server will scale as far as MySQL 5.7 ?
- since Percona Server will move to the MySQL 5.7 code base
- and XtraDB moves to InnoDB code base from MySQL 5.7
-
not before ;-)
- or both are re:implementing all these changes in their 5.6 / 10.1 code ;-)
- And hope I don't say you here any news, because the same story was already with MySQL 5.6 too, but who cares? ;-))
Well, what to say.. -- #MySQL 5.7 rocks! ;-)
Rgds,
-Dimitri
Friday, 06 November, 2015
Slides from my talk about MySQL Performance @OpenWorld 2015
Slides from my talk during MySQL Central @OpenWorld 2015 are available
from here now :
- http://dimitrik.free.fr/Presentations/MySQL_Perf-Tuning-OOW2015-dim.pdf
they should be soon available from the OpenWorld site as well.
Rgds,
-Dimitri
Thursday, 05 November, 2015
MySQL Performance: 1M QPS on mixed OLTP_RO with MySQL 5.7 GA
This article is following the MySQL 5.7 Performance series started from 1.6M
QPS details post
Let's focus now on the Sysbench "mixed"
OLTP_RO workload (so, not only Point-Selects, but all RO queries as it
was initially designed in OLTP_RO scenario in Sysbench), which is
composed of :
- x10 point-selects
- x1 simple-ranges
- x1 order-ranges
- x1 sum-ranges
- x1 distinct-ranges
Note about test conditions :
- in this and in the previous article we're seeking for MySQL & InnoDB scalability limits ;-)
- so, yes, the client and server are running locally on the same host (we're not testing here network stuff vendors)
- the load is not IO-bound either, very quickly the whole dataset is reaching BP and remains in memory (we're not testing IO vendors here)
- again, all the focus here is on MySQL scalability limits, nothing else..
Note about tested workloads :
- why we're paying so many attention to these "simple" queries from Sysbench ?..
- well, just consider it like the "entry ticket" for any database engine ;-)
- these simple tests in fact are extremely aggressive, and bombarding all engine internals very heavily..
- the point-select, for ex., is extremely fast and crossing on every pass the whole engine stack from entry to end point & back..
- while the distinct-ranges is extremely aggressive on malloc() scalability + in-memory temp tables management..
- etc. etc. etc..
- so, if your production workload is based on much more complex queries, and you're suspecting scalability issues -- rather to stay negative, send us your test workload and share your observations -- we cannot improve everything within a one single shot, right? -- there is still so many things to do yet..
- but I just may say you one thing : without improved scalability on "simple" loads any "complex" load scalability is just impossible.. -- so, stay tuned, we're coming ;-)
Note about the tested HW :
- I was told several times during the MySQL Central conference and other user meeting that 72cores config is waaay toooo big..
- guys, is it really big ?? ;-)
- just think that this is the same 4CPU sockets server as we used before..
- just that today's Intel chip has 18cores per socket -vs- 10cores we saw before, and the CPU chip itself was also greatly improved..
- well, if 4CPU is still toooo biiiig for you, will be 2CPU is "good enough" ?..
- but even with 2CPU you're having 36cores-HT here ;-)
- and this 2CPU 36cores-HT config is already showing a way better QPS than we observed on 4CPU 40cores-HT before !!
- what to do with this then ?? ;-)
- keeping in mind that the next Intel chip will give you 48cores-HT (24cores-HT per CPU socket)..
- so, you want it, or not -- scalability is THE MUST today to give MySQL users a full power of their HW ;-))
Well, a long story short, let's go directly to the test results.
Sysbench OLTP_RO 1M x 8-tables 72cores-HT :

Observations :
- MySQL 5.7 is reaching 1M QPS on OLTP_RO !! (while seems like there is still a room for progress)..
- on the second position is MySQL 5.6, and in max-to-max comparison MySQL 5.7 is doing x2.5 times better than 5.6
- Persona Server 5.6 is taking #3position
- and, surprisingly MariaDB 10.1 here the worse, except MySQL 5.5
- Note that except MySQL 5.7, the difference between MySQL 5.5 result and other engines is not that big..
- this is because QPS gain here is coming for them mostly from "mixed" ranges queries, which was already not that bad in 5.5
- (and if you payed attention to the previous article, you may see that on point-selects MySQL 5.5 is reaching the same max QPS as all other engines, except 5.7)..
- so, yes, the huge gain you're seeing here for MySQL 5.7 is coming due all this heavy remastering started from TRX-list re-design 2 years ago and continued on all levels till 5.7 GA release..
- indeed, this was not easy, but yes, we done it !!! ;-))
What about scalability now?
MySQL 5.7 Scalability @Sysbench OLTP_RO 1M x 8-tables 72cores-HT :

MySQL 5.6 Scalability @Sysbench OLTP_RO 1M x 8-tables 72cores-HT :

MySQL 5.5 Scalability @Sysbench OLTP_RO 1M x 8-tables 72cores-HT :

Percona Server 5.6 Scalability @Sysbench OLTP_RO 1M x 8-tables 72cores-HT :

MariaDB 10.1 Scalability @Sysbench OLTP_RO 1M x 8-tables 72cores-HT :

Observations :
- only MySQL 5.7 is really scaling here up to 72cores-HT
- except MySQL 5.5, all other engines are having better QPS on 32cores-HT -vs- 18cores-HT
- however, this gain is not that big.. - but MySQL 5.6 is doing better than others
- MariaDB 10.1 is the worse again, just better than the oldest MySQL 5.5..
Now the same workload, but using only a single 10M rows table.
Sysbench OLTP_RO 10M x 1-table 72cores-HT :

Observations :
- MySQL 5.7 is the best again, but not yet reaching 1M QPS, a room for improvement ;-)
- MySQL 5.6 and Percona Server 5.6 on the #2 position
- and MariaDB 10.1 closing the group, just before MySQL 5.5
And scalability?
MySQL 5.7 Scalability @Sysbench OLTP_RO 10M x 1-table 72cores-HT :

MySQL 5.6 Scalability @Sysbench OLTP_RO 10M x 1-table 72cores-HT :

MySQL 5.5 Scalability @Sysbench OLTP_RO 10M x 1-table 72cores-HT :

Percona Server 5.6 Scalability @Sysbench OLTP_RO 10M x 1-table 72cores-HT :

MariaDB 10.1 Scalability @Sysbench OLTP_RO 10M x 1-table 72cores-HT :

Observations :
- the result is very similar to 8-tables results, except that Percona Server 5.6 is very close with MySQL 5.6 here
- while MySQL 5.7 is just the best ;-)
And, similar to the previous article, here are the results reflecting the evolution of tested HW and CPU power :
MySQL 5.7 Scalability @Sysbench OLTP_RO 1M x 8-tables :

MySQL 5.7 Scalability @Sysbench OLTP_RO 10M x 1-table :

Indeed, the difference is very impressive ;-)
Over last 2 weeks in all discussions I've got many times the same question : do we really need to upgrade our HW to get the best from MySQL Performance ?...
Let me show you then just few following graphs :
here is HW evolution related to MySQL 5.5 on OLTP_RO the presented workload :

Observations :
- as you can see, 5.5 was the best on 12cores-HT config on the old HW
- it was not able to show anything better on 32 or 40cores-HT configuration..
- however, moved to the newer CPU chip, even MySQL 5.5 is going x2 times faster here! ;-)
- and as you can see from the 5.5 scalability graphs, 1CPU socket is just enough here..
- and, unfortunately, 1CPU will be also your limit for MySQL 5.5 Performance ;-)
now the same for MySQL 5.6 :

Observations :
- MySQL 5.6 is scaling better, and already able to show over 50% better performance on an old, but bigger HW
- but on the newer CPU it's doing yet x2 times better (even without scaling well)..
And, of course, once you'll move to MySQL 5.7, you'll be able to go yet more far on these new 2CPU or 4CPU sockets :

Observations :
- no comments ;-))
And to finish, few more details about the test conditions :
my.conf -- used exactly the same config settings as in the previous article.
The Sysbench command used to run OLTP_RO test via IP port (starting 8 processes in parallel):
$ LD_PRELOAD=/usr/lib64/libjemalloc.so /BMK/sysbench --num-threads=$1 \ --test=oltp --oltp-table-size=1000000 \ --oltp-dist-type=uniform --oltp-table-name=sbtest_1M_$n \ --max-requests=0 --max-time=$2 --mysql-host=127.0.0.1 --mysql-port=5700 \ --mysql-user=dim --mysql-password=dim --mysql-db=sysbench \ --mysql-table-engine=INNODB --db-driver=mysql --oltp-skip-trx=on \ --oltp-read-only=on run > /tmp/test_$n.log &
Should I say once more again MySQL 5.7 rocks !!! ;-))
Rgds,
-Dimitri