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

我想创建一个 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.

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

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

296002 次浏览

MySQL is pretty clear about its maximum row size:

Every table (regardless of storage engine) has a maximum row size of 65,535 bytes. Storage engines may place additional constraints on this limit, reducing the effective maximum row size.

. . .

Individual storage engines might impose additional restrictions that limit table column count. Examples:

InnoDB permits up to 1000 columns.

InnoDB restricts row size to something less than half a database page (approximately 8000 bytes), not including VARBINARY, VARCHAR, BLOB, or TEXT columns.

Different InnoDB storage formats (COMPRESSED, REDUNDANT) use different amounts of page header and trailer data, which affects the amount of storage available for rows.

If you have 325 repeating sets of columns, you are exceeding several of the restrictions. This is also a suspicious data format. You should have 325 rows for each row in the table you want, one for each group of columns.

I struggled with the same error code recently, due to a change in MySQL Server 5.6.20. I was able to solve the problem by changing the innodb_log_file_size in the my.ini text file.

In the release notes, it is explained that an innodb_log_file_size that is too small will trigger a "Row size too large error."

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

I recently created a table with 82 columns and had the same error with InnoDB. To bypass the problem we switched the table format to MyISAM as it was just used for a basic form.

I also encountered that. Changing "innodb_log_file_size","innodb_log_buffer_size" and the other settings in "my.ini" file did not solve my problem. I pass it by changing my column types "text" to varchar(20) and not using varchar values bigger than 20 . Maybe you can decrease the size of columns, too, if it possible. text--->varchar(20) varchar(256) --> varchar(20)

None of the answers to date mention the effect of the innodb_page_size parameter. Possibly because changing this parameter was not a supported operation prior to MySQL 5.7.6. From the documentation:

The maximum row length, except for variable-length columns (VARBINARY, VARCHAR, BLOB and TEXT), is slightly less than half of a database page for 4KB, 8KB, 16KB, and 32KB page sizes. For example, the maximum row length for the default innodb_page_size of 16KB is about 8000 bytes. For an InnoDB page size of 64KB, the maximum row length is about 16000 bytes. LONGBLOB and LONGTEXT columns must be less than 4GB, and the total row length, including BLOB and TEXT columns, must be less than 4GB.

Note that increasing the page size is not without its drawbacks. Again from the documentation:

As of MySQL 5.7.6, 32KB and 64KB page sizes are supported but ROW_FORMAT=COMPRESSED is still unsupported for page sizes greater than 16KB. For both 32KB and 64KB page sizes, the maximum record size is 16KB. For innodb_page_size=32k, extent size is 2MB. For innodb_page_size=64k, extent size is 4MB.

A MySQL instance using a particular InnoDB page size cannot use data files or log files from an instance that uses a different page size. This limitation could affect restore or downgrade operations using data from MySQL 5.6, which does support page sizes other than 16KB.

I tried all the solutions here, but only this parameter

innodb_strict_mode             = 0

solved my day...

From the manual:

The innodb_strict_mode setting affects the handling of syntax errors for CREATE TABLE, ALTER TABLE and CREATE INDEX statements. innodb_strict_mode also enables a record size check, so that an INSERT or UPDATE never fails due to the record being too large for the selected page size.

For MySQL 5.7 on Mac OS X El Capitan:

OS X provides example configuration files at /usr/local/mysql/support-files/my-default.cnf

To add variables, first stop the server and just copy above file to, /usr/local/mysql/etc/my.cnf

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

NOTE: create 'etc' folder under 'mysql' in case it doesn't exists.

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

Once the my.cnf is created under etc. it's time to set variable inside that.

cmd: sudo nano my.cnf

set variables below [mysqld]

[mysqld]
innodb_log_file_size = 512M
innodb_strict_mode = 0

now start a server!

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:

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

on MS Windows the path will be something like:

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

Don't forget to retart the service (or restart your machine)

if you are using the MySQLWorkbench you have the option to change the to change the query_alloc_block_size= 16258 and save it.

Step 1. click on the options file at the left side. enter image description here

Step 2: click on General and select the checkBox of query_alloc_block_size and increase their size. for example change 8129 --> 16258

enter image description here

On my case it was casing from Limits on Table Column Count and Row Size and doing changes described in this answer saved my day.

  1. Add the following to the my.cnf file under [mysqld] section.

    innodb_file_per_table
    innodb_file_format = Barracuda

  2. ALTER the table to use ROW_FORMAT=COMPRESSED.

    ALTER TABLE table_name
    ENGINE=InnoDB
    ROW_FORMAT=COMPRESSED
    KEY_BLOCK_SIZE=8;

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

I just want to provide some other people with help with a more serious variant of this problem. In some situations, the error ("Row size too large .. Changing some columns to TEXT or BLOB") will occur even with "alter table drop column" and "alter table modify column" statements!

Consequently you can become completely stuck, not able to change a varchar to a text, or drop columns (trying to solve the problem ironically results in the same message).

If you have this problem, the solution is to alter or drop multiple columns at once. You can do this in MySQL with the syntax "alter table example drop column a, drop column b, drop column c" and if you drop enough columns at once, it will actually execute rather than raising the error.

What fixed mine was to add

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

At the beginning of my ".sql" file, as it is said in: https://gist.github.com/tonykwon/8910261

Changing into MyISAM is not the solution. For innodb following worked for me on mysql 8.0.27 on a huge server.

set followings on my.cnf and initialize it. Make sure you have taken backups if databases exist as initializing needs to be remove the data directory.

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

The key parameter is: innodb_page_size

Support for 32k and 64k page sizes was added in MySQL 5.7. For both 32k and 64k page sizes, the maximum row length is approximately 16000 bytes.

The trick is that this parameter can be only changed during the INITIALIZATION of the mysql service instance, so it does not have any affect if you change this parameter after the instance is already initialized (the very first run of the instance).

innodb_page_size can only be configured prior to initializing the MySQL instance and cannot be changed afterward. If no value is specified, the instance is initialized using the default page size. See Section 14.6.1, “InnoDB Startup Configuration”.

So if you do not change this value in my.ini before initialization, the default value will be 16K, which will have row size limit of ~8K. Thats why the error comes up.

If you increase the innodb_page_size, the innodb_log_buffer_size must be also increased. Set it at least to 16M. Also if the ROW_FORMAT is set to COMPRESSED you cannot increase innodb_page_size to 32k, or 64K. It should be DYNAMIC (default in 5.7).

ROW_FORMAT=COMPRESSED is not supported when innodb_page_size is set to 32KB or 64KB. For innodb_page_size=32k, extent size is 2MB. For innodb_page_size=64k, extent size is 4MB. innodb_log_buffer_size should be set to at least 16M (the default) when using 32k or 64k page sizes.

Furthermore the innodb_buffer_pool_size should be increased from 128M to 512M at least, otherwise you will get an error on initialization of the instance (I do not have the exact error).

After this, the row size error gone.

The problem with this is that you have to create a new MySql instance, and migrate data to your new DataBase instance, from old one.

Parameters that I changed and works (after creating a new instance and initialized with the my.ini that is first modified with these settings):

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

All the settings and descriptions in which I found the solution can be found here:

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

Hope this helps!

Regards!

Have similar issue this morning and following way saved my life:

Did you try to turn off the innodb_strict_mode?

SET GLOBAL innodb_strict_mode = 0;

and then try to import it again.

innodb_strict_mode is ON using MySQL >= 5.7.7, before it was OFF.

If you're getting this error on Google Cloud SQL (mysql 5.7 for example) then it's probably not at this time going to be a simple fix as not all InnoDB flags are supported. If you're coming across from Mysql 5.5 as I was (for an old Wordpress setup) this could mean you need to wrangle some column types in the source database before you export.

Some more information can be found here.

FIX FOR MYSQL IN DOCKER

I'm using @fefe's excellent answer here to show how to fix this problem within some minutes when using docker (via docker-compose). It's quite easy as you don't have to touch MySQL's configuration files, but it requires you to export and import your entire data:

The default situation of your MySQL setup probably looks like this. Your data is saved inside the data-mysql volume.

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. Make a backup of your entire data/database via SQL export, so you have a .sql.gz or something. I'm using Adminer for this.

  2. To fix (and as explained in @fefe's answer) we have to setup the MySQL instance from zero, meaning we have to delete the mysql docker container and the mysql volume docker container. Do a docker container ls and a docker volume ls to see all your containers and volumes, and pick the two names that are your mysql instance and your mysql volume, for me it's mysql (container) and docker_data-mysql (volume).

  3. Stop your running instances via docker-compose down (or however you usually stop your docker stuff).

  4. To delete them, I do docker container rm mysql and docker volume rm docker_data-mysql (note that there is an underscore AND a dash in the name).

  5. Add these settings to your mysql block in your docker setup:

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. Restart your instances, the mysql and mysql volume should be build automatically, now with the new settings.

  2. Import your database dump file, maybe with:

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

Voila! Worked very fine for me!

The following worked for me, nothing else -:

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

and

SET GLOBAL innodb_strict_mode = 0;

Hope this helps someone because it wasted couple of days of my time as I was trying to do this in my.cnf with no joy.

Switch the table format InnoDB to MyISAM

for change table format

run this query

ALTER TABLE table_name ENGINE = MyISAM;

(replace table_name with actual table name)

  • sql_mode=""
  • innodb_strict_mode=0
  • brew services stop mariadb
  • brew services start mariadb

For MariaDB users (version >= 10.2.2) and MySQL (version >= 5.7), the simple solution is:

ALTER TABLE `table` ROW_FORMAT=DYNAMIC;
innodb_log_file_size=512M


innodb_strict_mode=0

These two lines worked for me, in the mysql configuration !

I have changed the length of value from varchar(255) to varchar(25) to all varchar columns and i get the solution.

I was having same issue. I search "innodb_strict_mode" in my.ini but couldn't found.

I then added the same, it will still show you the warning, but you can continue. just add

innodb_strict_mode = 0;

I was using XAMPP on Windows 10 and had this issue using PHPMyAdmin.

enter image description here

when I added innodb_log_file_size = 500M and innodb_log_buffer_size = 800M to my my.ini file, MySQL would not start.

So I tried deleting ib_logfile0 and ib_logfile1 located in (C:\xampp\mysql\data) and this did not help at all.

luckily I could re-install (I needed to upgrade XAMPP anyway)

The simple solution in my case was to set innodb_strict_mode=0 in the my.ini file.

After this I was able to create the table.

STEPS:

  1. Close XAMPP completely.
  2. Edit the my.ini file (located in C:\xampp\mysql\data) add innodb_strict_mode=0 in the InnoDB section.
  3. Start XAMPP and import the table again.

N.B complete these steps as ADMIN

Tried many things but found the solution by adding the below line in my.ini and restarting the MySQL service.

innodb_strict_mode = 0

I experienced the same issue on an import of a data dump. Temporarily disabling the innodb strict mode solved my problem.

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

I had the issue when importing SQL-dumps (from MySQL 8) to MariaDB on MacOS (with Brew).

Start by editing your my.cnf.
If you use Brew, it's usually store at /usr/local/etc/:

pico /usr/local/etc/my.cnf

Add this to the config:

[mysqld]
innodb_log_file_size = 1024M
innodb_strict_mode = 0

Then restart MariaDB:

brew services restart mariadb

Please notice that this in a workaround and not a fix since turning of strict mode in not fixing the problem, but since it's my local environment and not a production environment i'm ok with that.

If InnoDB strict mode is enabled this error can show.

Check enabled or not

SHOW  variables LIKE '%strict%';

If enable then you can disable.

SET GLOBAL innodb_strict_mode=OFF;

For more detail information read here>>

In the case that this message appears when changing MariaDB version, I had exactly the same issue changing to MariaDB 10.6.5 and that's how I solved the issue:

  1. Using PhpMyAdmin, I exported the .sql file from the old MariaDB version
  2. Edited the .sql file using an editor such as Notepad++ and added the line SET GLOBAL innodb_default_row_format='dynamic'; on top as follows:
-- phpMyAdmin SQL Dump
-- version 5.1.1
-- https://www.phpmyadmin.net/
--
-- Host: (*Your host*)
-- Generation Time: Feb 12, 2022 at 05:22 PM
-- Server version: 10.6.4-MariaDB
-- PHP Version: 8.0.3


SET GLOBAL innodb_default_row_format='dynamic';
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";

3.Imported the altered .sql file to MariaDB 10.6.5

All worked fine

I'm using mysql 5.7.36

The below changes to my.ini file worked for me:

max_allowed_packet = 900M
innodb-default-row-format = dynamic
innodb-lock-wait-timeout = 1200
innodb-log-buffer-size=512M
innodb-log-file-size = 1G

Although I cannot confirm, but I think the 1st 2 settings made the most impact.

Restart the service for the changes to take effect.

The innodb_strict_mode = 0 solution works but it's not secure to use it.

One solution it's to change the type of the tables of glpi to DYNAMIC.

I ran this command to get the ALTER TABLE commands

use information_schema;
SELECT  CONCAT("ALTER TABLE `", TABLE_SCHEMA,"`.`", TABLE_NAME, "` ROW_FORMAT=DYNAMIC;")  AS MySQLCMD FROM TABLES  WHERE TABLE_SCHEMA = "glpi";

That command will return a list of commands you should run to change the row format of all glpi tables. Change the glpi within the quotes to fit the name of your database.

MariaDB has a fairly lengthy document specifically on this issue showing how and why with several ways to resolve it.

Troubleshooting Row Size Too Large Errors With InnoDB

Possible Options:

  • Converting the Table to the DYNAMIC Row Format (This is default is newer versions, so may not work if you're already set to dynamic)
  • Converting Some Columns to BLOB or TEXT
  • Increasing the Length of VARBINARY Columns
  • Increasing the Length of VARCHAR Columns
  • Refactoring the Table into Multiple Tables
  • Refactoring Some Columns into JSON
  • Disabling InnoDB Strict Mode ("Unsafe" way)