MySQL:错误代码:1118 行大小太大(> 8126)。将某些列更改为 TEXT 或 BLOB
Posted
技术标签:
【中文标题】MySQL:错误代码:1118 行大小太大(> 8126)。将某些列更改为 TEXT 或 BLOB【英文标题】:MySQL: Error Code: 1118 Row size too large (> 8126). Changing some columns to TEXT or BLOB 【发布时间】:2014-05-03 11:34:06 【问题描述】:我要创建一个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;
我用文本替换了所有的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.
编辑:我无法更改数据库的结构,因为它是旧版应用程序/系统/数据库。新表的创建,它是旧数据库的导出。
EDIT2:我写的这个问题与其他问题相似,但里面有一些我在互联网上找到的解决方案,如 VARCHAR 和梭子鱼,但我仍然有这个问题,所以我决定打开一个新问题,里面已经有经典答案看看是否有人有其他答案
【问题讨论】:
将TEXT
列作为主键听起来真的很奇怪。为什么不使用整数或“常规”varchar
列?
@pathikrit 我已经写了 EDIT 2,在那里我解释了为什么我创建了这个问题。对我来说,它相似但不是真正的重复,但如果它是重复的,我必须做什么?我必须删除它吗?
你的描述中有两个模糊的东西。请提供SHOW CREATE TABLE
,但您可以省略大部分 324。
如果您“跨列展开数组”,请参阅解决问题的“正确”方法:***.com/a/46714384/1766831
如果不是日志文件限制...将类型从 longtext 更改为 text 或 blob 会有所不同吗?
【参考方案1】:
我在这里尝试了所有的解决方案,但只有这个参数
innodb_strict_mode = 0
解决了我的一天......
来自手册:
innodb_strict_mode 设置影响语法错误的处理 对于 CREATE TABLE、ALTER TABLE 和 CREATE INDEX 语句。 innodb_strict_mode 还启用记录大小检查,以便 INSERT 或者 UPDATE 永远不会因为记录太大而失败 选择的页面大小。
【讨论】:
感谢您的解决方案!你救了我的一天!我正在使用 symfony 3 项目中的学说 2,我们有大约 200 列,并且在生成实体时遇到此错误。 您是否检查过您的文本是否被截断? 当然这并不能真正解决问题。您只是关闭验证以检查记录大小。 禁用检查不是解决办法 呃,我想投票,因为这行得通,但我不完全确定我是否对这个解决方案感到满意。【参考方案2】:由于 MySQL Server 5.6.20 的更改,我最近遇到了相同的错误代码。 我可以通过更改 my.ini 文本文件中的 innodb_log_file_size 来解决问题。
在发行说明中,解释过 innodb_log_file_size 太小会触发“Row size too large error”。
http://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-20.html
【讨论】:
我在“my.ini”中使用了这个设置,它对我有用。 innodb_log_file_size = 500M innodb_log_buffer_size = 800M @KingAlex1985 你确定可以将 innodb_log_buffer_size 设置为这么高的值吗?默认设置是 4M,文档说“因为它每秒刷新一次,所以让它非常大(即使是长事务)也没有意义”。还有另一个选项 innodb_buffer_pool_size (看起来很相似),800M 可能更有意义(文档:“你设置的越大,访问表中的数据所需的磁盘 I/O 就越少”)。 @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).
你可能不需要像你做的那样增加它们。
innodb_log_file_size 无法在 Amazon RDS 中修改。有谁知道如何解决这个问题?
更改 innodb_log_file_size 是不够的,请在您的答案中添加 innodb_strict_mode = 0 :)【参考方案3】:
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 中删除)——这是一个重要的过程;不打算这样做。
如果我将innodb_log_file_size = 512M
添加到我的配置文件中,MySQL 将无法重新启动。
@BadHorsie 我在 XAMPP windows 10 上遇到了同样的问题。我提供了我的解决方案以供将来参考。
我添加了 hust innodb_strict_mode = 0 并且它起作用了【参考方案4】:
关键参数是:innodb_page_size
在 MySQL 5.7 中添加了对 32k 和 64k 页面大小的支持。对于 32k 和 64k 页面大小,最大行长度约为 16000 字节。
诀窍是这个参数只能在mysql服务实例的初始化过程中改变,所以如果改变这个参数没有任何影响实例已经初始化后的参数(实例的第一次运行)。
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,extent 大小为 2MB。对于 innodb_page_size=64k,extent 大小为 4MB。使用 32k 或 64k 页面大小时,innodb_log_buffer_size 应设置为至少 16M(默认值)。
此外,innodb_buffer_pool_size 至少应该从 128M 增加到 512M,否则会在初始化实例时出错(我没有确切的错误)。
在此之后,行大小错误消失了。
问题在于您必须创建一个新的 MySql 实例,并将数据从旧实例迁移到新的数据库实例。
我更改和工作的参数(在创建新实例并使用首先使用这些设置修改的 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
希望这会有所帮助!
问候!
【讨论】:
我合法地回答了一堆问题,所以我可以获得足够的声誉来发表评论 - 谢谢你的修复。对于尝试这种方法的任何其他人:我遇到了一个问题,即在完成 MySQL 安装后,服务器将自动启动(使用默认的 innodb 参数初始化数据库,从而无法进行此修复)。我解决这个问题的方法是在安装 MySQL 之前放置“my.ini/my.conf”配置文件(带有@fefe 的 innodb 值)。再次感谢你绝对的传奇。 这比那些只是告诉你关闭严格模式的答案有用得多。【参考方案5】:今天早上有类似的问题,下面的方法救了我的命:
您是否尝试关闭innodb_strict_mode
?
SET GLOBAL innodb_strict_mode = 0;
然后尝试再次导入。
innodb_strict_mode
在关闭之前使用 MySQL >= 5.7.7 开启。
【讨论】:
对我来说显示 #1227 - 访问被拒绝;您需要(至少其中一项)超级权限才能执行此操作 是的,您的用户需要拥有所需的权限。 升级到 Zabbix 5 后,这对我来说非常有效。【参考方案6】:对于 MariaDB 用户(版本 >= 10.2.2)和 MySQL(版本 >= 5.7),简单的解决方案是:
ALTER TABLE `table` ROW_FORMAT=DYNAMIC;
【讨论】:
您需要有最新版本。例如。 MariaDB 版本 >= 10.2.2 或 mysql 版本 >= 5.7 ! 我的导出失败,因为创建几个表失败。然后更改表按预期工作,我不需要更改 innodb_strict_mode 值。 谢谢,这在 GLPI 升级期间节省了我的时间。 github.com/glpi-project/glpi/issues/7697 我很困惑,到 2021 年还有 12 票,但我无法更改尚未创建的表。【参考方案7】:在 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
请注意,这是一种变通方法,而不是修复,因为打开严格模式无法解决问题,但由于这是我的本地环境而不是生产环境,我可以接受。
【讨论】:
【参考方案8】:我最近创建了一个包含 82 列的表,并且在使用 InnoDB 时遇到了同样的错误。
为了绕过这个问题,我们将表格格式切换为MyISAM
,因为它只是用于基本表格。
【讨论】:
MyISAM 出现问题,我在尝试将它们转换为 InnoDB 时遇到此错误... @wobbily_col - 将限制缩小到合理值;如果您只有 ascii 字符(例如,邮政编码、十六进制),请使用 ascii。【参考方案9】:改用 MyISAM 不是解决办法。对于 innodb,在大型服务器上的 mysql 8.0.27 上为我工作。
在 my.cnf 上设置以下内容并对其进行初始化。如果数据库存在,请确保您已进行备份,因为初始化需要删除数据目录。
innodb-strict-mode=OFF
innodb-page-size=64K
innodb-log-buffer-size=256M
innodb-log-file-size=1G
innodb-data-file-path=ibdata1:2G:autoextend
【讨论】:
【参考方案10】:对于 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
现在启动一个服务器!
【讨论】:
【参考方案11】:MySQL 非常清楚它的最大行大小:
每个表(无论存储引擎如何)的最大行大小为 65,535 字节。存储引擎可能会对此施加额外的限制 限制,减少有效的最大行大小。
。 . .
单独的存储引擎可能会施加额外的限制, 限制表列数。例子:
InnoDB 最多允许 1000 列。
InnoDB 将行大小限制为小于数据库页面的一半 (大约 8000 字节),不包括 VARBINARY、VARCHAR、BLOB 或 TEXT 列。
不同的 InnoDB 存储格式(压缩、冗余)使用不同的 页头和尾数据的数量,这会影响 可用于行的存储空间。
如果您有 325 组重复的列,则超出了一些限制。这也是一种可疑的数据格式。表格中的每一行应该有 325 行,每列一组。
【讨论】:
首先:感谢您的建议!第二:你说的是真的,但我不能改变数据库的结构,因为它是遗留应用程序/系统/数据库。新表的创建,它是旧数据库的导出。 @user3410465 。 . .你必须。数据库不支持您尝试执行的操作。您可以使用不同的数据库,但仍然有数百个重复的列块似乎是个坏主意。 也许导出步骤可以重组并将 324 组列放在一个子表中,每个非空集有一行? 该报价需要修正。 MyISAM 和 InnoDB 都允许行包含超过 64K 字节。【参考方案12】:我只是想为其他一些人提供有关此问题更严重变体的帮助。在某些情况下,即使使用“alter table drop column”和“alter table modify column”语句,也会出现错误(“行大小太大..将某些列更改为 TEXT 或 BLOB”)!
因此,您可能会完全陷入困境,无法将 varchar 更改为文本或删除列(讽刺的是,尝试解决问题会导致相同的消息)。
如果您遇到此问题,解决方案是一次更改或删除多个列。您可以在 MySQL 中使用语法“alter table example drop column a, drop column b, drop column c”执行此操作,如果一次删除足够多的列,它将实际执行而不是引发错误。
【讨论】:
【参考方案13】:innodb_log_file_size=512M
innodb_strict_mode=0
这两行对我有用,在 mysql 配置中!
【讨论】:
何塞,你应该总是在 ***.com 上用英语回答。如果您更喜欢用西班牙语进行协作,可以使用 *** en español【参考方案14】:我的固定是添加
SET GLOBAL innodb_file_format=Barracuda;
SET GLOBAL innodb_file_per_table=ON;
在我的“.sql”文件的开头,如下所述: https://gist.github.com/tonykwon/8910261
【讨论】:
【参考方案15】:以下对我有用,没有别的-:
SET GLOBAL 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 是只读的【参考方案16】:
如果启用 InnoDB 严格模式,则会显示此错误。
检查是否启用
SHOW variables LIKE '%strict%';
如果启用,则可以禁用。
SET GLOBAL innodb_strict_mode=OFF;
更多详情请阅读here>>
【讨论】:
这对我有用,谢谢哥们【参考方案17】:我遇到了同样的问题。我在 my.ini 中搜索“innodb_strict_mode”但找不到。
然后我添加了相同的内容,它仍会向您显示警告,但您可以继续。只需添加
innodb_strict_mode = 0;
【讨论】:
【参考方案18】:我在 Windows 10 上使用 XAMPP,在使用 phpMyAdmin 时遇到了这个问题。
当我将innodb_log_file_size = 500M
和innodb_log_buffer_size = 800M
添加到我的my.ini
文件时,MySQL 将无法启动。
所以我尝试删除位于 (C:\xampp\mysql\data
) 的 ib_logfile0
和 ib_logfile1
,但这根本没有帮助。
幸运的是我可以重新安装(无论如何我需要升级 XAMPP)
就我而言,简单的解决方案是在my.ini
文件中设置innodb_strict_mode=0
。
在此之后我能够创建表。
步骤:
完全关闭 XAMPP。 编辑
my.ini
文件(位于C:\xampp\mysql\data
)在InnoDB 部分添加innodb_strict_mode=0
。 启动 XAMPP 并再次导入表。
请以管理员身份完成这些步骤
【讨论】:
【参考方案19】:尝试了很多方法,但通过在 my.ini 中添加以下行并重新启动 MySQL 服务找到了解决方案。
innodb_strict_mode = 0
【讨论】:
【参考方案20】:我也遇到过。更改“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
中。【参考方案21】:
sql_mode=""
innodb_strict_mode=0
brew services 停止 mariadb
brew services 启动 mariadb
【讨论】:
【参考方案22】:我已将值的长度从 varchar(255) 更改为 varchar(25) 到所有 varchar 列,我得到了解决方案。
【讨论】:
【参考方案23】:迄今为止,没有一个答案提到 innodb_page_size 参数的影响。可能是因为在 MySQL 5.7.6 之前更改此参数不是受支持的操作。来自documentation:
对于 4KB、8KB、16KB 和 32KB 页面大小,除了可变长度列(VARBINARY、VARCHAR、BLOB 和 TEXT)外,最大行长度略小于数据库页面的一半。例如,默认 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,extent 大小为 2MB。对于 innodb_page_size=64k,extent 大小为 4MB。
使用特定 InnoDB 页面大小的 MySQL 实例不能使用来自使用不同页面大小的实例的数据文件或日志文件。此限制可能会影响使用 MySQL 5.6 中的数据的还原或降级操作,该版本支持 16KB 以外的页面大小。
【讨论】:
另外,所有单个实例上的 InnoDB 表共享相同的页面大小。【参考方案24】:修复 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
通过 SQL 导出备份整个数据/数据库,这样您就有了 .sql.gz 或其他文件。我为此使用Adminer。
要修复(正如@fefe 的回答中所解释的),我们必须从零开始设置 MySQL 实例,这意味着我们必须删除 mysql docker 容器和 mysql 卷 docker 容器。执行docker container ls
和 docker volume ls
以查看所有容器和卷,并选择两个名称,即您的mysql 实例和mysql 卷,对我来说是mysql
(容器)和docker_data-mysql
(卷)。
通过 docker-compose down
停止正在运行的实例(或者您通常会停止 docker 的东西)。
要删除它们,我会使用 docker container rm mysql
和 docker volume rm docker_data-mysql
(请注意名称中有下划线和破折号)。
将这些设置添加到 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
# ...
重新启动您的实例,mysql 和 mysql 卷应该会自动构建,现在使用新设置。
导入您的数据库转储文件,可能带有:
gzip -dc < database.sql.gz | docker exec -i mysql mysql -uroot -pYOURPASSWORD
瞧!对我来说效果很好!
【讨论】:
【参考方案25】:如果您使用的是 MySQLWorkbench,您可以选择更改 query_alloc_block_size= 16258 并保存它。
步骤 1. 点击左侧的options file
。
第二步:点击General
,选择query_alloc_block_size的checkBox
,增加其大小。例如更改 8129 --> 16258
【讨论】:
【参考方案26】:在我的情况下,它是限制表列数和行大小的大小写 并进行此答案中描述的更改节省了我的时间。
将以下内容添加到 [mysqld] 部分下的 my.cnf 文件中。
innodb_file_per_table innodb_file_format = 梭子鱼
更改表以使用 ROW_FORMAT=COMPRESSED。
ALTER TABLE 表名 引擎=InnoDB ROW_FORMAT=压缩 KEY_BLOCK_SIZE=8;
https://***.com/a/15585700/2195130
【讨论】:
【参考方案27】:如果您在 Google Cloud SQL(例如 mysql 5.7)上遇到此错误,那么目前可能不是一个简单的修复方法,因为并非所有 InnoDB 标志都受支持。如果您像我一样使用 Mysql 5.5(对于旧的 Wordpress 设置),这可能意味着您需要在导出之前处理源数据库中的某些列类型。
更多信息可以在here找到。
【讨论】:
【参考方案28】:我在导入数据转储时遇到了同样的问题。暂时禁用 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;
【讨论】:
【参考方案29】:将 InnoDB 表格式切换为 MyISAM
用于更改表格格式
运行此查询
ALTER TABLE table_name ENGINE = MyISAM;
(将table_name替换为实际的表名)
【讨论】:
这并不能解决问题,您正在使用完全不同的方法解决问题。我不是说这行不通,但这无济于事,在这样做之前你必须知道 InnoDB 和 MyISAM 之间的区别是什么,并且不是轻微的区别。你的回答就像“我有一个 C# 语法错误,算了,我会用 PHP 重写一切”以上是关于MySQL:错误代码:1118 行大小太大(> 8126)。将某些列更改为 TEXT 或 BLOB的主要内容,如果未能解决你的问题,请参考以下文章
创建models.py时发现row size太大问题,如何解决