【发布时间】:2022-01-04 13:11:12
【问题描述】:
我想将数据库从 Maria10.1 升级到 Maria10.2,当我运行迁移时,在创建一些表时出现“Mysql Row size too large”错误。
抛出此错误的一个表有 40 个字段定义为:
varchar(250) DEFAULT NULL
表格本身是:
ENGINE=InnoDB DEFAULT CHARSET=latin1
我想我理解核心问题; innodb 将尝试存储大小
我有 2 个我发现可行的解决方案:
- 将列定义更改为将存储“页外”TEXT、BLOB 或 VARCHAR 大小 > 255 的类型(或大小),这允许将每一列作为 20 字节引用存储在行中,而不是存储列完全在行内。
- 设置 innodb_page_size=64k
这对于新数据库来说很好,但是我有现有的数据库需要升级,因为它们在不再受支持的 MariaDB 10.1 上运行。这些现有的数据库很大,应用这些解决方案很困难;对于解决方案 2,备份和导入 TB 的数据是“有风险的”且不容易,对于解决方案 1,可能需要考虑性能;可能是较慢的查询和增加的磁盘空间需求?
我的问题:
- 首先;是否有可用于大型已建立数据库的替代解决方案,以提供更轻松的升级路径?
- 其次;我可能不得不采用解决方案 1,如果这样做,我该如何减轻性能/存储影响/是否会对性能/存储产生重大影响?
其他一些相关信息:
[edit] 我知道规范化,但由于数据量大,这并不是一个真正的选择。
所有表都是innodb
关闭 innodb_strict_mode 不是一种选择
非常感谢您的观看!
【问题讨论】:
-
与外观相反,解决方案 1 可能更理想。如果您使用的是
varchar,则该行标记为` variable-length. So, if you are usingTINYTEXT, the allowance is identical tovarchar( -
MariaDB 中的 InnoDB 声称支持长达 64KiB 的行。可以将表从 MyISAM 转换为 InnoDB,同时保留表的
ROW_FORMAT=COMPACT特征。但是dynamic 行格式更强大。尝试做ALTER TABLE mytable ENGINE=InnoDB ROW_FORMAT=DYNAMIC,看看你是否得到了一张可行的桌子。您还可以考虑压缩行格式。这是一条评论,因为我不确定这是不是正确的答案。 -
而且,由于每行中有那么多文本列,您可能需要研究数据库规范化,将文本列拆分到自己的表中。特别是如果任何给定行中的许多列都是空的。
-
@O.Jones 但这些表已经是 innodb (我现在已将其添加到我的帖子中),并且 ROW_FORMAT=DYNAMIC 无法修复它
-
如何定义 varchars 以及您使用的字符集。错误发生在10.1版本吗?你想更新什么?你知道吗? :“在 MariaDB 10.2.26、MariaDB 10.3.17 和 MariaDB 10.4.7 之前,MariaDB 在执行 DDL 时无法正确计算行大小。在这些版本中,即使启用了 InnoDB 严格模式,也可以创建不安全的表MDEV-19292 在 MariaDB 10.2.26、MariaDB 10.3.17 和 MariaDB 10.4.7 中修复了计算。"