如何克服 Google-Cloud MySQL5.7 第二代上的 Row size too large (> 8126) 错误

How to overcome Row size too large (> 8126) error on Google-Cloud MySQL5.7 Second Generation

Google Cloud MySQL 引擎仅支持 InnoDB 存储引擎。

创建包含 300 列的 table 时出现以下错误。

[Err] 1118 - Row size too large (> 8126).

将某些列更改为 TEXTBLOB 可能会有所帮助。在当前行格式中,0字节的BLOB前缀被内联存储。

我尝试创建一个 table,将一些列组合为文本类型,将另一些列组合为 blob 类型,但没有成功。 甚至修改 innodb_log_file_size 也是不可能的,因为在 Google Cloud-SQL 平台上是不允许的。

您在这里没有太多选择。 InnoDB 默认页面大小是 16KB,你必须设计你的 tables 所以至少两行适合一个页面。这就是每行 8126 字节限制的来源。

VARCHAR、VARBINARY、BLOB 和 TEXT 等可变长度列可以更长,因为超过行大小限制的数据可以存储在额外的页面上。要利用这一点,您必须启用 Barracuda table 格式,并选择 ROW_FORMAT=DYNAMIC。

在配置中:

[mysqld]
innodb_file_per_table = ON
innodb_file_format = Barracuda
innodb_default_row_format = DYNAMIC;

我不知道这些设置是否已在 Google 云 SQL 中启用,或者它们是否允许您更改这些设置。

阅读https://dev.mysql.com/doc/refman/5.7/en/innodb-row-format.html了解更多信息

同样,动态行格式的优势仅适用于可变长度数据类型。如果你有 300 个固定长度的列,比如 CHAR,那么它就没有用了。

顺便说一下,innodb_log_file_size 与这个关于行大小的错误无关。

为了在云 SQL 实例上执行您想执行的操作,首先关闭 运行 设置 innodb_strict_mode 变量:

SET innodb_strict_mode = 0 ;

之后您应该可以创建 table。

"Vertical Partitioning"

具有很多列的 table 正在突破几个限制;你打了其中一个。有几种合理的解决方法,垂直分区可能是最好的,特别是如果很多是 TEXT/BLOB.

而不是单个 table,有多个具有相同 PRIMARY KEY 的 table,除了一个 可能 AUTO_INCREMENT. JOIN 根据需要将它们组合在一起以收集列。您甚至可以使用 VIEWs 来隐藏您拆分 table 的事实。我建议根据应用程序和需要哪些列,通过一些逻辑分组对列进行分组 'together'。

不要跨列展开一系列内容;相反,有另一个 table 多行来处理重复。示例:address1, state1, country1, address2, state2, country2.

除了真正固定长度的列外,不要使用 CHARBINARY。其中大多数都很短。此外,大多数 CHAR 列应该是 CHARACTER SET ascii,而不是 utf8。 (想想,country_code,邮政编码, md5。)

innodb_log_file_size 仅与您的问题间接相关。它的价值是多少?

直接相关的是 innodb_page_size,默认为 16K,几乎没有人更改过。我希望 Cloud Engines 禁止更改它。

(我和 Bill 一起希望获得有关您的架构的更多信息——这样我们就可以更具体地说明如何帮助您。)