首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >恢复Django-mailer数据库时MySQL错误1118 (行大小太大)

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

Stack Overflow用户
提问于 2014-08-14 03:03:53
回答 4查看 21.3K关注 0票数 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.

我在网上读过很多关于这个错误的文章,但都没有解决我的问题。

注:这个错误是,不是来自创建表的,而是插入包含相当大数据的行。

备注:

  1. innodb_file_format和innodb_file_format_max变量被设置为Barracuda。
  2. ROW_FORMAT被设置为动态表创建。
  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 to )时,才会发生错误;创建表很好,并且在失败之前添加了大约50万行。

我没有想法;我尝试过DYANMIC和压缩的行格式,并且我已经三次检查了相关的无害数据库变量的值:

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

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-08-19 19:09:37

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

InnoDB备注 重要的更改:对于大型外部存储的BLOB字段,重做日志写入可能会覆盖最近的检查点。5.6.20修补程序将重做日志写入的大小限制为重做日志文件大小的10%。5.7.5修补程序解决了错误,但没有施加限制。对于MySQL 5.5,bug仍然是已知的限制。 由于为MySQL 5.6引入了重做日志BLOB写入限制,innodb_log_file_size设置应该比表中的最大BLOB数据大小以及其他可变长度字段(VARCHAR、VARBINARY和TEXT类型字段)的长度大10倍。如果您的innodb_log_file_size设置已经足够大,或者您的表不包含BLOB数据,则不需要操作。 注在MySQL 5.6.22中,重做日志的写入限制放宽到重做日志大小的10% (innodb_log_file_size * innodb_log_files_in_group)。 (Bug #16963396,Bug #19030353,Bug #69477)

如果你把innodb_log_file_size改成50米以上的东西,会有帮助吗?(更改该变量需要一些步骤才能正确工作:

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

票数 19
EN

Stack Overflow用户

发布于 2016-05-31 14:49:01

如果这对任何人都有用,那么@klasske解决方案对我来说就不起作用了,但是用'my.cnf‘写这一行就行了:

代码语言:javascript
运行
复制
innodb_file_format=Barracuda
票数 2
EN

Stack Overflow用户

发布于 2021-05-12 10:02:52

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

对我有用的是以下几点:

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

直到做完这件事,我才摆脱了这个错误。

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

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

我突然意识到,我的主要项目迁移可能出了问题。也许运行manage.py test会使用我以前对冒犯的CharFields的迁移吗?我不太确定。

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

代码语言:javascript
运行
复制
class DisableMigrations(object):                                                                                                                     
                                                                                                                                                     
    def __contains__(self, item):                                                                                                                    
        return True                                                                                                                                  
                                                                                                                                                     
    def __getitem__(self, item):                                                                                                                     
        return None                                                                                                                                  
                                                                                                                                                     
                                                                                                                                                     
if 'test' in sys.argv[1:]:                                                                                                                           
    MIGRATION_MODULES = DisableMigrations() 

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

代码片段snippet.py的源

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25299370

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档