如何克服 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).
将某些列更改为 TEXT
或 BLOB
可能会有所帮助。在当前行格式中,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.
除了真正固定长度的列外,不要使用 CHAR
或 BINARY
。其中大多数都很短。此外,大多数 CHAR
列应该是 CHARACTER SET ascii
,而不是 utf8。 (想想,country_code
,邮政编码, md5
。)
innodb_log_file_size
仅与您的问题间接相关。它的价值是多少?
直接相关的是 innodb_page_size
,默认为 16K
,几乎没有人更改过。我希望 Cloud Engines 禁止更改它。
(我和 Bill 一起希望获得有关您的架构的更多信息——这样我们就可以更具体地说明如何帮助您。)
Google Cloud MySQL 引擎仅支持 InnoDB 存储引擎。
创建包含 300 列的 table 时出现以下错误。
[Err] 1118 - Row size too large (> 8126).
将某些列更改为 TEXT
或 BLOB
可能会有所帮助。在当前行格式中,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.
除了真正固定长度的列外,不要使用 CHAR
或 BINARY
。其中大多数都很短。此外,大多数 CHAR
列应该是 CHARACTER SET ascii
,而不是 utf8。 (想想,country_code
,邮政编码, md5
。)
innodb_log_file_size
仅与您的问题间接相关。它的价值是多少?
直接相关的是 innodb_page_size
,默认为 16K
,几乎没有人更改过。我希望 Cloud Engines 禁止更改它。
(我和 Bill 一起希望获得有关您的架构的更多信息——这样我们就可以更具体地说明如何帮助您。)