【MySQL】ibdata檔案增大的原因
背景
早上和一個同事討論技術問題,談到ibdata檔案會隨著資料的使用而增大,而且在事務隔離級別RR 隔離級別下要比RC 隔離級別的大。本文嘗試分析兩個問題之一
a ibdata 檔案隨著資料庫的使用而增大。
b RR 隔離級別下比RC 隔離級別下增長的快大。
ibdata1 存放哪些資料?
表資料/索引 (innodb_file_per_table=0 時)
data dictionary aka metadata of InnoDB tables
undo 表空間 回滾段相關記錄
doublewrite buffer
change buffer
什麼原因導致ibdata 迅速增大呢?
從ibdata1檔案存放的內容來分析
我們都知道innodb的表有兩種存放方式:
當innodb_file_per_table=0時也即共享表空間方式,所有表的索引/資料統一存放在一個共享表空間中ibdata1檔案,隨著資料量的增大,共享表空間的檔案大小也迅速增長,同時空間回收困難;
當innodb_file_per_table=1時也即獨佔表空間方式,也就是一張表一個表空間(ibd檔案),表中的索引和資料存放在獨立的表空間中,執行drop/truncate 操作可以快速的回收獨立表空間。
對於buffer 可以分別使用引數 innodb_doublewrite_file ,innodb_ibuf_max_size控制大小,他們帶來的空間增長可以忽略不計,最終 ibdata最終的大小取決於事務的大小/長短。
a 資料庫系統中存在長時間未提交的事務,或者在同一個事務中更新/插入很多資料,導致innodb需要維護很大的undo segments來保障一致性讀。
透過執行命令
SHOW ENGINE INNODB STATUSG
---TRANSACTION 36E, ACTIVE 1256288 sec
MySQL thread id 42, OS thread handle 0x7f8baaccc700, query id 7900290 localhost root
show engine innodb status
Trx read view will not see trx with id >= 36F, sees < 36F
例子中顯示有一個長達 1256288秒(14年)的事務未提交。active 意味著innodb在undo segment裡面建立資料的快照以便提供一致性讀。如果資料庫存在大量的長事務,就要耗費大量的undo segment。
b 5.5版本之前 purge undo thread是和master thread 共用的。存在大量長事務的時候導致purge undo的速度小於undo segment產生的速度。透過 innodb 引數 History list length
History list length 2308 表示有 2308個事務沒有清理,過大的值意味著purge thread 速度達到了瓶頸。5.5 版本開始MySQL 將purge thread 和master thread 分開,我們可以透過調整引數來加快purge undo的速度。
# yzsql 3311 param purge
如何檢視ibdata檔案中的內容呢?
MySQL 官方並沒有提供工具查ibata儲存了什麼內容,不過我們可以透過如下兩種工具
innochecksum,(感謝 Mark Callaghan)。
./innochecksum /var/lib/mysql/ibdata1
從上面的分析來看 undo log佔用了總ibdata1 的93%。
第二個工具: ( made by Jeremy Col)可以清晰地分析出ibdata1的組成(該工具需要bindata環境)
如何解決 ibdata1 不停的增大呢?
坦白的說我們沒有方法阻止其不停的增大,但是我們可以使用
1 規範開發同學的資料庫使用習慣,使用短小的事務替代大事務,並確保每個事務都有commit機制。
2 增加purge thread 數量,加快purge undo的速度儘快釋放undo空間。
3 升級到5.6 版本 獨立出undo 表空間來保持ibdata檔案在一個合理的大小。
當然我們也沒有優雅的辦法上增大的ibdata檔案縮小,這個檔案只增加不減小。
參考資料
[1] Reasons for run-away main Innodb Tablespace
[2] Why is the ibdata1 file continuously growing in MySQL?
[3]
早上和一個同事討論技術問題,談到ibdata檔案會隨著資料的使用而增大,而且在事務隔離級別RR 隔離級別下要比RC 隔離級別的大。本文嘗試分析兩個問題之一
a ibdata 檔案隨著資料庫的使用而增大。
b RR 隔離級別下比RC 隔離級別下增長的快大。
ibdata1 存放哪些資料?
表資料/索引 (innodb_file_per_table=0 時)
data dictionary aka metadata of InnoDB tables
undo 表空間 回滾段相關記錄
doublewrite buffer
change buffer
什麼原因導致ibdata 迅速增大呢?
從ibdata1檔案存放的內容來分析
我們都知道innodb的表有兩種存放方式:
當innodb_file_per_table=0時也即共享表空間方式,所有表的索引/資料統一存放在一個共享表空間中ibdata1檔案,隨著資料量的增大,共享表空間的檔案大小也迅速增長,同時空間回收困難;
當innodb_file_per_table=1時也即獨佔表空間方式,也就是一張表一個表空間(ibd檔案),表中的索引和資料存放在獨立的表空間中,執行drop/truncate 操作可以快速的回收獨立表空間。
對於buffer 可以分別使用引數 innodb_doublewrite_file ,innodb_ibuf_max_size控制大小,他們帶來的空間增長可以忽略不計,最終 ibdata最終的大小取決於事務的大小/長短。
a 資料庫系統中存在長時間未提交的事務,或者在同一個事務中更新/插入很多資料,導致innodb需要維護很大的undo segments來保障一致性讀。
透過執行命令
SHOW ENGINE INNODB STATUSG
---TRANSACTION 36E, ACTIVE 1256288 sec
MySQL thread id 42, OS thread handle 0x7f8baaccc700, query id 7900290 localhost root
show engine innodb status
Trx read view will not see trx with id >= 36F, sees < 36F
例子中顯示有一個長達 1256288秒(14年)的事務未提交。active 意味著innodb在undo segment裡面建立資料的快照以便提供一致性讀。如果資料庫存在大量的長事務,就要耗費大量的undo segment。
b 5.5版本之前 purge undo thread是和master thread 共用的。存在大量長事務的時候導致purge undo的速度小於undo segment產生的速度。透過 innodb 引數 History list length
- ------------
-
TRANSACTIONS
------------
Trx id counter 43831607347
Purge done for trx's n:o < 43831607342 undo n:o < 0 state: running but idle
History list length 2308
LIST OF TRANSACTIONS FOR EACH SESSION:
# yzsql 3311 param purge
-
Variable_name Value
-
innodb_max_purge_lag 0
-
innodb_max_purge_lag_delay 0
-
innodb_purge_batch_size 300
- innodb_purge_threads 12
MySQL 官方並沒有提供工具查ibata儲存了什麼內容,不過我們可以透過如下兩種工具
innochecksum,(感謝 Mark Callaghan)。
./innochecksum /var/lib/mysql/ibdata1
-
0 bad checksum
-
13 FIL_PAGE_INDEX
-
19272 FIL_PAGE_UNDO_LOG --佔用了總ibdata1 的93%
-
230 FIL_PAGE_INODE
-
1 FIL_PAGE_IBUF_FREE_LIST
-
892 FIL_PAGE_TYPE_ALLOCATED
-
2 FIL_PAGE_IBUF_BITMAP
-
195 FIL_PAGE_TYPE_SYS
-
1 FIL_PAGE_TYPE_TRX_SYS
-
1 FIL_PAGE_TYPE_FSP_HDR
-
1 FIL_PAGE_TYPE_XDES
-
0 FIL_PAGE_TYPE_BLOB
-
0 FIL_PAGE_TYPE_ZBLOB
-
0 other
- 3 max index_id
第二個工具: ( made by Jeremy Col)可以清晰地分析出ibdata1的組成(該工具需要bindata環境)
-
# innodb_space -f /var/lib/mysql/ibdata1 space-summary | grep UNDO_LOG | wc -l
- 19272
坦白的說我們沒有方法阻止其不停的增大,但是我們可以使用
1 規範開發同學的資料庫使用習慣,使用短小的事務替代大事務,並確保每個事務都有commit機制。
2 增加purge thread 數量,加快purge undo的速度儘快釋放undo空間。
3 升級到5.6 版本 獨立出undo 表空間來保持ibdata檔案在一個合理的大小。
當然我們也沒有優雅的辦法上增大的ibdata檔案縮小,這個檔案只增加不減小。
參考資料
[1] Reasons for run-away main Innodb Tablespace
[2] Why is the ibdata1 file continuously growing in MySQL?
[3]
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26250550/viewspace-2119006/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- mysql ibdata1太大的原因MySql
- mysql關於ibdata檔案的理解MySql
- 增大redo log檔案大小
- 【Mysql】誤刪ibdata ib_logfile等檔案的恢復MySql
- 為什麼 MySQL 裡的 ibdata1 檔案不斷的增長?MySql
- MySQL資料災難挽救之ibdata檔案誤刪恢復MySql
- MySQL Aborted_connects值不斷增大的可能性原因分析MySql
- mysql 5.7 刪除ibdata1 、ib_logfile 檔案的資料恢復MySql資料恢復
- 誤刪除InnoDB ibdata資料檔案(無備份)
- mysql啟動後隨即關閉問題解決(ibdata1檔案損壞導致)MySql
- MySQL:5.7.11 超過最大開啟檔案數crash原因解析MySql
- MySQL 5.6.26 誤刪ibdata恢復MySql
- mysql ibdata1 ib_logfile的恢復MySql
- 未刪除的表結構從ibdata1檔案進行恢復
- 修改hosts檔案不生效原因
- ibdata1檔案損壞時恢復InnoDB單表測試
- ORACLE 11G RAC 增加日誌組及增大日誌檔案Oracle
- mysql的資料檔案MySql
- 病毒感染檔案後圖示模糊的原因
- 隨身碟複製不了大檔案的原因
- mysql 資料庫備份及ibdata1的瘦身(轉)MySql資料庫
- MySQL配置檔案MySql
- mysql 配置檔案MySql
- MySQL檔案概述MySql
- git commit未能提交指定檔案原因GitMIT
- mysql之 [ERROR] InnoDB: Unable to lock ./ibdata1, error: 11MySqlError
- MySQL ibdata1撐爆佔滿磁碟空間MySql
- MySQL匯入匯出檔案檔案MySql
- mysql 主從日誌檔案mysql-bin檔案清除方法MySql
- MySQL 選錯索引的原因?MySql索引
- hibernate無法自動建表的原因以及.sql檔案無法執行的原因SQL
- mysql物理檔案 02MySql
- MySQL Cluster 配置檔案MySql
- 大量小檔案不適合儲存於HDFS的原因
- mysql的配置檔案my.cnfMySql
- 探究MySQL中的日誌檔案MySql
- mysql的日誌檔案詳解MySql
- MySQL資料庫的套接字檔案和pid檔案MySql資料庫