MySQL gtid репликация docker
Мастер
Создаейте каталог /srv/docker/mysql
docker-compose.yml
version: '3.8'
services:
mysql:
image: mysql:5
restart: unless-stopped
container_name: mysql
user: mysql:mysql
ports:
- 3306:3306
volumes:
# Сохраняем данные вне контейнера, создайте каталог /var/lib/mydata/mysql
# и дайте на него права на пользователя с ID 999.
- /var/lib/mydata/mysql:/var/lib/mysql
# Это наш конфиг
- /srv/docker/mysql/my.cnf:/etc/mysql/mysql.conf.d/my.cnf
environment:
#Не меняем эти параметры
MYSQL_ROOT_PASSWORD: root-password
my.cnf
[mysqld]
# Уникальный идентификатор сервера
server-id = 1
# Тут можно указать путь и название файла, в данном случаем бинлог будет в /var/lib/mysql
log-bin = mysql-bin
# Сколько дней хранить бинлог
expire-logs-days = 14
# Максимальный размер файла
max-binlog-size = 500M
# Формат бинлога. MIXED я думаю оптимально.
binlog-format = MIXED
# Включаем gtid
gtid-mode = on
# Запрещает все, что может поломать транзакции.
enforce-gtid-consistency = true
# Указывает подчиненному серверу, чтобы тот вел записи об обновлениях, происходящих на подчиненном сервере, в двоичном журнале.
# По умолчанию эта опция выключена. Ее следует включить, если требуется организовать подчиненные серверы в гирляндную цепь.
# log-slave-updates = true
Запускаем/перезапускаем mysql
Создаем пользователя для репликации.
# docker exec -it mysql mysql -u root -p
sql> GRANT REPLICATION SLAVE ON *.* TO 'slave_user'@'%' IDENTIFIED BY 'password';
Делаем дамп базы
docker exec -i mysql sh -c 'mysqldump -u root -p"$MYSQL_ROOT_PASSWORD" --all-databases --single-transaction --flush-logs --triggers --routines --events' > master.sql
Слейв
Делаем все то же что на мастере, но чуть чуть меняем конфиг
[mysqld]
# Тут меняем ID
server-id = 2
# Тут можно указать путь и название файла, в данном случаем бинлог будет в /var/lib/mysql
# log-bin = mysql-bin
# Указываем имя файлов relay лога. Если нужно создать гирляндовую сеть
# relay-log=relay-bin
# Сколько дней хранить бинлог
# expire-logs-days = 15
# Максимальный размер файла
# max-binlog-size = 500M
# Формат бинлога. MIXED я думаю оптимально.
# binlog-format = MIXED
# Включаем gtid
gtid-mode = on
# Запрещает все, что может поломать транзакции.
enforce-gtid-consistency = true
# Указывает подчиненному серверу, чтобы тот вел записи об обновлениях, происходящих на подчиненном сервере, в двоичном журнале.
# По умолчанию эта опция выключена. Ее следует включить, если требуется организовать подчиненные серверы в гирляндную цепь.
# log-slave-updates = true
Если нужно сбросить старый слейв то вводим команды:
# docker exec -it mysql-slave mysql -u root -p
sql> stop slave;
sql> reset slave;
Импорт базы
docker exec -i mysql-slave sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD" ' < master.sql
Иногда бывает ошибка при сохранении позиции на слейве
ERROR 1840 (HY000): @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty.
В таком случае вводим комнаду.
reset master;
И запускаем реплику повторно.
Далее настраиваем репликацию. 10.10.0.1 - адрес мастера.
# docker exec -it mysql-slave mysql -u root -p
sql> CHANGE MASTER TO MASTER_HOST='10.10.0.1', MASTER_PORT=3306, MASTER_USER='slave_user', MASTER_PASSWORD='password', MASTER_AUTO_POSITION=1;
sql> start slave;
Ну и смотрим результат
show slave status \G;
Если нужно на мастере посмотреть текущую позицию то набираем
SHOW MASTER STATUS;
Правки для mariadb
В mysql gtid вставляется автоматически в файл дампа, но в mariadb такого, как я знаю не происходит. Поэтому нужно перед дампом сделать следующее. И записать значние gtid_current_pos
mysql> FLUSH TABLES WITH READ LOCK;
mysql> SET GLOBAL read_only = ON;
mysql> SELECT @@GLOBAL.gtid_current_pos;
Далее делаем дамп. И после того, как оно будет создан, можно разрешить запись в базу.
mysql> SET GLOBAL read_only = OFF;
mysql> UNLOCK TABLES;
Далее уже на слейве заменяем 0-155-4480752978
на ранее сохраненный gtid_current_pos
mysql> SET GLOBAL gtid_slave_pos = '0-155-4480752978';
mysql> CHANGE MASTER TO master_host="10.10.0.1", master_user="root", MASTER_PASSWORD='password', master_use_gtid=current_pos;
Полезные команды
Что бы сразу залить дамп на слейв можно использовать вот такую команду на мастере. Где 10.10.0.2
адрес слейва.
mysqldump --all-databases --single-transaction --flush-logs --triggers --routines --events --compress -u root -ppassword | mysql --host=10.10.0.2 --port=3306 -u root -ppassword
[ Править ]