04.10.2010 - MySQL Master-Master-Slave(s) репликация баз данных

0.250 Предисловие:

Как я уже писал, существует такая связка (репликация) база данных MySQL как Мастер - Мастер. И вот, как обычно, встала необходимость присоединить еще одного слейва к этой конструкции. Попробую рассказать о связке (репликаций) MySQL Master-Master-Slave.

0.500 Имею:

3 железки с MySQL, две из них уже реплицируются как мастер-мастер, на третьей предустановлен Centos 5.5, MySQL(MariaDB).

0.750 Надо:

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

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

Самым безопасным решением является просто никогда не записывать данные на обоих мастерах. Хотя, Есть стратегии, которые позволяют безопасно писать на несколько мастеров. Например, каждый мастер пишет только в конкретные таблицы на каждом главном сервере. В моем случае я использую вторичного мастера в качестве источника репликации и горячего резервирования в случае если мне нужно, снять Primary Master на техническое обслуживание. Использование вторичного мастера, как источник репликации принимает бремя на себя.

1.1 Конфигурация мастера

Мы имеем двух мастеров. Их ид 1 и 2. (Слейвы будем обозначать как 11, 12, итд.)

Первым делом, вы должны установить пароли root`а для каждого из ваших мастер серверов MySQL.

Master 1

Добавим следующее в секцию [mysqld] вашего my.cnf и перезапустим mysqld:

# primary master server id
server-id=1
auto_increment_offset=1
# total number of master servers
auto_increment_increment=2
# local slave replication options
log-bin=master1-bin
log-slave-updates
# remote master replication options
master-host=master2.yourdomain.com
master-port=3306
master-user=replica
master-password=replic8
master-connect-retry=10


Master 2
Добавим следующее в секцию [mysqld] вашего my.cnf и перезапустим mysqld:

# secondary master server id
server-id=2
auto_increment_offset=2
# total number of master servers
auto_increment_increment=2
# local slave replication options
log-bin=master2-bin
log-slave-updates
# remote master replication options
master-host=master1.yourdomain.com
master-port=3306
master-user=replica
master-password=replic8
master-connect-retry=10



1.2 Создаем аккаунты для репликации
На каждом из мастер серверов выполняем следующий запрос от root:
mysql> GRANT REPLICATION SLAVE ON *.* TO 'replica'@'%' IDENTIFIED BY 'replic8';

1.3 Дампим/Загружаем данные и запускаем репликацию

На Master 1

Запрещаем запись данных в мастер1

mysql> FLUSH TABLES WITH READ LOCK;
mysql> SHOW MASTER STATUS\G
*************************** 1. row ***************************
File: master1-bin.000001
Position: 254
Binlog_Do_DB:
Binlog_Ignore_DB:
1 row in set (0.20 sec)


Запоминаем название бинлог-файла и позицию. Необходимо не забыть эти данные, они потребуются позже.
Из терминала вы дожны сдампить базу, для загрузки ее на слейвах.

bash> mysqldump -A -u root -p > master1.sql


На Master 2

Загружаем данные с Master 1 на Master 2.

bash> mysql -h master2.yourdomain.com -u root -p < master1.sql

Добаляем Master 2 как слев для Master 1 (refer to master 1's show master status above for MASTER_LOG* values)

mysql> CHANGE MASTER TO
MASTER_HOST='master1.yourdomain.com',
MASTER_USER='replica',
MASTER_PASSWORD='replic8',
MASTER_LOG_FILE='master1-bin.000001',
MASTER_LOG_POS=254;
mysql> START SLAVE;


Настраиваем лог для Master 2

mysql> SHOW MASTER STATUS\G
*************************** 1. row ***************************
File: master2-bin.000005
Position: 12314580
Binlog_Do_DB:
Binlog_Ignore_DB:
1 row in set (0.00 sec)


На Master 1
Включаем Master 1 как слейв для Master 2
mysql> CHANGE MASTER TO
MASTER_HOST='master2.yourdomain.com',
MASTER_USER='replica',
MASTER_PASSWORD='replic8',
MASTER_LOG_FILE='master2-bin.000005',
MASTER_LOG_POS=12314580;
mysql> START SLAVE;


Настройка Мастер-Мастер закончена!

Если вам нужна была настройка MySQL master-master то она уже закончена. Любые запросы, выполенные на мастер 1 так же будут также выполнены на мастер2.

2. Добавление Слейвов к вашей Master-Master конфигурации.

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

Добавляем следующее в [mysqld] секцию вашего my.cnf, изменяя server-id и перезапускаем mysqld:

# this slave's server-id
server-id=11
# replicate from master 2
master-host=master2.yourdomain.com
master-port=3306
master-user=replica
master-password=replic8
master-connect-retry=10


Загружаем данные из дампа с Master 1, если необходимо:


bash> mysql -h slave11.yourdomain.com -u root -p < master1.sql


Запускаем репликацию с Мастера 2 для каждого слейва

mysql> CHANGE MASTER TO
MASTER_HOST='master2.yourdomain.com',
MASTER_USER='replica',
MASTER_PASSWORD='replic8',
MASTER_LOG_FILE='master2-bin.000005',
MASTER_LOG_POS=12314580;
mysql> START SLAVE;


Настройка Мастер-Мастер-Слейв (Master-Master-Slave) завершена!!!
Поздравляю, Вы закончили настройку сервера! Теперь любые изменения вносимые на любой из мастер серверов будут автоматически обновляться и на каждом из ваших слейв серверов.

От автора без перевода...

Client Access Considerations
To take full advantage of this configuration your client applications will need to be written in such a way that they perform all critical writes (that is, writing data that you want to keep) on Master 1. Also consider that some or all reads immediately following a write may need to come from the master. This is because it can take a few seconds for the slaves to synchronize with Master 1. This is what we call a "dirty" read. Clients performing only reads or creating temporary tables for use with those reads can access your pool of slaves and never touch the master.

Examples

* Generate query-intense reports on dedicated slaves.
* A portal page that doesn't need up-to-the-second data.
* Statistics calculations can be performed on the slaves.

Enforcing Safe Practices
You would be well advised to GRANT only SELECT privileges to clients accessing your tables via a slave. This way a rogue client application cannot manipulate upstream data on the slave. Any changes made on the slave would not be known to any other slave nor the masters. This could be a devastatingly bad situation to find yourself in. Please think through these issues before you implement your clients.
You almost certainly will want to allow clients to create temporary tables, though.


Advanced Stuff
MySQL doesn't require slave tables to have the same schema as masters, either. This allows you to do interesting things like create your master database tables as InnoDB tables with full referential integrity and foreign keys while creating your slave tables as high performance MyISAM tables. You can create different indexing strategies on the slaves to fine-tune specific slaves to specific tasks such as report generation.




Вас также может заинтересовать:

Backup mysql и как пользоваться mysqldump для резервного копирования баз данных
Закрытие базы данных с информацией о часовых поясах
Бекапирование данных GNU Centos Linux на Amazon S3 без дополнительных костылей
Создатели Wikipedia представили проект структурированной базы данных Wikidata
Анонсирован стабильный релиз MySQL 5.6
Mysql и с чем его едят, основные команды...