當啟用innodb_file_per_table時,表存儲在它們自己的表空間中,但是* * *共享表空間仍然存儲其他innodb內部數據:
數據字典,即InnoDB表的元數據。
更改緩沖區
雙寫緩沖器
撤銷日誌
其中壹些可以在Percona服務器上配置,以避免過度增長。例如,可以通過innodbibufmax_size設置最大更改緩沖區,或者設置innodbdoublewritefile將雙寫緩沖區存儲在單獨的文件中。
在MySQL版中,還可以創建外部還原表空間,這樣就可以將它們放入自己的文件中,而不是存儲在ibdata1中。妳可以看看這份文件。
是什麽原因導致了ibdata1的快速增長?
當MySQL出現問題時,我們通常需要執行的第壹個命令是:
顯示引擎INNODB狀態/G
這將向我們展示壹些有價值的信息。讓我們從**交易部分開始,然後我們會發現:
-交易36E,活躍1256288秒
MySQL線程id 42,OS線程句柄0x7f8baaccc700,查詢id 7900290 localhost root
顯示引擎innodb狀態
事務處理讀取視圖看不到id為& gt的事務處理。=36F,見& lt36F
這是最常見的原因之壹,14天前創建的壹個相當舊的事務。這種狀態是活動的,這意味著InnoDB已經創建了數據的快照,因此有必要在撤銷日誌中維護舊頁面,以確保在事務開始之前數據庫視圖的壹致性。如果您的數據庫有大量的寫任務,這意味著存儲了大量的撤消頁。
如果找不到任何長時間運行的事務,還可以在INNODB STATUS中監視其他變量。“歷史列表長度”顯示了壹些等待清除的操作。這種情況下經常會出現問題,因為清理線程(或者主線程的舊版本)處理撤銷的速度跟不上這些記錄進來的速度。
如何檢查存儲在ibdata1中的內容?
不幸的是,MySQL沒有提供信息來查看在ibdata1 ***共享表空間中存儲了什麽,但是有兩個工具會有所幫助。第壹個是Mark Callahan制作的innochecksum的修改版,在本次漏洞報告中發布。
它非常容易使用:
# ./inno checksum/var/lib/MySQL/ibdata 1
0錯誤校驗和
13文件_頁面_索引
19272文件_頁面_撤銷_日誌
230文件頁面信息節點
1 FIL_PAGE_IBUF_FREE_LIST
892文件_頁面_類型_分配
2填充頁面位圖
195文件_頁面_類型_系統
1文件_頁面_類型_ TRX _系統
1 HDR FSP
1 FIL_PAGE_TYPE_XDES
0 FIL_PAGE_TYPE_BLOB
0 FIL_PAGE_TYPE_ZBLOB
0其他
3最大索引標識
總共有19272個撤消日誌頁面。這占據了93%的表空間。
檢查清單空間內容的第二種方法是Jeremy Cole制作的InnoDB Ruby工具。它是檢查InnoDB內部結構的更高級的工具。例如,我們可以使用space-summary參數來獲取每個頁面及其數據類型的列表。我們可以使用標準的Unix工具來計算撤消日誌頁數:
# innodb _ space-f/var/lib/MySQL/ibdata 1 space-summary | grep UNDO _ LOG | WC-l
19272
雖然在這種特殊情況下,innochedcksum更快更容易使用,但我還是推薦您使用Jeremy的工具來更多地了解InnoDB的數據分布和內部結構。
好了,現在我們知道問題了。下壹個問題:
我該如何解決這個問題?
這個問題的答案很簡單。如果妳還能提交聲明,那就提交吧。否則,您必須終止線程並啟動回滾過程。那會讓ibdata1停止增長,但是很明顯,妳的軟件會有漏洞,會有人遇到錯誤。現在您已經知道如何識別問題,您需要使用自己的調試工具或普通的查詢日誌來找出是誰或什麽導致了問題。
如果問題出在清理線程,解決方法通常是升級到新版本,用獨立的清理線程代替主線程。有關更多信息,請參見本文檔。
有什麽方法可以回收使用過的空間?
不,目前沒有簡單快捷的方法。InnoDB表空間從不收縮...見10歲漏洞報告,詹姆斯戴最新更新(謝謝):
當您刪除壹些行時,該頁面會被標記為已刪除並在以後重用,但此空間將永遠不會被回收。唯壹的方法是用新的ibdata1啟動數據庫。為此,您應該使用mysqldump進行邏輯完整備份,然後停止MySQL並刪除所有數據庫、ib_logfile和ibdata1文件。當您再次啟動MySQL時,將會創建壹個新的表空間。然後恢復邏輯備份。