Репликация MySQL на уже работающем сервере

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

При использовании описанного ниже подхода стоит рассчитывать на даунтайм основного сервера на время его перезапуска. В примере использовался сервер под управлением Ubuntu и MySQL 5.0 из основного репозитория с настройками по умолчанию. Я исходил из того, что реплицировать нужно все базы данных, за исключением системных.

На главном сервере.

Надо поправить файл /etc/mysql/my.cnf:

[mysqld]
# Необходимо открыть доступ к серверу по сети,
# что бы slave имел возможность подключиться
# и не забыть закрыть этот доступ, например файрволом, для тех, кому он не нужен
bind-address            = 0.0.0.0
server-id               = 1
log_bin                 = /var/log/mysql/mysql-bin.log
expire_logs_days        = 10
max_binlog_size         = 100M
# Исключим ненужные БД
#binlog_do_db           = include_database_name
binlog_ignore_db        = information_schema
binlog_ignore_db        = mysql
binlog_ignore_db        = test
# Это рекомендуется для более стабильной работы репликации баз на InnoDB
innodb_flush_log_at_trx_commit=1
sync_binlog=1

Перезапускаем mysql:

/etc/init.d/mysql restart

Выдаем slave права на репликацию:

mysql -u root
GRANT REPLICATION SLAVE ON *.* TO 'replication'@'10.0.0.2' IDENTIFIED BY 'slave_password';
FLUSH PRIVILEGES;

Посмотреть статус можно командой:

SHOW MASTER STATUS;
+------------------+----------+--------------+-------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB              |
+------------------+----------+--------------+-------------------------------+
| mysql-bin.000015 |       98 |              | information_schema,mysql,test |
+------------------+----------+--------------+-------------------------------+
1 row in set (0.00 sec)

Далее делаем дамп существующих баз данных. Ключи –single-transaction –master-data –flush-logs должны глобально заблокировать на время дампа базу данных на запись и вписать в дамп номер и позицию лога, с которых надо начать репликацию на slave. Это обеспечит точность совпадения данных на главном и slave серверах, даже если с главным сервером в этот момент идет работа и записываются данные.

mysqldump -u root --single-transaction --master-data --flush-logs --databases db1 db2 db3 > ALL_DB.sql

Если посмотреть внутрь ALL_DB.sql, то там должна присутствовать строка:

CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000015', MASTER_LOG_POS=98;

Далее копируем дамп на slave:

scp ALL_DB.sql 10.0.0.2:

Продолжаем на втором сервере.

Убеждаемся что там нет остатков настроек репликации, в принципе, если на сервере нет нужных данных, не помешает переустановить mysql с очисткой папок БД.

Так как начиная с версии MySQL 5.2 параметры доступа для репликации убираются из my.cnf сразу перейдем на использование такой схемы.

Правим файл /etc/mysql/my.cnf:

[mysqld]
# ID slave должен отличаться от главного сервера
server-id               = 2
replicate-ignore-db     = information_schema
replicate-ignore-db     = mysql
replicate-ignore-db     = test
relay-log               = /var/log/mysql/mysqld-relay-bin.log

Перезапускаем сервер:

/etc/init.d/mysql restart

Поправим файл ALL_DB.sql:

Дописываем к строке

CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000015', MASTER_LOG_POS=98;

параметры доступа:

CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000015', MASTER_LOG_POS=98, MASTER_HOST='10.0.0.1', MASTER_USER='replication',
MASTER_PASSWORD='slave_password', MASTER_CONNECT_RETRY=60;

Загружаем данные:

mysql -u root < ALL_DB.sql

Проверяем состояние репликации, она НЕ должна быть запущена (Slave_IO_Running, Slave_SQL_Running: no, no):

mysql -u root
show slave status;

Запускаем репликацию (теперь должно быть Slave_IO_Running, Slave_SQL_Running: yes, yes):

START SLAVE;
show slave status;

Для проверки можно попробовать перезапустить mysql и проверить состояние репликации еще раз:

/etc/init.d/mysql restart
mysql -u root
show slave status;

Остается по желанию проверить репликацию, создав, например, тестовую таблицу или добавив данные в существующую и убедиться, что изменения отразились на slave.

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

One thought on “Репликация MySQL на уже работающем сервере

  1. Вы серьезно? Название “… на уже работающем…”, читаем дальше, “перезапускаем”. А если нельзя перезапускать? Он же работает под сотнями запросов в секунду.

Оставить комментарий