恢复 Django-mailer 数据库时出现 MySQL 错误 1118(行大小太大)

Posted

技术标签:

【中文标题】恢复 Django-mailer 数据库时出现 MySQL 错误 1118(行大小太大)【英文标题】:MySQL Error 1118 (Row size too large) when restoring Django-mailer database 【发布时间】:2014-10-07 14:13:15 【问题描述】:

我从 django 应用程序中转储了一个工作生产数据库,并试图将其迁移到我的本地开发环境。生产服务器运行 mysql 5.1,本地我有 5.6。

在迁移 django-mailer 的“messagelog”表时,我遇到了可怕的错误 1118:

ERROR 1118 (42000) at line 2226: Row size too large (> 8126). Changing some columns to TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline.

我在网上阅读了很多关于这个错误的资料,但没有一个能解决我的问题。

注意此错误不是来自表的创建,而是插入了包含大量数据的行。

注意事项:

    innodb_file_format 和 innodb_file_format_max 变量设置为 Barracuda。 在创建表时将 ROW_FORMAT 设置为 DYNAMIC。

    该表没有很多列。架构如下:

    +----------------+------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------------+------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | message_data | longtext | NO | | NULL | | | when_added | datetime | NO | | NULL | | | priority | varchar(1) | NO | | NULL | | | when_attempted | datetime | NO | | NULL | | | result | varchar(1) | NO | | NULL | | | log_message | longtext | NO | | NULL | | +----------------+------------+------+-----+---------+----------------+

同样,只有当我尝试插入一个相当大的(message_data 大约为 5 兆字节)行时才会发生错误;创建表工作正常,并且在失败之前添加了大约 500,000 行。

我没有主意了;我已经尝试过 DYANMIC 和 COMPRESSED 行格式,并且我已经三次检查了相关 innodb 变量的值:

mysql> show variables like "%innodb_file%"; +--------------------------+-----------+ | Variable_name | Value | +--------------------------+-----------+ | innodb_file_format | Barracuda | | innodb_file_format_check | ON | | innodb_file_format_max | Barracuda | | innodb_file_per_table | ON | +--------------------------+-----------+

创建代码(来自 SHOW CREATE TABLE)如下所示:

CREATE TABLE `mailer_messagelog` ( `id` int(11) NOT NULL AUTO_INCREMENT, `message_data` longtext NOT NULL, `when_added` datetime NOT NULL, `priority` varchar(1) NOT NULL, `when_attempted` datetime NOT NULL, `result` varchar(1) NOT NULL, `log_message` longtext NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=869906 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC

【问题讨论】:

这可能对MySQL "Row size too large" when saving many text fields有帮助 【参考方案1】:

根据this 问题的答案之一,您的问题可能是由 MySQL 5.6 中的更改引起的(请参阅http://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-20.html 上的 InnoDB 注释):

InnoDB 笔记

重要更改:为大型外部存储的 BLOB 重做日志写入 字段可能会覆盖最近的检查点。 5.6.20 补丁 将重做日志 BLOB 写入的大小限制为重做日志文件的 10% 尺寸。 5.7.5 补丁解决了该错误,但没有施加限制。 对于 MySQL 5.5,该错误仍然是一个已知限制。

由于 MySQL 5.6 引入了重做日志 BLOB 写入限制, innodb_log_file_size 设置应该比 在表的行中找到的最大 BLOB 数据大小加上 其他可变长度字段的长度(VARCHAR、VARBINARY 和 TEXT 类型字段)。如果您的 innodb_log_file_size 不需要任何操作 设置已经足够大或您的表不包含 BLOB 数据。

注意在 MySQL 5.6.22 中,redo log BLOB 写入限制放宽到 10% 总重做日志大小(innodb_log_file_size * innodb_log_files_in_group)。

(错误 #16963396、错误 #19030353、错误 #69477)

如果您将innodb_log_file_size 更改为大于 50M 的值会有帮助吗? (更改该变量需要一些步骤才能正常工作:

https://dba.stackexchange.com/questions/1261/how-to-safely-change-mysql-innodb-variable-innodb-log-file-size)。

【讨论】:

谢谢,这对我也有用,但起初我不愿意增加对建议大小的限制。我在 InnoDB 中存储了 20 个 meg 文件作为 blob,我真的必须将 log_file_size 增加到 200M 并将缓冲区大小增加到 800M 才能正确导入它们。生病了。【参考方案2】:

如果这对任何人有用,@klasske 解决方案对我不起作用,但是在 'my.cnf' 中写下这一行:

innodb_file_format=Barracuda

【讨论】:

这实际上是做什么的? 允许数据库以较新的梭子鱼格式创建表。但这并不意味着它会(取决于您的 MySQL 版本和其他设置)。您可能还需要在表创建语句中添加innodb_file_per_tableROW_FORMAT=COMPRESSEDROW_FORMAT=DYNAMIC。这解决了我在 MySQL 5.5 上的行大小问题【参考方案3】:

我在我的项目中遇到了同样的错误。我尝试了很多建议,例如增加innodb_log_file_sizeinnodb_buffer_pool_size 甚至在my.cnf 文件中禁用严格模式innodb_strict_mode=0,但对我没有任何效果。

对我有用的是:

    将带有大 max_length 的有问题的 CharFields 更改为 TextFields。例如,models.CharField(max_length=4000)models.TextField(max_length=4000) 仅在第一个解决方案之后将表拆分为多个表是不够的。

只有在这样做之后我才摆脱了错误。


最近,在同一个项目中,同样的错误再次困扰着我。这一次,当我运行python manage.py test 时。我很困惑,因为我已经拆分了表格并将CharFields 更改为TextFields

所以我创建了另一个虚拟 Django 项目,其数据库与我的主项目不同。我将主项目中的models.py 复制到虚拟项目中并运行迁移。令我惊讶的是,一切都很顺利。

我突然意识到我的主要项目迁移可能有问题。也许运行 manage.py test 会使用我之前的迁移与有问题的 CharFields?我不确定。

所以我在运行测试时通过编辑 settings.py 并在文件末尾添加以下 sn-p 来禁用迁移。它在测试时禁用迁移并解决错误。

class DisableMigrations(object):                                                                                                                     
                                                                                                                                                     
    def __contains__(self, item):                                                                                                                    
        return True                                                                                                                                  
                                                                                                                                                     
    def __getitem__(self, item):                                                                                                                     
        return None                                                                                                                                  
                                                                                                                                                     
                                                                                                                                                     
if 'test' in sys.argv[1:]:                                                                                                                           
    MIGRATION_MODULES = DisableMigrations() 

这样做为我解决了测试时的问题。我希望其他人觉得它有用。

sn-p 的来源settings_test_snippet.py

【讨论】:

【参考方案4】:
ERROR 1118 (42000) at line 1852: Row size too large (> 8126). Changing some columns to TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline.
[mysqld]
innodb_log_file_size = 512M
innodb_strict_mode = 0

ubuntu 16.04 edit path : nano /etc/mysql/mysql.conf.d/mysqld.cnf
it work!!….

[http://dn59-kmutnb.blogspot.com/2017/06/error-1118-42000-at-line-1852-row-size.html][1]

【讨论】:

以上是关于恢复 Django-mailer 数据库时出现 MySQL 错误 1118(行大小太大)的主要内容,如果未能解决你的问题,请参考以下文章

恢复Oracle数据库镜像时出现的错误及处理方式

使用从 Atlas 快照恢复的 mongodb 在本地运行流星时出现问题

装MySQL数据库时出现一个错误这怎么解决

关闭路由时出现不可恢复的语法错误

运行选定的编码生成器时出现错误:'包恢复失败。没有详细错误

Wikitude - 恢复应用程序时出现奇怪的输出