KEMBAR78
SQL-ник DevDay. Рубцов. Новое в Percona Server и MariaDB в сравнении с MySQL 5.5 | PDF
Новое в Percona Server и
MariaDB в сравнении с
MySQL 5.5
               Григорий Рубцов
               sakila@sqlinfo.ru
План доклада

        –   Введение. Percona Server и MariaDB
 ●   Часть I. Обзор возможностей
        –   Новое для разработчика
        –   Новое для администратора
        –   Улучшение производительности
        –   Миграция
 ●   Часть II. Технические детали
        –   Хранилище XtraDB
        –   Percona Tools
        –   Алгоритмы оптимизации подзапросов в
                                                  2
            MariaDB
Введение:
 Percona Server и MariaDB
Percona Server



●   Компания основана в августе 2006 года
    Петром Зайцевым и Вадимом Ткаченко
●   Специализация — производительность
    MySQL           http://percona.com
●   Разработали патчи для улучшения
    производительности MySQL, которые
    вошли в состав Percona Server           4
Percona Server



●   Percona Server = MySQL Community +
    XtraDB + PT патчи + DBA патчи
●   Полностью Open Source
●   Версия соответствует версии MySQL:
    Percona 5.5.21 на базе MySQL 5.5.21
●   + Percona Tools — радикальное
                                          5
    усиление DBA (применимы и к MySQL)
MariaDB


 ●   В 2008 году MySQL AB была куплена Sun
     Microsystems (последняя поглощена
     Oracle в 2009)
 ●   Основатель MySQL Monty Widenius в
     2009 выпустил fork MySQL: MariaDB
     http://mariadb.org http://kb.askmonty.org
 ●   Мотивация: развитие свободного MySQL
     не должно останавливаться          6
MariaDB


 ●   В MariaDB перерабатывается ядро
     MySQL с исправлением архитектурных
     проблем (многие остались еще от 3.23)
 ●   MariaDB = переработанный код MySQL +
     XtraDB + патчи от Percona + новые фичи
 ●   Разрабатываются открытые аналоги
     всех возможностей MySQL Enterprise
     (например, pluggable authentication)    7
Связь проектов:
downstream
 ●   Percona использует каждую новую
     стабильную версию за основу и
     применяет свои патчи + заменяет
     InnoDB на XtraDB
 ●   MariaDB основана на коде MySQL 5.1 (с
     использованием dev-кода 6.0).
     Возможности новых версий MySQL
     встраиваются в код MariaDB.
 ●   MariaDB использует XtraDB и многие
     патчи Percona                           8
Связь проектов:
upstream
 ●   Percona и команда Monty - лидеры по
     количеству баг-репортов MySQL.
     Включая баги производительности,
     баги InnoDB и критические баги ядра
     (некоторые очень старые).
 ●   Многие патчи от Percona и Monty
     адаптируются и входят в MySQL:
     микросек. slow_log в 5.5, улучшения
     InnoDB, оптимизация подзапросов в 5.6
     — параллельная разработка.           9
Новые функции и
новые баги
 ●   Percona:
     ●   улучшенная производительность и новый
         движок XtraDB
     ●   наследует баги и фиксы MySQL; новые баги
         возможны в XtraDB
 ●   MariaDB:
     ●   улучшены алгоритмы выполнения запросов +
         новые возможности (также, XtraDB)
     ●   баги ядра не будут совпадать с MySQL — у
         Монти собственная система QC               10
Системные требования

 ●   32 или 64-битная система (32-бит теряет
     актуальность из-за ограничений
     памяти)
 ●   MySQL: Linux, FreeBSD, Solaris, Windows,
     Mac OS X, source code
 ●   Percona: Linux, source code
 ●   MariaDB: Linux, Solaris, Windows, source
     code
                                                11
I. Обзор возможностей
Новое для разработчика

 ●   Percona:
     ●   Плагин HandlerSocket: NoSQL доступ к базе
         данных (также в MariaDB)
     ●   динамическая длина строк в MEMORY-
         таблицах
 ●   MariaDB:
     ●   виртуальные колонки и индексы на них
     ●   динамические колонки
     ●   неблокирующая клиентская библиотека
                                                 13
Плагин HandlerSocket

 ●   Позволяет обращаться к XtraDB/InnoDB
     таблицам по индексу с помощью
     NOSQL протокола (без авторизации,
     SQL-запроса и др.)
 ●   Использует два дополнительных TCP-
     порта: для чтения и записи
     ●   mysql> INSTALL PLUGIN handlersocket
         SONAME 'handlersocket.so';
     ●   my.cnf: loose_handlersocket_port=9998
                                                    14
     ●   my.cnf: loose_handlersocket_port_wr=9999
Плагин 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
                                                                  15
Виртуальные колонки

 ●   CREATE TABLE money (
       debit int NOT NULL,
       credit int NOT NULL,
       balance int AS (debit - credit)
     PERSISTENT,
       KEY(balance));
 ●   Два типа: VIRTUAL и PERSISTENT,
     индексы поддерживаются только на
     последних
                                         16
Динамические колонки

  ●   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 в
      динамических колонках
                                                   17
Неблокирующая
клиентская библиотека
         –   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
                                                            18
Динамические строки в
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
                                                   19
Новое для
администратора
 ●   MariaDB:
     ●   поддержка плагинов аутентификации
 ●   Percona:
     ●   работа с побившимися таблицами
     ●   импорт отдельных таблиц из .ibd файлов
     ●   транзакционность реплик
     ●   улучшение диагностики
     ●   улучшение лога медленных запросов
                                                  20
Хранилище по-умолчанию

 ●   в MySQL 5.5 по умолчанию
     используется InnoDB (в 5.1 — MyISAM)
 ●   в Percona — по умолчанию XtraDB
     (который называется InnoDB)
 ●   в MariaDB — по умолчанию MyISAM
     (разрабатывается Aria — пока бета)
 ●   Параметр настраивается (в my.cnf)
     ●   default_storage_engine=InnoDB
                                            21
Работа с побившимися
таблицами
 ●   В InnoDB можно использовать опцию
     innodb_file_per_table
         –   Каждая таблица хранится в отдельном файле,
             ссылка на который — в общем tablespace.
         –   Если таблица повреждена, то стандартный
             InnoDB падает с ошибкой и все таблицы
             становятся недоступны
 ●   Percona:
         –   innodb_corrupt_table_action=warn
     ●   В этом случае — прекращается доступ
         только к одной таблице.                          22
Импорт отдельных
таблиц из .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;    23
Транзакционность реплик

 ●   В MySQL, при внезапной остановке реплики
     информация о выполненной транзакции
     может не записаться в relay-log.info и
     master.info. Репликация собъется.
 ●   Percona:
     ●   rpl_transaction_enabled=1
     ●   статус репликации хранится в журнале
         транзакций InnoDB.


                                                24
Улучшение диагностики

 ●   Percona: в SHOW PROCESSLIST
     добавлены колонки статуса исполнения
         –   Rows_sent, Rows_examined, Rows_read
         –   MariaDB: добавлено время в мс, но нет rows*.
 ●   Расширены
     ●   SHOW ENGINE INNODB STATUS;
     ●   INFORMATOION_SCHEMA:
         –   CLIENT_STATISTICS
         –   INDEX_STATISTICS (ROWS_READ)
                                                            25
         –   TABLE_STATISTICS
Лог медленных запросов

 ●   Информация расширена
 ●   # 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: 5
     select 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

                                                                                          26
Улучшения
производительности
 ●   Percona:
     ●   улучшение масштабируемости и
         устойчивости по отношению к нагрузкам
     ●   улучшения в XtraDB по сравнению с
         InnoDB (см. часть II)
     ●   полностью отключаемый query_cache
     ●   многое, не вошедшее в доклад
         http://www.percona.com/doc/percona-
         server/5.5/feature_comparison.html
                                                 27
Улучшения
производительности
 ●   MariaDB:
     ●   алгоритмы оптимизации подзапросов
         (см. часть II)
     ●   новые алгоритмы JOIN
     ●   оптимизация index_condition_pushdown
     ●   сегментированный key_cache
     ●   групповой коммит при репликации


                                                28
Устойчивость к нагрузкам
см. часть II




                           29
Полностью отключаемый
query_cache
     ●   При большом количестве простых
         запросов, query_cache может стать узким
         местом, так как он работает в один поток
         (общий mutex)
 ●   query_cache_type=0
     ●   в MySQL query_cache не работает, но mutex
         используется
     ●   в Percona в этом случае mutex отсутствует
         (включение кэша потребует рестарт
         сервера)
                                                     30
MariaDB — новые
алгоритмы
 ●   Оптимизация подзапросов (см. часть II).
 ●   Реализован классический алгоритм Hash
     join: JOIN посредством промежуточного
     построения хэш-таблицы для одной из
     таблиц (работает для JOIN с оператором =).
 ●   Улучшен алгоритм index_merge для
     запросов с OR. WHERE City='Moscow' OR
     Country='Germany';

                                               31
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)                              32
Групповой коммит при
репликации
 ●   Реплика выполняет все транзакции в
     один тред, поэтому в ряде случаев
     может отставать
 ●   Чтобы ускорить работу реплики,
     сохранив надежность, выполняется
     общий коммит для группы транзакций
     и делается fsync()
       –   Важно при innodb_flush_logs_at_trx_commit=1
 ●   Опция работает по-умолчанию
                                                         33
Миграция на
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       34
Порядок миграции

 ●   сделать backup (mysqldump /
     innobackupex)
 ●   заменить MySQL на Percona Server или
     MariaDB, сохранив my.cnf
 ●   запустить mysqld с опцией --skip-grant-
     tables
 ●   запустить скрипт mysql_upgrade - может
     занять время (выполняет check table *.*)
 ●   перезапустить mysqld
                                                35
Миграция обратно

 ●   Данные: в общем случае —
     восстановление из дампа
 ●   Приложения: если не использовали
     возможности, не доступные в MySQL
 ●   Если не использовались
     несовместимые оцпии XtraDB (см. часть
     II), данные обладают бинарной
     обратной совместимостью

                                         36
II. Технические детали
Хранилище XtraDB

 ●   Разделение mutex InnoDB buffer pool.
 ●   Настраиваемый Insert buffer.
 ●   Масштабируемость ввода-вывода.
 ●   Партиционирование adaptive hash
     index.
 ●   Возможность сохранения LRU.
 ●   Настройка параметров физического
     хранения с потерей обратной
                                            38
     совместимости.
Разделение mutex InnoDB
buffer pool
 ●   Общий mutex разбит на несколько:




                                        39
Настраиваемый Insert
buffer
 ●   Для неуникальных индексов, InnoDB
     накапливает обновление страниц индекса в
     Insert buffer
 ●   Стандартное поведение — сбрасывать Insert
     buffer на диск, когда наполнится или при
     обращении на чтение
        –   innodb_ibuf_active_merge=1 разрешает
            сбрасывать на диск ненаполненный буфер
        –   innodb_ibuf_max_size — позволяет настроить
            размер (по умолчанию - половина
            innodb_buffer_pool_size, что может быть
            слишком много)                             40
Масштабируемость ввода-
вывода
 ●   Дисковый ввод-вывод стал многопоточным:
     ●   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                      41
Партиционирование
adaptive hash index
 ●   Для ускорения запросов InnoDB на свое
     усмотрение может создавать hash-
     индекс в памяти
 ●   Новый параметр:
     ●   innodb_adaptive_hash_index_partitions
         –   по умолчанию 1
     ●   позволяет партиционировать хэш-индексы
         и сделать обращения к ним
         многопоточными
                                                 42
Сохранение LRU

 ●   При перезапуске сервера, innodb_buffer_pool
     обнуляется и разогрев кэша может занимать
     много времени (производительность низкая
     пока не разогрелся)
 ●   В Percona появилась возможность сохранить
     содержимое buffer_pool (номера страниц) на
     диск в файл ib_lru_dump, а потом быстро
     загрузить в память при старте:
     ●   innodb_auto_lru_dump=1

                                               43
Несовместимые
параметры XtraDB
 ●   innodb_page_size — по умолчанию 16kb
        –   можно уменьшить, например для SSD или
            увеличить для дисковых накопителей
        –   изменение параметра требует пересоздание
            tablespace (случайно изменить невозможно)
 ●   innodb_expand_undo_slots=on
        –   по-умолчанию InnoDB поддерживает не более
            1023 одновременных транзакций; опция
            превращает ограничение в 4072
 ●   innodb_extra_rsegments
        –   увеличение количества сегментов отката      44
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/
                                                    45
innobackupex

 ●   Open source замена mysqlbackup,
     доступной только в Enterprise версии.
 ●   Инкрементальное резервное
     копирование (InnoDB).
 ●   Отделение отдельных InnoDB-таблиц.
 ●   Может использоваться для MySQL.
 ●   Пример: настройка реплики без
     остановки мастера.
                                             46
Алгоритмы оптимизации
подзапросов в MariaDB
 ●   Подзапросы в MySQL
 ●   Подзапросы типа semi-join
 ●   Обзор новых алгоритмов MariaDB
 ●   Материализация и кэширование
 ●   Индексы на временных таблицах для
     подзапросов в поле FROM


                                         47
Подзапросы в MySQL

  ●   Подзапросы в поле FROM используют
      временную таблицу
  ●   Подзапросы с IN/ALL/ANY/SOME используют 2
      вида преобразования:
      ●   IN → EXISTS
      ●   MIN/MAX
      ●   затем прямое выполнение
  ●   Остальные: прямое многократное
      исполнение (кэш для результата
      независимых запросов; план исполнения
                                              48
      используется повторно)
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 часто применяет метод по ошибке к
     независимому подзапросу и он исполняется
     как зависимый (много раз)
                                                 49
MIN/MAX

 ●   Для подзапросов вида
     value {ALL|ANY|SOME} {> | < | >= | <=}
     (uncorrelated subquery)
     преобразование с использованием
     min/max
     WHERE 5 > ALL (SELECT x FROM t)
     WHERE 5 > (SELECT MAX(x) FROM t)

                                              50
«Прямое выполнение»




                      51
Пример semi-join запроса

 ●   Пример: выбрать все европейские страны, в которых
     есть город с населением больше миллиона:
     ●   SELECT * FROM Country WHERE Continent='Europe' AND
         Country.Code IN (SELECT City.country FROM City WHERE
         City.Population>1000*1000);
          –   алгоритмически возможно два порядка исполнения




                                                            52
Отличие от 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 исключает дубликаты по ходу. 53
Карта алгоритмов




                   54
Алгоритмы MariaDB: обзор

 ●   Semi-join выполнятся нативно и это
     быстрее, чем эквивалентный JOIN.
 ●   Semi-join выбирает порядок outer-to-
     inner или inner-to-outer
 ●   MySQL всегда выполняет подчиненный
     подзапрос до объединения внешней
     таблицы с третьей таблицей. MariaDB
     может выполнить сначала внешний
     JOIN, а затем подзапрос.
                                            55
Материализация

     SELECT * FROM Country WHERE Country.code IN
     (SELECT City.Country FROM City WHERE City.Population
     > 7000000) AND Country.continent='Europe'




 ●   Два направления объединения

                                                        56
Оптимизация
подзапросов FROM
     Два алгоритма для оптимизации
     подзапросов в части FROM:
 ●   Derived table merge
 ●   Derived table with keys




                                     57
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';




                                            58
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';


                                             59
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




                                                                                    60
Спасибо за внимание!

 ●   приходите на форум SQLinfo.ru/forum/
 ●   пишите на sakila@sqlinfo.ru


 ●   Также:
     ●   Услуги по оптимизации MySQL
     ●   Онлайн-курс «Оптимизация
         производительности MySQL»

                                            61

SQL-ник DevDay. Рубцов. Новое в Percona Server и MariaDB в сравнении с MySQL 5.5

  • 1.
    Новое в PerconaServer и MariaDB в сравнении с MySQL 5.5 Григорий Рубцов sakila@sqlinfo.ru
  • 2.
    План доклада – Введение. Percona Server и MariaDB ● Часть I. Обзор возможностей – Новое для разработчика – Новое для администратора – Улучшение производительности – Миграция ● Часть II. Технические детали – Хранилище XtraDB – Percona Tools – Алгоритмы оптимизации подзапросов в 2 MariaDB
  • 3.
  • 4.
    Percona Server ● Компания основана в августе 2006 года Петром Зайцевым и Вадимом Ткаченко ● Специализация — производительность MySQL http://percona.com ● Разработали патчи для улучшения производительности MySQL, которые вошли в состав Percona Server 4
  • 5.
    Percona Server ● Percona Server = MySQL Community + XtraDB + PT патчи + DBA патчи ● Полностью Open Source ● Версия соответствует версии MySQL: Percona 5.5.21 на базе MySQL 5.5.21 ● + Percona Tools — радикальное 5 усиление 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 не должно останавливаться 6
  • 7.
    MariaDB ● В MariaDB перерабатывается ядро MySQL с исправлением архитектурных проблем (многие остались еще от 3.23) ● MariaDB = переработанный код MySQL + XtraDB + патчи от Percona + новые фичи ● Разрабатываются открытые аналоги всех возможностей MySQL Enterprise (например, pluggable authentication) 7
  • 8.
    Связь проектов: downstream ● Percona использует каждую новую стабильную версию за основу и применяет свои патчи + заменяет InnoDB на XtraDB ● MariaDB основана на коде MySQL 5.1 (с использованием dev-кода 6.0). Возможности новых версий MySQL встраиваются в код MariaDB. ● MariaDB использует XtraDB и многие патчи Percona 8
  • 9.
    Связь проектов: upstream ● Percona и команда Monty - лидеры по количеству баг-репортов MySQL. Включая баги производительности, баги InnoDB и критические баги ядра (некоторые очень старые). ● Многие патчи от Percona и Monty адаптируются и входят в MySQL: микросек. slow_log в 5.5, улучшения InnoDB, оптимизация подзапросов в 5.6 — параллельная разработка. 9
  • 10.
    Новые функции и новыебаги ● Percona: ● улучшенная производительность и новый движок XtraDB ● наследует баги и фиксы MySQL; новые баги возможны в XtraDB ● MariaDB: ● улучшены алгоритмы выполнения запросов + новые возможности (также, XtraDB) ● баги ядра не будут совпадать с MySQL — у Монти собственная система QC 10
  • 11.
    Системные требования ● 32 или 64-битная система (32-бит теряет актуальность из-за ограничений памяти) ● MySQL: Linux, FreeBSD, Solaris, Windows, Mac OS X, source code ● Percona: Linux, source code ● MariaDB: Linux, Solaris, Windows, source code 11
  • 12.
  • 13.
    Новое для разработчика ● Percona: ● Плагин HandlerSocket: NoSQL доступ к базе данных (также в MariaDB) ● динамическая длина строк в MEMORY- таблицах ● MariaDB: ● виртуальные колонки и индексы на них ● динамические колонки ● неблокирующая клиентская библиотека 13
  • 14.
    Плагин HandlerSocket ● Позволяет обращаться к XtraDB/InnoDB таблицам по индексу с помощью NOSQL протокола (без авторизации, SQL-запроса и др.) ● Использует два дополнительных TCP- порта: для чтения и записи ● mysql> INSTALL PLUGIN handlersocket SONAME 'handlersocket.so'; ● my.cnf: loose_handlersocket_port=9998 14 ● 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 15
  • 16.
    Виртуальные колонки ● CREATE TABLE money ( debit int NOT NULL, credit int NOT NULL, balance int AS (debit - credit) PERSISTENT, KEY(balance)); ● Два типа: VIRTUAL и PERSISTENT, индексы поддерживаются только на последних 16
  • 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 в динамических колонках 17
  • 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 18
  • 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 19
  • 20.
    Новое для администратора ● MariaDB: ● поддержка плагинов аутентификации ● Percona: ● работа с побившимися таблицами ● импорт отдельных таблиц из .ibd файлов ● транзакционность реплик ● улучшение диагностики ● улучшение лога медленных запросов 20
  • 21.
    Хранилище по-умолчанию ● в MySQL 5.5 по умолчанию используется InnoDB (в 5.1 — MyISAM) ● в Percona — по умолчанию XtraDB (который называется InnoDB) ● в MariaDB — по умолчанию MyISAM (разрабатывается Aria — пока бета) ● Параметр настраивается (в my.cnf) ● default_storage_engine=InnoDB 21
  • 22.
    Работа с побившимися таблицами ● В InnoDB можно использовать опцию innodb_file_per_table – Каждая таблица хранится в отдельном файле, ссылка на который — в общем tablespace. – Если таблица повреждена, то стандартный InnoDB падает с ошибкой и все таблицы становятся недоступны ● Percona: – innodb_corrupt_table_action=warn ● В этом случае — прекращается доступ только к одной таблице. 22
  • 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; 23
  • 24.
    Транзакционность реплик ● В MySQL, при внезапной остановке реплики информация о выполненной транзакции может не записаться в relay-log.info и master.info. Репликация собъется. ● Percona: ● rpl_transaction_enabled=1 ● статус репликации хранится в журнале транзакций InnoDB. 24
  • 25.
    Улучшение диагностики ● Percona: в SHOW PROCESSLIST добавлены колонки статуса исполнения – Rows_sent, Rows_examined, Rows_read – MariaDB: добавлено время в мс, но нет rows*. ● Расширены ● SHOW ENGINE INNODB STATUS; ● INFORMATOION_SCHEMA: – CLIENT_STATISTICS – INDEX_STATISTICS (ROWS_READ) 25 – 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: 5 select 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 26
  • 27.
    Улучшения производительности ● Percona: ● улучшение масштабируемости и устойчивости по отношению к нагрузкам ● улучшения в XtraDB по сравнению с InnoDB (см. часть II) ● полностью отключаемый query_cache ● многое, не вошедшее в доклад http://www.percona.com/doc/percona- server/5.5/feature_comparison.html 27
  • 28.
    Улучшения производительности ● MariaDB: ● алгоритмы оптимизации подзапросов (см. часть II) ● новые алгоритмы JOIN ● оптимизация index_condition_pushdown ● сегментированный key_cache ● групповой коммит при репликации 28
  • 29.
  • 30.
    Полностью отключаемый query_cache ● При большом количестве простых запросов, query_cache может стать узким местом, так как он работает в один поток (общий mutex) ● query_cache_type=0 ● в MySQL query_cache не работает, но mutex используется ● в Percona в этом случае mutex отсутствует (включение кэша потребует рестарт сервера) 30
  • 31.
    MariaDB — новые алгоритмы ● Оптимизация подзапросов (см. часть II). ● Реализован классический алгоритм Hash join: JOIN посредством промежуточного построения хэш-таблицы для одной из таблиц (работает для JOIN с оператором =). ● Улучшен алгоритм index_merge для запросов с OR. WHERE City='Moscow' OR Country='Germany'; 31
  • 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) 32
  • 33.
    Групповой коммит при репликации ● Реплика выполняет все транзакции в один тред, поэтому в ряде случаев может отставать ● Чтобы ускорить работу реплики, сохранив надежность, выполняется общий коммит для группы транзакций и делается fsync() – Важно при innodb_flush_logs_at_trx_commit=1 ● Опция работает по-умолчанию 33
  • 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 34
  • 35.
    Порядок миграции ● сделать backup (mysqldump / innobackupex) ● заменить MySQL на Percona Server или MariaDB, сохранив my.cnf ● запустить mysqld с опцией --skip-grant- tables ● запустить скрипт mysql_upgrade - может занять время (выполняет check table *.*) ● перезапустить mysqld 35
  • 36.
    Миграция обратно ● Данные: в общем случае — восстановление из дампа ● Приложения: если не использовали возможности, не доступные в MySQL ● Если не использовались несовместимые оцпии XtraDB (см. часть II), данные обладают бинарной обратной совместимостью 36
  • 37.
  • 38.
    Хранилище XtraDB ● Разделение mutex InnoDB buffer pool. ● Настраиваемый Insert buffer. ● Масштабируемость ввода-вывода. ● Партиционирование adaptive hash index. ● Возможность сохранения LRU. ● Настройка параметров физического хранения с потерей обратной 38 совместимости.
  • 39.
    Разделение mutex InnoDB bufferpool ● Общий mutex разбит на несколько: 39
  • 40.
    Настраиваемый Insert buffer ● Для неуникальных индексов, InnoDB накапливает обновление страниц индекса в Insert buffer ● Стандартное поведение — сбрасывать Insert buffer на диск, когда наполнится или при обращении на чтение – innodb_ibuf_active_merge=1 разрешает сбрасывать на диск ненаполненный буфер – innodb_ibuf_max_size — позволяет настроить размер (по умолчанию - половина innodb_buffer_pool_size, что может быть слишком много) 40
  • 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 41
  • 42.
    Партиционирование adaptive hash index ● Для ускорения запросов InnoDB на свое усмотрение может создавать hash- индекс в памяти ● Новый параметр: ● innodb_adaptive_hash_index_partitions – по умолчанию 1 ● позволяет партиционировать хэш-индексы и сделать обращения к ним многопоточными 42
  • 43.
    Сохранение LRU ● При перезапуске сервера, innodb_buffer_pool обнуляется и разогрев кэша может занимать много времени (производительность низкая пока не разогрелся) ● В Percona появилась возможность сохранить содержимое buffer_pool (номера страниц) на диск в файл ib_lru_dump, а потом быстро загрузить в память при старте: ● innodb_auto_lru_dump=1 43
  • 44.
    Несовместимые параметры XtraDB ● innodb_page_size — по умолчанию 16kb – можно уменьшить, например для SSD или увеличить для дисковых накопителей – изменение параметра требует пересоздание tablespace (случайно изменить невозможно) ● innodb_expand_undo_slots=on – по-умолчанию InnoDB поддерживает не более 1023 одновременных транзакций; опция превращает ограничение в 4072 ● innodb_extra_rsegments – увеличение количества сегментов отката 44
  • 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/ 45
  • 46.
    innobackupex ● Open source замена mysqlbackup, доступной только в Enterprise версии. ● Инкрементальное резервное копирование (InnoDB). ● Отделение отдельных InnoDB-таблиц. ● Может использоваться для MySQL. ● Пример: настройка реплики без остановки мастера. 46
  • 47.
    Алгоритмы оптимизации подзапросов вMariaDB ● Подзапросы в MySQL ● Подзапросы типа semi-join ● Обзор новых алгоритмов MariaDB ● Материализация и кэширование ● Индексы на временных таблицах для подзапросов в поле FROM 47
  • 48.
    Подзапросы в MySQL ● Подзапросы в поле FROM используют временную таблицу ● Подзапросы с IN/ALL/ANY/SOME используют 2 вида преобразования: ● IN → EXISTS ● MIN/MAX ● затем прямое выполнение ● Остальные: прямое многократное исполнение (кэш для результата независимых запросов; план исполнения 48 используется повторно)
  • 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 часто применяет метод по ошибке к независимому подзапросу и он исполняется как зависимый (много раз) 49
  • 50.
    MIN/MAX ● Для подзапросов вида value {ALL|ANY|SOME} {> | < | >= | <=} (uncorrelated subquery) преобразование с использованием min/max WHERE 5 > ALL (SELECT x FROM t) WHERE 5 > (SELECT MAX(x) FROM t) 50
  • 51.
  • 52.
    Пример semi-join запроса ● Пример: выбрать все европейские страны, в которых есть город с населением больше миллиона: ● SELECT * FROM Country WHERE Continent='Europe' AND Country.Code IN (SELECT City.country FROM City WHERE City.Population>1000*1000); – алгоритмически возможно два порядка исполнения 52
  • 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 исключает дубликаты по ходу. 53
  • 54.
  • 55.
    Алгоритмы MariaDB: обзор ● Semi-join выполнятся нативно и это быстрее, чем эквивалентный JOIN. ● Semi-join выбирает порядок outer-to- inner или inner-to-outer ● MySQL всегда выполняет подчиненный подзапрос до объединения внешней таблицы с третьей таблицей. MariaDB может выполнить сначала внешний JOIN, а затем подзапрос. 55
  • 56.
    Материализация SELECT * FROM Country WHERE Country.code IN (SELECT City.Country FROM City WHERE City.Population > 7000000) AND Country.continent='Europe' ● Два направления объединения 56
  • 57.
    Оптимизация подзапросов FROM Два алгоритма для оптимизации подзапросов в части FROM: ● Derived table merge ● Derived table with keys 57
  • 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'; 58
  • 59.
    Derived table withkeys 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'; 59
  • 60.
    Derived table withkeys 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 60
  • 61.
    Спасибо за внимание! ● приходите на форум SQLinfo.ru/forum/ ● пишите на sakila@sqlinfo.ru ● Также: ● Услуги по оптимизации MySQL ● Онлайн-курс «Оптимизация производительности MySQL» 61