[MySQL FAQ]系列 — 你所不知的table is full那些事
當我們要寫入新數據而發生“The table is full”告警錯誤時,先不要着急,按照下面的思路來逐步分析即可:
1、查看操作系統以及MySQL的錯誤日志文件
確認操作系統的文件系統沒有報錯,並且MySQL的錯誤日志文件中是否有一些最直觀的可見的錯誤提示。
有可能是數據庫文件超過操作系統層的文件大小限制,比如fat/fat32以及低版本的Linux,文件最大不可以大於2G(最大擴展到4G),這就需要轉換fat32為NTFS,或升級Linux版本。
2、確認磁盤空間沒有滿
執行 df -h 查看剩余磁盤空間,如果發現磁盤空間確實已經用完,則盡快刪除不需要的文件。
如果通過 du 計算各個目錄的總和卻發現根本不會用完磁盤空間時,就需要注意了,可能是某個被刪除的文件還沒完全釋放,導致 df 看起來已經用完,但 du 卻又統計不到。
這時候可以執行 lsof | grep -i deleted 找到被刪除的大文件,將其對應的進程殺掉,釋放該文件描述符。
如果該進程不能被殺掉,例如是 mysqld 進程在占用的話,可以在 MySQL 里找到是哪個內部線程在用,停止該線程即可。
曾經發生過這樣一個例子:
用vim打開MySQL的slow query log,退出時選擇了 “wq” 指令,也就是保存退出,結果悲劇發生了。
因為在其打開的那段時間內,slow query log有新日志產生,會持續寫入,但他退出時采用保存退出的方式,變成了一個“新”文件(或者說新文件句柄 file handler),這個“新”文件無法被mysqld進程識別,
mysqld進程依舊將slow query log寫入到原來它打開的那個文件(或者說文件句柄)里,該日志文件在持續增長,但手工保存退出的文件卻再也不增長了,直接查看文件看不出任何異常。
這時候只能用 lsof -p `pidof mysqld` 才能看到該文件。
解決方法很簡單,將原來的文件備份一下,執行下面的指令:
FLUSH SLOW LOGS;
備注:MySQL 5.5開始才支持 BINARY/ENGINE/ERROR/GENERAL/RELAY/SLOW 等關鍵字,之前的版本只能刷新全部日志。
3、確認數據表狀態
- 如果是MyISAM引擎
默認配置下,MyISAM引擎最大可支持256TB( myisam_data_pointer_size = 6,256^6 = 256TB),除非操作系統層有限制。
在MySQL5.0中,MyISAM引擎行記錄默認是動態長度,單表最大可達256TB,MyISAM行指針(myisam_data_pointer_size)長度為6字節。
在這之前,MyISAM行指針默認長度為4字節,只支持4GB的數據。改行指針最大值可設為8字節。
在行指針設置較小不夠用的時候,為提高MyISAM表最大容量,可以修改表定義設定MAX_ROWS的值:
ALTER TABLE `xx` ENGINE=MyISAM MAX_ROWS=nn
備注: 表定義中, AVG_ROW_LENGTH 屬性定義的是 BLOB/TEXT 字段類型的最大長度。
- 如果是InnoDB引擎
ibdata*共享表空間最后一個文件沒有設置成自增長,或者超過32位系統的單文件大小限制。
解決方法:
1、ibdata*的最后一個文件( 非最后一個文件無法設置為自動增長 )設置成自動增長;
2、檢查操作系統,遷移到64位操作系統下;
3、轉成獨立表空間;
4、刪除歷史數據,重整表空間;
- 如果是MEMORY引擎
1、適當提高 max_heap_table_size 設置(注意該值是會話級別,不要設置過大,例如1GB,一般不建議超過256MB);
2、執行ALTER TABLE t_mem ENGINE=MEMORY; 重整表空間, 否則無法寫入新數據 ;
3、刪除部分歷史數據或者直接清空,重整表空間;
4、設置 big_tables = 1 ,將所有臨時表存儲在磁盤,而非內存中,缺點是如果某個SQL執行時需要用到臨時表,則性能會差很多;
順便說下,如果數據表有一列自增INT做主鍵,但是該ID值達到了INT最大值的話,MyISAM、MEMORY、InnoDB三種引擎的告警信息是不一樣的。
InnoDB引擎的告警信息類似這樣:
ERROR 1467 (HY000): Failed to read auto-increment value from storage engine
而MyISAM和MEMORY引擎則都是這樣: ERROR 1062 (23000): Duplicate entry ’4294967295′ for key ‘PRIMARY’
參考
MySQL手冊: B.5.2.12 The table is full
查看是否己修改
mysql> show variables like '%max_heap_table_size%';
mysql出現"the table is full"的問題,一般有兩個原因:
一 .You are using the MEMORY (HEAP) storage engine; in this case you need to increase the value of the max_heap_table_size system variable. See Section 5.1.3, “Server System Variables”.
於是就修改Mysql的配置文件/etc/my.cnf,在[mysqld]下添加/修改兩行:
tmp_table_size = 256M
max_heap_table_size = 256M
系統默認是16M,修改完后重啟mysql
二.硬盤空間滿了,清理硬盤即可.