Репликация MySQL на одном компьютере

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

Прелюдия. Понадобилось мне организовать двухстороннюю репликацию БД на двух mysql-серверах, запущенных на одной машине (для обхода блокировки myisam-таблиц). Казалось бы ничего сложного и особенного тут нет, учитывая то, что я знаю как запускать несколько mysql-серверов на одной машине и как организовать репликацию БД между двумя разными машинами. Но задача оказалась не самой простой. Не буду рассказывать, как в течение целого дня бился с конфигами, сколько вариантов запуска перепробовал и т.д., а просто напишу про подводные камни:

Подводный камень №1. У mysql есть параметры master-host, master-port, но нет параметра master-socket, поэтому когда я для первого сервера написал
master-host = localhost
master-port = 3307,
он цеплялся не к 127.0.0.1:3307, а к /tmp/mysql.sock, т.е. к самому себе, а не ко второму серверу. Причём в логах информация о том, куда он на самом деле цепляется случайно появилась только когда я там сильно нахимичил.
Обход этой проблемы — написать master-host = 127.0.0.1.

Подводный камень №2. Даже просле того, как я в my.cnf изменил master-host на 127.0.0.1, система ни хрена не заработала. Тут причина в том, что оказывается параметр master-host и некоторые другие параметры репликации считываются из основного конфига только в том случае, если что-то не в порядке с файлом master.info (он создаётся автоматом в каталоге данных), например, он просто отсутствует, а если он существует, то master-host считывается оттуда, и серверу положить, что я там поменял в my.cnf. В документации об этом сказано, но я это нашёл уже после того, как сам выяснил путём эксперимента… надо было выделить это красным жирным шрифтом, блин.

Обход этой проблемы — отредактировать вручную, либо, что проще, удалить master.info, не забыв перед этим остановить сервер mysql. При удалении потеряется оперативная инфа по репликации — текущий файл журнала — так что надо быть осторожным, безопаснее всё же отредактировать.

Что в итоге получилось. Вот кусок my.cnf, относящийся к делу, с которым всё работает замечательно (версия mysql 4.0.18):

################
# MySQL server 1
[mysqld1]
port           = 3306
socket         = /tmp/mysql.sock
datadir        = /data/mysql1
pid-file       = /data/mysql1/mysqld.pid
user           = mysql

# replication
log-bin
server-id      = 1
binlog-do-db   = test

master-host       = 127.0.0.1
master-port       = 3307
master-user       = replicator
master-connect-retry = 10
replicate-do-db   = test
################

################
# MySQL server 2
[mysqld2]
port           = 3307
socket         = /tmp/mysql2.sock
datadir        = /data/mysql2
pid-file       = /data/mysql2/mysqld.pid
user           = mysql

# replication
log-bin
server-id      = 2
binlog-do-db   = test

master-host       = localhost
master-port       = 3306
master-user       = replicator
master-connect-retry = 10
replicate-do-db   = test
################

На первом сервере следует сделать:
GRANT REPLICATION SLAVE ON *.* TO replicator@localhost;

на втором:
GRANT REPLICATION SLAVE ON *.* TO replicator@127.0.0.1;

О производительности (вместо заключения). Как видите, для второго сервера я оставил master-host = localhost, это вполне правомерно, т.к. он будет соединяться с /tmp/mysql.sock, т.е. к первому серверу, а нам туда и надо. Вроде бы как обмен через unix domain около двух раз быстрее, чем через сетевые сокеты. Вряд ли это может сильно повлиять на производительность репликации, тем более, что в большинстве случаев она реализуется между двумя разными машинами через сеть. Но несмотря на это смущает то, что разработчики mysql не предположили случая репликации на одном компьютере и не реализовали параметр master-socket. Написал им feature-request по этому поводу, посмотрим что скажут…

Автор: нет данных