sql-ник devday. Рубцов. Новое в percona server и mariadb в сравнении с...
DESCRIPTION
Григорий Рубцов — руководитель проектов SQLinfo.ru (http://sqlinfo.ru/) и Webew.ru (http://webew.ru/), автор онлайн-курса по MySQL (http://sqlinfo.ru/classes/) и спикер конференции РИТ++. Новое в Percona Server и MariaDB в сравнении с MySQL 5.5 Обзор возможностей: — новое для разработчика; — новое для администратора; — улучшения производительности; — миграция и вопросы совместимости. Технические детали: — хранилище XtraDB; — Percona Tools; — алгоритмы оптимизации подзапросов в MariaDB.TRANSCRIPT
Новое в Percona Server и MariaDB в сравнении с MySQL 5.5
Григорий Рубцов[email protected]
10 апреля 2012 г.
2
План доклада
– Введение. Percona Server и MariaDB● Часть I. Обзор возможностей
– Новое для разработчика– Новое для администратора– Улучшение производительности– Миграция
● Часть II. Технические детали– Хранилище XtraDB– Percona Tools– Алгоритмы оптимизации подзапросов в
MariaDB
Введение:Percona Server и MariaDB
4
Percona Server
● Компания основана в августе 2006 года Петром Зайцевым и Вадимом Ткаченко
● Специализация — производительность MySQL http://percona.com
● Разработали патчи для улучшения производительности MySQL, которые вошли в состав Percona Server
5
Percona Server
● Percona Server = MySQL Community + XtraDB + PT патчи + DBA патчи
● Полностью Open Source● Версия соответствует версии MySQL:
Percona 5.5.21 на базе MySQL 5.5.21● + Percona Tools — радикальное
усиление DBA (применимы и к MySQL)
6
MariaDB
● В 2008 году MySQL AB была куплена Sun Microsystems (последняя поглощена Oracle в 2009)
● Основатель MySQL Monty Widenius в 2009 выпустил fork MySQL: MariaDB http://mariadb.org http://kb.askmonty.org
● Мотивация: развитие свободного MySQL не должно останавливаться
●
7
MariaDB
● В MariaDB перерабатывается ядро MySQL с исправлением архитектурных проблем (многие остались еще от 3.23)
● MariaDB = переработанный код MySQL + XtraDB + патчи от Percona + новые фичи
● Разрабатываются открытые аналоги всех возможностей MySQL Enterprise (например, pluggable authentication)
8
Связь проектов: downstream
● Percona использует каждую новую стабильную версию за основу и применяет свои патчи + заменяет InnoDB на XtraDB
● MariaDB основана на коде MySQL 5.1 (с использованием dev-кода 6.0). Возможности новых версий MySQL встраиваются в код MariaDB.
● MariaDB использует XtraDB и многие патчи Percona
9
Связь проектов: upstream
● Percona и команда Monty - лидеры по количеству баг-репортов MySQL. Включая баги производительности, баги InnoDB и критические баги ядра (некоторые очень старые).
● Многие патчи от Percona и Monty адаптируются и входят в MySQL: микросек. slow_log в 5.5, улучшения InnoDB, оптимизация подзапросов в 5.6 — параллельная разработка.
10
Новые функции иновые баги
● Percona:● улучшенная производительность и новый
движок XtraDB● наследует баги и фиксы MySQL; новые баги
возможны в XtraDB● MariaDB:
● улучшены алгоритмы выполнения запросов + новые возможности (также, XtraDB)
● баги ядра не будут совпадать с MySQL — у Монти собственная система QC
11
Системные требования
● 32 или 64-битная система (32-бит теряет актуальность из-за ограничений памяти)
● MySQL: Linux, FreeBSD, Solaris, Windows, Mac OS X, source code
● Percona: Linux, source code● MariaDB: Linux, Solaris, Windows, source
code
I. Обзор возможностей
13
Новое для разработчика
● Percona:● Плагин HandlerSocket: NoSQL доступ к базе
данных (также в MariaDB)● динамическая длина строк в MEMORY-
таблицах● MariaDB:
● виртуальные колонки и индексы на них● динамические колонки● неблокирующая клиентская библиотека
14
Плагин HandlerSocket
● Позволяет обращаться к XtraDB/InnoDB таблицам по индексу с помощью NOSQL протокола (без авторизации, SQL-запроса и др.)
● Использует два дополнительных TCP-порта: для чтения и записи● mysql> INSTALL PLUGIN handlersocket
SONAME 'handlersocket.so';● my.cnf: loose_handlersocket_port=9998● my.cnf: loose_handlersocket_port_wr=9999
15
Плагин HandlerSocket
● Обращение с помощью клиентской библиотеки (C++,Perl,PHP,Java,Python,..)● Как это выглядит в PHP:
– $hs = new HandlerSocket($host, $port);– $hs->openIndex(0, $dbname, $table,
HandlerSocket::PRIMARY, 'k,v'))– $retval = $hs->executeSingle(0, '=', array('k1'));– см. http://code.google.com/p/php-handlersocket/
● Доступны: GET, UPDATE, REMOVE
16
Виртуальные колонки
● CREATE TABLE money (debit int NOT NULL,credit int NOT NULL,balance int AS (debit - credit)
PERSISTENT,KEY(balance));
● Два типа: VIRTUAL и PERSISTENT, индексы поддерживаются только на последних
17
Динамические колонки
● CREATE TABLE people (name varchar(100),dynattr mediumblob);
● INSERT INTO people VALUES ('Ivan', COLUMN_CREATE(1, 'tall', 2, 'blue eyes'));
● SELECT name, COLUMN_GET(dynattr, 1 AS char) FROM people;
● | Ivan | tall |● Ограничение: нельзя хранить blob в
динамических колонках
18
Неблокирующая клиентская библиотека
– int mysql_real_query_start(&status, MYSQL, query, query_length)
– int mysql_real_query_cont(&status, MYSQL, wait_status)
● Возвращают 0, если запрос выполнен или не ноль, если необходимо ожидание● http://kb.askmonty.org/en/using-the-non-
blocking-library● Появилась в MariaDB 5.5 (16.03.2012),
но работает также с MySQL и Percona
19
Динамические строки в MEMORY-таблицах
● В MySQL в MEMORY-таблицах запрещены blob-ы, а varchar(20) хранится как char(20), занимая максимальный объем
● Percona:● CREATE TABLE articles ( id int, title
varchar(300), full text) ENGINE=MEMORY;● MariaDB: планируется в 5.5.X, X>23
20
Новое для администратора
● MariaDB:● поддержка плагинов аутентификации
● Percona:● работа с побившимися таблицами● импорт отдельных таблиц из .ibd файлов● транзакционность реплик● улучшение диагностики● улучшение лога медленных запросов
21
Хранилище по-умолчанию
● в MySQL 5.5 по умолчанию используется InnoDB (в 5.1 — MyISAM)
● в Percona — по умолчанию XtraDB (который называется InnoDB)
● в MariaDB — по умолчанию MyISAM (разрабатывается Aria — пока бета)
● Параметр настраивается (в my.cnf)● default_storage_engine=InnoDB
22
Работа с побившимися таблицами
● В InnoDB можно использовать опцию innodb_file_per_table
– Каждая таблица хранится в отдельном файле, ссылка на который — в общем tablespace.
– Если таблица повреждена, то стандартный InnoDB падает с ошибкой и все таблицы становятся недоступны
● Percona:– innodb_corrupt_table_action=warn
● В этом случае — прекращается доступ только к одной таблице.
23
Импорт отдельных таблиц из .ibd файлов
– В MySQL даже с использованием innodb_file_per_table невозможно восстановить таблицу из одного ibd-файла
● Percona:– innobackupex позволяет отделить таблицу и
подключить ее бинарно к XtraDB(!) серверу– $ xtrabackup --prepare --export —innodb-file-per-
table --target-dir=/data/backups/mysql/– my.cnf: innodb_import_table_from_xtrabackup=1
● CREATE TABLE mytable (same structure);● ALTER TABLE mytable DISCARD TABLESPACE;● ALTER TABLE mytable IMPORT TABLESPACE;
24
Транзакционность реплик
● В MySQL, при внезапной остановке реплики информация о выполненной транзакции может не записаться в relay-log.info и master.info. Репликация собъется.
● Percona:● rpl_transaction_enabled=1● статус репликации хранится в журнале
транзакций InnoDB.
25
Улучшение диагностики
● Percona: в SHOW PROCESSLIST добавлены колонки статуса исполнения
– Rows_sent, Rows_examined, Rows_read– MariaDB: добавлено время в мс, но нет rows*.
● Расширены● SHOW ENGINE INNODB STATUS;● INFORMATOION_SCHEMA:
– CLIENT_STATISTICS– INDEX_STATISTICS (ROWS_READ)– TABLE_STATISTICS
26
Лог медленных запросов
● Информация расширена● # User@Host: mailboxer[mailboxer] @ [192.168.10.165]
# Thread_id: 11167745 Schema: board# QC_Hit: No Full_scan: No Full_join: No Tmp_table: Yes Disk_tmp_table: No# Filesort: Yes Disk_filesort: No Merge_passes: 0# Query_time: 0.000659 Lock_time: 0.000070 Rows_sent: 0 Rows_examined: 30 Rows_affected: 0 Rows_read: 30# innodb_IO_r_ops: 1 innodb_IO_r_bytes: 16384 innodb_IO_r_wait: 0.028487# innodb_rec_lock_wait: 0.000000 innodb_queue_wait: 0.000000# innodb_pages_distinct: 5select count(distinct author_id) from art87.article87 force index (forum_id) where forum_id = 240215 and thread_id = ``710575``
● Дополнительные настройки● log_slow_filter=tmp_table_on_disk,filesort_on_disk
27
Улучшения производительности
● Percona:● улучшение масштабируемости и
устойчивости по отношению к нагрузкам● улучшения в XtraDB по сравнению с
InnoDB (см. часть II)● полностью отключаемый query_cache● многое, не вошедшее в доклад
http://www.percona.com/doc/percona-server/5.5/feature_comparison.html
28
Улучшения производительности
● MariaDB:● алгоритмы оптимизации подзапросов
(см. часть II)● новые алгоритмы JOIN● оптимизация index_condition_pushdown● сегментированный key_cache● групповой коммит при репликации
29
Устойчивость к нагрузкамсм. часть II
30
Полностью отключаемый query_cache
● При большом количестве простых запросов, query_cache может стать узким местом, так как он работает в один поток (общий mutex)
● query_cache_type=0● в MySQL query_cache не работает, но mutex
используется● в Percona в этом случае mutex отсутствует
(включение кэша потребует рестарт сервера)
31
MariaDB — новые алгоритмы
● Оптимизация подзапросов (см. часть II).● Реализован классический алгоритм Hash
join: JOIN посредством промежуточного построения хэш-таблицы для одной из таблиц (работает для JOIN с оператором =).
● Улучшен алгоритм index_merge для запросов с OR. WHERE City='Moscow' OR Country='Germany';
32
index_condition_pushdown
● Пусть имеется составной ключ KEY(key_col1, key_col2)
● SELECT * FROM tbl WHERE key_col1 between 10 and 11 and key_col2 like '%foo%';
● MySQL использует первую часть индекса для выборки, а второе условие будет проверять по данными таблицы (using where)
● MariaDB проверит второе условие по информации из индекса (using index condition)
33
Групповой коммит при репликации
● Реплика выполняет все транзакции в один тред, поэтому в ряде случаев может отставать
● Чтобы ускорить работу реплики, сохранив надежность, выполняется общий коммит для группы транзакций и делается fsync()
– Важно при innodb_flush_logs_at_trx_commit=1● Опция работает по-умолчанию
34
Миграция на Percona/MariaDB
● Поддерживается совместимость:● на уровне SQL● на бинарном уровне
● Модификация приложений не требуется● Репликация:
● Slave может быть на одну версию новее мастера (5.0 -> 5.1, 5.1 -> 5.5)
● http://www.percona.com/doc/percona-server/5.5/upgrading_guide_51_55.html
35
Порядок миграции
● сделать backup (mysqldump / innobackupex)
● заменить MySQL на Percona Server или MariaDB, сохранив my.cnf
● запустить mysqld с опцией --skip-grant-tables
● запустить скрипт mysql_upgrade - может занять время (выполняет check table *.*)
● перезапустить mysqld
36
Миграция обратно
● Данные: в общем случае — восстановление из дампа
● Приложения: если не использовали возможности, не доступные в MySQL
● Если не использовались несовместимые оцпии XtraDB (см. часть II), данные обладают бинарной обратной совместимостью
II. Технические детали
38
Хранилище XtraDB
● Разделение mutex InnoDB buffer pool.● Настраиваемый Insert buffer.● Масштабируемость ввода-вывода.● Партиционирование adaptive hash
index.● Возможность сохранения LRU.● Настройка параметров физического
хранения с потерей обратнойсовместимости.
39
Разделение mutex InnoDB buffer pool
● Общий mutex разбит на несколько:
40
Настраиваемый Insert buffer
● Для неуникальных индексов, InnoDB накапливает обновление страниц индекса в Insert buffer
● Стандартное поведение — сбрасывать Insert buffer на диск, когда наполнится или при обращении на чтение
– innodb_ibuf_active_merge=1 разрешает сбрасывать на диск ненаполненный буфер
– innodb_ibuf_max_size — позволяет настроить размер (по умолчанию - половина innodb_buffer_pool_size, что может быть слишком много)
41
Масштабируемость ввода-вывода
● Дисковый ввод-вывод стал многопоточным:● innodb_read_io_threads● Innodb_write_io_threads
– По умолчанию 1, но на RAID-системах имеет смысл записывать и читать в несколько потоков
● Добавилось много параметров конфигурации: ● innodb_flush_log_at_trx_commit_session
– 0 flush раз в секунду– 1 flush после каждого commit– 2 запись после commit, но не делать flush– 3(default) использовать значение глобальной настройки
innodb_flush_log_at_trx_commit
42
Партиционирование adaptive hash index
● Для ускорения запросов InnoDB на свое усмотрение может создавать hash-индекс в памяти
● Новый параметр:● innodb_adaptive_hash_index_partitions
– по умолчанию 1● позволяет партиционировать хэш-индексы
и сделать обращения к ним многопоточными
43
Сохранение LRU
● При перезапуске сервера, innodb_buffer_pool обнуляется и разогрев кэша может занимать много времени (производительность низкая пока не разогрелся)
● В Percona появилась возможность сохранить содержимое buffer_pool (номера страниц) на диск в файл ib_lru_dump, а потом быстро загрузить в память при старте:● innodb_auto_lru_dump=1
44
Несовместимые параметры XtraDB
● innodb_page_size — по умолчанию 16kb– можно уменьшить, например для SSD или
увеличить для дисковых накопителей– изменение параметра требует пересоздание
tablespace (случайно изменить невозможно)● innodb_expand_undo_slots=on
– по-умолчанию InnoDB поддерживает не более 1023 одновременных транзакций; опция превращает ограничение в 4072
● innodb_extra_rsegments– увеличение количества сегментов отката
●
45
Percona Tools
● innobackupex — бинарный онлайн-бэкап● mk-query-digest — анализ slow_log● pt-table-checksum / pt-table-sync —
корректная синхронизация slave● pt-kill — устранение перегрузки● pt-heartbeat — отставание реплики● многие другие утилиты● http://www.percona.com/software/percona-toolkit/
46
innobackupex
● Open source замена mysqlbackup, доступной только в Enterprise версии.
● Инкрементальное резервное копирование (InnoDB).
● Отделение отдельных InnoDB-таблиц.● Может использоваться для MySQL.● Пример: настройка реплики без
остановки мастера.
47
Алгоритмы оптимизации подзапросов в MariaDB
● Подзапросы в MySQL● Подзапросы типа semi-join● Обзор новых алгоритмов MariaDB● Материализация и кэширование● Индексы на временных таблицах для
подзапросов в поле FROM
48
Подзапросы в MySQL
● Подзапросы в поле FROM используют временную таблицу
● Подзапросы с IN/ALL/ANY/SOME используют 2 вида преобразования:
● IN EXISTS→● MIN/MAX● затем прямое выполнение
● Остальные: прямое многократное исполнение (кэш для результата независимых запросов; план исполнения используется повторно)
49
IN EXISTS→
● outer_expr IN (SELECT inner_expr FROM ... WHERE subquery_where)
=> EXISTS (SELECT 1 FROM ... WHERE subquery_where AND outer_expr=inner_expr)
● Порядок исполнения всегда от внешнего к внутреннему
● MySQL часто применяет метод по ошибке к независимому подзапросу и он исполняется как зависимый (много раз)
50
MIN/MAX
● Для подзапросов вида value {ALL|ANY|SOME} {> | < | >= | <=} (uncorrelated subquery)преобразование с использованием min/maxWHERE 5 > ALL (SELECT x FROM t)WHERE 5 > (SELECT MAX(x) FROM t)
51
«Прямое выполнение»
52
Пример semi-join запроса
● Пример: выбрать все европейские страны, в которых есть город с населением больше миллиона:
● SELECT * FROM Country WHERE Continent='Europe' AND Country.Code IN (SELECT City.country FROM City WHERE City.Population>1000*1000);– алгоритмически возможно два порядка исполнения
53
Отличие от JOIN
● Отличие от JOIN — отсутствие дубликатов; интересует информация только из одной таблицы
● SELECT * FROM Country WHERE Continent='Europe' AND Country.Code IN (SELECT City.country FROM City WHERE City.Population>1000*1000);
● Эквивалентный JOIN с DISTINCT:● SELECT DISTINCT Country.* FROM Country JOIN City ON
City.country=Country.Code WHERE City.Population>1000*1000;
● MariaDB выполняет подзапрос специальным алгоритмом semi-join, который эффективнее эквивалентного запроса, так как последний для DISTINCT делает группировку результата, а semi-join исключает дубликаты по ходу.
54
Карта алгоритмов
55
Алгоритмы MariaDB: обзор
● Semi-join выполнятся нативно и это быстрее, чем эквивалентный JOIN.
● Semi-join выбирает порядок outer-to-inner или inner-to-outer
● MySQL всегда выполняет подчиненный подзапрос до объединения внешней таблицы с третьей таблицей. MariaDB может выполнить сначала внешний JOIN, а затем подзапрос.
56
Материализация
SELECT * FROM Country WHERE Country.code IN (SELECT City.Country FROM City WHERE City.Population > 7000000) AND Country.continent='Europe'
● Два направления объединения
57
Оптимизация подзапросов FROM
Два алгоритма для оптимизации подзапросов в части FROM:
● Derived table merge● Derived table with keys
58
Derived table merge
SELECT * FROM (SELECT * FROM City WHERE Population > 10*1000) AS big_city WHERE big_city.Country='DEU';
MariaDB преобразует в
SELECT * FROM City WHERE Population > 10*1000 AND big_city.Country='DEU';
59
Derived table with keys
SELECT * FROM Country, (SELECT City.Country, sum(City.Population) as urban_population FROM City GROUP BY City.Country HAVING urban_population > 1*1000*1000) as cities_in_country WHERE Country.Code=cities_in_country.Country AND Country.Continent='Europe';
60
Derived table with keys
id select_type table type key key_len ref rows
1 PRIMARY Country ref Population 17 NULL 60
1 PRIMARY < derived2> ref key0 3 world.Country.Code 17
2 DERIVED City ALL NULL null 4069
61
Спасибо за внимание!
● приходите на форум SQLinfo.ru/forum/● пишите на [email protected]
● Также:● Услуги по оптимизации MySQL● Онлайн-курс «Оптимизация
производительности MySQL»