Статьи

Отключить ведомое устройство репликации проще с MySQL 5.5+

Это сообщение  написано Стефаном Комбоудоном в блоге MySQL Performance.

Нередко продвигать сервер от подчиненного к ведущему. Одна из ключевых вещей для защиты вашей целостности данных — убедиться, что продвигаемое ведомое устройство постоянно отключено от своего старого мастера. Если нет, он может получить записи от старого мастера, что может вызвать все виды повреждения данных. MySQL предоставляет удобную RESET SLAVEкоманду. Но, как мы увидим, его поведение изменилось вместе с версиями MySQL, и вы легко можете выстрелить себе в ногу, если используете его неправильно. Так как же безопасно отключить подчиненное устройство репликации?

Вкратце

  • Для MySQL 5.0 и 5.1 запустите STOP SLAVE, CHANGE MASTER TO MASTER_HOST=''а затем RESET SLAVE.
  • Для MySQL 5.5 и 5.6 запустите STOP SLAVEи затем RESET SLAVE ALL.
  • Для всех версий, запрет master-user, master-hostи master-passwordнастройки в my.cnf, это может вызвать большие проблемы (это уже в любом случае не поддерживается MySQL 5.5).

Если вы хотите узнать больше деталей, пожалуйста, читайте дальше!

MySQL 5.0 / 5.1

Сначала давайте рассмотрим MySQL 5.0 и 5.1. RESET SLAVEудалит файлы master.info и relay-log.info, а также все файлы журнала ретрансляции. Это выглядит великолепно, но гарантирует, что реплика отключена от своего хозяина?
Давай попробуем:

mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
mysql> reset slave;
Query OK, 0 rows affected (0.03 sec)
mysql> show slave status\G
*************************** 1. row ***************************
             Slave_IO_State:
                Master_Host: 127.0.0.1
                Master_User: test
                Master_Port: 3306
              Connect_Retry: 60
            Master_Log_File:
        Read_Master_Log_Pos: 4
             Relay_Log_File: mysql_sandbox35302-relay-bin.000001
              Relay_Log_Pos: 4
      Relay_Master_Log_File:
           Slave_IO_Running: No
          Slave_SQL_Running: No
          		[...]

Этого не ожидается: вместо удаления всех настроек некоторые из них сбрасываются до значений по умолчанию. Это означает, что если вы запустите START SLAVE(или если это будет сделано автоматически, например, при перезапуске сервера без skip-slave-startопции), репликация может начаться снова. Но поскольку основная позиция была удалена, репликация будет перезапущена в начале первого доступного двоичного журнала, что очень может повредить ваши данные, выполнив некоторые запросы повторно.

Вот трюк, чтобы сделать RESET SLAVEработу, как ожидалось: использоватьCHANGE MASTER TO MASTER_HOST='':

mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
mysql> change master to master_host='';
Query OK, 0 rows affected (0.02 sec)
mysql> reset slave;
Query OK, 0 rows affected (0.04 sec)
mysql> show slave status\G
Empty set (0.00 sec)
mysql> start slave;
ERROR 1200 (HY000): The server is not configured as slave; fix in config file or with CHANGE MASTER TO

Намного лучше! Если мы попытаемся перезапустить репликацию, произойдет сбой. Тем не менее, мне не нравится сообщение об ошибке, в частности, часть «исправить в файле конфигурации». Что произойдет , если мы указываем master-user, master-password, master-hostи master-portв файле my.cnf?

# cat my.cnf
[...]
master-user=rsandbox
master-password=rsandbox
master-host=127.0.0.1
master-port=35301
[...]

Давайте отключим раб:

mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
mysql> change master to master_host='';
Query OK, 0 rows affected (0.03 sec)
mysql> reset slave;
Query OK, 0 rows affected (0.03 sec)
mysql> show slave status\G
*************************** 1. row ***************************
             Slave_IO_State:
                Master_Host: 127.0.0.1
                Master_User: rsandbox
                Master_Port: 35301
              Connect_Retry: 60
            Master_Log_File:
        Read_Master_Log_Pos: 4
             Relay_Log_File: mysql_sandbox35302-relay-bin.000001
              Relay_Log_Pos: 4
      Relay_Master_Log_File:
           Slave_IO_Running: No
          Slave_SQL_Running: No
          [...]

Настройки подключения автоматически восстанавливаются, что делает невозможным отключение реплики. И снова, если вы перезапустите репликацию, он будет читать события из первого доступного двоичного файла журнала на главном сервере, что, вероятно, не то, что вам нужно. Поэтому никогда не устанавливайте переменные master-xxx в my.cnf!

Из MySQL 5.5

Начиная с MySQL 5.5, ситуация немного изменилась. Сначала переменные master-xxx больше не поддерживаются, что является большим улучшением. Но RESET SLAVEутверждение также ведет себя по-другому:

mysql> stop slave;
Query OK, 0 rows affected (0,01 sec)
mysql > reset slave;
Query OK, 0 rows affected (0,11 sec)
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State:
                  Master_Host: 127.0.0.1
                  Master_User: rsandbox
                  Master_Port: 18675
                Connect_Retry: 60
              Master_Log_File:
          Read_Master_Log_Pos: 4
               Relay_Log_File: mysql_sandbox18676-relay-bin.000001
                Relay_Log_Pos: 4
        [...]

Как указано в документации , параметры подключения по-прежнему хранятся в памяти. В любом случае вы сможете перезапустить репликацию, но, опять же, поскольку координата репликации не указана, репликация начнется в начале первого доступного двоичного файла журнала со всеми неприятными последствиями, которые мы можем себе представить.

Хуже того, CHANGE MASTER TO MASTER_HOST=''трюк больше не работает:

mysql> stop slave;
Query OK, 0 rows affected (0,01 sec)
mysql> change master to master_host='';
ERROR 1210 (HY000): Incorrect arguments to MASTER_HOST

К счастью, в документации также указано, что мы можем использовать RESET SLAVE ALLдля удаления всех настроек, связанных с репликацией:

mysql> stop slave;
Query OK, 0 rows affected (0,00 sec)
mysql> reset slave all;
Query OK, 0 rows affected (0,04 sec)
mysql> show slave status\G
Empty set (0,00 sec)

Очень хорошо! Команда работает должным образом без каких-либо дополнительных уловок. Как только вы узнаете о разнице между RESET SLAVEи RESET SLAVE ALL, отключение репликации ведомого становится намного проще с MySQL 5.5+.