Переход к предыдущей публикации Хитрый Апач или алфавит на первом месте Самый простой вариант использования SSH туннеля или… как обойти сисадмина :) Переход к следущей публикации

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

Четверг, 18 сентября, 2008 00:26:48 EEST

Исправления от 23 марта, 2009 13:54:43

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

Daemony

Автор: mms@

MySQL Logo

Цели которые ставились:

Есть два сервера MySQL работающих на разных хостах соединенных между собой VPN каналом. Два сервера независимы и работают со своими базами данных. Есть задача настроить репликацию  с первого на второй и со второго на первый серверы.

Далее привожу пример готового решения.

На обеих хостах версии MySQL 5.0.51. Сразу оговорюсь, “счастливым обладателям” MySQL 3.x.x версий все-таки обновиться до последних, ну или хотя бы до 4.1.

Важный момент: Сервера должны работать с одинаковыми кодировками.

Итак поехали. Для начала необходимо сделать копию директорий для нашего первого SLAVE сервера. Предварительно необходимо остановить процесс на сервере с которого мы копируем данные:

$mysqladmin -u root -p shutdown

После остановки делаем копию /var/db/mysql, запаковываем переносим на удаленный хост и например распаковываем в /var/db/mysql_slave. Не забываем стартануть MySQL на первой машине.

Теперь опять возвращаемся к первой машине и настраиваем сервер как MASTER. Для начала создаем пользователя который у нас будет использоваться для удаленного доступа.

Для примера:
MASTER HOST - IP 10.0.0.1
SLAVE  HOST - IP 10.0.0.5

Далее:

mysql> GRANT ALL ON *.* TO replicator_user@"10.0.0.5" IDENTIFIED 'verystrongpassword';

После того как пользователь создан добавляем в /etc/my.cnf или /usr/local/etc/my.cnf, (если файла нет то создаем его), в секцию [mysqld] две строчки:

[mysqld]
#путь для бинарного лога который будет читать slave server
log-bin=/var/db/mysql/mysql-bin
#ID сервера должен быть уникальным для каждого хоста в системе MASTER-SLAVE
server-id=1

После чего перезапускаем сервер, проверяем работает ли он как MASTER:

mysql> show master status \G
*************************** 1. row ***************************
File: mysql-bin.000008
Position: 12304226
Binlog_Do_DB:
Binlog_Ignore_DB:
1 row in set (0.00 sec)

Если появилось что-то подобное, значит все в порядке. Теперь переходим к настройке SLAVE сервера на хосте 10.0.0.5. Задача немного усложняется, так как на этом сервере уже есть MySQL и нам надо запустить еще один сервер но на другом порту. Например на 3308 , создаем файл конфигурации для запуска этого сервера:

$touch mysql3308.sh
$chmod +x mysql3308.sh

Прописываем в него следующие параметры:

/usr/local/bin/mysqld_safe
#тут все понятно, пользователь от имени которого запускается процесс.
--user=mysql \
#путь к базам банных, (которые мы скопировали с хоста 10.0.0.1)
--datadir=/var/db/mysql_slave \
#порт на котором наш сервер будет работать
--port=3308 \
#сокет, (ну куда же без него)
--socket=/tmp/mysql3308.sock \
#пид - файл, (ситуация такая же как и с сокетом)
--pid-file=/var/db/mysql_slave/mysql3308.pid \
#наш мастер-хост
--master-host=10.0.0.1 \
#пользователь
--master-user=replicator_user \
#пароль
--master-password=verystrongpassword \
#удаленный порт
--master-port=3306 \
#очень важная опция, я поставил так, как в одном месте имею кривую таблицу и лень ее править,
#дело в том, что без этой опции при возникновении любой ошибки при репликации, например в случае,
#когда дублируется уникальный ключ, SLAVE будет падать и вам необходимо будет самостоятельно устранять
#ошибку после чего перезапускать SLAVE.
--slave-skip-errors=all \
#ID сервера, должен быть уникальным.
--server-id=2 &

Сохраняем файл, запускаем. Получаем ошибку. Точно! Надо поставить правильные права на папку /var/db/mysql_slave

$chown -R mysql:mysql /var/db/mysql_slave

Запускаем снова. Если запуск прошел без ошибок заходим на SLAVE. Внимание: при подключении на порт, отличающемся от порта по умолчанию, необходимо обязательно указывать сокет).

$mysql -u root -p --port=3308 --socket=/tmp/mysql3308.sock

Проверяем работу SLAVE

mysql> show slave status \G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.0.01
Master_User: replicator_user
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000005
Read_Master_Log_Pos: 6572646
Relay_Log_File: mysql3307-relay-bin.000009
Relay_Log_Pos: 6299527
Relay_Master_Log_File: mysql-bin.000005
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:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 6572646
Relay_Log_Space: 0
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
1 row in set (0.00 sec)

Если получаем вот такую таблицу, значит все хорошо, если в первой строке отличная от “Waiting for master to send event” значит что-то пошло не так. Читаем ошибку и пробуем с ней разобраться, хотя в нашем случае с добавленной опцией –slave-skip-errors=all это маловероятно, вероятно что запрос вернет пустой результат, тогда необходимо сделать старт SLAVE.

mysql> START SLAVE;

После всего этого на хосте 10.0.0.5 проверяем:

$netstat -a | grep 330

Мы должны увидеть примерно такую картину

#установлено соединение на MASTER
tcp4       0      0  10.0.0.5.55588         10.0.0.1.3306    ESTABLISHED
#наш сервер MySQL на 3308 порту
tcp4       0      0  *.3308                 *.*                    LISTEN
#наш сервер MySQL на 3306 порту
tcp4       0      0  *.3306                 *.*                    LISTEN
c240c510 stream      0      0 c29ae880        0        0        0 /tmp/mysql3308.sock

После всех этих действий выполняем все то же самое только наоборот, после того как все поднялось и заработало, пьем пиво и тащимся от того, что все работает.

Что еще полезно знать о репликации:

  • Если у вас на MASTER хосте в запросах используются MySQL ф-ции RAND,NOW(),CURTIME() и другие не ждите, что на SLAVE хосте значения окажутся точно такими же.
  • SLAVE может быть сколько угодно времени отключенным, после запуска он начинает потихоньку догонять MASTER`a
  • При переносе данных с одного хоста на другой можно смело удалять бинарные логи, на работу это никак не влияет.
  • Если вы делаете LOAD DATA FROM MASTER и получаете ошибку, скорее всего у вас на MASTER хосте естьInnoDB таблицы с которыми данная комманда благополучно не работает, в этом случае делайте тогда LOAD TABLE dbname.table FROM MASTER

Также рекомендуется почитать о репликации в Википедии.

Успехов. Надеюсь статья окажется кому нибудь полезной. :)

Похожие публикации

Выделенные сервера дешевле обычного хостинга

1 комментарий

cod 5 ноября, 2008 17:10:42 EET .:. ID #1014 .:.

Сохраняем файл, запускаем. Получаем ошибку.

Посмеялся. Опасно, вот так, пошагово делать, нужно сперва прочитать до конца и сделать за один раз ;)

Возник вопрос по этой теме, или есть что добавить? Говорите!

  1. Зарегистрированным пользователям вводить защитный код (captcha) не приходится.
  2. Загрузить свою аватарку Вы сможете, зарегистрировавшись на сервисе www.gravatar.com
Публикуя комментарий Вы подтверждаете, что ознакомились c Правилами и принимаете их!
HOMOSAPIENS ONLY! :)