MySQL出现The maximum row size for the used table type, not counting BLOBs, is 8126.错误

http://www.fengfly.com/plus/view-210290-1.html


一、背景

我们的MySQL数据库有一张10个Text的字段的表,还包括几个char和varchar字段,由于业务需求,我在表中加多一个Text字段的时候,插入记录的出现了下面的错误:

Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs

MySQL出现The maximum row size for the used table type, not counting BLOBs, is 8126.错误_www.fengfly.com

 

(图1:错误信息)

 

二、过程

首先我们执行下面的SQL,查看这个表的相关信息:

SHOW TABLE STATUS LIKE 'eventanalysis%';

MySQL出现The maximum row size for the used table type, not counting BLOBs, is 8126.错误_www.fengfly.com

MySQL出现The maximum row size for the used table type, not counting BLOBs, is 8126.错误_www.fengfly.com

 

 

(图:表信息)

从上面的这个表使用的Row_format是Compact,这个跟我们上面出现的错误有什么关系呢?

首先让我们来了解下Row_format的Compact,【MySQL技术内幕InnoDB存储引擎】书中的第4.4节(83-98页)中提到:

1. Compact行记录是在MySQL 5.0时被引入的,其设计目标是能高效存放数据。

2. Redundant是MySQL 5.0版本之前InnoDB的行记录存储方式。

3. InnoDB存储引擎可以将一条记录中的某些数据存储在真正的数据页面之外,即作为行溢出数据。一般认为BLOB、LOB这类的大对象列类型的存储会把数据存放在数据页面之外,这个理解有点偏差,BLOB可以不将数据放在溢出页面,而即使是varchar列数据类型,依然有可能存放为行溢出数据。

4. Oracle VARCHAR2最大存放4000个字节,SQL Server 最大存放8000个字节,MySQL的VARCHAR可以存放65535个字节。

5. TXET(一个BLOB或TEXT列,最大长度为65535(2^16-1)个字符。)

6. MEDIUMTEXT(一个BLOB或TEXT列,最大长度为16777215(2^24-1)个字符。)

7. VARCHAR(N)中,N指的是字符的长度,VARCHARL类型最大支持65535指的是65535个字节。

8. 在Compact行记录中,数据页只保存数据的钱768个字节,实际数据保存在BLOB页中。

9. Barracuda文件格式下拥有两种新的行记录格式Compressed和Dynamic两种,新的两种格式对于存放BLOB的数据采用了完全的行溢出的方式,在数据页中只存放20个字节的指针,实际的数据都存放在BLOB Page中,而之前的Compact和Redundant两种格式会存放768个前缀字节。Compressed行记录格式的另一个功能就是存储在其中的数据会以zlib的算法进行压缩。

通过上面的一些了解,MySQL默认是使用Compact行记录的,所以我决定修改表结构,修改为Barracuda中的Compressed行记录。

在创建表的SQL语句中加入粗体内容:ENGINE=INNODB AUTO_INCREMENT=202 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED;

 

(一) 执行创建表SQL的时候出现下面的错误信息:

0 row(s) affected, 2 warning(s)

Execution Time : 0.090 sec

Transfer Time : 1.066 sec

Total Time : 1.056 sec

Warning Code : 1478

InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table.

Warning Code : 1478

InnoDB: assuming ROW_FORMAT=COMPACT.

 

(二) 根据上面的提示,设置innodb_file_per_table,重启MySQL后,再次执行创建表SQL,出现下面的错误:

135 row(s) affected, 2 warning(s)

Execution Time : 4.004 sec

Transfer Time : 1.064 sec

Total Time : 5.069 sec

Warning Code : 1478

InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope.

Warning Code : 1478

InnoDB: assuming ROW_FORMAT=COMPACT.

 

(三) 根据提示,执行下面的SQL:SET GLOBAL innodb_file_format='Barracuda';再次执行创建表的SQL,这次终于成功了,没有报错了。通过SQL:SHOW TABLE STATUS LIKE 'eventanalysis%';查看新表(eventanalysis4)信息:

MySQL出现The maximum row size for the used table type, not counting BLOBs, is 8126.错误_www.fengfly.com

 

(图:row_format)

 

三、解决步骤

1. 在MySQL的配置文件中添加:

[mysqld]

max_allowed_packet=16M

2. 在MySQL的配置文件中添加:

[mysqld]

innodb_file_per_table=1

3. 修改MySQL全局变量:

SET GLOBAL innodb_file_format='Barracuda';

4. 删除原表,创建一个新表,并设置表的属性:

ROW_FORMAT=COMPRESSED

 

四、知识点

ROW_FORMAT几个典型值:

ROW_FORMAT=COMPACT

ROW_FORMAT=REDUNDANT

ROW_FORMAT=COMPRESSED

 

ROW_FORMAT还有其他一些值:

DEFAULT

FIXED

DYNAMIC

COMPRESSED

REDUNDANT

COMPACT


五、参考文献

《MySQL技术内幕InnoDB存储引擎》

Exploring New Features in InnoDB Plugin-1.0

Issue with maximum row size in MySQL

max-allowed-packet

Innodb row size limitation

 

---------------------------------------------MySQL TEXT数据类型的最大长度----------------------------------------

MySQL supports 4 TEXT field types (TINYTEXT, TEXT, MEDIUMTEXT and LONGTEXT) and this post looks at the maximum length of each of these field types.

 

MyISAM tables in MySQL have a maximum size of a row of 65,535 bytes, so all the data in a row must fit within that limit. However, the TEXT types are stored outside the table itself and only contribute 9 to 12 bytes towards that limit. (For more information about this refer to the MySQL Manual - Data Storage Requirements chapter).

TEXT data types are also able to store much more data than VARCHAR and CHAR text types so TEXT types are what you need to use when storing web page or similar content in a database.

The maximum amount of data that can be stored in each data type is as follows:

TINYTEXT256 bytes
TEXT65,535 bytes~64kb
MEDIUMTEXT16,777,215 bytes~16MB
LONGTEXT4,294,967,295 bytes~4GB

In most circumstances the TEXT type is probably sufficient, but if you are coding a content management system it's probably best to use the MEDIUMTEXT type for longer pages to ensure there are no issues with data size limits.

-----------------------------------------Mysql的row_format----------------------------------------------------

 

在mysql中, 若一张表里面不存在varchar、text以及其变形、blob以及其变形的字段的话,那么张这个表其实也叫静态表,即该表的row_format是fixed,就是说每条记录所占用的字节一样。其优点读取快,缺点浪费额外一部分空间。
 
若一张表里面存在varchar、text以及其变形、blob以及其变形的字段的话,那么张这个表其实也叫动态表,即该表的row_format是dynamic,就是说每条记录所占用的字节是动态的。其优点节省空间,缺点增加读取的时间开销。
所以,做搜索查询量大的表一般都以空间来换取时间,设计成静态表。
 
row_format还有其他一些值:
DEFAULT
FIXED
DYNAMIC
COMPRESSED
REDUNDANT
COMPACT
 
修改行格式
ALTER TABLE table_name ROW_FORMAT = DEFAULT
 
修改过程导致:
fixed--->dynamic: 这会导致CHAR变成VARCHAR
dynamic--->fixed: 这会导致VARCHAR变成CHAR

mysql 5.1 innodb plugin压缩测试

 

 
 
  1. Microsoft Windows [版本 6.0.6001]  
  2.  版权所有 (C) 2006 Microsoft Corporation。保留所有权利。  
  3.    
  4. C:\Users\rjkfcuser>d:  
  5.    
  6. D:\>cd app\mysql41\bin  
  7.  系统找不到指定的路径。  
  8.    
  9. D:\>cd app\mysql51\bin  
  10.    
  11. D:\app\mysql51\bin>mysql -uroot  
  12.  ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)  
  13.    
  14. D:\app\mysql51\bin>mysql -uroot -P5030  
  15.  Welcome to the MySQL monitor.  Commands end with ; or \g.  
  16.  Your MySQL connection id is 1  
  17.  Server version: 5.1.54-community MySQL Community Server (GPL)  
  18.    
  19. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.  
  20.    
  21. mysql> select CONCAT('storage engine: ', @@storage_engine) as INFO;  
  22.  +------------------------+  
  23.  | INFO                   |  
  24.  +------------------------+  
  25.  | storage engine: MyISAM |  
  26.  +------------------------+  
  27.  1 row in set (0.03 sec)  
  28.    
  29. mysql> set default_storage_engine=InnoDB;  
  30.  ERROR 1193 (HY000): Unknown system variable 'default_storage_engine'  
  31.  mysql> set @@storage_engine=InnoDB;  
  32.  Query OK, 0 rows affected (0.00 sec)  
  33.    
  34. mysql> select CONCAT('storage engine: ', @@storage_engine) as INFO;  
  35.  +------------------------+  
  36.  | INFO                   |  
  37.  +------------------------+  
  38.  | storage engine: InnoDB |  
  39.  +------------------------+  
  40.  1 row in set (0.00 sec)  
  41.    
  42. mysql> create database empc;  
  43.  Query OK, 1 row affected (0.00 sec)  
  44.    
  45. mysql> use empc  
  46.  Database changed  
  47.  mysql> CREATE TABLE employees (    emp_no      INT             NOT NULL,    birth_date  DATE            NOT NULL,    first_name  VARCHAR(14)     NOT NULL,    last_name   VARCHAR(16  
  48.  )     NOT NULL,    gender      ENUM ('M','F')  NOT NULL,        hire_date   DATE            NOT NULL,    PRIMARY KEY (emp_no))ROW_FORMAT=COMPRESSED 
  49.      ->  KEY_BLOCK_SIZE=4;CREATE TABLE departments (    dept_no     CHAR(4)         NOT NULL,    dept_name   VARCHAR(40)     NOT NULL,    PRIMARY KEY (dept_no),    UNIQUE  KEY (dept  
  50.  _name))ROW_FORMAT=COMPRESSED 
  51.  Query OK, 0 rows affected, 5 warnings (0.00 sec)  
  52.    
  53.     ->  KEY_BLOCK_SIZE=4;CREATE TABLE dept_manager (   dept_no      CHAR(4)         NOT NULL,   emp_no       INT             NOT NULL,   from_date    DATE            NOT NULL,   to  
  54.  _date      DATE            NOT NULL,   KEY         (emp_no),   KEY         (dept_no),   FOREIGN KEY (emp_no)  REFERENCES employees (emp_no)    ON DELETE CASCADE,   FOREIGN KEY (dep  
  55.  t_no) REFERENCES departments (dept_no) ON DELETE CASCADE,   PRIMARY KEY (emp_no,dept_no))ROW_FORMAT=COMPRESSED 
  56.  Query OK, 0 rows affected, 5 warnings (0.01 sec)  
  57.    
  58.     ->  KEY_BLOCK_SIZE=4; CREATE TABLE dept_emp (    emp_no      INT             NOT NULL,    dept_no     CHAR(4)         NOT NULL,    from_date   DATE            NOT NULL,    to_d  
  59.  ate     DATE            NOT NULL,    KEY         (emp_no),    KEY         (dept_no),    FOREIGN KEY (emp_no)  REFERENCES employees   (emp_no)  ON DELETE CASCADE,    FOREIGN KEY (de  
  60.  pt_no) REFERENCES departments (dept_no) ON DELETE CASCADE,    PRIMARY KEY (emp_no,dept_no))ROW_FORMAT=COMPRESSED 
  61.  Query OK, 0 rows affected, 5 warnings (0.02 sec)  
  62.    
  63.     ->  KEY_BLOCK_SIZE=4;CREATE TABLE titles (    emp_no      INT             NOT NULL,    title       VARCHAR(50)     NOT NULL,    from_date   DATE            NOT NULL,    to_date  
  64.       DATE,    KEY         (emp_no),    FOREIGN KEY (emp_no) REFERENCES employees (emp_no) ON DELETE CASCADE,    PRIMARY KEY (emp_no,title, from_date))ROW_FORMAT=COMPRESSED 
  65.  Query OK, 0 rows affected, 5 warnings (0.00 sec)  
  66.    
  67.     ->  KEY_BLOCK_SIZE=4; CREATE TABLE salaries (    emp_no      INT             NOT NULL,    salary      INT             NOT NULL,    from_date   DATE            NOT NULL,    to_d  
  68.  ate     DATE            NOT NULL,    KEY         (emp_no),    FOREIGN KEY (emp_no) REFERENCES employees (emp_no) ON DELETE CASCADE,    PRIMARY KEY (emp_no, from_date))ROW_FORMAT=CO 
  69.  MPRESSED  
  70.  Query OK, 0 rows affected, 5 warnings (0.00 sec)  
  71.    
  72.     ->  KEY_BLOCK_SIZE=4;  
  73.  Query OK, 0 rows affected, 5 warnings (0.01 sec)  
  74.    
  75. mysql> show warnings;  
  76.  +---------+------+----------------------------------------------------------------+  
  77.  | Level   | Code | Message                                                        |  
  78.  +---------+------+----------------------------------------------------------------+  
  79.  | Warning | 1478 | InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.         |  
  80.  | Warning | 1478 | InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. |  
  81.  | Warning | 1478 | InnoDB: ignoring KEY_BLOCK_SIZE=4.                             |  
  82.  | Warning | 1478 | InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table.  |  
  83.  | Warning | 1478 | InnoDB: assuming ROW_FORMAT=COMPACT.                           |  
  84.  +---------+------+----------------------------------------------------------------+  
  85.  5 rows in set (0.00 sec)  
  86.    
  87. mysql> 

MySQL字段类型详解

MySQL支持大量的列类型,它可以被分为3类:数字类型、日期和时间类型以及字符串(字符)类型。本节首先给出可用类型的一个概述,并且总结每个列类型的存储需求,然后提供每个类中的类型性质的更详细的描述。

概述有意简化,更详细的说明应该考虑到有关特定列类型的附加信息,例如你能为其指定值的允许格式。由MySQL支持的列类型列在下面。下列代码字母用于描述中:M指出最大的显示尺寸。最大的合法的显示尺寸是 255 。D适用于浮点类型并且指出跟随在十进制小数点后的数码的数量。最大可能的值是30,但是应该不大于M-2。方括号(“[”和“]”)指出可选的类型修饰符的部分。注意,如果你指定一个了为ZEROFILL,MySQL将为该列自动地增加UNSIGNED属性。

TINYINT[(M)] [UNSIGNED] [ZEROFILL]

一个很小的整数。有符号的范围是-128到127,无符号的范围是0到255。

SMALLINT[(M)] [UNSIGNED] [ZEROFILL]

一个小整数。有符号的范围是-32768到32767,无符号的范围是0到65535。

MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]

一个中等大小整数。有符号的范围是-8388608到8388607,无符号的范围是0到16777215。

INT[(M)] [UNSIGNED] [ZEROFILL]

一个正常大小整数。有符号的范围是-2147483648到2147483647,无符号的范围是0到4294967295。

INTEGER[(M)] [UNSIGNED] [ZEROFILL]

这是INT的一个同义词。

BIGINT[(M)] [UNSIGNED] [ZEROFILL]

一个大整数。有符号的范围是-9223372036854775808到9223372036854775807,无符号的范围是0到

18446744073709551615。注意,所有算术运算用有符号的BIGINT或DOUBLE值完成,因此你不应该使用大于9223372036854775807(63位)的有符号大整数,除了位函数!注意,当两个参数是INTEGER值时,-、+和*将使用BIGINT运算!这意味着如果你乘2个大整数(或来自于返回整数的函数),如果结果大于9223372036854775807,你可以得到意外的结果。一个浮点数字,不能是无符号的,对一个单精度浮点数,其精度可以是<=24,对一个双精度浮点数,是在25 和53之间,这些类型如FLOAT和DOUBLE类型马上在下面描述。FLOAT(X)有对应的FLOAT和DOUBLE相同的范围,但是显示尺寸和小数位数是未定义的。在MySQL3.23中,这是一个真正的浮点值。在更早的MySQL版本中,FLOAT(precision)总是有2位小数。该句法为了ODBC兼容性而提供。

FLOAT[(M,D)] [ZEROFILL]

一个小(单精密)浮点数字。不能无符号。允许的值是-3.402823466E+38到-1.175494351E-38,0 和1.175494351E-38到3.402823466E+38。M是显示宽度而D是小数的位数。没有参数的FLOAT或有<24 的一个参数表示一个单精密浮点数字。

DOUBLE[(M,D)] [ZEROFILL]

一个正常大小(双精密)浮点数字。不能无符号。允许的值是-1.7976931348623157E+308到-2.2250738585072014E-308、 0和2.2250738585072014E-308到1.7976931348623157E+308。M是显示宽度而D是小数位数。没有一个参数的 DOUBLE或FLOAT(X)(25 < = X < = 53)代表一个双精密浮点数字。

DOUBLE PRECISION[(M,D)] [ZEROFILL]

REAL[(M,D)] [ZEROFILL]

这些是DOUBLE同义词。

DECIMAL[(M[,D])] [ZEROFILL]

一个未压缩(unpack)的浮点数字。不能无符号。行为如同一个CHAR列:“未压缩”意味着数字作为一个字符串被存储,值的每一位使用一个字符。小数点,并且对于负数,“-”符号不在M中计算。如果D是0,值将没有小数点或小数部分。DECIMAL值的最大范围与DOUBLE相同,但是对一个给定的 DECIMAL列,实际的范围可以通过M和D的选择被限制。如果D被省略,它被设置为0。如果M被省掉,它被设置为10。注意,在MySQL3.22 里,M参数包括符号和小数点。

NUMERIC(M,D) [ZEROFILL]

这是DECIMAL的一个同义词。

DATE

一个日期。支持的范围是'1000-01-01'到'9999-12-31'。MySQL以'YYYY-MM-DD'格式来显示DATE值,但是允许你使用字符串或数字把值赋给DATE列。

DATETIME

一个日期和时间组合。支持的范围是'1000-01-01 00:00:00'到'9999-12-31 23:59:59'。MySQL以'YYYY-MM-DD HH:MM:SS'格式来显示DATETIME值,但是允许你使用字符串或数字把值赋给DATETIME的列。

TIMESTAMP[(M)]

一个时间戳记。范围是'1970-01-01 00:00:00'到2037年的某时。MySQL以YYYYMMDDHHMMSS、YYMMDDHHMMSS、YYYYMMDD或YYMMDD 格式来显示TIMESTAMP值,取决于是否M是14(或省略)、12、8或6,但是允许你使用字符串或数字把值赋给TIMESTAMP列。一个 TIMESTAMP列对于记录一个INSERT或UPDATE操作的日期和时间是有用的,因为如果你不自己给它赋值,它自动地被设置为最近操作的日期和时间。你以可以通过赋给它一个NULL值设置它为当前的日期和时间。

TIME

一个时间。范围是'-838:59:59'到'838:59:59'。MySQL以'HH:MM:SS'格式来显示TIME值,但是允许你使用字符串或数字把值赋给TIME列。

YEAR[(2|4)]

一个2或4位数字格式的年(缺省是4位)。允许的值是1901到2155,和0000(4位年格式),如果你使用2位,1970-2069( 70-69)。MySQL以YYYY格式来显示YEAR值,但是允许你把使用字符串或数字值赋给YEAR列。(YEAR类型在MySQL3.22中是新类型。)

CHAR(M) [BINARY]

一个定长字符串,当存储时,总是是用空格填满右边到指定的长度。M的范围是1 ~ 255个字符。当值被检索时,空格尾部被删除。CHAR值根据缺省字符集以大小写不区分的方式排序和比较,除非给出BINARY关键词。NATIONAL CHAR(短形式NCHAR)是ANSI SQL的方式来定义CHAR列应该使用缺省字符集。这是MySQL的缺省。CHAR是CHARACTER的一个缩写。

[NATIONAL] VARCHAR(M) [BINARY]

一个变长字符串。注意:当值被存储时,尾部的空格被删除(这不同于ANSI SQL规范)。M的范围是1 ~ 255个字符。 VARCHAR值根据缺省字符集以大小写不区分的方式排序和比较,除非给出BINARY关键词值。 VARCHAR是CHARACTER VARYING一个缩写。

TINYBLOB

TINYTEXT

一个BLOB或TEXT列,最大长度为255(2^8-1)个字符。

BLOB

TEXT

一个BLOB或TEXT列,最大长度为65535(2^16-1)个字符。

MEDIUMBLOB

MEDIUMTEXT

一个BLOB或TEXT列,最大长度为16777215(2^24-1)个字符。

LONGBLOB

LONGTEXT

一个BLOB或TEXT列,最大长度为4294967295(2^32-1)个字符。

ENUM('value1','value2',...)

枚举。一个仅有一个值的字符串对象,这个值式选自与值列表'value1'、'value2', ...,或NULL。一个ENUM最多能有65535不同的值。

SET('value1','value2',...)

一个集合。能有零个或多个值的一个字符串对象,其中每一个必须从值列表'value1', 'value2', ...选出。一个SET最多能有64个成员。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值