Статьи

MySQL и Percona Server в тесте LinkBench

Это сообщение от  Алексея Строганова из MySQL Performance Blog.

Около месяца назад Facebook объявил о тестировании Linkbench, которое моделирует рабочую нагрузку социального графа OLTP. Источники, а также очень хорошее описание того, как установить и запустить этот тест, можно найти здесь . Мы решили запустить этот тест для MySQL Server 5.5.30, 5.6.11 и Percona Server 5.5.30 и проверить, как эти серверы будут обрабатывать такие рабочие нагрузки OLTP в случаях ЦП и IO. Для этого теста мы использовали коробку PowerEdge R720 с быстрой флеш-картой PCI-e в качестве хранилища.

По умолчанию набор данных linkbench имеет 10M идентификаторов (после загрузки данных размер каталога данных ~ 10 ГБ). Мы использовали этот набор данных для проверки поведения сервера, когда данные полностью соответствуют пулу буферов (размер пула буферов составляет 30 ГБ). Так что в основном это процесс, связанный с процессором.

linkbench.1x.v3

Как вы можете видеть, существует очень небольшая разница между серверами в 64 потоках, но гораздо более заметное снижение для 5.6.11 в 128 потоках.

Затем мы загрузили набор данных 10x — 100M идентификаторов (размер dadadir ~ 100GB), размер пула буферов такой же — 30GB. Итак, теперь мы исследуем IO-связанный сценарий.

linkbench.10x.v3

Percona Server 5.5 превосходит MySQL примерно в 2 раза .
И MySQL 5.5.30, и MySQL 5.6.11 демонстрируют заметное снижение производительности. Что может быть причиной этого?
Ниже представлена ​​диаграмма с верхними мьютексами для каждого сервера в 64 потоках:

linkbench.10x.mutexes

Для MySQL 5.5.30 верхний мьютекс — это & ​​doublewrite-> mutex: trx0sys.c: 196. И, скорее всего, этот симптом связан с ошибкой № 67808 .

Для MySQL 5.6.11 верхними мьютексами являются & buf_pool-> mutex и & new_index-> ​​lock. Я профилировал 5.6.11 в этом сценарии, связанном с IO, с помощью perf — смотрите профиль ниже:

# Overhead  Samples    Command        Shared Object
# ........ ..........  .......  ...................  ..................................................................................................................................
#
    35.85%   17738833   mysqld  mysqld               [.] buf_LRU_free_block(buf_page_t*, unsigned long)
             |
             --- buf_LRU_free_block(buf_page_t*, unsigned long)
                |
                |--99.94%-- buf_LRU_scan_and_free_block(buf_pool_t*, unsigned long)
                |          buf_LRU_get_free_block(buf_pool_t*)
                |          |
                |          |--94.84%-- buf_page_init_for_read(dberr_t*, unsigned long, unsigned long, unsigned long, unsigned long, long, unsigned long)
...
    31.41%   15534570   mysqld  mysqld               [.] rw_lock_x_lock_func(rw_lock_t*, unsigned long, char const*, unsigned long)
             |
             --- rw_lock_x_lock_func(rw_lock_t*, unsigned long, char const*, unsigned long)
                |
                |--99.14%-- buf_LRU_free_block(buf_page_t*, unsigned long)
                |          |
                |          |--100.00%-- buf_LRU_scan_and_free_block(buf_pool_t*, unsigned long)
                |          |          buf_LRU_get_free_block(buf_pool_t*)
     2.53%    1338484   mysqld  mysqld               [.] ut_delay(unsigned long)

So basically most of the time 5.6.11 spent in LRU_scan. I tried to increase innodb_lru_scan_depth variable to 8k,16k,32k but that had no notably impact on result. In the best possible combination I got ~15k operations per second for MySQL 5.6.11.

Conclusion:

In CPU-bounds case MySQL performs quite well, though we can see small performance drop in MySQL 5.6.
In IO-bound cases MySQL still has performance issues around mutexes and Percona Server shows much better results

Configurations and how to run benchmark:

[mysqld]
user=root
port=3306

innodb_buffer_pool_size = 30G
innodb_flush_method = O_DIRECT
innodb_log_file_size = 2000M
innodb_log_files_in_group = 2
innodb_flush_log_at_trx_commit = 1
innodb_log_buffer_size=128M
innodb_max_dirty_pages_pct=80
innodb_file_format=barracuda
innodb_file_per_table
innodb_read_io_threads = 8
innodb_write_io_threads = 8
innodb_io_capacity = 5000

sync_binlog=0
max_connections=5000
table_open_cache=5000
table-definition-cache=1000
query_cache_size=0
query_cache_type=0
performance_schema=0

#56only
loose-innodb_flush_neighbors=0
loose-metadata_locks_hash_instances=256
innodb_buffer_pool_instances=16 # MySQL 5.5 and 5.6
loose-innodb_io_capacity_max = 15000

#Percona only
innodb_adaptive_hash_index_partitions=8
innodb_buffer_pool_instances=1
innodb_adaptive_flushing_method=keep_average
innodb_flush_neighbor_pages=none

command line to load 10x dataset:
./bin/linkbench -D dbid=linkdb -D host=127.0.0.1 -D user=root -D port=3306 -D password= -D maxid1=100000001 -c config/MyConfig.properties -l
command line to run test for 10x dataset:
./bin/linkbench  -D requesters=64 -D dbid=linkdb -D host=127.0.0.1 -D user=root -D port=3306 -D password= -D maxid1=100000001 -c config/MyConfig.properties -csvstats final-stats.csv -csvstream streaming-stats.csv -D requests=5000000 -D maxtime=1800 -r