Mysql線上回收undo表空間實戰記錄
1 Mysql5.6
1.1 相關引數
MySQL 5.6增加了引數innodb_undo_directory、innodb_undo_logs和innodb_undo_tablespaces這3個引數,可以把undo log從ibdata1移出來單獨存放。
- innodb_undo_directory:指定單獨存放undo表空間的目錄,預設為.(即datadir),可以設定相對路徑或者絕對路徑。該引數例項初始化之後雖然不可直接改動,但是可以通過先停庫,修改配置檔案,然後移動undo表空間檔案的方式去修改該引數。
預設引數:
mysql> show variables like '%undo%'; +-------------------------+-------+ | Variable_name | Value | +-------------------------+-------+ | innodb_undo_directory | . | | innodb_undo_logs | 128 | | innodb_undo_tablespaces | 0 | +-------------------------+-------+
- innodb_undo_tablespaces:指定單獨存放的undo表空間個數,例如如果設定為3,則undo表空間為undo001、undo002、undo003,每個檔案初始大小預設為10M。該引數我們推薦設定為大於等於3,原因下文將解釋。該引數例項初始化之後不可改動
例項初始化是修改innodb_undo_tablespaces:
mysql_install_db ...... --innodb_undo_tablespaces $ ls ... undo001 undo002 undo003
- innodb_rollback_segments:預設128個。每個回滾段可同時支援1024個線上事務。這些回滾段會平均分佈到各個undo表空間中。該變數可以動態調整,但是物理上的回滾段不會減少,只是會控制用到的回滾段的個數。
1.2 使用
初始化例項之前,我們只需要設定innodb_undo_tablespaces引數(建議大於等於3)即可將undo log設定到單獨的undo表空間中。如果需要將undo log放到更快的裝置上時,可以設定innodb_undo_directory引數,但是一般我們不這麼做,因為現在SSD非常普及。innodb_undo_logs可以預設為128不變。
undo log可以儲存於ibdata之外。但這個特性依然雞肋:
- 首先你必須在install例項的時候就指定好獨立Undo tablespace,在install完成後不可更改。
- Undo tablepsace的space id必須從1開始,無法增加或者刪除undo tablespace。
1.3 大事務測試
mysql> create table test.tbl( id int primary key auto_increment,name varchar(200)); Query OK,0 rows affected (0.03 sec) mysql> start transaction; Query OK,0 rows affected (0.00 sec) mysql> insert into test.tbl(name) values(repeat('1',00)); Query OK,1 row affected (0.00 sec) mysql> insert into test.tbl(name) select name from test.tbl; Query OK,1 row affected (0.00 sec) Records: 1 Duplicates: 0 Warnings: 0 ... mysql> insert into test.tbl(name) select name from test.tbl; Query OK,2097152 rows affected (24.84 sec) Records: 2097152 Duplicates: 0 Warnings: 0 mysql> commit; Query OK,0 rows affected (7.90 sec)
觀察undolog已經開始膨脹了!事務commit後空間也沒有回收。
$ du -sh undo* 10M undo001 69M undo002 10M undo003
2 Mysql5.7
5.7引入了線上truncate undo tablespace
2.1 相關引數
必要條件:
- innodb_undo_tablespaces:最少有兩個,這樣一個在清理的時候可以使用另一個,該引數例項初始化之後不可改動
- innodb_rollback_segments:回滾段的個數,總會有一個回滾段分配給系統表空間,32個保留給臨時表空間。所以如果想使用undo表空間的話,這個值要至少為33。例如使用兩個undo表空間,這個值就配35。如果設定多個undo表空間,系統表空間中的回滾段會變成非活躍狀態。
啟動引數:
- innodb_undo_log_truncate=on
- innodb_max_undo_log_size:超過這個值的表空間會標記為truncate,動態引數預設是1G
- innodb_purge_rseg_truncate_frequency:指定purge操作被喚起多少次之後才釋放rollback segments。當undo表空間裡面的rollback segments被釋放時,undo表空間才會被truncate。由此可見,該引數越小,undo表空間被嘗試truncate的頻率越高。
2.2 清理過程
- undo表空間大小超過innodb_max_undo_log_size後,標記該表空間需要清理。標記會迴圈進行,避免一個表空間被反覆清理。
- 標記表空間內的回滾段變為非活躍狀態,正在執行的事務等待執行完。
- 開始purge
- 釋放undo表空間中的所有回滾段後,執行truncate並將undo表空間截斷為其初始大小,初始大小由innodb_page_size決定,預設16KB的大小對應表空間為10MB
- 重新啟用回滾段,以便將它們分配給新事務
2.3 效能建議
truncate表空間時避免影響效能的最簡單方法是增加撤消表空間的數量
2.4 大事務測試
配置8個undo表空間,innodb_purge_rseg_truncate_frequency=10
mysqld --initialize ... --innodb_undo_tablespaces=8
開始測試
mysql> show global variables like '%undo%'; +--------------------------+------------+ | Variable_name | Value | +--------------------------+------------+ | innodb_max_undo_log_size | 1073741824 | | innodb_undo_directory | ./ | | innodb_undo_log_truncate | ON | | innodb_undo_logs | 128 | | innodb_undo_tablespaces | 8 | +--------------------------+------------+ mysql> select @@innodb_purge_rseg_truncate_frequency; +----------------------------------------+ | @@innodb_purge_rseg_truncate_frequency | +----------------------------------------+ | 10 | +----------------------------------------+ select @@innodb_max_undo_log_size; +----------------------------+ | @@innodb_max_undo_log_size | +----------------------------+ | 10485760 | +----------------------------+ mysql> create table test.tbl( id int primary key auto_increment,0 rows affected (7.90 sec)
undo表空間情況,膨脹到100MB+後成功回收
$ du -sh undo*
10M undo001
10M undo002
10M undo003
10M undo004
10M undo005
10M undo006
125M undo007
10M undo008$ du -sh undo*
10M undo001
10M undo002
10M undo003
10M undo004
10M undo005
10M undo006
10M undo007
10M undo008
3 Reference
https://dev.mysql.com/doc/ref...
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對我們的支援。