This is a continuation post on InnoDB plugin row format performance with few more test scenarios to cover based on the feedback and questions that I got in my Inbox.
This time the initial table looks like this
1 2 3 4 5 6 7 8 9 |
<span class="kwrd">CREATE</span> <span class="kwrd">TABLE</span> `sbtest` ( `id` <span class="kwrd">int</span>(10) unsigned <span class="kwrd">NOT</span> <span class="kwrd">NULL</span>, `k` <span class="kwrd">int</span>(10) unsigned <span class="kwrd">NOT</span> <span class="kwrd">NULL</span> <span class="kwrd">DEFAULT</span> <span class="str">'0'</span>, `c` <span class="kwrd">char</span>(120) <span class="kwrd">NOT</span> <span class="kwrd">NULL</span> <span class="kwrd">DEFAULT</span> <span class="str">''</span>, `<span class="kwrd">pad</span>` <span class="kwrd">char</span>(60) <span class="kwrd">NOT</span> <span class="kwrd">NULL</span> <span class="kwrd">DEFAULT</span> <span class="str">''</span>, <span class="kwrd">PRIMARY</span> <span class="kwrd">KEY</span> (`id`), ) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; |
This time, the table does not have a secondary index in the create time, instead it will be added after the table is populated with the data to test the performance of the new faster index support from the plugin. I also added a new scenario to test 2K compression as we noticed 4K compression seems to be a bottleneck in the earlier case.
Same test environment is chosen as of the first one, RHEL-4 64-Bit having MySQL-5.1.24 with InnoDB plugin 1.0 statically linked.
InnoDB configuration variables:
1 2 3 |
<span style="color: #606060"> 1:</span> mysql> show variables <span style="color: #0000ff">like</span> <span style="color: #006080">'%innodb%'</span>; |
1 2 3 |
<span style="color: #606060"> 2:</span> +---------------------------------+--------------------------+ |
1 2 3 |
<span style="color: #606060"> 3:</span> | Variable_name | <span style="color: #0000ff">Value</span> | |
1 2 3 |
<span style="color: #606060"> 4:</span> +---------------------------------+--------------------------+ |
1 2 3 |
<span style="color: #606060"> 5:</span> | have_innodb | YES | |
1 2 3 |
<span style="color: #606060"> 6:</span> | innodb_adaptive_hash_index | <span style="color: #0000ff">ON</span> | |
1 2 3 |
<span style="color: #606060"> 7:</span> | innodb_additional_mem_pool_size | 104857600 | |
1 2 3 |
<span style="color: #606060"> 8:</span> | innodb_autoextend_increment | 8 | |
1 2 3 |
<span style="color: #606060"> 9:</span> | innodb_autoinc_lock_mode | 1 | |
1 2 3 |
<span style="color: #606060"> 10:</span> | innodb_buffer_pool_size | 6442450944 | |
1 2 3 |
<span style="color: #606060"> 11:</span> | innodb_checksums | <span style="color: #0000ff">ON</span> | |
1 2 3 |
<span style="color: #606060"> 12:</span> | innodb_commit_concurrency | 0 | |
1 2 3 |
<span style="color: #606060"> 13:</span> | innodb_concurrency_tickets | 500 | |
1 2 3 |
<span style="color: #606060"> 14:</span> | innodb_data_file_path | ibdata1:256M:autoextend | |
1 2 3 |
<span style="color: #606060"> 15:</span> | innodb_data_home_dir | /mysql/ibdata | |
1 2 3 |
<span style="color: #606060"> 16:</span> | innodb_doublewrite | <span style="color: #0000ff">ON</span> | |
1 2 3 |
<span style="color: #606060"> 17:</span> | innodb_fast_shutdown | 1 | |
1 2 3 |
<span style="color: #606060"> 18:</span> | innodb_file_format | Barracuda | |
1 2 3 |
<span style="color: #606060"> 19:</span> | innodb_file_io_threads | 4 | |
1 2 3 |
<span style="color: #606060"> 20:</span> | innodb_file_per_table | <span style="color: #0000ff">ON</span> | |
1 2 3 |
<span style="color: #606060"> 21:</span> | innodb_flush_log_at_trx_commit | 1 | |
1 2 3 |
<span style="color: #606060"> 22:</span> | innodb_flush_method | O_DIRECT | |
1 2 3 |
<span style="color: #606060"> 23:</span> | innodb_force_recovery | 0 | |
1 2 3 |
<span style="color: #606060"> 24:</span> | innodb_lock_wait_timeout | 50 | |
1 2 3 |
<span style="color: #606060"> 25:</span> | innodb_locks_unsafe_for_binlog | <span style="color: #0000ff">OFF</span> | |
1 2 3 |
<span style="color: #606060"> 26:</span> | innodb_log_buffer_size | 8388608 | |
1 2 3 |
<span style="color: #606060"> 27:</span> | innodb_log_file_size | 268435456 | |
1 2 3 |
<span style="color: #606060"> 28:</span> | innodb_log_files_in_group | 2 | |
1 2 3 |
<span style="color: #606060"> 29:</span> | innodb_log_group_home_dir | /mysql/iblog | |
1 2 3 |
<span style="color: #606060"> 30:</span> | innodb_max_dirty_pages_pct | 90 | |
1 2 3 |
<span style="color: #606060"> 31:</span> | innodb_max_purge_lag | 0 | |
1 2 3 |
<span style="color: #606060"> 32:</span> | innodb_mirrored_log_groups | 1 | |
1 2 3 |
<span style="color: #606060"> 33:</span> | innodb_open_files | 300 | |
1 2 3 |
<span style="color: #606060"> 34:</span> | innodb_replication_delay | 0 | |
1 2 3 |
<span style="color: #606060"> 35:</span> | innodb_rollback_on_timeout | <span style="color: #0000ff">OFF</span> | |
1 2 3 |
<span style="color: #606060"> 36:</span> | innodb_strict_mode | <span style="color: #0000ff">OFF</span> | |
1 2 3 |
<span style="color: #606060"> 37:</span> | innodb_support_xa | <span style="color: #0000ff">ON</span> | |
1 2 3 |
<span style="color: #606060"> 38:</span> | innodb_sync_spin_loops | 20 | |
1 2 3 |
<span style="color: #606060"> 39:</span> | innodb_table_locks | <span style="color: #0000ff">ON</span> | |
1 2 3 |
<span style="color: #606060"> 40:</span> | innodb_thread_concurrency | 32 | |
1 2 3 |
<span style="color: #606060"> 41:</span> | innodb_thread_sleep_delay | 10000 | |
1 2 3 |
<span style="color: #606060"> 42:</span> +---------------------------------+--------------------------+ |
1 2 3 |
<span style="color: #606060"> 43:</span> 37 <span style="color: #0000ff">rows</span> <span style="color: #0000ff">in</span> <span style="color: #0000ff">set</span> (0.00 sec) |
Normally I disable the following InnoDB configuration options when running any benchmark tests; but this time enabled all of them (including in the first case)…
1 2 3 4 5 |
innodb_checksums innodb_doublewrite innodb_support_xa |
Table Load:
Load time from a dump of SQL script having 10M rows (not batched)
Compact | Compressed (8K) | Compressed (4K) | Compressed (2K) | Dynamic | |
6G buffer pool | 27m 34s | 28m 25s | 29m 37s | 32m 49s | 27m 23s |
Secondary Index Creation:
Secondary Index create time after the table has been populated. The index added using
1 2 3 |
<span style="color: #0000ff">CREATE</span> <span style="color: #0000ff">INDEX</span> k <span style="color: #0000ff">ON</span> sbtest(k) |
Compact | Compressed (8K) | Compressed (4K) | Compressed (2K) | Dynamic | |
6G buffer pool | 0m 51s | 1m 23s | 7m 0s | 7m 42s | 0m 51s |
File Sizes:
Here is the size of the .ibd file after each data load
Compact | Compressed (8K) | Compressed (4K) | Compressed (2K) | Dynamic | |
Before Secondary Index | 2.2G | 1.1G | 552M | 284M | 2.2G |
After Secondary Index | 2.3G | 1.2G | 592M | 324M | 2.3G |
Testing:
I used the sysbench to run the tests by varying the threads to run mixed read/write on a pre-populated table by creating the table with different ROW_FORMATS along with KEY_BLOCK_SIZE. The server is taken down by cleaning its logs and data directories completely and a fresh server is started back to re-run a different row-format .
Here is the sysbench options:
1 2 3 4 5 6 7 8 |
--test=oltp --db-driver=mysql --oltp-<span style="color: #0000ff">table</span>-<span style="color: #0000ff">size</span>=10000000 --oltp-skip-trx=<span style="color: #0000ff">on</span> --oltp-auto-inc=<span style="color: #0000ff">off</span> --mysql-<span style="color: #0000ff">table</span>-engine=innodb --mysql-<span style="color: #0000ff">user</span>=root --mysql-<span style="color: #0000ff">ignore</span>-duplicates=<span style="color: #0000ff">on</span> --<span style="color: #0000ff">max</span>-requests=100000 --init-rng=<span style="color: #0000ff">on</span> --oltp-test-mode=complex --oltp-dist-type=uniform --mysql-engine-trx=yes --oltp-<span style="color: #0000ff">read</span>-<span style="color: #0000ff">only</span>=<span style="color: #0000ff">off</span> --num-threads=XXX run |
Some variables are non-relevant to test, but I use the same scripts to run lot of other cases, –mysql-ignore-duplicates is not a standard sysbench option, its a patch that I created to make sure the test does not bail on duplicate key errors due to poor random number generator.
The test typically executes 950000 queries in each iteration (700K read queries and 250K write queries) with max of 50000 transactions in this test and 100K transactions in the part-I case. Here is the typical output from sysbench:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
LTP test <span style="color: #0000ff">statistics</span>: queries performed: <span style="color: #0000ff">read</span>: 700000 <span style="color: #0000ff">write</span>: 250000 other: 0 total: 950000 transactions: 50000 (206.00 per sec.) deadlocks: 0 (0.00 per sec.) <span style="color: #0000ff">read</span>/<span style="color: #0000ff">write</span> requests: 950000 (3914.01 per sec.) other operations: 0 (0.00 per sec.) Test execution summary: total <span style="color: #0000ff">time</span>: 242.7179s total number <span style="color: #0000ff">of</span> events: 50000 total <span style="color: #0000ff">time</span> taken <span style="color: #0000ff">by</span> event execution: 123984.2189 per-request <span style="color: #0000ff">statistics</span>: <span style="color: #0000ff">min</span>: 0.2133s <span style="color: #0000ff">avg</span>: 2.4797s <span style="color: #0000ff">max</span>: 15.6503s approx. 95 percentile: 4.0491s |
Performance:
Here is the performance of various row formats with threads ranging from 1 to 512 for 6G buffer pool size for both concurrent reads and writes.
Observations:
- The load time is almost same for both Compact and Dynamic row formats. In this table and data scenario, both perform same amount of transactions (as you can see from the graph, they overlap)
- The load/insert time increases based on the compression ratio from 8K, 4K, 2K, 1K etc
- When the whole data set can fit in memory; then compression will relatively slowdown the transaction rate
- When the whole data set can not fit in memory, then compression on the table seems to be a right choice (8K in this case)
- Creation of secondary index still takes lot of time when the compression is enabled. The 8K compression is much better and bit close to Compact/Dynamic; but 4K/2K seems to take ~6 times more time than 8K
- The best compression in terms of performance is 8K; but it may vary based on the table structure and data and its distribution.
- Part-I observations can be found from here
Looks like there is something wrong in terms of performance of 4K/2K compression when compared with 8K when the data set can fit everything in memory (as we have 6G buffer pool). I will dig further and see if we can find a solution for the actual problem or file a bug report..more later.
Convert from one row format to another:
Alter table seems to be a right choice to change from one row format to another one or to change the compression ratio and it is efficient. For example, here is a case where the table is converted from compressed to compact and compact to Compressed and InnoDB re-creates both .frm and .ibd by using temp files. Even here you can see that 4K takes much longer time than expected.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
mysql> <span style="color: #0000ff">alter</span> <span style="color: #0000ff">table</span> sbtest ROW_FORMAT=Compact; Query OK, 10000000 <span style="color: #0000ff">rows</span> affected, 1 warning (2 <span style="color: #0000ff">min</span> 56.48 sec) Records: 10000000 Duplicates: 0 Warnings: 0 mysql> <span style="color: #0000ff">alter</span> <span style="color: #0000ff">table</span> sbtest ROW_FORMAT=Compressed KEY_BLOCK_SIZE=8; Query OK, 10000000 <span style="color: #0000ff">rows</span> affected (4 <span style="color: #0000ff">min</span> 11.56 sec) Records: 10000000 Duplicates: 0 Warnings: 0 mysql> <span style="color: #0000ff">alter</span> <span style="color: #0000ff">table</span> sbtest ROW_FORMAT=Compressed KEY_BLOCK_SIZE=4; Query OK, 10000000 <span style="color: #0000ff">rows</span> affected (20 <span style="color: #0000ff">min</span> 6.36 sec) Records: 10000000 Duplicates: 0 Warnings: 0 mysql> <span style="color: #0000ff">alter</span> <span style="color: #0000ff">table</span> sbtest ROW_FORMAT=Compact; Query OK, 10000000 <span style="color: #0000ff">rows</span> affected, 1 warning (2 <span style="color: #0000ff">min</span> 56.61 sec) Records: 10000000 Duplicates: 0 Warnings: 0 mysql> show warnings; +---------+------+-----------------------------------------------------------------+ | <span style="color: #0000ff">Level</span> | Code | Message | +---------+------+-----------------------------------------------------------------+ | Warning | 1478 | InnoDB: ignoring KEY_BLOCK_SIZE=4 unless ROW_FORMAT=COMPRESSED. | +---------+------+-----------------------------------------------------------------+ 1 <span style="color: #0000ff">row</span> <span style="color: #0000ff">in</span> <span style="color: #0000ff">set</span> (0.00 sec) mysql> <span style="color: #0000ff">alter</span> <span style="color: #0000ff">table</span> sbtest ROW_FORMAT=<span style="color: #0000ff">Dynamic</span>; Query OK, 10000000 <span style="color: #0000ff">rows</span> affected, 1 warning (2 <span style="color: #0000ff">min</span> 42.12 sec) Records: 10000000 Duplicates: 0 Warnings: 0 mysql> show warnings; +---------+------+-----------------------------------------------------------------+ | <span style="color: #0000ff">Level</span> | Code | Message | +---------+------+-----------------------------------------------------------------+ | Warning | 1478 | InnoDB: ignoring KEY_BLOCK_SIZE=4 unless ROW_FORMAT=COMPRESSED. | +---------+------+-----------------------------------------------------------------+ 1 <span style="color: #0000ff">row</span> <span style="color: #0000ff">in</span> <span style="color: #0000ff">set</span> (0.00 sec) mysql> <span style="color: #0000ff">alter</span> <span style="color: #0000ff">table</span> sbtest ROW_FORMAT=Compressed KEY_BLOCK_SIZE=2; Query OK, 10000000 <span style="color: #0000ff">rows</span> affected (20 <span style="color: #0000ff">min</span> 53.76 sec) Records: 10000000 Duplicates: 0 Warnings: 0 |
Nice to have:
It will be nice if InnoDB team can extend the SHOW TABLE STATUS to show the compression details. Right now the Information schema.cmp will only lists general compression statistics but not on per table basis.
Also, it will be added advantage if they can support the following two config variables:
innodb_default_row_format (default compact or dynamic) and innodb_default_key_block_size (optionally, and make sure it does not raise a warning on default row_format)
Great stuff, Venu! Thanks!
Thanks Ken. It will be nice if you guys could support two new InnoDB config variables..
innodb_default_row_format and optionally innodb_default_key_block_size
and making innodb_default_row_format=compact by default.
Thank you Venu … we will consider these requests for a future release. The best place for these suggestions is the Suggestion Box on the InnoDB Forums. I’ll copy your suggestions there for you! 😉
No further significant changes are planned in the InnoDB Plugin for now. We’re pretty happy with its stability (as your results seem to show), and we’re working on a couple of bugs and compatibility with MySQL releases.
Thank you for your excellent work!
Ken
Venu Anuganti Blog » InnoDB plugin row format performance – II http://bit.ly/igp7TI