Pull to refresh

Галопом по европам: изменения в MySQL 5.4

MySQL *
Так получилось, что я довольно давно не работал с MySQL, поскольку в Рамблере используется, в основном, PostgreSQL. Сейчас у меня, наконец, появилось свободное время, и я решил догнать упущенное. Как выяснилось, за последние полтора года в мире MySQL изменилось довольно многое.


MySQL AB была куплена Sun, которую вскоре саму купил и поглотил Oracle. Многие разработчики успели покинуть проект, а кое-кто успел начать собственные форки.

Кроме старых знакомых — MyISAM и InnoDB (а также Merge, Heap, Archive, и прочих), появились новые storage engine-ы: Falcon и Maria. Судя по всему, Falcon пока не годится для production-использования, так как ветка 6.0 находится в стадии ранней альфы, но, со временем, возможно, превзойдёт InnoDB по возможностям и удобству использования. А вот необходимость существования Maria, персонально для меня, пока не очевидна.

Судя по всему, нынешние разработчики MySQL решили, что не потянут одновременное развитие двух веток — информацию по 6.0 на dev.mysql.org найти довольно непросто. Последняя из доступных на сайте community-версий носит номер 5.4.2 и имеет статус беты, хотя в документации упоминается версия 5.4.5.

В своё время, мне пришлось немного поработать с 5.1, поэтому я решил начать со списка изменений 5.1->5.4, который оказался не таким уж и длинным. Полностью его можно посмотреть на сайте MySQL, а здесь я приведу несколько пунктов, которые мне показались значимыми.

— MySQL стал лучше масштабироваться на многоядерных CPU — улучшена работа с блокировками и управление памятью ( dev.mysql.com/doc/refman/5.4/en/smp-improvements.html ).
— InnoDB более эффективно использует возможности подсистемы ввода-вывода ( dev.mysql.com/doc/refman/5.4/en/innodb-io-changes.html ).
— Добавлены новые возможности для диагностики и поиска «узких мест», большая часть функциональности — те самые «патчи от Гугла» ( dev.mysql.com/doc/refman/5.4/en/monitoring-improvements.html ), которые, наконец, внедрены в основную ветку.
— MySQL, наконец-то, поставляется с более-менее вменяемыми файлами настроек, вместо старых примеров, расчитанных едва ли не на 386 компьютеры. :)
— Улучшения в оптимизаторе запросов, которые должны привести к более быстрому выполнению подзапросов и JOIN-ов на InnoDB и MyISAM.
— Поддержка «полусинхронной» репликации. Сие означает, что мастер должен дождаться, пока хотя бы с одного из слейвов придёт подтверждение о получении транзакции, прежде, чем считать её завершённой. По-умолчанию, MySQL использует асинхронную репликацию, то есть, мастера не волнует, в каком состоянии находятся слейвы ( dev.mysql.com/doc/refman/5.4/en/replication-semisync.html ). Однако, теперь можно включить и альтернативный режим — это даст большую сохранность данных при репликации, ценой некоторой потери в производительности.

Кстати, ещё одно важное изменение — InnoDB-plugin теперь перекочевал на место старого «умолчального» InnoDB, то есть, по-отдельности его подключать больше нет необходимости.

Чтобы убедиться, что обещанное увеличение производительности действительно имеет место, я попробовал протестировать две версии MySQL: 5.1.37 (сборка от Fedora) и MySQL 5.4.2 (сборка от MySQL AB) при помощи MySQL-benchmark.

Тестовая машина — двухъядерный Core2 с 4 гб RAM, работающий под управлением Fedora 11, x86_64. Тестируемые версии были также собраны под x86_64. Жёсткий диск — SATA, hdparm -t /dev/sda выдал линейную скорость чтения порядка 78 MB/sec

В тесте использовался следующий конфиг (некоторые незначимые фрагменты опущены):

[mysqld]
skip-locking
key_buffer_size = 256M
max_allowed_packet = 1M
table_open_cache = 256
sort_buffer_size = 1M
read_buffer_size = 1M
read_rnd_buffer_size = 4M
myisam_sort_buffer_size = 64M
thread_cache_size = 8
query_cache_size= 16M
thread_concurrency = 4
default-storage-engine=InnoDB
skip-networking

innodb_data_home_dir = /var/lib/mysql/
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = /var/lib/mysql/
innodb_buffer_pool_size = 1024M
innodb_additional_mem_pool_size = 256M
innodb_log_file_size = 256M
innodb_log_buffer_size = 16M
innodb_flush_log_at_trx_commit = 2
innodb_lock_wait_timeout = 50


Судя по всему, MySQL 5.4.2 собранный MySQL (с dev.mysql.com) не поддерживает использование атомарных операций CPU, так что влияние этого фактора на увеличение производительности пока непонятно. Тем не менее, увеличение производительности при работе с БД действительно есть.

Для того, чтобы уменьшить влияние autoextend, каждый тест запускался по два раза. Результаты повторных запусков практически не отличались. Строка запуска для теста:
./run-all-tests --server=MySQL --log --cmp=mysql --random --verbose

К сожалению, бенчмарк от MySQL с опцией --server=MySQL, считает, что сервер не поддерживает транзакции (не смотря на default-storage-engine=InnoDB). Полные результаты тестов я приводить здесь не хочу, поскольку их довольно много. Но, вкратце, результаты следующие.

5.1.37 — общее время выполнения: 981 секунда.
5.4.2 — общее время выполнения: 955 секунд.

5.4.2 выигрывает в следующих тестах (указано время в секундах):
Название теста 5.1 5.4
update_of_key_big (501) 25.00 11.00
create_key+drop (10000) 77.00 70.00
delete_all_many_keys (1) 16.00 14.00
delete_big_many_keys (128) 16.00 14.00
drop_table_when_MANY_tables (10000) 20.00 16.00
insert (350768) 39.00 35.00
select_key2_return_key (200000) 41.00 38.00
select_key2_return_prim (200000) 42.00 40.00
update_big (10) 24.00 20.00
update_of_key (50000) 8.00 7.00
update_of_key_big (501) 25.00 11.00


К сожалению, покамест есть несколько тестов, в которых 5.4 сливает более старой версии.
Название теста 5.1 5.4
create+drop (10000) 39.00 40.00
create_MANY_tables (10000) 22.00 30.00
insert_key (100000) 32.00 42.00
select_cache2 (10000) 41.00 44.00
update_of_primary_key_many_keys (256) 43.00 46.00
update_with_key_prefix (100000) 13.00 14.00
wisc_benchmark (114) 1.00 2.00


Напоследок, приношу извинения тем, кто увидел незаконченную версию этого текста. Дело в том, что из редактора почему-то пропала очень удобная галка «показать статью только друзьям». Чтобы показать статью только друзьям, я просто опубликовал текст в своём блоге, надеясь, что его никто не увидит, кроме тех, кого я попрошу посмотреть. Как оказалось, это не сработало. :)

UPD: Заодно, оценил влияние гуглового tcmalloc на работу MySQL. Есть довольно заметный выигрыш, который достигается простой установкой google-perftools и установкой переменной LD_PRELOAD.
Tags:
Hubs:
Total votes 67: ↑60 and ↓7 +53
Views 2.3K
Comments Comments 24