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

问题描述 投票:47回答:17

我想创建一个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文件中添加了Barracuda,这是添加的属性:

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.

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

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

mysql sql create-table
17个回答
49
投票

由于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


2
投票

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


2
投票

我要补充的是什么

SET GLOBAL innodb_file_format=Barracuda;
SET GLOBAL innodb_file_per_table=ON;

在我的“.sql”文件的开头,正如在:https://gist.github.com/tonykwon/8910261中所说的那样


1
投票

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

你试图关掉innodb_strict_mode吗?

SET GLOBAL innodb_strict_mode = 0;

然后再次尝试导入。

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


1
投票

FIX FOR MYSQL IN DOCKER

我在这里使用@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卷docker容器。做一个docker container ls和一个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
投票

以下内容对我有用,没有别的 - :

SET GLOBAL innodb_log_buffer_size = 80 * 1024 * 1024 * 1024;

SET GLOBAL innodb_strict_mode = 0;

希望这有助于某人,因为我浪费了几天的时间,因为我试图在my.cnf上做这件事而没有任何喜悦。


0
投票

迄今为止的答案都没有提到innodb_page_size参数的效果。可能是因为在MySQL 5.7.6之前更改此参数不是受支持的操作。来自documentation

除了可变长度列(VARBINARY,VARCHAR,BLOB和TEXT)之外,最大行长度略小于4KB,8KB,16KB和32KB页面大小的数据库页面的一半。例如,16KB的默认innodb_page_size的最大行长度约为8000字节。对于InnoDB页面大小为64KB,最大行长度约为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中的数据进行恢复或降级操作,MySQL 5.6支持16KB以外的页面大小。


0
投票

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

步骤1.单击左侧的options fileenter image description here

第2步:单击General并选择query_alloc_block_size的checkBox并增加它们的大小。例如,更改8129 - > 16258

enter image description here


0
投票

在我的情况下,它是来自表格列数和行大小的限制的套管,并且在此答案中描述的更改节省了我的一天。

  1. 将以下内容添加到[mysqld]部分下的my.cnf文件中。 innodb_file_per_table innodb_file_format =梭子鱼
  2. ALTER表使用ROW_FORMAT = COMPRESSED。 ALTER TABLE table_name ENGINE = InnoDB的 ROW_FORMAT = COMPRESSED KEY_BLOCK_SIZE = 8;

https://stackoverflow.com/a/15585700/2195130


0
投票

如果您在Google Cloud SQL(例如mysql 5.7)上收到此错误,那么此时可能不会是一个简单的修复,因为并非所有InnoDB标志都受支持。如果你像我一样遇到Mysql 5.5(对于旧的Wordpress设置),这可能意味着你需要在导出之前在源数据库中纠缠一些列类型。

可以找到更多信息here


42
投票

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

innodb_strict_mode             = 0

解决了我的一天......

从手册:

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


24
投票
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

不要忘记重启服务(或重启机器)


7
投票

我最近创建了一个包含82列的表,并且与InnoDB有相同的错误。为了绕过这个问题,我们将表格格式转换为MyISAM,因为它只用于基本表格。


6
投票

(真正的解决方案MYSQL 5.7)

我在当前最新的mysql服务器(5.7.21)上遇到了同样的错误:

行大小太大(> 8126)。将某些列更改为TEXT或BLOB可能会有所帮助。在当前行格式中,0字节的BLOB前缀以内联方式存储。

花了几个小时阅读MYSQL手册后,找到了解决方案!

关键参数是: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。它应该是DYNAMIC(默认为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实例迁移到新的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

希望这可以帮助!

问候!


4
投票

MySQL非常清楚它的最大行大小:

每个表(无论存储引擎如何)的最大行大小为65,535字节。存储引擎可能会对此限制设置其他限制,从而减少有效的最大行大小。

. . .

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

InnoDB最多允许1000列。

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

不同的InnoDB存储格式(COMPRESSED,REDUNDANT)使用不同数量的页眉和尾部数据,这会影响行的可用存储量。

如果您有325个重复的列集,则超出了几个限制。这也是一种可疑的数据格式。对于所需的表,每行应该有325行,每列对应一行。


4
投票

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

因此,您可能会完全陷入困境,无法将varchar更改为文本或删除列(尝试解决问题,从而产生相同的消息)。

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


3
投票

适用于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

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

cmd: sudo nano my.cnf

设置下面的变量[mysqld]

[mysqld]
innodb_log_file_size = 512M
innodb_strict_mode = 0

现在启动服务器!


3
投票

换成MyISAM不是解决方案。对于innodb以下为我工作。

在my.cnf上设置以下内容

innodb_strict_mode = 0

© www.soinside.com 2019 - 2024. All rights reserved.