Mysql [Err] 1118 - Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535.


對於越來越多的數據,數據庫的容量越來越大,壓縮也就越來越常見了。在我的實際工作中進行過多次壓縮工作,也遇到多次問題,在此和大家分享一下。

首先,我們先說說怎么使用innodb的壓縮.

第一,mysql的版本需要大於5.5
第二,設置innodb_file_format=barracuda
第三,create table或者alter talble 增加 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;(默認的key_block_size=16)

其實很簡單,根據經驗,一般壓縮比例可以達到30%-40%

 

然后,我們說說我在壓縮過程中遇到的坑和發現的關聯,當然有些比較二。

No1:


 

問題:使用腳本批量alter操作,只動態修改了實例的innodb_file_format=barracuda,然后alter所有數據庫中的表。並沒有修改配置文件中的設置。

結果:表中已有數據被壓縮,但是在重啟之后,由於innodb_file_format參數被重新修改成antelope,導致后續寫入的數據沒有被壓縮(雖然表結構中有row_format=compressed,但是不會起作用),最終表體積仍然很大。

教訓:實例和配置文件要同步修改。(這個錯誤最二,太低級 T_T,不解釋了。)

 

No2:


 

問題:在innodb_file_format=antelope的情況下,建立壓縮表(表結構中帶有row_format=compressed),然后在設置innodb_file_format=barracuda。

結果:表結構中的row_format=compressed被忽略,后續寫入表的數據並沒有被壓縮,最終導致表體積大。

教訓:先修改innodb_file_format(session和global都需要修改),在create table或者alter table。

但是以上這點有個坑人的地方,在錯誤的順序下,表是可以被成功建立了,只是會有warning,但是表結構中會有row_format=compressed,在后期排查的時候非常誤導人!

復制代碼
+--------------------------+----------+
| Variable_name            | Value    |
+--------------------------+----------+
| innodb_file_format       | Antelope |
| innodb_file_format_check | ON       |
| innodb_file_format_max   | Antelope |
+--------------------------+----------+
3 rows in set (0.00 sec)

test> create table test_1 (x int) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
Query OK, 0 rows affected, 4 warnings (0.07 sec)

 

test> show warnings;
+---------+------+-----------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+-----------------------------------------------------------------------+
| Warning | 1478 | InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. |
| Warning | 1478 | InnoDB: ignoring KEY_BLOCK_SIZE=8. |
| Warning | 1478 | InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. |
| Warning | 1478 | InnoDB: assuming ROW_FORMAT=COMPACT. |
+---------+------+-----------------------------------------------------------------------+
4 rows in set (0.00 sec)

復制代碼

我們可以從warnings中看見,壓縮設置被忽略了。但是最坑爹的一點是,如果我們show create table會有如下結果:

test_1 | CREATE TABLE `test_1` (
  `x` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8

在這種情況下,我們吸取教訓,不能使用show create table看壓縮狀態,而是應該用show table status;

復制代碼
show table status like 'test_1'\G;
*************************** 1. row ***************************
           Name: test_1
         Engine: InnoDB
        Version: 10
     Row_format: Compact
           Rows: 0
 Avg_row_length: 0
    Data_length: 16384
Max_data_length: 0
   Index_length: 0
      Data_free: 0
 Auto_increment: NULL
    Create_time: 2013-09-27 15:59:13
    Update_time: NULL
     Check_time: NULL
      Collation: utf8_general_ci
       Checksum: NULL
 Create_options: row_format=COMPRESSED KEY_BLOCK_SIZE=8
        Comment:
1 row in set (0.00 sec)
復制代碼

坑爹啊,不說了。正常應該這個樣子

復制代碼
show table status like 'test_2'\G;
*************************** 1. row ***************************
           Name: test_2
         Engine: InnoDB
        Version: 10
     Row_format: Compressed
           Rows: 0
 Avg_row_length: 0
    Data_length: 8192
Max_data_length: 0
   Index_length: 0
      Data_free: 0
 Auto_increment: NULL
    Create_time: 2013-09-27 16:09:51
    Update_time: NULL
     Check_time: NULL
      Collation: utf8_general_ci
       Checksum: NULL
 Create_options: row_format=COMPRESSED KEY_BLOCK_SIZE=8
        Comment:
1 row in set (0.00 sec)
復制代碼

 

No3:


 

發現和innodb_file_format相關的2個參數:

復制代碼
+--------------------------+-----------+
| Variable_name            | Value     |
+--------------------------+-----------+
| innodb_file_format       | Barracuda |
| innodb_file_format_check | ON        |
| innodb_file_format_max   | Barracuda |
+--------------------------+-----------+
3 rows in set (0.00 sec)
復制代碼

官方的解釋可以參考如下的鏈接:http://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar_innodb_file_format

測試過程中發現,如果是innodb_file_format=barracuda而innodb_file_format_max=antelop,那么在建立壓縮表的時候,max會自動變成barracuda。

復制代碼
localhost.test>show global variables like 'innodb_file_format%';
+--------------------------+-----------+
| Variable_name            | Value     |
+--------------------------+-----------+
| innodb_file_format       | Barracuda |
| innodb_file_format_check | ON        |
| innodb_file_format_max   | Antelope  |
+--------------------------+-----------+
3 rows in set (0.00 sec)

localhost.test>create table test_4(x int) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
Query OK, 0 rows affected (0.01 sec)

localhost.test>show global variables like 'innodb_file_format%';
+--------------------------+-----------+
| Variable_name            | Value     |
+--------------------------+-----------+
| innodb_file_format       | Barracuda |
| innodb_file_format_check | ON        |
| innodb_file_format_max   | Barracuda |
+--------------------------+-----------+
3 rows in set (0.00 sec)
復制代碼

如果innodb_file_format_check這參數解釋的,決定innodb是否會檢查共享表空間中的表格式的tag,如果檢查開啟,那么當標記的表格式的tag高於innodb可以支撐的表格式,那么innodb會報錯,並停止啟動。如果支持,那么會將innodb_file_format_max的值改為這個tag的值。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM