概述
做主从复制的目的,并不是为了备份
- 为了解决主库的单点故障,快速切换到从库;
- 为了减少主库的压力(读写分离);
- 可以在从库中执行备份,避免备份期间影响主库服务;
主从复制原理
核心是:二进制文件
从上图看,复制分为三步:
1、master主库在事务提交的时候会把数据变更记录写进二进制日志文件binlog中;
2、从库通过IOthread读取二进制日志文件binlog,写入到从库的中继日志 Relay log中;
3、从库重做中继日志中的事件,将改变反映;
搭建主从复制
服务器准备
请关闭防火墙,不让端口访问会有问题
IP | 角色 |
10.10.204.16 | mster |
10.10.204.8 | slave |
主库配置
# 修改配置文件
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
server_id=1
#mysql服务ID,不要相同和从库
# 修改配置文件后重启数据库&&&&&&&&&&
#######
# 创建主从复制用户,赋予主从复制的权限
mysql> create user 'repl'@'%' identified by 'repl@123';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
mysql> flush privileges;
# 查看主库master状态
mysql> show master status;
+------------------+----------+--------------+------------------+------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000006 | 193 | | | 54a2c4bc-89dc-11ee-a732-5254d7f9c2f7:1-5 |
+------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)
从库配置
super-read-only=1 #超级用户也是只读模式
3、关联主库
# 执行change master to 语句
CHANGE MASTER TO
MASTER_HOST='172.16.1.51',
MASTER_PORT = 3306,
MASTER_USER='rep',
MASTER_PASSWORD='rep@123',
MASTER_LOG_FILE='mysql-bin.000006',
MASTER_LOG_POS=193;
master_port:主库的ip地址
master_port:主库的端口
master_user:用户名
master_password:密码
master_log_file:上节中主库查询的file项对应的值
master_log_pos:上节中主库查询的的值
# 开启主从复制
mysql> start slave;
# 查看主从复制状态
mysql> show slave status\G
这里有个数据库版本问题,指令变化:
主从故障
1、主键冲突,错误代码1062
观察问题
定位原因
看错误,它是因为不能执行这个语句导致的:
could not execute write_rows event on table zcm_cluster_container.pod_stats;duplicate entry '16207771' for key 'PRIMARY',error_code:1062;handler error HA_ERR_FOUND_DUPP_KEY;the event's master log bin-log-mysqld3306.000025,end_log_pos 908557976
锁定事件
问题是主键冲突,在数据库 zcm_cluster_container的表pod_stats 中,已经存在一个具有相同主键值 16207771 的记录,而试图插入的新记录也具有相同的主键值,进程停滞。
日志:
主机日志到了96,而备机停在25。
- 要查看主服务器的二进制日志,可以使用以下命令:
SHOW BINARY LOGS;
这将显示主服务器上当前可用的二进制日志文件列表。
- 要查看特定二进制日志文件的内容,可以使用以下命令:
SHOW BINLOG EVENTS IN 'bin-log-mysqld3306.000025';
请将 'bin-log-mysqld3306.000025' 替换为实际的二进制日志文件名。
end_log_pos 908557976(若是日志文件过大怎么办?mysqlbinlog)
mysqlbinlog 是一个用于解析和显示 MySQL 二进制日志文件内容的命令行工具。它可以帮助你查看二进制日志文件中的事件,以便了解数据库中发生的更改和操作。
下面是使用 mysqlbinlog 命令的基本语法:
mysqlbinlog [options] [log_file ...]
其中,options 是可选的命令行选项,log_file 是要解析的二进制日志文件的路径。你可以指定一个或多个日志文件进行解析。
以下是一些常用的 mysqlbinlog 命令选项:
- -h, --host=name:MySQL 服务器的主机名。
- -u, --user=name:连接 MySQL 服务器的用户名。
- -p, --password[=name]:连接 MySQL 服务器的密码。如果密码为空,则会提示输入密码。
- --start-datetime=datetime:指定开始解析的日期和时间。
- --stop-datetime=datetime:指定停止解析的日期和时间。
- -r, --result-file=name:将解析结果输出到指定的文件中。
- -v, --verbose:显示详细的解析信息。
以下是一些示例用法:
- 解析单个二进制日志文件:
mysqlbinlog binlog.000001
- 解析多个二进制日志文件:
mysqlbinlog binlog.000001
mysqlbinlog -v binlog.000002|more
- 解析特定日期范围内的二进制日志文件:
mysqlbinlog --start-datetime="2023-11-25 00:00:00" --stop-datetime="2023-11-26 00:00:00" binlog.000001
- 将解析结果输出到文件:
mysqlbinlog binlog.000001 > output.txt
这只是 mysqlbinlog 命令的一些基本用法示例,还有更多高级选项可供使用。你可以使用 mysqlbinlog --help 命令查看完整的命令选项列表和用法说明。
请注意,使用 mysqlbinlog 命令需要具有适当的权限,并且只能解析服务器上的二进制日志文件。
解决方案
使用参数:sql_slave_skip_counter,当主从同步错误时,若已确定从库数据与主库一致,可以设置该参数,跳过一个事务。
mysql> set global sql_slave_skip_counter=1;
先stop slave,然后执行了一下提示的语句,就是把重复的主键记录删除,再
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
START SLAVE;
show slave status\G;
以上方法解决不了建议直接重建备机,可以直接source SQL文件,不需要将备机都清除,当SQL文件中有删除数据库指令。