MySQL всегда использовали под высокой нагрузкой. Недаром эта база была и остаётся самым популярным бэкэндом для web. Однако наши представления о хайлоде с каждым годом расширяются. Большая скорость передачи данных -> больше устройств с подключением к интернет -> больше пользователей -> больше данных.
Задачи, стоящие перед разработчиками MySQL, с каждым годом усложняются.
В этом докладе я расскажу как менялись сценарии использования MySQL за [почти] 25 лет её истории и что делали инженеры, чтобы MySQL оставалась актуальной. Мы затронем такие темы, как работа с большим количеством активных соединений и высокими объёмами данных. Я покажу насколько современные версии лучше справляются с возросшими нагрузками.
Я надеюсь, что после моего доклада те слушатели, которые используют старые версии, захотят обновиться и те, кто уже обновились, узнают как использовать современный MySQL на полную мощность.
Прочитана на конференции OST 2020: https://ostconf.com/materials/2857#2857
Современному хайлоду - современные решения: MySQL 8.0 и улучшения Percona
1. MySQL 8.0 и Улучшения Percona
Современному Хайлоаду — Современные Решения
10-13 августа 2020
Света Смирнова
2. • Инженер тех. поддержки MySQL
•
Автор
• MySQL Troubleshooting
•
JSON UDF функции
• FILTER clause для MySQL
• Докладчик
•
Percona Live, OOW, Fosdem,
DevConf, HighLoad...
Света Смирнова
2
3. •Как Работать при Высокой Нагрузке
•Улучшения в MySQL 8.0
Новый Словарь
Оптимизатор Запросов
Другие Улучшения
Содержание
3
13. ? <= ядер процессора?
Что Происходит с Потоками
9
14. ? <= ядер процессора?
Да Выполняются одновременно
Что Происходит с Потоками
9
15. ? <= ядер процессора?
Да Выполняются одновременно
Нет Ждут в очереди
Что Происходит с Потоками
9
16. ? <= ядер процессора?
Да Выполняются одновременно
Нет Ждут в очереди
? Может диск писать параллельно?
Что Происходит с Потоками
9
17. ? <= ядер процессора?
Да Выполняются одновременно
Нет Ждут в очереди
? Может диск писать параллельно?
Да Запись происходит
Что Происходит с Потоками
9
18. ? <= ядер процессора?
Да Выполняются одновременно
Нет Ждут в очереди
? Может диск писать параллельно?
Да Запись происходит
Нет Ждут в очереди
Что Происходит с Потоками
9
20. • Обычно большинство неактивны
•
Threads_running
• Много активных?
Percona Thread Pool Plugin
Thread Pool in MariaDB
MySQL Enterprise Thread Pool
Много Соединений?
10
26. 5.6 Несколько purge threads
5.6 Хранимая Optimizer Statistics
5.6 Сохранение InnoDB Buffer Pool
•
Percona Server с версии 5.1
Что Менялось в InnoDB
14
27. 5.6 Несколько purge threads
5.6 Хранимая Optimizer Statistics
5.6 Сохранение InnoDB Buffer Pool
5.6 Быстрый checksum алгоритм CRC32
5.6 Undo log в отдельном tablespace
5.6 Полнотекстовые индексы
5.6 Перемещаемые tablespaces
5.6 Read only транзакции
Что Менялось в InnoDB
14
28. 5.7 Убран mutex contention для read view
5.7 SELECTs: read only по умолчанию
5.7 Не присвается ID read-only транзакциям
5.7 SELECT COUNT(*) читает clustered index
5.7 Нет redo log для временных таблиц
5.7 Temporary tablespace
5.7 Несколько потоков page cleaner
5.7 Native partitioning
Что Менялось в InnoDB
14
29. 5.7 AHI partitioned
5.7 innodb_log_checksum_algorithm
5.7 Page-level компрессия
5.7 General tablespaces
Что Менялось в InnoDB
14
30. 8.0 Системные таблицы в InnoDB
8.0 Descending индексы
8.0 MySQL data dictionary вместо собственного
8.0 Многопоточная инициализация Buffer Pool
8.0 Redo log оптимизация
8.0 CATS
Что Менялось в InnoDB
14
45. mysql> explain format=tree select * from ol where thread_id=10432 and site_id != 9939
-> order by id limit 3G
*************************** 1. row ***************************
EXPLAIN: -> Limit: 3 row(s)
-> Filter: ((ol.thread_id = 10432) and (ol.site_id <> 9939)) (cost=0.06 rows=3)
-> Index scan on ol using PRIMARY (cost=0.06 rows=33)
Пример по мотивам MySQL bug #78651
EXPLAIN ANALYZE
26
46. mysql> explain format=tree select * from ol where thread_id=10432 and site_id != 9939
-> order by id limit 3G
*************************** 1. row ***************************
EXPLAIN: -> Limit: 3 row(s)
-> Filter: ((ol.thread_id = 10432) and (ol.site_id <> 9939)) (cost=0.06 rows=3)
-> Index scan on ol using PRIMARY (cost=0.06 rows=33)
Пример по мотивам MySQL bug #78651
mysql> explain analyze select * from ol where thread_id=10432 and site_id != 9939
-> order by id limit 3G
*************************** 1. row ***************************
EXPLAIN: -> Limit: 3 row(s) (actual time=364.792..364.792 rows=0 loops=1)
-> Filter: ((ol.thread_id = 10432) and (ol.site_id <> 9939)) (cost=0.06 rows=3)
(actual time=364.789..364.789 rows=0 loops=1)
-> Index scan on ol using PRIMARY (cost=0.06 rows=33)
(actual time=0.417..337.585 rows=100000 loops=1)
EXPLAIN ANALYZE
26
47. Nested-Loop Join Algorithm
for each row in t1 matching range {
for each row in t2 matching reference key {
for each row in t3 {
if row satisfies join conditions, send to client
}
}
}
Before 8.0: Block Nested Loop
27
48. Nested-Loop Join Algorithm
for each row in t1 matching range {
for each row in t2 matching reference key {
for each row in t3 {
if row satisfies join conditions, send to client
}
}
}
• Неэффективный!
Циклы!
Before 8.0: Block Nested Loop
27
49. Hash join в MySQL 8
•
select first_name, last_name, dept_no
from employees straight_join emp_dept
using(emp_no) where
last_name=’Neiman’ and
to_date=’9999-01-01’;
Hash Joins
28
50. Hash join в MySQL 8
•
Фаза build
employees
emp_dept
Hash table в памяти
By JOIN condition
hash
Hash Joins
28
51. Hash join в MySQL 8
•
Фаза probe
employees
emp_dept
Hash table
в памяти
hash
Client
Hash Joins
28
63. • Функциональные
mysql> explain select year(hire_date), count(*) as hired from employees
-> group by year(hire_date)G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: employees
partitions: NULL
type: ALL
possible_keys: hire_date
key: NULL
key_len: NULL
ref: NULL
rows: 299645
filtered: 100.00
Extra: Using temporary
Индексы
30
64. • Функциональные
mysql> alter table employees add index hire_date_year((year(hire_date)));
mysql> explain select year(hire_date), count(gender) as hired from employees
-> group by year(hire_date)G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: employees
partitions: NULL
type: index
possible_keys: hire_date_year
key: hire_date_year
key_len: 5
ref: NULL
rows: 299468
filtered: 100.00
Extra: NULL
Индексы
30
65. • Index skip scan
• Многоколоночные индексы
key_part_1, key_part_2
• ... WHERE key_part_2 > N
• Запросы к одной таблице
•
Обращается только к колонкам индекса
Индексы
30
66. • Index skip scan
mysql> show create table salariesG
*************************** 1. row ***************************
Table: salaries
Create Table: CREATE TABLE ‘salaries‘ (
‘emp_no‘ int NOT NULL,
‘salary‘ int NOT NULL,
‘from_date‘ date NOT NULL,
‘to_date‘ date NOT NULL,
PRIMARY KEY (‘emp_no‘,‘from_date‘),
KEY ‘from_date‘ (‘from_date‘,‘to_date‘),
CONSTRAINT ‘salaries_ibfk_1‘ FOREIGN KEY (‘emp_no‘) REFERENCES ‘employees‘ (‘emp_no‘)
ON DELETE CASCADE
) /*!50100 TABLESPACE ‘innodb_system‘ */ ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
Индексы
30
67. • Index skip scan
mysql> explain select emp_no, from_date, to_date, salary from salaries
-> where to_date > ’1999-01-01’G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: salaries
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 2632946
filtered: 33.33
Extra: Using where
Индексы
30
68. • Index skip scan
mysql> explain select emp_no, from_date, to_date from salaries
-> where to_date > ’1999-01-01’G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: salaries
partitions: NULL
type: range
possible_keys: from_date
key: from_date
key_len: 6
ref: NULL
rows: 877560
filtered: 100.00
Extra: Using where; Using index for skip scan
Индексы
30
69. • CTEs
•
Нерекурсивные
mysql> with
-> dept_data as
-> (select emp_no, dept_name from dept_emp join departments using (dept_no))
-> select first_name, last_name, dept_name
-> from employees join dept_data using(emp_no)
-> order by hire_date desc limit 3;
+––––––––––––+–––––––––––+––––––––––––––––––––+
| first_name | last_name | dept_name |
+––––––––––––+–––––––––––+––––––––––––––––––––+
| Bikash | Covnot | Quality Management |
| Yucai | Gerlach | Production |
| Hideyuki | Delgrande | Development |
+––––––––––––+–––––––––––+––––––––––––––––––––+
3 rows in set (0.00 sec)
SQL DML
31
70. • CTEs
• Рекурсивные
mysql> with recursive rand_generator(id, rand_value) as
-> (select 1, rand() union all select id+1, rand() from rand_generator where id < 5)
-> select * from rand_generator;
+––––––+–––––––––––––––––––––+
| id | rand_value |
+––––––+–––––––––––––––––––––+
| 1 | 0.5599308382346582 |
| 2 | 0.2151867702744778 |
| 3 | 0.39614136740205935 |
| 4 | 0.33514655692050843 |
| 5 | 0.4873087131300091 |
+––––––+–––––––––––––––––––––+
5 rows in set (0.00 sec)
SQL DML
31
71. • Window functions
mysql> select
-> row_number() over win as id, dept_no, dept_name from departments
-> window win
-> as (order by dept_no);
+––––+–––––––––+––––––––––––––––––––+
| id | dept_no | dept_name |
+––––+–––––––––+––––––––––––––––––––+
| 1 | d001 | Marketing |
| 2 | d002 | Finance |
| 3 | d003 | Human Resources |
| 4 | d004 | Production |
| 5 | d005 | Development |
| 6 | d006 | Quality Management |
| 7 | d007 | Sales |
| 8 | d008 | Research |
| 9 | d009 | Customer Service |
+––––+–––––––––+––––––––––––––––––––+
SQL DML
31
72. • ORDER BY и DISTINCT поддерживают ROLLUP
• Только для запросов с GROUP BY
SQL DML
31
89. •
Несколько адресов для –bind-address
•
Admin port
•
В Percona Server с версии 5.5
•
extra_port
Сеть
40
90. •
Несколько адресов для –bind-address
•
Admin port
•
В Percona Server с версии 5.5
•
extra_port
• Убран mutex bottleneck для
connect/disconnect
Сеть
40
91. •
Несколько адресов для –bind-address
•
Admin port
•
В Percona Server с версии 5.5
•
extra_port
• Убран mutex bottleneck для
connect/disconnect
• Хосты длиннее 60 знаков
Сеть
40
99. • Фильтры per channel
• Write-set dependency tracking
•
Быстрый multi-thread
• Уменьшена contention между receiver и
applier
Репликация
42
100. • Фильтры per channel
• Write-set dependency tracking
•
Быстрый multi-thread
• Уменьшена contention между receiver и
applier
•
Можно изменять GTID_PURGED при непустой
GTID_EXECUTED
Репликация
42
101. •
Не нужно писать повторяющиеся GRANT
mysql> create role read_only, admin;
Query OK, 0 rows affected (0.05 sec)
mysql> grant select on *.* to ’read_only’;
Query OK, 0 rows affected (0.01 sec)
mysql> grant super on *.* to ’admin’;
Query OK, 0 rows affected, 1 warning (0.01 sec)
Роли
43
102. •
Не нужно писать повторяющиеся GRANT
mysql> create user sveta;
Query OK, 0 rows affected (0.01 sec)
mysql> create user kim;
Query OK, 0 rows affected (0.01 sec)
mysql> create user privileged;
Query OK, 0 rows affected (0.01 sec)
mysql> grant ’read_only’ to sveta;
Query OK, 0 rows affected (0.01 sec)
mysql> grant ’read_only’ to kim;
Query OK, 0 rows affected (0.01 sec)
mysql> grant ’admin’ to privileged;
Query OK, 0 rows affected (0.02 sec)
Роли
43
104. • SUPER разбита на несколько динамических
привилегий
Security
44
105. • SUPER разбита на несколько динамических
привилегий
•
Secure session variables settings
• MYSQL_SESSION_ADMIN
Старый пост "Ещё раз про бесправных
пользователей" не актуален
Security
44
106. • SUPER разбита на несколько динамических
привилегий
•
Secure session variables settings
• MYSQL_SESSION_ADMIN
Старый пост "Ещё раз про бесправных
пользователей" не актуален
• Частичный REVOKE
Security
44
109. • MySQL Shell
• Более понятные сообщения об ошибках
Ease of Use
46
110. • MySQL Shell
• Более понятные сообщения об ошибках
• Поддержка NoSQL
• Schemaless
• JSON Schema
Ease of Use
46
111. • MySQL Shell
• Более понятные сообщения об ошибках
• Поддержка NoSQL
• Schemaless
• JSON Schema
•
Современный SQL
Ease of Use
46
112. • Новые версии включают новый функционал
• Продвинутый
• Упрощающий работу
Выводы
47
113. • Новые версии включают новый функционал
• Продвинутый
• Упрощающий работу
•
Старый код улучшает производительность
Выводы
47
114. • Новые версии включают новый функционал
• Продвинутый
• Упрощающий работу
•
Старый код улучшает производительность
•
Обновляйтесь
Выводы
47
115. • Новые версии включают новый функционал
• Продвинутый
• Упрощающий работу
•
Старый код улучшает производительность
•
Обновляйтесь
• Даже если не используете новый синтаксис!
Выводы
47
116. •
Вебинар про Optimizer Histograms
Window functions
MySQL 8.0: Common Table Expressions
MySQL Performance Schema in Action
Как программировать для Performance Schema
Подробнее
48
117. • Что нового в репликации в MySQL 8.0?
MySQL 8.0 Roles
Enhanced Encryption в Percona Server
MySQL Shell - the best DBA tool!
Подробнее
48
118. The complete list of new features in MySQL 8.0
Modern SQL
Dimitri KRAVTCHUK про MySQL 8.0
Чем отличается Percona Server от MySQL
Дополнительная Информация
49