V R*_*lli 5 mysql replication binlog
我正在尝试修复一个 MySQL 复制设置。从属侧的数据库表之一被删除,并接收到来自主侧的更新,但由于缺少表,这些更新不会写入数据库。这个设置已经好几个月没有修复了,奴隶有很多事情要赶上。我观察到 Exec_Master_Log_Pos 值大于 Read_Master_Log_Pos ,这不应该是这种情况。这是某种错误吗?估计等slave赶上master就会恢复正常。有人熟悉这种情况吗?
Rol*_*DBA 10
这是我在 DBA 职业生涯中见过数十次的经典场景。在我解释这个之前,我想和你分享一些东西。很久以前我学到了一些关于二进制日志中的位置的知识。它实际上表示记录 SQL 事务时到特定位置的字节数。
当你第一次启动一个启用了二进制日志的 mysql 实例时,你会得到一个空的二进制日志。每个版本的 MySQL 都有不同大小的空二进制日志(请参阅我的Feb 04, 2011
帖子MySQL master binlog corruption)让我们在此示例中使用 MySQL 5.5。这是mysqlbinlog
在我的 Windows 桌面上运行的 MySQL 5.5 的空二进制日志的输出:
C:\MySQL_5.5.12\data>dir mysql-bin.000001
Volume in drive C has no label.
Volume Serial Number is 2C92-485B
Directory of C:\MySQL_5.5.12\data
08/16/2012 02:29 PM 107 mysql-bin.000001
1 File(s) 107 bytes
0 Dir(s) 191,225,950,208 bytes free
C:\MySQL_5.5.12\data>mysqlbinlog mysql-bin.000001
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#120816 14:29:55 server id 1 end_log_pos 107 Start: binlog v 4, server v 5.5.12-log created 120816 14:29:55 at startup
# Warning: this binlog is either in use or was not closed properly.
ROLLBACK/*!*/;
BINLOG '
IzwtUA8BAAAAZwAAAGsAAAABAAQANS41LjEyLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAjPC1QEzgNAAgAEgAEBAQEEgAAVAAEGggAAAAICAgCAA==
'/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
Run Code Online (Sandbox Code Playgroud)
该文件正好是 107 个字节,其中包含标有end_log_pos 107
. 如果您要设置新安装的从站,您将运行
CHANGE MASTER TO
MASTER_HOST='IP_of_Master',
MASTER_PORT=3306,
MASTER_USER='repluser',
MASTER_PASSWORD='replpass',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=107;
Run Code Online (Sandbox Code Playgroud)
然后,运行START SLAVE;
。就是这样。MySQL 复制从那里起飞。
我遇到你的情况(MySQL Exec_Master_Log_Pos value greater than Read_Master_Log_Pos
)的唯一原因是这个(仍在写作)......
具有两个线程的 MySQL 复制功能
您的问题与 IO 线程有关。如果 IO 线程遇到任何间歇性,它很可能会计算出来自 Master 的传入 SQL 语句的大小,但从未有机会实际读取 SQL 语句。我可以绝对肯定地说,因为在上面发布的示例中,在end_log_pos
实际读取语句本身之前,在 SQL 语句的标题中读取了 。这通常发生在以下情况下:
发生这种情况时最简单的补救方法是跳到 Master 上的下一个二进制日志。
假设你有以下
Read_Master_Log_File
在SHOW SLAVE STATUS\G
是mysql-bin.012345
补救方法是运行这个(跳到下一个二进制日志mysql-bin.012346
)
STOP SLAVE;
CHANGE MASTER TO
master_log_file='mysql-bin.012346',
master_log_pos=107;
START SLAVE;
Run Code Online (Sandbox Code Playgroud)
这将从 Slave 上次停止的地方开始。这应该是您在低写入环境中的解决方案,并且如果 Master 拥有 Slave 需要的所有二进制日志。
你说奴隶被打破已经有几个月了。Master 上的下一个二进制日志可能不再存在。如果您CHANGE MASTER TO
现在运行命令,它将清除您现在拥有的所有二进制日志。你能做什么 ???
不幸的是,您必须从头开始重建 Slave。
您必须在 Slave 上执行以下操作
echo "STOP SLAVE;" > MySQLData.sql
MYSQLDUMP_OPTIONS="-hIP_of_Master -u... -p..."
MYSQLDUMP_OPTIONS="${MYSQLDUMP_OPTIONS} --all-databases --triggers --routines"
MYSQLDUMP_OPTIONS="${MYSQLDUMP_OPTIONS} --master-data=1 --single-transaction"
mysqldump ${MYSQLDUMP_OPTIONS} >> MySQLData.sql
echo "START SLAVE;" >> MySQLData.sql
mysqldump -uroot -prootpass < MySQLData.sql
Run Code Online (Sandbox Code Playgroud)
这将停止从站,重新加载数据,并启动从站。该选项master-data=1
将CHANGE MASTER TO
在 MySQLData.sql 的第 23 行写入命令。
试一试 !!!