天天看點

mysql ibdata_Mysql ibdata1簡述

What is stored in ibdata1?

當啟用innodb_file_per_table時,表存儲在它們自己的表空間中,但共享表空間仍用于存儲其他InnoDB的内部資料:

資料字典也就是InnoDB表的中繼資料

改變緩沖區

雙寫緩沖區

撤消日志

其中一些可以在Percona Server上配置,以避免變得太大。例如,您可以使用innodb_ibuf_max_size為更改緩沖區設定最大大小,或者使用innodb_doublewrite_file将doublewrite緩沖區存儲在單獨的檔案中。

在MySQL 5.6中,您還可以建立外部UNDO表空間,以便它們位于自己的檔案中,而不是存儲在ibdata1中。文檔連結:http://dev.mysql.com/doc/refman/5.6/en/innodb-performance.html#innodb-undo-tablespace

What is causing the ibdata1 to grow that fast?

當出現MySQL問題時、通暢需要運作的第一個指令是:

SHOW ENGINE INNODB STATUSG

這将展示非常有價值的資訊。開始從檢查TRANSACTIONS部分,發現:---TRANSACTION 36E, ACTIVE 1256288 sec

MySQL thread id 42, OS thread handle 0x7f8baaccc700, query id 7900290localhost root

show engine innodb status

Trxread view will not see trx with id >= 36F, sees < 36F

這是最常見的原因,是14天前建立的一個非常古老的交易。狀态為ACTIVE,這意味着InnoDB已建立資料快照,是以需要在undo中維護舊頁面,以便能夠在啟動事務後提供資料庫的一緻視圖。如果資料庫被大量寫入任務,則意味着存儲了大量的撤消頁面。

如果找不到任何長時間運作的事務,還可以監控INNODB STATUS中的另一個變量,即“History list length(曆史記錄清單長度)”。它顯示待處理的清除操作的數量。在這種情況下,問題通常是由于清除線程(或舊版本中的主線程)無法以與它們進入的速度相同的速度處理撤消記錄。

How can I check what is being stored in the ibdata1?

不幸的是,MySQL沒有提供ibdata1共享表空間上存儲内容的資訊,但有兩個工具非常有用。首先是由Mark Callaghan制作并在此錯誤報告中發表的innochecksum的修改版本。http://bugs.mysql.com/bug.php?id=57611

它很容易使用:

./innochecksum /var/lib/mysql/ibdata10bad checksum13FIL_PAGE_INDEX19272FIL_PAGE_UNDO_LOG230FIL_PAGE_INODE1FIL_PAGE_IBUF_FREE_LIST892FIL_PAGE_TYPE_ALLOCATED2FIL_PAGE_IBUF_BITMAP195FIL_PAGE_TYPE_SYS1FIL_PAGE_TYPE_TRX_SYS1FIL_PAGE_TYPE_FSP_HDR1FIL_PAGE_TYPE_XDES0FIL_PAGE_TYPE_BLOB0FIL_PAGE_TYPE_ZBLOB0other3 maxindex_id

全部的20608 中有 19272 個撤銷日志頁。這占用了表空間的 93%。

檢查表空間内容的第二種方法是由Jeremy Cole制作的InnoDB Ruby工具。它是檢查InnoDB内部的更進階工具。例如,我們可以使用space-summary參數來擷取包含每個頁面及其資料類型的清單。我們可以使用标準的Unix工具來擷取UNDO_LOG頁面的數量:

innodb_space -f /var/lib/mysql/ibdata1 space-summary | grep UNDO_LOG | wc -l19272

盡管這種特殊的情況下,innochedcksum 更快更容易使用,但是推薦使用傑裡米的工具去了解更多的 InnoDB 内部的資料分布及其内部結構。

好,現在知道問題所在了。下一個問題:

How can I solve the problem?

這個問題的答案很簡單。如果仍然可以送出該查詢,請執行此操作。如果不是,将不得不殺死線程以啟動復原過程。這将阻止ibdata1的增長,但顯然某個軟體有一個錯誤或有人犯了錯誤。既然已經知道如何确定問題所在,是以需要使用自己的調試工具或正常查詢日志查找導緻問題的人員或原因。

如果問題是由清除線程引起的,那麼解決方案通常是更新到更新的版本,可以使用專用的清除線程而不是主線程。有關以下文檔連結的更多資訊。http://dev.mysql.com/doc/innodb/1.1/en/innodb-improved-purge-scheduling.html

Is there any way to recover the used space?

不,至少在一個簡單快捷的方式是不可能的。 InnoDB表空間從未縮小

請參閱James Day最近更新的以下10年的錯誤報告http://bugs.mysql.com/bug.php?id=1341

删除某些行時,頁面将标記為已删除,以便稍後重複使用,但永遠不會恢複該空間。唯一的方法是使用新的ibdata1啟動資料庫。要做到這一點,需要使用mysqldump進行完整的邏輯備份。然後停止MySQL并删除所有資料庫,ib_logfile *和ibdata *檔案。再次啟動MySQL時,它将建立一個新的共享表空間。然後,恢複邏輯轉儲

Summary

當ibdata1檔案在MySQL中增長太快時,通常是Mysql長時間運作被遺忘的事務引起的。嘗試盡快解決問題(送出或終止事務),因為如果沒有緩慢的mysqldump程序,将無法回收浪費的磁盤空間。

還建議監視資料庫以避免這類問題。MySQL監控插件包含一個Nagios腳本,如果發現運作的事務太舊,可以提醒。

本文出處:https://www.percona.com/blog/2013/08/20/why-is-the-ibdata1-file-continuously-growing-in-mysql/