docker 搭建 MySQL 主从
Page content
文件
完整文件放在这里:github
创建docker-file
目录,用于保存容器配置文件
创建子目录 mysql-master-slave
用于保存搭建mysql主从容器的配置文件
mysql-master-slave/master/my.cnf
文件
[mysqld]
# 服务器唯一ID
server-id=1
# 启用 binlog
log-bin=mysql-bin
# binlog 设置为 row 模式
binlog_format=ROW
# 过滤mysql数据库,不做主从同步
binlog-ignore-db=mysql
mysql-master-slave/master/Dockerfile
文件
FROM mysql:5.7
WORKDIR /
COPY my.cnf /etc/my.cnf
# 允许无密码登录
ENV MYSQL_ALLOW_EMPTY_PASSWORD=yes
mysql-master-slave/slave/my.cnf
文件
[mysqld]
# 服务器唯一ID
server-id=2
# 启用 binlog
log-bin=mysql-bin
# binlog 设置为 row 模式
binlog_format=ROW
# 过滤mysql数据库,不做主从同步
binlog-ignore-db=mysql
mysql-master-slave/slave/Dockerfile
文件
FROM mysql:5.7
WORKDIR /
COPY my.cnf /etc/my.cnf
# 允许无密码登录
ENV MYSQL_ALLOW_EMPTY_PASSWORD=yes
mysql-master-slave/docker-compose.yml
文件
version: '3'
services:
mysql-master:
# 端口映射
ports:
- "3306:3306"
build:
# 指定上下文路径
context: ./master
# 指定Dockerfile,默认为Dockerfile
# dockerfile: Dockerfile
# 设置网络,一个容器可以同时属于多个网络
networks:
- mynetwork
mysql-slave:
ports:
- "3406:3306"
build:
context: ./slave
# dockerfile: Dockerfile
networks:
- mynetwork
# 配置容器的网络,控制容器之间的连接
networks:
# 定义网络名,同属一个网络的容器可以通过容器名连接彼此
mynetwork:
# 指定网络类型,默认为bridge
driver: bridge
启动容器
docker-file/mysql-master-slave 目录下执行:
docker-compose build
docker-compose up -d
设置主从同步
连接主库,即 mysql-master
容器对应的数据库,创建用户,用于主从同步
# mysql-master
CREATE USER repl;
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' IDENTIFIED BY 'repl';
查看 master
状态
# mysql-master
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000004 | 397 | | mysql | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
File 为当前 binlog 文件名
Position 为当前 binlog 文件的偏移量,也即是从库要从此位置开始同步
连接从库,即 mysql-slave
容器对应的数据库,设置连接主库的参数
# mysql-slave
CHANGE MASTER TO
MASTER_HOST='mysql-master',
MASTER_USER='repl',
MASTER_PASSWORD='repl',
MASTER_LOG_FILE='mysql-bin.000004',
MASTER_LOG_POS=397;
MASTER_LOG_FILE 为主库当前使用的binlog文件
MASTER_LOG_POS 从主库binlog的哪个位置开始同步
启动 slave
# mysql-slave
start slave;
查看 slave 状态
# mysql-slave
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: mysql-master
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000004
Read_Master_Log_Pos: 397
Relay_Log_File: mysqld-relay-bin.000002
Relay_Log_Pos: 283
Relay_Master_Log_File: mysql-bin.000004
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: 397
Relay_Log_Space: 457
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
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: 3c13e73a-a852-11ee-871e-0242ac130003
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
重点关注以下参数
- Slave_IO_State: Waiting for master to send event
- Slave_IO_Running: Yes
- Slave_SQL_Running: Yes
- Last_Erro:
主从同步设置完成后,就可以开始模拟了,先创建一个test
数据库,然后建一张数据表 score
,并插入一条测试数据
# mysql-master
CREATE DATABASE `test` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
USE `test`;
CREATE TABLE `score` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(128) NOT NULL,
`score` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `score` (`name`, `score`) VALUES ('zhangsan', 10);
# 查看主键自增情况
mysql> SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME = 'score';
+----------------+
| AUTO_INCREMENT |
+----------------+
| 2 |
+----------------+
查看从库的数据库列表,发现已经成功同步了 test
数据库以及 score
数据表
# mysql-slave
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
mysql> use test;
mysql> select * from score;
+----+----------+-------+
| id | name | score |
+----+----------+-------+
| 1 | zhangsan | 10 |
+----+----------+-------+
主从切换
# mysql-slave
mysql> stop slave;
在 mysql-slave 创建 repl
用户,用于从库连接
# mysql-slave
create user repl;
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' IDENTIFIED BY 'repl';
查看 master
状态
# mysql-slave
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000004 | 405 | | mysql | |
+------------------+----------+--------------+------------------+-------------------+
设置从库
# mysql-master
CHANGE MASTER TO
MASTER_HOST='mysql-slave',
MASTER_PORT = 3306,
MASTER_USER='repl',
MASTER_PASSWORD='repl',
MASTER_LOG_FILE='mysql-bin.000004',
MASTER_LOG_POS=405;
mysql> start slave;
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: mysql-slave
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000004
Read_Master_Log_Pos: 405
Relay_Log_File: mysqld-relay-bin.000002
Relay_Log_Pos: 283
Relay_Master_Log_File: mysql-bin.000004
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
......
主从切换成。