MySQL配置从库(当做个人笔记,不做任何解答)
本篇不适合Linux、MySQL小白查看,不做任何解答。当做个人笔记,不做任何解答。
假设我现在拥有一台生产环境的数据库:
bash
192.168.1.10:3306/erp-db
我需要将"erp-db"中的所有数据、表结构都实时同步到从数据库:
bash
192.168.1.20:3306/erp-db
首先要保证2个MySQL的版本要保持一致,我的都为8.0.x,理论上来说小版本应该也要保持一致,不过我实测主库"8.0.37" 从库 "8.0.24" 可以正常使用,不过实际还是更推荐连小版本也要保持一致。顺便在说一下主库与从库的数据库名称需要保持一致。
主库配置
主库需要增加/修改的配置:
bash
[mysqld]
server-id=100 主从唯一ID(2台不能相同,id具体设置为多少貌似也没讲究)
log-bin=mysql-bin 开启binlog
binlog_format=ROW 推荐ROW模式
binlog-do-db=erp-db 只记录指定数据库
binlog-do-db=如果有多条就指定数据库名称,没有就删除这行
重启主库
bash
systemctl restart mysqld
检查配置
bash
mysql> SHOW VARIABLES LIKE 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | ON |
+---------------+-------+
创建主库专用复制账号:
bash
我创建了用户名为repl,密码为abc123def456,仅允许IP为192.168.1.20的用户
CREATE USER 'repl'@'192.168.1.20' IDENTIFIED BY 'abc123def456';
接着给此用户单独赋予复制的权限
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.20';
然后刷新
FLUSH PRIVILEGES;
查看用户是否创建成功
SELECT user,host FROM mysql.user WHERE user='repl';
+----------+---------------+
| user | host |
+----------+---------------+
| repl | 192.168.1.20 |
+----------+---------------+
接下来的一步原本是需要锁数据库的同时导出数据,但现实中生产环境根本就不方便暂停业务,所以在这里我也就不讲如何锁库,跳过这一步。
然后即记录当前二进制日志的位置,过会要用到:
bash
mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+--------------------------------------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+--------------------------------------------------+-------------------+
| mysql-bin.000005 | 32 | erp-db | test,mysql,information_schema,performance_schema | |
+------------------+----------+--------------+--------------------------------------------------+-------------------+
这里记住名称: mysql-bin.000005
索引:32
然后再导出数据库,你可以用各Linux面板的一键导出功能,也可以选择例如Navicat、SQLyog等连接工具导出sql文件,或者你选择以下命令导出数据:
bash
mysqldump \
-h192.168.1.10 \
-P3306 \
-u数据库用户名 \
-p数据库密码 \
--databases erp-db \
--single-transaction \ 不锁表
--master-data=2 \ 自动记录binlog位置
--routines \ 存储过程
--events \ 事件
--triggers \ 触发器
> dump.sql 导出文件名称
从库配置
修改从库配置:
bash
server-id=200 从库ID
relay-log=relay-log 中继日志
replicate-do-db=erp-db 只同步指定库
replicate-do-db=如果有多条就指定数据库名称,没有就删除这行
重启从库 MySQL:
bash
systemctl restart mysqld
提前创建从库的erp-db,创建过程忽略,直接用各面板工具还比较方便。
向从库中导入来自主库的数据,你可以使用各Linux面板的一键导入功能,也可以选择例如Navicat、SQLyog等连接工具导入sql文件,或者你选择以下命令导入数据:
bash
mysql -h192.168.1.20 -P3306 -uroot -p < dump.sql
接下来在从库中登录MySQL执行:
bash
CHANGE MASTER TO
MASTER_HOST='192.168.1.10', 主库的ip
MASTER_PORT=3306, 主库的端口
MASTER_USER='repl', 主库的用户名
MASTER_PASSWORD='abc123def456', 主库的密码
MASTER_LOG_FILE='mysql-bin.000005', 前面记录的主库二进制文件名称
MASTER_LOG_POS=32; 前面记录的主库索引位置
从库启动复制:
bash
START SLAVE;
检查状态
从库中执行:
bash
SHOW SLAVE STATUS\G
会给你输出一大堆的内容,只需要找到关键两项:
bash
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
如果都是yes就成功了,你只需要测试一下修改主库后,从库是否也会同步更新就结束了。
异常案例
如果前面都正常就可以跳过以下内容了,如果遇到异常可以看看。
我之前遇到过:
bash
Slave_IO_Running: Connecting
中间找到
bash
Last_IO_Error:
查看异常大多都为用户名密码错误、无权限、端口未授权,检查身份认证后再重试。
还遇到过例如:
bash
Slave_SQL_Running: No
...
Last_Error: Could not execute Write_rows event on table erp-db.xxx; Duplicate entry xxx for key 'xxx.PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log mysql-bin.000005, end_log_pos xxx Last_SQL_Error: Could not execute Write_rows event on table erp-db.xxx; Duplicate entry 'xxx' for key 'xxx.PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log mysql-bin.000005, end_log_pos xxx
如果遇到这个问题就说明是主键冲突,在导出mysql的时候没有锁库,同时也有数据写入,所以出现这样的问题也很正常,
解决方法1:
在从库中执行语句:
bash
跳过这1条错误
STOP SLAVE;
SET GLOBAL sql_slave_skip_counter = 1;
START SLAVE;
然后再次查看Slave_IO_Running 与 Slave_SQL_Running 是否都为 Yes,如果还是错误就反复多执行几次直到正常为止
SHOW SLAVE STATUS\G
解决方法2:
修改MySQL从库配置文件,增加/修改:
bash
slave-skip-errors=1062
这行代表自动跳过主键冲突的错误
然后重启从库MySQL就解决了