MySQL 5.7 имеет множество улучшений и новых функций. Я суммировал этот список ранее в этом сообщении в блоге .
Добавление фильтров репликации в режиме онлайн является одной из функций MySQL 5.7, описанных в этом руководстве . Тем не менее, я опишу и обобщу несколько примеров в этом посте.
Фильтрация событий репликации также известна как частичная репликация. Частичная репликация может быть сделана от ведущего или ведомого. Фильтрация событий на главном сервере через binlog-do-db и binlog-ignore-db не очень хорошая идея, как объясняется в этом посте . Однако, если вам это действительно нужно, лучше использовать частичную репликацию на ведомом устройстве. Наш генеральный директор Питер Зайцев некоторое время назад написал подробный пост в блоге о фильтрованной репликации MySQL, который может оказаться полезным.
Частичная репликация работает по-разному для репликации на основе операторов и строк. Вы можете найти подробности в руководстве и на этой странице руководства . Полезно знать, как MySQL оценивает правила частичной репликации.
До MySQL 5.7 добавление / изменение правил репликации требовало отказов сервера MySQL. В MySQL 5.7 добавление / изменение правил фильтра репликации становится оперативной операцией без перезапуска сервера MySQL с помощью команды CHANGE REPLICATION FILTER. Позвольте мне поделиться несколькими примерами:
В настоящее время подчиненный сервер работает без фильтрованной репликации, и это можно проверить по статусу подчиненного устройства и последним пяти переменным. Replicate_ * имеет пустое значение, что означает, что правила фильтра репликации не установлены.
mysql> show slave statusG
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.0.130
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000002
Read_Master_Log_Pos: 351
Relay_Log_File: centos59-relay-bin.000003
Relay_Log_Pos: 566
Relay_Master_Log_File: master-bin.000002
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:
.
Главный сервер базы данных содержит db1-db4. Давайте реплицируем только db1 и db2 из четырех баз данных. Это можно сделать с помощью опции replicate-do-db .
mysql> CHANGE REPLICATION FILTER REPLICATE_DO_DB = (db1, db2);
ERROR 3017 (HY000): This operation cannot be performed with a running slave sql thread; run STOP SLAVE SQL_THREAD first
Эта ошибка CHANGE REPLICATION FILTER не поддерживается на работающем ведомом устройстве. Сначала нужно остановить подчиненный поток SQL и повторно запустить команду, чтобы установить параметр replicate-do-db. Проверка статуса подчиненного устройства подтвердила, что подчиненное устройство теперь реплицирует только базы данных db1 и db2 из четырех баз данных.
mysql> STOP SLAVE SQL_THREAD;
Query OK, 0 rows affected (0.00 sec)
mysql> CHANGE REPLICATION FILTER REPLICATE_DO_DB = (db1, db2);
Query OK, 0 rows affected (0.00 sec)
mysql> show slave statusG
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.0.130
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000002
Read_Master_Log_Pos: 505
Relay_Log_File: centos59-relay-bin.000003
Relay_Log_Pos: 720
Relay_Master_Log_File: master-bin.000002
Slave_IO_Running: Yes
Slave_SQL_Running: No
Replicate_Do_DB: db1,db2
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
.
Чтобы удалить этот фильтр, вам нужно пустое значение для имени фильтра; то есть, replicate-do-db, как показано ниже. Статус ведомого подтвердил, что для переменной replicate-do-db не заданы фильтры репликации.
mysql> STOP SLAVE SQL_THREAD;
Query OK, 0 rows affected (0.03 sec)
mysql> CHANGE REPLICATION FILTER REPLICATE_DO_DB = ();
Query OK, 0 rows affected (0.00 sec)
mysql> START SLAVE SQL_THREAD;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW SLAVE STATUSG
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.0.130
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000002
Read_Master_Log_Pos: 1629
Relay_Log_File: centos59-relay-bin.000003
Relay_Log_Pos: 1844
Relay_Master_Log_File: master-bin.000002
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> STOP SLAVE SQL_THREAD;
Query OK, 0 rows affected (0.03 sec)
mysql> CHANGE REPLICATION FILTER
REPLICATE_WILD_DO_TABLE = ('db1.db1_new%'),
REPLICATE_WILD_IGNORE_TABLE = ('db1.db1_old%');
mysql> START SLAVE SQL_THREAD;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW SLAVE STATUSG
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.0.130
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000003
Read_Master_Log_Pos: 448
Relay_Log_File: centos59-relay-bin.000006
Relay_Log_Pos: 663
Relay_Master_Log_File: master-bin.000003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table: db1.db1_new%
Replicate_Wild_Ignore_Table: db1.db1_old1%
.
Состояние ведомого устройства проверяет, что есть несколько установленных фильтров репликации, где db1.db1_new реплицирует двоичные события журнала на ведомое устройство, которое игнорирует события репликации на ведомом устройстве для таблиц db1.db1_old согласно фильтру Replicate_Wild_Ignore_Table . Кроме того, если имя базы данных или таблицы не содержит каких-либо специальных символов, тогда нет необходимости указывать в качестве значения для фильтра. Однако Replicate_Wild_Do_Table и Replicate_Wild_Ignore_Table являются строковыми выражениями и могут содержать символы подстановки, поэтому их необходимо заключать в кавычки.
С помощью команды CHANGE REPLICATION FILTER вы не можете установить одно и то же правило фильтрации несколько раз, в отличие от поведения, когда вы можете установить несколько фильтров для одного и того же правила в файле my.cnf, указав его несколько раз. С помощью команды CHANGE REPLICATION FILTER, если вы попытаетесь установить несколько фильтров для одного и того же правила, будет активировано только последнее правило, а все вышеперечисленные правила будут проигнорированы, как показано в следующем примере:
mysql> SELECT * FROM db1.db1_old;
Empty set (0.00 sec)
mysql> STOP SLAVE SQL_THREAD;
Query OK, 0 rows affected (0.03 sec)
mysql> CHANGE REPLICATION FILTER
REPLICATE_WILD_DO_TABLE = ('db2.db2_tbl1%'),
REPLICATE_WILD_DO_TABLE = ('db2.db2_tbl2%');
mysql> START SLAVE SQL_THREAD;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW SLAVE STATUSG
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.0.130
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000003
Read_Master_Log_Pos: 980
Relay_Log_File: centos59-relay-bin.000006
Relay_Log_Pos: 1195
Relay_Master_Log_File: master-bin.000003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table: db2.db2_tbl2%
Replicate_Wild_Ignore_Table:
.
Как видите, таблица db2.db2_tbl1 игнорируется и активируется только последнее правило для таблицы db2.db2_tbl2.
Как я упоминал ранее, чтобы отменить фильтры любого типа, вам нужно установить этот конкретный фильтр на пустое значение. В приведенном ниже примере будет отключен фильтр Replicate_Wild_Do_Table.
mysql> CHANGE REPLICATION FILTER REPLICATE_WILD_DO_TABLE = ();
Однако вы можете установить несколько фильтров в одной команде, разделяя каждое правило запятой, как в предыдущем примере с Replicate_Do_DB. Давайте установим несколько правил для опции Replicate_Wild_Do_Table с помощью команды CHANGE REPLICATION FILTER.
mysql> STOP SLAVE SQL_THREAD;
Query OK, 0 rows affected (0.03 sec)
mysql> CHANGE REPLICATION FILTER
REPLICATE_WILD_DO_TABLE = ('db2.db2_tbl1%','db2.db2_tbl2%');
Query OK, 0 rows affected (0.00 sec)
mysql> START SLAVE SQL_THREAD;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW SLAVE STATUSG
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.0.130
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000008
Read_Master_Log_Pos: 154
Relay_Log_File: centos59-relay-bin.000013
Relay_Log_Pos: 369
Relay_Master_Log_File: master-bin.000008
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table: db2.db2_tbl1%,db2.db2_tbl2%
Replicate_Wild_Ignore_Table:
Last_Errno: 0
.
.
Вывод:
частичная репликация не является хорошим решением в большинстве случаев. Все параметры replicate-do-table, replicate-ignore-table , replicate-wild-do-table и replicate-wild- do-table и replicate-wild-ignore-table работают по-разному. Вам нужно использовать базу данных по умолчанию для нормальной работы фильтрации, и она ведет себя по-разному в другом формате binlog. Фильтры, отличные от replicate-wild-do-table и replicate-wild-ignore-table, могут работать не так, как ожидалось, и события с wild% фильтрами хранимых процедур и хранимых функций могут быть несовместимыми .
[Эта статья была написана Мухаммедом Ирфаном в Перконе]