MySQL:错误代码:1118行大小太大(> 8126)。将某些列更改为TEXT或BLOB


73

我想创建一个包含325列的表:

CREATE TABLE NAMESCHEMA.NAMETABLE 
(   
      ROW_ID TEXT NOT NULL ,        //this is the primary key

324 column of these types:
      CHAR(1), 
      DATE, 
      DECIMAL(10,0), 
      DECIMAL(10,7), 
      TEXT, 
      LONG,

) ROW_FORMAT=COMPRESSED;

我用TEXT替换了所有VARCHAR,并在MySQL的my.ini文件中添加了梭子鱼,这是添加的属性:

innodb_file_per_table=1
innodb_file_format=Barracuda
innodb_file_format_check = ON

但是我仍然有这个错误:

Error Code: 1118
 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.

编辑:我不能更改数据库的结构,因为它是旧的应用程序/系统/数据库。创建一个新表,它是旧数据库的导出。

EDIT2:我写的这个问题与其他问题类似,但是里面有一些我在互联网上找到的解决方案,例如VARCHAR和Barracuda,但是我仍然有这个问题,所以我决定打开一个新问题,里面已经有经典答案,看是否有人还有其他答案


一个TEXT作为主键列听起来真的很奇怪。为什么不使用整数或“常规”varchar列?
a_horse_with_no_name 2014年


@pathikrit我已经写了EDIT 2,我为什么要创建这个问题呢?对我来说,它是相似的但不是真正的重复项,但是如果它是重复项,我该怎么办?我必须删除它?
Diego87

您的描述中有两件含糊的内容。请提供SHOW CREATE TABLE,但你可以离开了大部分的324
里克·詹姆斯

如果您正在“跨列展开数组”,请参见解决问题的“正确”方法: stackoverflow.com/a/46714384/1766831
Rick James

Answers:


56

由于MySQL Server 5.6.20的更改,最近我一直在使用相同的错误代码。我可以通过更改my.ini文本文件中的innodb_log_file_size来解决此问题。

在发行说明中,解释了innodb_log_file_size太小会触发“行大小太大错误”。

http://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-20.html


7
我在“ my.ini”中使用了此设置,然后对我有用。innodb_log_file_size = 500M innodb_log_buffer_size = 800M
KingAlex1985

4
@ KingAlex1985您确定可以将innodb_log_buffer_size设置为如此高的值吗?默认设置为4M,文档说“由于每秒刷新一次,因此将其设置得很大(即使交易很长)也没有意义”。还有另一个选项innodb_buffer_pool_size(看起来类似),对于该选项,800M可能更有意义(文档:“设置得越大,访问表中数据所需的磁盘I / O越少”)。
Mariusz 2015年

1
@ KingAlex1985顺便说一下,As a result of the redo log BLOB write limit introduced for MySQL 5.6, the innodb_log_file_size setting should be 10 times larger than the largest BLOB data size found in the rows of your tables plus the length of other variable length fields (VARCHAR, VARBINARY, and TEXT type fields).您可能不需要像以前那样大幅度地提高它们。
马特·帕瑟

1
innodb_log_file_size不能在Amazon RDS中修改。有谁知道如何解决这个问题?
拉胡尔2015年

4
更改innodb_log_file_size不够,请在您的答案中添加innodb_strict_mode = 0 :)
Khan Sharukh

80

我在这里尝试了所有解决方案,但仅此参数

innodb_strict_mode             = 0

解决了我的一天...

从手册中:

innodb_strict_mode设置影响CREATE TABLE,ALTER TABLE和CREATE INDEX语句的语法错误的处理。innodb_strict_mode还启用记录大小检查,以使INSERT或UPDATE永远不会失败,因为记录对于所选页面大小而言太大。


1
感谢您的解决方案!你救了我的一天!我正在symfony 3项目中使用教义2,那里有大约200列,并且在生成实体时出现此错误。
阿尼尔·康萨尔(Annil Konsal)2016年

1
您是否检查过文字是否被截断?
里克·詹姆斯

11
当然,这实际上并不能解决问题。您只是关闭验证以检查记录大小。
BadHorsie

5
禁用支票不是解决方案
Ventoh

当所有其他方法都失败或只是暂时起作用时,此方法将起作用。注意*增加我的innodb_log_file_size会冻结myswl服务器,使其无法启动...不确定原因。这就像一个魅力!
杰森

41
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编辑路径:

sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

在MS Windows上,路径将类似于:

C:\ProgramData\MySQL\MySQL Server 5.7\my.ini

不要忘记重新提供服务(或重新启动计算机)


这对我有用!导入后删除这些设置是否安全-会中断吗?
乔尼·阿斯玛

innodb_log_file_size在文件建立之后进行更改(包括从my.cnf中删除)-这是一个不容易的过程;不打算这样做。
里克·詹姆斯

2
如果我将其添加innodb_log_file_size = 512M到配置文件中,则MySQL无法重启。
BadHorsie

@BadHorsie我在XAMPP Windows 10上遇到了同样的问题。我提供了我的解决方案,以备将来参考。
乔纳斯(Jonas)

我添加了innodb_strict_mode = 0,它起作用了
ILIAS M. DOLAPO

16

关键参数是:innodb_page_size

MySQL 5.7中增加了对32k和64k页面大小的支持。对于32k和64k页面大小,最大行长度约为16000字节。

诀窍是只能在mysql服务实例的INITIALIZATION期间更改此参数,因此,如果在实例已初始化实例的第一次运行)后更改此参数,则该参数不会有任何影响

innodb_page_size只能在初始化MySQL实例之前进行配置,之后不能进行更改。如果未指定任何值,则使用默认页面大小初始化实例。请参见第14.6.1节“ InnoDB启动配置”。

因此,如果不在初始化前在my.ini中更改此值,则默认值为16K,行大小限制为〜8K。这就是为什么出现错误。

如果增加innodb_page_size,则也必须增加innodb_log_buffer_size将其设置为至少16M。同样,如果ROW_FORMAT设置为COMPRESSED,则不能将innodb_page_size增加到32k或64K。它应该是动态的(5.7中的默认值)。

当innodb_page_size设置为32KB或64KB时,不支持ROW_FORMAT = COMPRESSED。对于innodb_page_size = 32k,扩展区大小为2MB。对于innodb_page_size = 64k,扩展区大小为4MB。使用32k或64k页面大小时,应将innodb_log_buffer_size设置为至少16M(默认值)。

此外,应将innodb_buffer_pool_size至少从128M增加到512M否则在实例初始化会出现错误(我没有确切的错误)。

此后,行大小错误消失了。

问题是您必须创建一个新的MySql实例,并将数据从旧实例迁移到新的DataBase实例。

我更改和工作的参数(在创建新实例并使用首先使用这些设置修改的my.ini初始化之后):

innodb_page_size=64k
innodb_log_buffer_size=32M
innodb_buffer_pool_size=512M

我在其中找到解决方案的所有设置和说明都可以在这里找到:

https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html

希望这可以帮助!

问候!


3
我合理地回答了一堆q,所以我可以获得足够的声誉来发表评论-谢谢您的修复。对于尝试这种方法的其他人:我遇到一个问题,即在完成MySQL安装后,服务器将自动启动(使用默认的innodb参数初始化数据库,从而阻止了此修复程序)。我解决这个问题的方法是在安装MySQL之前放置“ my.ini / my.conf”配置文件(带有@fefe的innodb值)。再次感谢您,绝对的传奇。
camaulay

这比仅告诉您关闭严格模式的答案有用得多。
SteenSchütt20年

11

今天早上有类似的问题,以下方法挽救了我的生命:

您是否尝试关闭了innodb_strict_mode

SET GLOBAL innodb_strict_mode = 0;

然后尝试再次导入。

innodb_strict_mode 在关闭之前使用MySQL> = 5.7.7开启。


对我来说,它显示#1227-访问被拒绝;您需要(至少其中一个)超级用户权限才能进行此操作
M.suleman Khan

是的,您的用户需要具有所需的特权。

升级到Zabbix 5后,这对我来说非常有效
。– robe007

10

对于MariaDB用户(版本> = 10.2.2)和MySQL(版本> = 5.7),简单的解决方案是:

ALTER TABLE `table` ROW_FORMAT=DYNAMIC;

您需要具有最新版本。例如MariaDB版本> = 10.2.2或mysql版本> = 5.7!
FranzCC'3

我的导出失败,因为创建一些表失败。然后,更改表即可按预期工作,并且无需更改innodb_strict_mode值。
赫伯特·范弗利特

谢谢,这节省了我在GLPI升级期间的工作。github.com/glpi-project/glpi/issues/7697
Kepi

7

我最近创建了一个包含82列的表,并且InnoDB出现了相同的错误。为了绕过该问题,我们将表格式切换MyISAM为仅用于基本表单的格式。


1
由于MyISAM,我遇到了问题,并且在尝试将其转换为InnoDB时遇到此错误...
wobbily_col 2016年

@wobbily_col-将限制缩小到合理值;如果您只会使用ascii字符(例如,邮政编码,十六进制),请使用ascii。
里克·詹姆斯

5

MySQL非常清楚其最大行大小:

每个表(与存储引擎无关)的最大行大小为65,535字节。存储引擎可能会对此限制施加其他限制,从而减小有效的最大行大小。

。。。

各个存储引擎可能会施加其他限制表列数量的限制。例子:

InnoDB最多允许1000列。

InnoDB将行大小限制为小于数据库页面的一半(大约8000个字节),不包括VARBINARY,VARCHAR,BLOB或TEXT列。

不同的InnoDB存储格式(压缩,冗余)使用不同数量的页面标题和尾部数据,这会影响行可用的存储量。

如果您有325个重复的列集,则超出了几个限制。这也是可疑的数据格式。您想要的表中的每一行应该有325行,每组列应该有325行。


首先:THX的建议!第二:您说的是真的,但是我无法更改数据库的结构,因为它是遗留的应用程序/系统/数据库。创建一个新表,它是旧数据库的导出。
Diego87 2014年

3
@ user3410465。。。你必须。该数据库不支持您要尝试执行的操作。您可以使用其他数据库,但是仍然有数百个重复的列块似乎是个坏主意。
Gordon Linoff 2014年

1
也许导出步骤可以重组324组列并将其放置在每个非空集有一行的子表中?
Kjell Rilbe

该报价需要修正。MyISAM和InnoDB各自允许行包含超过64K字节。
瑞克·詹姆斯

5

对于Mac OS X El Capitan上的MySQL 5.7:

OS X在/usr/local/mysql/support-files/my-default.cnf中提供了示例配置文件

要添加变量,请首先停止服务器,然后将以上文件复制到/usr/local/mysql/etc/my.cnf

cmd : sudo cp /usr/local/mysql/support-files/my-default.cnf /usr/local/mysql/etc/my.cnf

注意:如果不存在,请在“ mysql”下创建“ etc”文件夹。

cmd : sudo mkdir /usr/local/mysql/etc

一旦在etc下创建了my.cnf,就可以在其中设置变量了。

cmd: sudo nano my.cnf

在[mysqld]下设置变量

[mysqld]
innodb_log_file_size = 512M
innodb_strict_mode = 0

现在启动服务器!


5

更改为MyISAM不是解决方案。对于innodb,以下对我有用。

在my.cnf上设置关注者

innodb_strict_mode=0

5

在MacOS(使用Brew)上将SQL转储(从MySQL 8)导入MariaDB时遇到问题。

首先编辑您的my.cnf
如果您使用Brew,通常将其存储在/usr/local/etc/

pico /usr/local/etc/my.cnf

将此添加到配置中:

[mysqld]
innodb_log_file_size = 1024M
innodb_strict_mode = 0

然后重新启动MariaDB:

brew services restart mariadb

请注意,这是一种解决方法,而不是解决方法,因为在未解决问题的情况下转为严格模式,但这是我的本地环境,而不是生产环境,我对此表示满意。


谢谢!你救我的天..
穆罕默德Dahshan

4

我只想为其他人提供有关此问题的更严重变体的帮助。在某些情况下,即使使用“ alter table drop column”和“ alter table Modify column”语句,也会发生错误(“行大小太大..将某些列更改为TEXT或BLOB”)!

因此,您可能会完全陷入困境,无法将varchar更改为文本或删除列(试图讽刺地解决问题会导致出现相同的消息)。

如果遇到此问题,解决方案是立即更改或删除多列。您可以在MySQL中使用语法“更改表示例删除列a,删除列b,删除列c”来执行此操作,如果一次删除足够多的列,它将实际上执行而不是引发错误。



3

以下对我有用,别无他处:

设置全局innodb_log_buffer_size = 80 * 1024 * 1024 * 1024;

SET GLOBAL innodb_strict_mode = 0;

希望这对某人有帮助,因为这浪费了我几天的时间,因为我试图在my.cnf中这样做很无聊。


执行时SET GLOBAL innodb_log_buffer_size = 80*1024*1024*1024;出现错误变量innodb_log_buffer_size是只读的
dmikam


3

我在Windows 10上使用XAMPP,使用PHPMyAdmin遇到此问题。

在此处输入图片说明

当我说 innodb_log_file_size = 500Minnodb_log_buffer_size = 800M我的my.ini文件中,MySQL将不会启动。

因此,我尝试删除ib_logfile0ib_logfile1位于(C:\xampp\mysql\data)中,但这根本没有帮助。

幸运的是我可以重新安装(无论如何我都需要升级XAMPP)

就我而言,简单的解决方案是innodb_strict_mode=0my.ini文件中进行设置。

之后,我可以创建表。

脚步:

  1. 完全关闭XAMPP。
  2. 编辑InnoDB部分中的my.ini文件(位于中C:\xampp\mysql\datainnodb_strict_mode=0
  3. 启动XAMPP并再次导入该表。

NB以ADMIN的身份完成这些步骤


2

我也遇到了。更改“ innodb_log_file_size”,“ innodb_log_buffer_size”和“ my.ini”文件中的其他设置不能解决我的问题。我通过将列类型“ text”更改为varchar(20)而不使用大于20的varchar值来传递它。如果可能的话,也许您也可以减小列的大小。文字-> varchar(20)varchar(256)-> varchar(20)


我以为TEXT比VARCHAR小,因为它恰好是指针,不是吗?
库·帕林斯基

盲目使用VARCHAR(255)是引起该问题大多数讨论的原因。
里克·詹姆斯

TEXT被实现为2字节长度的字段以及最多64KB的文本。 VARCHAR是1或2字节长度的字段,再加上给定中CHARACTER SET最大长度所需的字节数。
里克·詹姆斯


2

我已经将值的长度从varchar(255)更改为varchar(25),更改为所有varchar列,并且得到了解决方案。


1

迄今为止,没有答案提到innodb_page_size参数的作用。可能是因为在MySQL 5.7.6之前不支持更改此参数。从文档中

除可变长度列(VARBINARY,VARCHAR,BLOB和TEXT)外,最大行长度略小于数据库页面(对于4KB,8KB,16KB和32KB页面大小)的一半。例如,默认innodb_page_size为16KB的最大行长度约为8000个字节。对于64KB的InnoDB页面大小,最大行长约为16000字节。LONGBLOB和LONGTEXT列必须小于4GB,包括BLOB和TEXT列在内的总行长必须小于4GB。

请注意,增加页面大小并非没有缺点。再次从文档中:

从MySQL 5.7.6开始,支持32KB和64KB页面大小,但是对于大于16KB的页面大小,仍不支持ROW_FORMAT = COMPRESSED。对于32KB和64KB页面大小,最大记录大小为16KB。对于innodb_page_size = 32k,扩展区大小为2MB。对于innodb_page_size = 64k,扩展区大小为4MB。

使用特定InnoDB页面大小的MySQL实例不能使用来自使用不同页面大小的实例的数据文件或日志文件。此限制可能会影响使用MySQL 5.6中的数据进行的还原或降级操作,该数据确实支持16KB以外的页面大小。


同样,单个实例上的所有InnoDB表共享相同的页面大小。
里克·詹姆斯

1

在DOCKER中修复MYSQL

我在这里使用@fefe的绝佳答案来展示如何在使用docker时(通过docker-compose)在几分钟内解决此问题。这很简单,因为您不必接触MySQL的配置文件,但是它需要您导出和导入整个数据:

MySQL安装程序的默认情况可能如下所示。您的数据保存在data-mysql卷内。

mysql:
  image: mysql:5.7.25
  container_name: mysql
  restart: always
  volumes:
    - data-mysql:/var/lib/mysql
  environment:
    - "MYSQL_DATABASE=XXX"
    - "MYSQL_USER=XXX"
    - "MYSQL_PASSWORD=XXX"
    - "MYSQL_ROOT_PASSWORD=XXX"
  expose:
    - 3306
  1. 通过SQL导出对整个数据库进行备份,因此您拥有.sql.gz之类的东西。我为此使用Adminer

  2. 要修复(如@fefe的回答所述),我们必须将MySQL实例设置为零,这意味着我们必须删除mysql docker容器mysql volume docker容器。执行adocker container ls和a docker volume ls查看所有容器和卷,并选择两个名称,分别是您的mysql实例和mysql卷,对我来说,它们是mysql(容器)和docker_data-mysql(卷)。

  3. 通过停止运行的实例docker-compose down(或者通常停止docker的东西)。

  4. 要删除它们,我可以这样做(docker container rm mysqldocker volume rm docker_data-mysql注意名称中包含下划线和破折号)。

  5. 将这些设置添加到docker设置中的mysql块中:

mysql:
  image: mysql:5.7.25
  command: ['--innodb_page_size=64k', '--innodb_log_buffer_size=32M', '--innodb_buffer_pool_size=512M']
  container_name: mysql
  # ...
  1. 重新启动实例,现在应该使用新设置自动构建mysql和mysql卷。

  2. 导入数据库转储文件,也许用:

gzip -dc < database.sql.gz | docker exec -i mysql mysql -uroot -pYOURPASSWORD

瞧!对我来说很好!


1

我有同样的问题。我在my.ini中搜索“ innodb_strict_mode”,但找不到。

然后,我添加了同样的内容,它仍然会向您显示警告,但是您可以继续。只需添加

innodb_strict_mode = 0;


0

如果使用的是MySQLWorkbench,则可以选择更改,以更改query_alloc_block_size = 16258并保存。

步骤1.单击options file左侧的。 在此处输入图片说明

第2步:点击General 并选择checkBoxquery_alloc_block_size并增加其大小。例如更改8129-> 16258

在此处输入图片说明



0

如果您在Google Cloud SQL(例如mysql 5.7)上遇到此错误,那么由于可能不支持所有InnoDB标志,因此目前可能不是一个简单的解决方法。如果您像以前一样(对于旧的Wordpress安装程序)遇到的是Mysql 5.5,则可能意味着您需要在导出之前纠缠源数据库中的某些列类型。

一些更多的信息可以在这里找到。


0

我在导入数据转储时遇到了相同的问题。暂时禁用innodb严格模式可以解决我的问题。

-- shows the acutal value of the variable
SHOW VARIABLES WHERE variable_name = 'innodb_strict_mode';

-- change the value (ON/OFF)
SET GLOBAL innodb_strict_mode=ON;

-1

将表格式InnoDB切换为MyISAM

用于变更表格式

运行此查询

ALTER TABLE table_name ENGINE = MyISAM;

(用实际的表名替换table_name)


1
这不能解决问题,您正在使用完全不同的方法来解决。我并不是说这行不通,但这无济于事,您必须先了解InnoDB和MyISAM之间的区别,并且区别不大。您的答案就像“我有C#语法错误,算了,我将用PHP重写所有内容”
Leandro

这是共享主机的好解决方案
RBT
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.