最近,使用mysql主从的时候,发现主库修改的数据没有同步到从库。
立马开发排查。
- 首先连接从库
show slave status\G;
查看从库的信息。
从上面箭头的两处,我们可以看到是 x_daily_shares 表出了问题,以及是 mysql-bin.000009
文件对应的 end_log_pos
。
- 连接主库所在的服务器(不是连接数据库)
首先我们要知道mysql binlog的日志位置,所以我们先需要知道mysql配置文件的位置
- 查看mysql命令所在的位置
which mysql
# 输出如下:
/usr/local/mysql/bin/mysql
- 查找配置文件的位置
/usr/local/mysql/bin/mysql --verbose --help | grep -A 1 'Default options'
# 输出如下:
Default options are read from the following files in the given order:
/etc/my.cnf /etc/mysql/my.cnf /usr/local/mysql/etc/my.cnf ~/.my.cnf
- 查找mysql 日志存放的位置
cat /etc/my.cnf
# 找到如下的位置
innodb_data_home_dir = /usr/local/mysql/data
- 主库查询对应的binlog记录
# 切换到数据目录
cd /usr/local/mysql/data
# 生成对应binlog记录的文件,生成的文件可能比较大,最慢的情况下会跟这个binlog文件一样大,需要等一会。
mysqlbinlog -v --stop-position=241735305 mysql-bin.000009 > /tmpbinlog.log;
- 查询记录
end_log_pos=241735305
所在位置,找到对应出错的语句
cat /tmpbinlog.log | awk '/end_log_pos 241735305/ {print NR}'
#输出所在行数为:15798826
#查看其前后行(50行左右差不多够了),找出其对应的sql语句
cat /tmpbinlog.log | awk 'NR==15798800,NR==15798850'
这里的第一个字段 @1是 主键,拿该条件来查询即可
select * from x_daily_shares;
# 果然从库是没有数据的
Empty set (0.00 sec)
- 数据修复
如果是数据是特别简单的,可以直接写
insert
语句在从库插入,当然,从库一般都是只读的。
# 临时设置为 read_only = 1,方可写入数据
set global read_only=0;
如果较为复杂,则在主库创建临时表并
dump
,在从库执行dump
文件中的insert
语句。
mysqldump -h127.0.0.1 -uroot -p -t infzm x_daily_shares --where="id > 190000" --triggers=false --replace > /test.sql
参数如下:
-
-t:只导数据
-
-d:只导结构
-
–where:条件
-
–triggers=false:不导触发器
-
–replace:使用 REPLACE INTO 取代INSERT INTO
dump
完,直接找到相关的 sql 语句在从库执行即可
INSERT INTO `infzm_x`.`x_daily_shares` (`id`, `content_id`, `date`) VALUES (208810, 147176, '2021-12-27 00:00:00');
- 恢复同步
stop slave;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; -- 跳过一个事务,可选
start slave;
show slave status\G;
如果没有其他问题,同步成功。