MySQL 主从复制

本文演示一个简单的 MySQL 主从复制的示例。
0. 说明
- 本示例为一主一从的架构。
- 使用 Docker 启动两个 MySQL 容器来做演示,确保已经安装了 Docker,并且懂得 Docker 的基本用法。
1. 创建并启动容器
主库:
docker run --name=mysql-dn-m --env=MYSQL_ROOT_PASSWORD=admin123 -p 3316:3306 -p 33160:33060 -d mysql:latest
从库
docker run --name=mysql-dn-s --env=MYSQL_ROOT_PASSWORD=admin123 -p 3326:3306 -p 33260:33060 --link mysql-dn-m:master -d mysql:latest
以上操作的说明:
- 启动两个 MySQL 容器(镜像的具体信息可以在这里查看),主库容器命名为
mysql-dn-m
,从库容器命名为mysql-dn-s
。 - 设置
root
用户的密码为admin123
(只作为演示实用)。 - 映射相应的端口号。
- 在从库容器创建时,使用
--link mysql-dn-m:master
创建从库容器到主库容器的网络连接,这样可以在从库内以master
为主机名,访问主库。
使用 docker ps
命令,查看当前正在运行的容器,保证以上操作正常。
1. 主库配置
使用 docker exec -it mysql-dn-m /bin/bash
命令进入主库容器的命令行。编辑 /etc/mysql/my.cnf
配置文件。
首先,在 [mysqld]
的下方,添加一下配置(# 符号后面的内容为注释):
log-bin=mysql-bin # 开启二进制日志
server-id=1 # 设置唯一的 server-id
然后在配置文件的最后添加如下内容:
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
binlog-ignore-db=performance_schema
binlog-ignore-db=sys
这样可以忽略复制 MySQL 内置的四个数据库。
如果需要自定义复制的库,可以用 binlog-do-db
参数来配置,不配置的话,默认复制所有库。
操作完以后重启主库容器。
可以连接主库,执行一下 SQL 语句,查看日志的开启状态。
show variables like '%log_bin%';
如果 log_bin
的值是 ON
,则表示没有问题。
2. 从库配置
使用与主库同样的方法,编辑从库容器中的 /etc/mysql/my.cnf
配置文件。从库的配置只需要在 [mysqld]
的下方添加一行即可:
server-id=2 # 设置唯一的 server-id
操作完以后重启从库容器。
3. 在主库创建用与数据同步的用户账号
进入主库。
执行如下命令创建用户,用户名、主机、密码按需设置,然后记住:
CREATE USER 'repl'@'%' IDENTIFIED BY 'slavepass';
然后,为刚刚创建的用户授权:
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'
最后刷新权限:
flush privileges;
完成后,可以使用下面的查询语句来验证这一步的操作:
show grants for 'repl';
4. 配置主从复制
先连接主库,执行一下查询操作:
show master status\G;
查询结果类似以下内容:
***************************[ 1. row ]***************************
File | mysql-bin.000009
Position | 435
Binlog_Do_DB |
Binlog_Ignore_DB | mysql,information_schema,performance_schema,sys
Executed_Gtid_Set |
记下 File
和 Position
的值。
连接从库,使用之前创建的用户,和刚刚记下的两个值,执行以下操作来创建复制:
change master to MASTER_HOST = 'master', MASTER_PORT = 3306, MASTER_USER = 'repl', MASTER_PASSWORD = 'slavepass', MASTER_LOG_FILE = 'mysql-bin.000009', MASTER_LOG_POS = 435;
参数说明:
- MASTER_HOST:主库的主机,可以是 IP 或者主机名,这里输入我们之前配置的
master
。 - MASTER_PORT:主库的端口号,使用默认端口号时可以省略这个参数。
- MASTER_USER:之前配置的用于复制的用户名。
- MASTER_PASSWORD:之前配置的用于配置的用户密码。
- MASTER_LOG_FILE:之前记下的主库日志文件名。
- MASTER_LOG_POS:之前记下的主库日志位置。
执行以上语句后,就创建成功了。可以在从库上执行以下查询语句验证主从复制的状态:
show slave status\G;
如果 Slave_IO_Running
和 Slave_SQL_Running
两项的值都是 Yes
就说明成功了。
如果没有成功,查询结果中的相应字段也会给出失败的信息,供排查错误。我在配置的过程中遇到了 Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection
的错误,通过 Google 搜索,在主库执行了 ALTER USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'slavepass';
语句解决了问题,这个应该是验证方式不匹配导致从库连接主库失败。
其他导致连接不成功的错误还包括容器之间网络不通、用户名密码或者权限配置错误、日志文件和位置配置错误等,出错时可以排查一下这些内容。
5. 测试验证
至此就配置完成了,可以在主库创建数据库、表,或者插入、修改、删除数据来验证配置是否成功。
6. 如果一个数据库挂掉了怎么办?
如果从库挂掉了,主库内容发生了变化,在从库再次启动后,会自动同步期间发生变化的数据。
在此主要说明一下主库挂掉以后,怎样重新建立数据同步。
首先,重新查看主库日志文件和位置:show master status\G
。
然后在从库执行如下步骤:
- 停止复制:
stop slave
。 - 重新配置主从复制的参数:
change master to MASTER_HOST = 'master', MASTER_PORT = 3306, MASTER_USER = 'repl', MASTER_PASSWORD = 'slavepass', MASTER_LOG_FILE = 'mysql-bin.000009', MASTER_LOG_POS = 435;
- 启动复制:
start slave;
。
立 FLAG:
- 🚩研究一下前面提到的用户认证出问题的原理。
- 🚩研究主从复制的更多细节问题。
- 🚩写篇 Docker 入门的文。