Репликация MySQL: различия между версиями

Материал из Linux Wiki
Перейти к навигацииПерейти к поиску
м (про узкий канал между master и slave)
Строка 169: Строка 169:


* '''Slave_IO_State: Waiting FOR master TO send event''', '''Slave_IO_Running: Yes''' и '''Slave_SQL_Running: Yes''' - все работает хорошо :)
* '''Slave_IO_State: Waiting FOR master TO send event''', '''Slave_IO_Running: Yes''' и '''Slave_SQL_Running: Yes''' - все работает хорошо :)
* '''Seconds_Behind_Master''' - на сколько слейв отстал от мастера. В нормальном режиме должен быть 0
* '''Seconds_Behind_Master''' - на сколько слейв отстал от мастера. В нормальном режиме должен быть 0, однако 0 при реальном отставании может быть и в том случае, если на мастере производится много изменений, а канал между мастером и слейвом узкий и последний не успевает скачивать бинлоги с мастера. В таком случае "0" корректен, но лишь для того, что успело скачаться из логов.


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

Версия 17:02, 17 сентября 2012

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

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

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

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

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

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

# Включаем сжатие пересылаемых на Slave логов
slave_compressed_protocol = 1

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

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

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

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

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

где:

  • repluser - имя пользователя для подключения. Пользователь создается в момент выполнения команды.
  • replhost - IP-адрес или домен хоста слейв-сервера, который будет подключаться к этому мастеру
  • replpass - пароль для подключения
Ограничение на базу для репликации в grant replication вроде как не работает - т.е., разрешаем все, а в конфиге указываем только ту базу / базы, которые нужны

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


mysql> SHOW MASTER STATUS;

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

Slave-сервер

  • Добавляем нужные опции в конфиге my.cnf на 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

# Включаем сжатие пересылаемых на Slave логов
slave_compressed_protocol = 1

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

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

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


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

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


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

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


mysql> SET GLOBAL read_only = OFF;

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

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


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

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

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


mysql> 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-консоль:


mysql> START SLAVE;

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


mysql> SHOW SLAVE STATUS;

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

  • Slave_IO_State: Waiting FOR master TO send event, Slave_IO_Running: Yes и Slave_SQL_Running: Yes - все работает хорошо :)
  • Seconds_Behind_Master - на сколько слейв отстал от мастера. В нормальном режиме должен быть 0, однако 0 при реальном отставании может быть и в том случае, если на мастере производится много изменений, а канал между мастером и слейвом узкий и последний не успевает скачивать бинлоги с мастера. В таком случае "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)

--dump-slave[=value]

This option is similar to --master-data except that it is used to dump a replication slave server 
to produce a dump file that can be used to set up another server as a slave that has the same master as the dumped server.
It causes the dump output to include a CHANGE MASTER TO statement that indicates the binary log coordinates (file name and position)
of the dumped slave's master (rather than the coordinates of the dumped server, as is done by the --master-data option).
These are the master server coordinates from which the slave should start replicating. This option was added in MySQL 5.5.3. 

Соответственно, одна опция - для клонирования слейва, вторая - для создания субслейва. Иначе говоря, dump-slave позволяет в цепочке master-slave1-slave2 создать (с помощью slave1) еще один slave1 (в дамп запишется позиция в логе и файл лога относительно логов master), master-data позволяет создать slave2 - в дамп запишется позиция/лог относительно бинлогов slave1.

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

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

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

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


skip-errors = 1062,1063

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

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


mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
mysql> START SLAVE;

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

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

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

Ссылки