MySQL 5.7 поставляется с новым набором функций, и одна из них — репликация из нескольких источников. В нескольких словах это означает, что один раб может копировать от разных мастеров одновременно.
В течение последних нескольких месяцев я много играл с этим, пытаясь проанализировать его потенциал в реальном случае, с которым я столкнулся при работе с клиентом.
Это было мотивировано, потому что мой клиент уже использует ведомые устройства с несколькими источниками с Tungsten Replicator, и я хотел сделать параллельное сравнение между Tungsten Replicator и Multi-source Replication в MySQL 5.7
Рассмотрим следующий сценарий
DB1 является нашим главным мастером, обслуживающим в основном записи из нескольких приложений, он также должен обслуживать трафик чтения, что приближает его емкость к пределу. Он подключил 6 подчиненных репликаций с использованием обычной репликации.
A1, A2, A3, B1, B2 и DB7 являются подчиненными подчиненными, используемыми для разгрузки некоторых чтений с главного устройства, а также просыпаются в некоторых автономных процессах ETL.
Поскольку у них была свободная емкость, клиент решил пойти дальше и установить другую архитектуру:
A1 и B1 стали также хозяевами других ведомых устройств, использующих Tungsten Replicator, в этом случае группа A представляет собой набор серверов для приложения статистики, а B посещает финансовый отдел. приложение, поэтому A2, A3 и B2 стали рабами с несколькими источниками.
Новые приложения записывают напрямую в A1 и B1, не влияя на емкость записи основного мастера.
Плюсы и минусы этого подхода
Pros
- Это просто работает. Мы работали так давно, и у нас не было серьезных проблем.
- В Tungsten Replicator есть несколько встроенных инструментов и скриптов, которые упрощают подчиненное управление.
Cons
- Tungsten Replicator — отличный продукт, но больше, чем нужно для этой архитектуры. В некоторых случаях нам приходилось настраивать виртуальную машину Java с 4 ГБ ОЗУ для правильной работы.
- Tungsten — это сложный инструмент, для развертывания которого требуется дополнительная экспертиза, чтобы он работал и устранял проблемы, возникающие при возникновении ошибок (например, обработка ошибок дублирующихся ключей).
Имея все это в виду, мы сделали шаг вперед и начали проверять, можем ли мы переместить эту архитектуру для использования только устаревшей репликации.
Новый архитектурный дизайн
Мы добавили некоторую емкость хранилища в DB7 для наших целей тестирования, и цель здесь состоит в том, чтобы заменить все реплицированные вольфрамовые ведомые устройства одним сервером, на котором консолидируются все базы данных.
Для некоторой зависимости от данных мы не смогли полностью разделить серверы A1 и B1, чтобы стать только ведущими, поэтому они в настоящее время действуют как хозяева DB7 и подчиненные устройства DB1. Под зависимостью от данных я имею в виду, что DB1 реплицирует свои схемы всем своим прямым подчиненным, в том числе DB7. DB7 также получает репликацию финансовой базы данных, работающей локально, на B1 и статистики DB, работающей локально на A1.
Как это было сделано и что реализовано в нескольких источниках
- Основное различие между обычной репликацией, известной до версии 5.6, заключается в том, что теперь у вас есть каналы репликации, каждый канал означает другой источник, другими словами, у каждого мастера есть свой собственный канал репликации.
- Репликация должна быть настроена как безопасная для отказа, а это означает, что
master_info_repository
иrelay_log_info_repository
переменные, и переменные должны быть установлены вTABLE
- Мы не рассматривали GTID, потому что серверы, действующие как мастера, имеют версии, отличные от нашего тестового ведомого ведомого с несколькими источниками.
log_slave_updates
необходимо отключить в A1 и B2, чтобы избежать дублирования данных в DB7 из-за потока репликации.
Плюсы и минусы этого подхода
Pros
- MySQL 5.7 может реплицироваться из разных версий master, мы тестировали многоисточниковую репликацию, работающую одновременно с 5.5 и 5.6, и не испытывали проблем, кроме тех известных изменений с полями, основанными на отметке времени.
- Администрация становится проще. Любой администратор базы данных, уже знакомый с унаследованной репликацией, может адаптироваться для работы с несколькими каналами без особого изучения, каких-то новых переменных и пары новых таблиц, и вы готовы к этому.
Cons
- 5.7 еще не готов к производству. На данный момент у нас нет данных о выпуске GA, что означает, что мы можем ожидать появления ошибок в краткосрочной / среднесрочной перспективе.
- С несколькими источниками все еще сложно в некоторых особых случаях: фильтрация базы данных и таблиц работает глобально (не могут устанавливать фильтры для каждого канала), а команды администрирования, такие
sql_slave_skip_counter
как глобальная команда, все еще означают, что вы не можете легко пропустить оператор в определенном канале ,
Теперь забавная часть: как
Это было проще, чем вы думаете. Прежде всего нам нужно было начать с резервного копирования данных, поступающих от наших мастеров. Из-за версий, используемых в производстве (основной мастер — 5,5, А1 и В1 — 5,6), мы начали с логического дампа, поэтому мы избежали решения проблем mysql_upgrade.
Отказ от ответственности: это не претендует на то, как настроить репликацию из нескольких источников
Для нашего случая мы сделали резервное копирование / восстановление, используя mydumper / myloader следующим образом:
[root@db1]$ mydumper -l 600 -v 3 -t 8 --outputdir /mnt/backup_db1/20150708 --less-locking --regex="^(database1.|database2.|database3.)"
[root@a1]$ mydumper -l 600 -v 3 -t 8 --outputdir /mnt/backup_a1/20150708 --less-locking --regex="^(tungsten_stats.|stats.)"
[root@b1]$ mydumper -l 600 -v 3 -t 8 --outputdir /mnt/backup_b1/20150708 --less-locking --regex="^(tungsten_finance.|finance.)"
Обратите внимание, что каждая команда была запущена на каждом главном сервере, теперь часть восстановления:
[root@db7]$ myloader -d /mnt/backup_db1/20150708 -o -t 8 -q 10000 -h localhost
[root@db7]$ myloader -d /mnt/backup_a1/20150708 -o -t 8 -q 10000 -h localhost
[root@db7]$ myloader -d /mnt/backup_b1/20150708 -o -t 8 -q 10000 -h localhost
Таким образом, на данный момент у нас есть новый ведомый с копией баз данных от 3 разных мастеров, просто для контекста нам нужно создавать / восстанавливать базы данных Tungsten *, потому что они постоянно обновляются Replicator (который на данный момент все еще используется). Довольно легко, верно?
Теперь самая важная часть всего этого процесса, настройка репликации. Процедура очень похожа на обычную репликацию, но теперь нам нужно рассмотреть, какая позиция бинлога необходима для каждого канала репликации, это очень легко получить из каждой резервной копии, прочитав в этом случае файл метаданных, созданный mydumper. В известных способах резервных копирования (или логический или физический) у вас есть способ получить Двоичные координаты, например -МАСТЕР-данные = 2 в туздЫшпре или xtrabackup_binlog_info файла в XtraBackup.
Как только мы получим информацию о репликации (и создадим пользователя репликации в master), нам нужно только запустить известные команды CHANGE MASTER TO
и START SLAVE
команды, но здесь у нас есть новый способ сделать это:
db7:information_schema> change master to master_host='db1', master_user='rep', master_password='rep', master_log_file='db1-bin.091487', master_log_pos=74910596 FOR CHANNEL 'main_master';
Query OK, 0 rows affected (0.02 sec)
db7:information_schema> change master to master_host='a1', master_user='rep', master_password='rep', master_log_file='a1-bin.394460', master_log_pos=56004 FOR CHANNEL 'a1_slave';
Query OK, 0 rows affected (0.02 sec)
db7:information_schema> change master to master_host='b1', master_user='rep', master_password='rep', master_log_file='b1-bin.1653245', master_log_pos=2563356 FOR CHANNEL 'b1_slave';
Query OK, 0 rows affected (0.02 sec)
Репликация установлена, и теперь мы готовы идти:
db10:information_schema> START SLAVE FOR CHANNEL 'main_master';
Query OK, 0 rows affected (0.00 sec)
db10:information_schema> START SLAVE FOR CHANNEL 'a1_slave';
Query OK, 0 rows affected (0.00 sec)
db10:information_schema> START SLAVE FOR CHANNEL 'b1_slave';
Query OK, 0 rows affected (0.00 sec)
Новые команды включают FOR CHANNEL 'channel_name'
возможность обрабатывать каналы репликации независимо
На этом этапе у нас есть подчиненное устройство, запускающее 3 канала репликации из разных источников, мы можем проверить состояние репликации с помощью нашей известной команды SHOW SLAVE STATUS
(TL; DR).
db10:information_schema> show slave statusG
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: db1
Master_User: rep
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: db1-bin.077011
Read_Master_Log_Pos: 15688468
Relay_Log_File: db7-relay-main_master.000500
Relay_Log_Pos: 18896705
Relay_Master_Log_File: db1-bin.076977
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table: mysql.%,temp.%
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 18896506
Relay_Log_Space: 2260203264
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 31047
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1004
Master_UUID: 65107c0c-7ab5-11e4-a85a-bc305bf01f00
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: System lock
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name: main_master
*************************** 2. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: a1
Master_User: slave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: a1-bin.072336
Read_Master_Log_Pos: 10329256
Relay_Log_File: db7-relay-db3_slave.000025
Relay_Log_Pos: 10329447
Relay_Master_Log_File: a1-bin.072336
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table: mysql.%,temp.%
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 10329256
Relay_Log_Space: 10329697
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 4000
Master_UUID: 0f061ec4-6fad-11e4-a069-a0d3c10545b0
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name: a1_slave
*************************** 3. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: b1.las1.fanops.net
Master_User: slave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: b1-bin.093214
Read_Master_Log_Pos: 176544432
Relay_Log_File: db7-relay-db8_slave.000991
Relay_Log_Pos: 176544623
Relay_Master_Log_File: b1-bin.093214
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table: mysql.%,temp.%
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 176544432
Relay_Log_Space: 176544870
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1001
Master_UUID:
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name: b1_slave
3 rows in set (0.00 sec)
Да, я знаю, что вывод слишком велик, и ребята из Oracle тоже это заметили, поэтому они создали набор новых таблиц в БД performance_schema, чтобы помочь нам получить эту информацию в дружественной манере, проверьте эту ссылку для получения дополнительной информации. Мы могли бы также запустить, SHOW SLAVE STATUS FOR CHANNEL 'b1_slave'
например,
Некоторые ограничения, найденные во время испытаний
- Как уже упоминалось, некоторые конфигурации все еще являются глобальными и не могут быть установлены для каждого канала репликации, например фильтры репликации, которые можно установить без перезапуска MySQL, но они будут влиять на все каналы репликации, как вы можете видеть здесь.
- События репликации каким-то образом сериализуются на ведомой стороне, как глобальный счетчик, который еще недостаточно документирован. В действительности это означает, что вам нужно быть очень осторожным при устранении неполадок, потому что вы можете столкнуться с неожиданными проблемами, например, если у вас 2 канала репликации, выходящие из строя с ошибкой дублирующегося ключа, тогда нелегко предсказать, что вы даже пропустите при запуске set global SQL_SLAVE_SKIP_COUNTER = 1
Выводы
Пока что эта новая функция выглядит очень красиво и обеспечивает некоторую дополнительную гибкость для подчиненных, что помогает уменьшить сложность архитектуры, когда мы хотим объединить базы данных из разных источников на одном сервере. После некоторого времени тестирования я бы сказал, что я предпочитаю этот тип репликации вместо Tungsten Replicator в таких сценариях, потому что это просто для администрирования, то есть pt-table-checkum и pt-table-sync будут работать без надлежащих ограничений Tungsten.
За исключением некоторых ограничений, которые необходимо устранить, я считаю, что эта новая функция меняет игру и, безусловно, облегчит жизнь администраторам баз данных. Мне еще предстоит многое проверить, но это материал для будущего поста.
Автор Франсисо Борденаве .