7

我从 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.

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

NB 这个错误不是来自表的创建,而是来自于插入具有相当大数据的行。

笔记:

  1. innodb_file_format 和 innodb_file_format_max 变量设置为 Barracuda。
  2. ROW_FORMAT 在创建表时设置为 DYNAMIC。
  3. 该表没有很多列。架构如下:

    +----------------+------------+------+-----+---------+----------------+ | 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

4

4 回答 4

19

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

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 中,重做日志 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)。

于 2014-08-19T19:09:37.247 回答
2

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

innodb_file_format=Barracuda
于 2016-05-31T14:49:01.317 回答
1

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

对我有用的是以下内容:

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

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


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

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

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

因此,我在运行测试时通过settings.py在文件末尾编辑并添加以下代码段来禁用迁移。它在测试时禁用迁移并解决错误。

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

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

片段settings_test_snippet.py的来源

于 2021-05-12T10:02:52.983 回答
0
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]
于 2017-06-30T09:22:29.010 回答