我们正在使用带有一主一从的 MySQL 数据库。我们已经使用这个设置几个月了。从同步今天停止,我们得到的错误是:
Last_IO_Errno: 1236
Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'log event entry exceeded max_allowed_packet; Increase max_allowed_packet on master'
Last_SQL_Errno: 1594
Last_SQL_Error: Relay log read failure: Could not parse relay log event entry. The possible reasons are: the master's binary log is corrupted (you can check this by running 'mysqlbinlog' on the binary log), the slave's relay log is corrupted (you can check this by running 'mysqlbinlog' on the relay log), a network problem, or a bug in the master's or slave's MySQL code. If you want to check the master's binary log or slave's relay log, you will be able to know their names by issuing 'SHOW SLAVE STATUS' on this slave.
Run Code Online (Sandbox Code Playgroud)
我们尝试重新启动slave的mysql服务并在没有帮助的情况下启动和停止slave复制。经过进一步调查,我们发现存在查询量特别大的问题。在主服务器的错误日志中,我们得到如下错误日志:
[ERROR] Error in Log_event::read_log_event(): 'Event too big', data_len: 1936941420, event_type: 109
Run Code Online (Sandbox Code Playgroud)
我们已经确定了导致此问题的查询。我们可以忽略来自该查询的更新。此错误会不断记录在 mysql 错误日志中。
问题是,在特定的日志位置之后,主服务器无法从中继日志中读取。我们只想从主服务器的二进制日志中删除那个特定的中继日志号。我们如何从二进制日志文件中删除特定的中继日志条目?是的,由于这个原因,我们的应用程序处于危急状态。:(
想到的一个可能的解决方案是将 master_log_position 设置为下一个:
change master to master_log_position = <next_pos>;
start slave;
Run Code Online (Sandbox Code Playgroud)
或者只使用sql_slave_skip_counter = 1。如果这不起作用,您可以尝试解析 binlog(如果 mysqlbinlog 能够解析它......):
mysqlbinlog filename > script.sql
Run Code Online (Sandbox Code Playgroud)
编辑脚本并删除包含长语句的部分。在slave上手动运行修改后的脚本,将master_logfile设置为下一个binlog:
change master to master_log_file ...;
start slave;
Run Code Online (Sandbox Code Playgroud)
您也可以检查,以防万一,如果主站和从站都使用相同的 *max_allowed_packet*。