什么max_allowed_pa​​cket够大,为什么要改?

Cod*_*key 18 mysql replication mysql-5.5

我在主从设置中有 MySQL (5.5) 并创建了另一个从服务器。

我停止了原来的奴隶,转储了数据,复制并重新导入,它工作正常。我记下了原始从站的 master_log pos 并使用这些命令在新从站上设置它

CHANGE MASTER TO MASTER_HOST='<ipaddress>', 
MASTER_USER='<username>', MASTER_PASSWORD='<password>', 
MASTER_PORT=3306, MASTER_LOG_FILE='mysql-bin.000851', 
MASTER_LOG_POS=15824150, 
MASTER_CONNECT_RETRY=10;
Run Code Online (Sandbox Code Playgroud)

当我开始新的奴隶时,我得到了

Last_IO_Error:从二进制日志读取数据时从主服务器得到致命错误 1236:'日志事件条目超过 max_allowed_pa​​cket; 在 master 上增加 max_allowed_pa​​cket'

但是,当我启动原始从站时,它赶上了,现在处于同步状态。

所以问题:

  • 当前值是16M,我怎么知道要走多大?(我宁愿避免在生产服务器上反复试验)。

  • 为什么我需要在原来的奴隶应付得很好的情况下增加主人的价值,问题真的出在新的奴隶身上吗?

更新

我将 max_allowed_pa​​cket 增加到 1073741824,正如 Rolando 在 master、old slave 和 new slave 上建议的那样,并重新启动它们(SET GLOBAL max_allowed_packet = 1073741824;由于某种原因似乎没有采取)

现在最后一个IO错误和以前一样,但现在我明白了

Last_SQL_Error:中继日志读取失败:无法解析中继日志事件条目。可能的原因有:master的二进制日志损坏(可以通过运行'mysqlbinlog'查看二进制日志),slave的relay log损坏(可以通过运行'mysqlbinlog'查看relay log),a网络问题,或者 master 或 slave 的 MySQL 代码中的错误。如果您想检查主站的二进制日志或从站的中继日志,您将能够通过在此从站上发出“显示从站状态”来知道它们的名称。

如果我在 master 的文件上做一个 mysqlbinlog,它会很高兴地滚动过去很长时间的命令 - 文件是 722M - 如果我为从中继日志这样做,我会得到

错误:Log_event::read_log_event() 中的错误:“健全性检查失败”,data_len:38916267,event_type:69

错误:无法读取偏移量 253 处的条目:日志格式错误或读取错误。

我检查了变量,但更改有效

mysql> 显示变量 LIKE '%max_allowed_pa​​cket%';

在新的从站上显示max_allowed_packetANDslave_max_allowed_packet在主站上它只有max_allowed_packet

所以我对主人做了一个版本检查:

mysql> show variables LIKE '%version%';
+-------------------------+--------------------------------------+
| Variable_name           | Value                                |
+-------------------------+--------------------------------------+
| innodb_version          | 1.1.6                                |
| protocol_version        | 10                                   |
| slave_type_conversions  |                                      |
| version                 | 5.5.11-log                           |
| version_comment         | MySQL Community Server (GPL) by Remi |
| version_compile_machine | x86_64                               |
| version_compile_os      | Linux                                |
+-------------------------+--------------------------------------+
Run Code Online (Sandbox Code Playgroud)

和新奴隶

mysql> show variables LIKE '%version%';
+-------------------------+--------------------------------------+
| Variable_name           | Value                                |
+-------------------------+--------------------------------------+
| innodb_version          | 5.5.32                               |
| protocol_version        | 10                                   |
| slave_type_conversions  |                                      |
| version                 | 5.5.32-log                           |
| version_comment         | MySQL Community Server (GPL) by Remi |
| version_compile_machine | x86_64                               |
| version_compile_os      | Linux                                |
+-------------------------+--------------------------------------+
Run Code Online (Sandbox Code Playgroud)

这两个版本相差太远了吗?

Rol*_*DBA 22

可以最大化max_allowed_packet到 1G。每当构建一个 MySQL Packet 时,它都不会从一开始就跳转到 1G。为什么?

首先你需要知道什么是MySQL Packet。本书第 99 页

了解 MySQL 内部

在第 1-3 段中解释如下:

MySQL 网络通信代码是在查询总是相当短的假设下编写的,因此可以在一个块中发送到服务器并由服务器处理,这在 MySQL 术语中称为数据包。服务器为临时缓冲区分配内存来存储数据包,并请求足够的内存来完全容纳它。这种架构需要采取预防措施以避免服务器内存不足——数据包大小的上限,此选项可实现这一点。

与此选项相关的代码可在sql/net_serv.cc 中找到 。查看my_net_read(),然后按照对my_real_read()的调用并特别注意 net_realloc()

此变量还限制了许多字符串函数的结果的长度。有关详细信息,请参阅sql/field.ccsql/intem_strfunc.cc

将其与 MySQL 文档进行比较max_allowed_packet

一个数据包或任何生成/中间字符串或由 mysql_stmt_send_long_data() C API 函数发送的任何参数的最大大小。从 MySQL 5.6.6 开始,默认值为 4MB,在此之前为 1MB。

数据包消息缓冲区初始化为 net_buffer_length 字节,但在需要时可以增长到 max_allowed_pa​​cket 字节。默认情况下,此值很小,以捕获大(可能不正确)的数据包。

如果您使用大 BLOB 列或长字符串,则必须增加此值。它应该与您要使用的最大 BLOB 一样大。max_allowed_pa​​cket 的协议限制为 1GB。该值应为 1024 的倍数;非倍数向下舍入到最接近的倍数。

当您通过更改 max_allowed_pa​​cket 变量的值来更改消息缓冲区大小时,如果您的客户端程序允许,您还应该更改客户端的缓冲区大小。在客户端,max_allowed_pa​​cket 的默认值为 1GB。某些程序(例如 mysql 和 mysqldump)使您能够通过在命令行或选项文件中设置 max_allowed_pa​​cket 来更改客户端值。

有了这些信息,您应该很高兴 MySQL 会根据需要扩展和收缩 MySQL 数据包。因此,继续并

Master 和 Slave 应该在谁传输数据方面匹配,尤其是 BLOB 数据。

更新 2013-07-04 07:03 EDT

从您关于中继日志的消息来看,您似乎有以下内容

  • 损坏的中继日志
  • 一个好的主日志

建议

SHOW SLAVE STATUS\G
STOP SLAVE;
CHANGE MASTER TO
MASTER_LOG_FILE='(Relay_Master_Log_File from SHOW SLAVE STATUS\G)',
MASTER_LOG_POS=(Exec_Master_Log_Pos from SHOW SLAVE STATUS\G);
START SLAVE;
Run Code Online (Sandbox Code Playgroud)

运行会CHANGE MASTER TO清除所有中继日志并从新日志开始。您将从在 Slave 上执行的 Last Master BinLog Event (BinLog,Position) 进行复制。

试一试 !!!

  • 仅供您参考:当我重置复制过程并意外输入错误的“MASTER_LOG_FILE”名称时,发生了这种情况。例如,当我应该使用“CHANGE MASTER TO”中的“SHOW MASTER STATUS”中的“mysql-bin.000003”时,使用了“mysql-bin.000001”。 (2认同)

Cod*_*key 11

相当令人尴尬的是,问题是日志的文件名不正确,导致奇怪的结果,使用正确的文件名重新导入,一切都很好,羞愧地垂头丧气

  • 即使它很愚蠢,也总是值得发布答案。每个人都会犯愚蠢的错误,因为我们都是人。除了我们这些机器人。 (6认同)