Репликация MySQL

Материал из Linux Wiki
Перейти к навигацииПерейти к поиску

Ниже собраны заметки и ссылки на тему репликации MySQL-баз данных.

Настройка репликации

Мастер-сервер

  • Добавляем нужные опции в конфиге на мастер-сервере:

[mysqld]
# Идентификатор сервера. На каждой связке серверов (как на мастерах, так и на слейвах) должен быть уникален.
# Является числом в диапазоне от 1 до 4294967295 (2^32-1)
server-id = 1
# Путь к бинарным логам, в которых сохраняются все изменения в базе данных мастер-сервера. Должно быть достаточно места под эти логи
log-bin = /var/lib/mysql/mysql-bin

# Сколько дней хранить бинарные логи на мастере. В некотором роде это еще и определяет, на сколько слейв может отстать от мастера
# expire_logs_days        = 10
# Размер файла бинлога (каждого отдельного файла)
# max_binlog_size         = 1024M

# Имя базы, для которой надо делать репликацию. При необходимости делать репликацию нескольких баз - повторить опцию с нужным именем базы
replicate-do-db = testdb

# Помимо этой опции, есть еще опции "обратного выбора" - для исключения выборки баз
# replicate-ignore-db=database_name 
# а также опции для репликации отдельных таблиц (аналогично - выбрать одну/несколько; исключить одну/несколько, а также определение имен через wildcard'ы)

# Эта опция нужна на тот случай, если этот мастер-сервер является слейвом по отношению к другому - чтобы слейв для данного мастера (суб-слейв основного мастера) тоже получал обновления
# Может пригодиться при репликации мастер-мастер с одним слейвом
# log-slave-updates

  • Даем права слейв-серверу делать репликацию с этого. Для этого в консоли mysql даем команду:

GRANT replication slave ON "testdb".* TO "repluser"@"replhost" IDENTIFIED BY "replpass";

где:

  • testdb - имя базы, к которой даем доступ на репликацию данному слейву
  • repluser - имя пользователя для подключения. Пользователь создается в момент выполнения команды.
  • replhost - IP-адрес или домен хоста слейв-сервера, который будет подключаться к этому мастеру
  • replpass - пароль для подключения

Перезапускаем сервер, после чего в консоли можно выполнить команду


SHOW MASTER STATUS;

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

Slave-сервер

  • Добавляем нужные опции в конфиге на slave-сервере:

[mysqld]
# Идентификатор сервера для данной связки серверов - см. описание выше
server-id = 2

# Relay-логи - логи, скачанные с мастер-сервера
# Указываем путь для этих логов; должно быть достаточно места для их хранения.
# relay-log = /var/lib/mysql/mysql-relay-bin
# relay-log-index = /var/lib/mysql/mysql-relay-bin.index

# Имя базы, которую будем реплицировать
replicate-do-db = testdb

Перезапускаем сервер для применения изменений

Запуск репликации

На мастере блокируем таблицы на запись для получения полностью корректного дампа:


FLUSH TABLES WITH READ LOCK;
SET GLOBAL read_only = ON;

Сливаем дамп с сервера. Кое-где обычно еще пишут про то, что необходимо смотреть позицию и имя лога на мастере - это не обязательно и решается ключом --master-data для mysqldump, который запишет необходимую информацию в сам дамп:


mysqldump --master-data -hmasterhost -umasteruser -pmasterpass masterdbname > dump.sql

После этого пускаем мастер в работу:


SET GLOBAL read_only = OFF;

(хотя возникает мысль - а действительно ли нужно лочить базу при дампе? Как только начал делаться дамп с --master-data - в него кидается имя лога и позиция, а таблицы автоматически лочатся на запись - т.е. все то же самое, только в автоматическом режиме)

Далее заливаем дамп на слейв-сервер как обычно:


mysql -hslavehost -uslaveuser -pslavepass slavedbname < dump.sql

В данном случае slavedbname = masterdbname, хотя при желании можно сделать так, чтобы база реплицировалась уже под другим именем.

Указываем слейву адрес мастер-сервера:


CHANGE MASTER TO MASTER_HOST = "masterip", MASTER_USER = "repluser", MASTER_PASSWORD = "replpass";

где masterip - IP-адрес или домен мастер-сервера, а остальные опции - те, что указывались выше при настройке мастера. Имя лог-файла и позиция берется из дампа, но при желании их можно вручную указать через опции MASTER_LOG_FILE = "имя_лога", MASTER_LOG_POS = позиция

После этой команды информация о мастере сохраняется в файле master.info в каталоге баз данных mysql-сервера. При желании можно указать эти опции в конфиге слейв-сервера:


master-host       = masterip
master-user       = repluser
master-password   = replpass
master-port       = 3306

После этого запускаем slave-сервер через mysql-консоль:


START SLAVE;

Теперь можно проверить статус slave-сервера командой


SHOW SLAVE STATUS;

Из интересной информации там могут быть поля:

  • Slave_IO_State: Waiting FOR master TO send event, Slave_IO_Running: Yes и Slave_SQL_Running: Yes - все работает хорошо :)
  • Seconds_Behind_Master - на сколько слейв отстал от мастера. В нормальном режиме должен быть 0

...и прочая текущая информация вроде отсутствия ошибок, текущей позиции и имени лога сервера, лога слейва и т.п.

Разное

Для mysqldump есть 2 опции для вписывания имени лога и позиции в файл дампа: --master-data и --dump-slave. Вторая есть не везде:


root@import:~# mysqldump --help | grep 'dump-slave'
root@import:~# mysqldump --version
mysqldump  Ver 10.13 Distrib 5.1.61, for portbld-freebsd8.2 (amd64)

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

Ошибки репликации

При работе репликации могут возникать ошибки - по какой-либо причине, например, ручном внесении данных на слейв-сервере.

Варианты решения:

1) Добавляем в конфиг слейв-сервера опцию для пропуска определенного типа ошибок, например:


skip-errors = 1062,1063

Перезапускаем сервер, после этого ошибки указанных типов будут игнорироваться

2) задать счетчик числа ошибок через mysql-консоль:


SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
START SLAVE;

Данный запрос установит счетчик пропуска ошибок равным единице (иными словами позволит пропустить одну ошибку).

Однако любой из вариантов предполагает, что после ошибки данные в базе слейв-сервера могут быть некорректны, поэтому лучше все же разобраться с ошибкой, залить на слейв дамп с бэкапа и запустить сервер заново.

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

Ссылки