关于mysql:maxallowedpacket引起MySQL迁移丢失数据的问题

59次阅读

共计 1403 个字符,预计需要花费 4 分钟才能阅读完成。

起因

最近迁徙了服务器,运维同学给导了数据库,数据库也跟着一起迁徙到了新机房。明天,有用户发现自己创立的一条记录不见了,我去新库查问的确没有,去旧库查问到了这条记录,确定了是数据失落。

排查过程

起初,狐疑迁徙到新库曾经有几天了,是否是这几天用户手动删除了这条记录?还好对用户的改变做了记录,通过查问发现,用户并没有删除动作。

所以,大概率是数据库迁徙引起的数据库失落,具体是哪个环节出错,还要持续排查。

运维同学给出了过后从老库里导出的 sql,发现是存在失落的这条记录的,这证实了 从老库导出没有问题,问题呈现在往新库导入的时候

找到了这条失落记录的导入 sql,因为有一个字段用了 longtext 类型,这个字段内存入了大量的 json 数据,将这条 sql 保留成 txt 后,居然有 1.7M 大小。把这条语句通过命令行独自导入,报错 MySQL server has gone away

问题

通过下面的排查,基本上能够确定是因为 sql 语句过大,导致插入失败,引起迁徙时数据失落的问题。

解决

MySQL 中有一个 max_allowed_packet 参数,用来管制一次插入语句的大小,像 Blob、longtext 类型的字段很容易导致 sql 语句过长,而达到 max_allowed_packet 的限度。

max_allowed_packet 以后大小是 1048576(1024 X 1024 X 1),也就是 1M 大小,而我那条语句居然达到了 1.7M,显然超过了下限。

mysql> show global variables like 'max_allowed_packet';
+--------------------+---------+
| Variable_name      | Value   |
+--------------------+---------+
| max_allowed_packet | 1048576 |
+--------------------+---------+
1 row in set (0.01 sec)

调大 max_allowed_packet

mysql> set global max_allowed_packet=1024*1024*16;
Query OK, 0 rows affected (0.00 sec)

比照新老两库后,发现了总共失落了两条记录,在调大 max_allowed_packet 值后,别离从新插入,复原了失落的数据。

反思

经验了这次事件后的几个小反思:

1. Text 字段是个坑。

Text 对数据库性能就曾经有显著影响了。更何况了是 LongText。LongText 最大能存 (2^32 -1)个字节,即 4GiB。应用 LongText 字段便是给本人和运维同学留下了一个坑。因为这个字段存储的是大文本 json,日后能够思考将此字段放入 MongoDB。

  • TEXT | 65,535(2 16 -1)个字节 = 64 个 KiB
  • MEDIUMTEXT | 16,777,215(2 24 -1)字节 = 16 MiB
  • LONGTEXT | 4,294,967,295(2 32 -1)个字节 = 4 个 GiB

2. 数据迁徙失败日志。

运维同学说应用 mysqldump 导得数据,如果数据迁徙时能有一个失败日志,那么就能及时发现这个问题。另外,迁徙库后,如果我立刻比拟一下表的记录数,或者也能早点发现这个问题。

[参考]

MySQL server has gone away 问题的解决办法

来自 https://mr-houzi.github.io/20…

正文完
 0