Проблемы эффективного использования mysql на...
DESCRIPTION
Доклад Алексея Копытова на HighLoad++ 2014.TRANSCRIPT
Кто я? Где я?
Алексей Копытов <[email protected]>I Percona ServerI Percona XtraBackup (руководитель проекта)I Percona XtraDB Cluster
Немного историиMySQL
I разработка началась в 1995г.I некоторый код был написан в 1979г.I изначально
разработка велась на Solaris/Sparc
InnoDBI разработка началась в 1995г.I включена в MySQL в 2000г.I изначально
разработка велась на Windows NT
Cтарые проекты по меркам IT
Критические участки кода писали под совсем другое“железо”:
/*************************************************************//**Runs an idle loop on CPU. The argument gives the desireddelay in microseconds on 100 MHz Pentium + Visual C++. */.../* Semaphore operations in operating systems are slow:Solaris on a 1993 Sparc takes 3 microseconds (us) for alock-unlock pair and Windows NT on a 1995 Pentium takes 20microseconds for a lock-unlock pair. */
Проблемы с современным «железом»:
I память (большие объёмы, NUMA встречается всё чаще)I процессоры: «больше лошадиных сил», но используются неэффективноI SSD часто требуют иного подхода для чтения/записи данныхI блокировки в сервере неадекватны высоким нагрузкам
jemallocI масштабируемая реализация malloc()http://www.canonware.com/jemalloc/
I целевая нагрузка: Nthreads > NcoresI используется по умолчанию в Firefox, FreeBSD, NetBSDI обязательное требование для TokuDB
jemalloc
I свежие версии в репозиториях PerconaI опция malloc-lib в my.cnf:
[mysqld_save]malloc-lib=/usr/lib/mysql/libjemalloc.so
Buffer pool
Buffer pool: контрольные суммы
I проблема при больших IOPS (SSD)
Buffer pool: контрольные суммы
Как обнаружить?
I buf_calc_page_new_checksum в PMP, OProfile, perfI Performance Schema — никак
Что делать?I innodb_fast_checksum=1 в Percona Server 5.1/5.5I innodb_checksum_algorithm=crc32 в Percona Server и MySQL 5.6
Buffer pool: контрольные суммы
innodb_checksum_algorithm=crc32
I выключено по умолчаниюI не strict_crc32!I использует аппаратное ускорение (если доступно)I работает только для обновлённых страниц!I почему-то оставили медленный алгоритм для redo log
Buffer pool: NUMA
Uniform Memory Access vs Non-Uniform Memory Access:
Buffer pool: NUMA
I всегда есть обращения к "чужой" памяти
Buffer pool: NUMAI память выделяется на текущей ноде по умолчанию
Buffer pool: NUMAI чередование (interleaving) памяти:
# numactl --interleave all mysqld ...
I interleaving на уровне BIOS – плохо!
Buffer pool: NUMAI файловый кэш тоже мешает:
I решение:
# sysctl -q -w vm.drop_caches=3
Buffer pool: NUMA
Linux memory overcommit:I память выделяется только в момент доступаI при старте mysqld нужно сделать memset() пока файловый кэш пустой
Buffer pool: NUMA
Как обнаружить?
I «А-а-а, тормозит всё!»I большой разброс в результатахI swapping при свободной памяти
Buffer pool: NUMA
Патчи от Twitter в Percona Server 5.5 / 5.6:
I опции mysqld_safe:
[mysqld_save]numa_interleave=1flush_caches=1
I опции сервера:
[server]innodb_buffer_pool_populate=1
Buffer pool: проблемы с DROP/TRUNCATE TABLE
innodb_file_per_table=1 + большой buffer pool
удаление старых страниц из buffer pool:
Buffer pool: проблемы с DROP/TRUNCATE TABLEbug #51325 “Dropping an empty innodb table takes a long time withlarge buffer pool”
I innodb_lazy_drop_table=1 в Percona Server 5.1/5.5I позже исправлен в MySQL 5.1/5.5/5.6I O(n), но buffer pool мьютекс периодически отпускают
bug #61188 “DROP TABLE extremely slow”
I та же проблема, но для компрессированных таблицI исправлено в MySQL 5.1/5.5/5.6
TRUNCATE TABLEI будет исправлено только в MySQL 5.7
Buffer pool: глобальный мьютекс
Buffer pool: глобальный мьютекс
Решение в MySQL 5.5:innodb_buffer_pool_instances= N
Buffer pool: глобальный мьютекс
Решение в MySQL:
проблемы:
I неравномерное использование (нет балансировки)I решает проблему лишь частичноI иногда даже ухудшает производительность (Bug #67808)
Buffer pool: глобальный мьютекс
Решение в Percona Server
I комбинируется с innodb_buffer_pool_instances
Buffer pool: глобальный мьютекс
Решение в Percona ServerI реализовано ещё для 5.1I всё ещё актуально для 5.6
MVCC: kernel_mutex и trx_sys->mutex
read views:
MVCC: kernel_mutex и trx_sys->mutex
read views:
MVCC: kernel_mutex и trx_sys->mutex
создание read view:
MVCC: kernel_mutex и trx_sys->mutex
read-only транзакции в MySQL 5.6:
I SELECT + AUTO_COMMIT=1 или START TRANSACTION READ ONLYI read-only транзакции не добавляются в trx_listI нет проблемы, если trx_list пустой (т.е. если нет других транзакций!)
будет в MySQL 5.7:
I + автоопределение для не AUTO_COMMIT транзакций
MVCC: trx descriptors
I в Percona Server 5.5 / 5.6:
I в MySQL 5.7 будет то же самое
MVCC: trx descriptors
MVCC: kernel_mutex и trx_sys->mutexКак обнаружить?
I SHOW ENGINE INNODB STATUS:
--Thread 140370743510784 has waited at trx0trx.c line 1184 for 0.0000 seconds the semaphore:Mutex at 0x2b0ccc8 ’&kernel_mutex’, lock var 1...
I PMP:
234 ... innobase_commit_low,innobase_commit...
I PERFORMANCE_SCHEMA:I wait/synch/mutex/innodb/kernel_mutex (5.5)
I wait/synch/mutex/innodb/trx_sys_mutex (5.6)
Что делать?
I попробовать jemallocI использовать read-only транзакции, если есть возможностьI перейти на Percona Server или MariaDB + XtraDB
Adaptive Hash Index:
узкое место на AHI mutex:
как обнаружить:
I PMP, OProfile, perf: btr_search_..., row_search_for_mysqlI PERFORMANCE_SCHEMA: wait/synch/rwlock/innodb/btr_search_latch
Adaptive Hash IndexРешение в Percona Server:innodb_adaptive_hash_index_partitions = N
I фрагментация ресурсовI работает только при доступе к нескольким таблицам
index lock2 механизма обновления B-Tree индексов:
I оптимистический — страница обновляется "по месту"I пессимистический — реорганизация страниц => блокировка всей таблицы!I может читать страницы с диска, пока индекс заблокирован
Как определить?
I PMP: btr_cur_search_to_nth_level()I PERFORMANCE_SCHEMA: &new_index->lock
Что делать?I использовать partitioningI обещают исправить «в большинстве случаев» в MySQL 5.7
Redo log: ALL_O_DIRECT
Проблема:
Решение в Percona Server:innodb_flush_method=ALL_O_DIRECT
Redo log: проблема с чтением при записи
I Размер redo log блока — 512 байтовI Размер страницы памяти – 4 килобайта
I если страница не в кэше, нужно сначала прочитать оставшуюсь часть
Redo log: проблема с чтением при записи
Как решать?
Решение в Percona Server 5.1/5.5/5.6:
I увеличиваем log block до размера страницыinnodb_log_block_size=4096
Решение в MySQL 5.7:
I записываем блок в 512 байтов и 3.5K нулей:innodb_log_write_ahead_size=4096
Больше IOPS на SSD!
Redo log: контрольные суммы
Клиент: хотим загружать ∼ 130mil записей очень быстро
I LOAD DATA INFILEI несколько потоковI без secondary indexesI много partitionsI сейчас 350k rows/secondI нужно в 2 раза быстрее
Redo log: контрольные суммыЗатор на log_sys->mutex:
ulintlog_block_calc_checksum(
const byte* block) /*!< in: log block */{
for (i = 0; i < OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE; i++) {ulint b = (ulint) block[i];sum &= 0x7FFFFFFFUL;sum += b;sum += b << sh;sh++;if (sh > 24) {
sh = 0;}
}return(sum);
}
Redo log: контрольные суммы
почему бы не использовать аппаратные контрольные суммы (какдля страниц в buffer pool)?
I 350k rows/sec => 800k rows/sec!
в Percona Server появилась опцияinnodb_log_checksum_algorithm = {none, crc32, innodb}
Redo log: контрольные суммы
Как определить?
I PERFORMANCE_SCHEMA: log_sys_mutexI PMP:
33 log_block_calc_checksum,log_block_store_checksum,...
Как решать?
I innodb_log_checksum_algorithm=crc32 в Percona Server 5.6
SSD: размер страницы
стандартный размер InnoDB страницы (16KB)
Percona Server 5.1, 5.5, 5.6, MySQL 5.6: innodb_page_size=4096+:
I меньше read/write amplificationI +10% на некоторых I/O bound нагрузках
—:I больший объём данных на диске (∼ 20%)I максимальный размер записи ∼ 2KBI избыточная запись в doublewrite: bug #69842
SSD:
Не имеют смысла для SSDI размер страницы в 16KB;I размер redo log блока в 512BI read-ahead
Однопоточная производительностьМасштабируемость на 100+ соединений важна, но:
I производительность в 1 соединение == время откликаI репликация работает в один поток (почти)I административные задачи – как правило один потокI в большинстве случаев сервер работает с небольшим количеством
соединений
Что есть пока:I innodb_page_size=4096I innodb_log_block_size=4096 (только в XtraDB)I innodb_use_atomic_writes (только в XtraDB)I адекватный flushing (XtraDB, MySQL 5.7)
работаем с производителями SSD
Однопоточная производительность
I нагрузки с количеством активных соединений < 100I практически никаких усилий по оптимизацииI каждый следующий релиз хуже предыдущегоI много подробностей в блоге Mark Callaghan:http://smalldatum.blogspot.com
Однопоточная производительностьИсточник: http://smalldatum.blogspot.com
Вопросы!