Undo 表空間包含 undo 日誌,這些日誌是記錄的集合,其中包含有關交易如何撤銷叢集索引記錄的最新變更的資訊。
本節將在下列主題下說明 Undo 表空間
在初始化 MySQL 執行個體時會建立兩個預設的 undo 表空間。預設的 undo 表空間會在初始化時建立,以提供回滾段的位置,這些回滾段必須在接受 SQL 陳述式之前存在。至少需要兩個 undo 表空間才能支援自動截斷 undo 表空間。請參閱 截斷 Undo 表空間。
預設的 undo 表空間會在 innodb_undo_directory
變數定義的位置中建立。如果 innodb_undo_directory
變數未定義,則會在資料目錄中建立預設的 undo 表空間。預設的 undo 表空間資料檔案名為 undo_001
和 undo_002
。在資料字典中定義的對應 undo 表空間名稱為 innodb_undo_001
和 innodb_undo_002
。
可以使用 SQL 陳述式在執行階段建立額外的 undo 表空間。請參閱 新增 Undo 表空間。
初始的 undo 表空間大小通常為 16MiB。當新的 undo 表空間由截斷操作建立時,初始大小可能會有所不同。在這種情況下,如果檔案延伸大小大於 16MB,且先前的檔案延伸發生在最後一秒內,則新的 undo 表空間會以 innodb_max_undo_log_size
變數定義的大小的四分之一建立。
undo 表空間的延伸量最少為 16MB。為了處理積極的增長,如果先前的檔案延伸發生在 0.1 秒之前,則檔案延伸大小會加倍。延伸大小的加倍可能會發生多次,最大值為 256MB。如果先前的檔案延伸發生在超過 0.1 秒之前,則延伸大小會減少一半,這也可能會發生多次,最小值為 16MB。如果為 undo 表空間定義了 AUTOEXTEND_SIZE
選項,則它會延伸 AUTOEXTEND_SIZE
設定與上述邏輯判定的延伸大小中較大的值。有關 AUTOEXTEND_SIZE
選項的資訊,請參閱 第 17.6.3.9 節,「表空間 AUTOEXTEND_SIZE 設定」。
由於在長時間執行的交易期間,復原日誌可能會變得很大,因此建立額外的復原表空間有助於防止個別的復原表空間變得過大。可以使用 CREATE UNDO TABLESPACE
語法在執行階段建立額外的復原表空間。
CREATE UNDO TABLESPACE tablespace_name ADD DATAFILE 'file_name.ibu';
復原表空間的檔名必須具有 .ibu
副檔名。定義復原表空間檔名時,不允許指定相對路徑。允許使用完整路徑,但該路徑必須是 InnoDB
所知的。已知的路徑是由 innodb_directories
變數定義的路徑。建議使用唯一的復原表空間檔名,以避免在移動或複製資料時可能發生的檔名衝突。
在複寫環境中,來源和每個複本都必須有自己的復原表空間檔案目錄。將復原表空間檔案的建立複寫到通用目錄會導致檔名衝突。
在啟動時,會掃描由 innodb_directories
變數定義的目錄以尋找復原表空間檔案。(掃描也會遍歷子目錄。)無論 innodb_directories
變數是否明確定義,由 innodb_data_home_dir
、innodb_undo_directory
和 datadir
變數定義的目錄都會自動附加到 innodb_directories
值。因此,復原表空間可以位於任何由這些變數定義的路徑中。
如果復原表空間檔名不包含路徑,則會在由 innodb_undo_directory
變數定義的目錄中建立復原表空間。如果該變數未定義,則會在資料目錄中建立復原表空間。
InnoDB
復原程序要求復原表空間檔案必須位於已知的目錄中。必須在還原重做和開啟其他資料檔案之前,先探索並開啟復原表空間檔案,以便允許回滾未提交的交易和資料字典變更。在復原之前找不到的復原表空間無法使用,這可能會導致資料庫不一致。如果在啟動時找不到資料字典已知的復原表空間,則會報告錯誤訊息。已知的目錄要求也支援復原表空間的可攜性。請參閱移動復原表空間。
若要在相對於資料目錄的路徑中建立復原表空間,請將 innodb_undo_directory
變數設定為相對路徑,並且在建立復原表空間時只指定檔名。
若要檢視復原表空間名稱和路徑,請查詢 INFORMATION_SCHEMA.FILES
SELECT TABLESPACE_NAME, FILE_NAME FROM INFORMATION_SCHEMA.FILES
WHERE FILE_TYPE LIKE 'UNDO LOG';
一個 MySQL 執行個體最多支援 127 個復原表空間,其中包括在初始化 MySQL 執行個體時建立的兩個預設復原表空間。
可以使用 DROP UNDO TABALESPACE
語法捨棄復原表空間。請參閱捨棄復原表空間。
使用 CREATE UNDO TABLESPACE
語法建立的復原表空間,可以在執行階段使用 DROP UNDO TABALESPACE
語法捨棄。
復原表空間必須先為空,才能捨棄。若要清空復原表空間,必須先使用 ALTER UNDO TABLESPACE
語法將復原表空間標示為非作用中,這樣該表空間就不會再用於將回滾區段指派給新的交易。
ALTER UNDO TABLESPACE tablespace_name SET INACTIVE;
在復原表空間標示為非作用中之後,允許目前使用復原表空間中回滾區段的交易完成,以及允許在這些交易完成之前開始的任何交易完成。交易完成後,清除系統會釋放復原表空間中的回滾區段,並且將復原表空間截斷為其初始大小。(截斷復原表空間時會使用相同的程序。請參閱截斷復原表空間。)一旦復原表空間為空,就可以將其捨棄。
DROP UNDO TABLESPACE tablespace_name;
或者,復原表空間可以保留在空的狀態,並在需要時,透過發出 ALTER UNDO TABLESPACE
陳述式重新啟用。tablespace_name
SET ACTIVE
可以使用查詢 Information Schema INNODB_TABLESPACES
表格來監控復原表空間的狀態。
SELECT NAME, STATE FROM INFORMATION_SCHEMA.INNODB_TABLESPACES
WHERE NAME LIKE 'tablespace_name';
inactive
狀態表示復原表空間中的回滾區段不再被新的交易使用。empty
狀態表示復原表空間為空,可以捨棄,或可以使用 ALTER UNDO TABLESPACE
陳述式再次設為作用中。嘗試捨棄非空的復原表空間會傳回錯誤。tablespace_name
SET ACTIVE
初始化 MySQL 執行個體時建立的預設復原表空間(innodb_undo_001
和 innodb_undo_002
)無法捨棄。但是,可以使用 ALTER UNDO TABLESPACE
陳述式將其設為非作用中。在將預設復原表空間設為非作用中之前,必須有另一個復原表空間取代它的位置。始終需要至少兩個作用中的復原表空間,以支援復原表空間的自動截斷。tablespace_name
SET INACTIVE
在伺服器離線時,可以使用 CREATE UNDO TABLESPACE
語法建立的復原表空間,移動到任何已知目錄。已知目錄是由 innodb_directories
變數定義的目錄。無論 innodb_directories
變數是否明確定義,由 innodb_data_home_dir
、innodb_undo_directory
和 datadir
定義的目錄都會自動附加到 innodb_directories
值。在啟動時,會掃描這些目錄及其子目錄以尋找復原表空間檔案。在啟動時,會探索到移動到這些目錄中的任何復原表空間檔案,並假設其為已移動的復原表空間。
初始化 MySQL 執行個體時建立的預設復原表空間(innodb_undo_001
和 innodb_undo_002
)必須位於由 innodb_undo_directory
變數定義的目錄中。如果 innodb_undo_directory
變數未定義,則預設的復原表空間會位於資料目錄中。如果在伺服器離線時移動預設的復原表空間,則必須使用設定為新目錄的 innodb_undo_directory
變數來啟動伺服器。
由於復原日誌的 I/O 模式,復原表空間很適合使用 SSD 儲存裝置。
innodb_rollback_segments
變數定義指派給每個復原表空間和全域暫存表空間的回滾區段的數量。可以在啟動時或在伺服器執行時設定 innodb_rollback_segments
變數。
innodb_rollback_segments
的預設設定為 128,這也是最大值。如需回滾區段支援的交易數量相關資訊,請參閱第 17.6.6 節「復原日誌」。
有兩種截斷復原表空間的方法,可以單獨使用或組合使用來管理復原表空間大小。一種方法是自動的,使用組態變數啟用。另一種方法是手動的,使用 SQL 陳述式執行。
自動方法不需要監控復原表空間大小,並且一旦啟用,它會在沒有手動干預的情況下執行停用、截斷和重新啟用復原表空間。如果您想要控制何時將復原表空間離線以進行截斷,則手動截斷方法可能更適合。例如,您可能想要避免在工作負載高峰時截斷復原表空間。
自動截斷
自動截斷復原表空間需要至少兩個作用中的復原表空間,這可確保在將一個復原表空間離線截斷時,另一個復原表空間仍然作用中。預設情況下,在初始化 MySQL 執行個體時會建立兩個復原表空間。
若要讓復原表空間自動截斷,請啟用 innodb_undo_log_truncate
變數。例如
mysql> SET GLOBAL innodb_undo_log_truncate=ON;
當 innodb_undo_log_truncate
變數啟用時,超過由 innodb_max_undo_log_size
變數定義的大小限制的復原表空間會受到截斷。 innodb_max_undo_log_size
變數是動態的,預設值為 1073741824 位元組 (1024 MiB)。
mysql> SELECT @@innodb_max_undo_log_size;
+----------------------------+
| @@innodb_max_undo_log_size |
+----------------------------+
| 1073741824 |
+----------------------------+
當 innodb_undo_log_truncate
變數啟用時
超過
innodb_max_undo_log_size
設定的預設和使用者定義的復原表空間會標示為要截斷。會以循環方式執行選擇要截斷的復原表空間,以避免每次都截斷相同的復原表空間。位於所選復原表空間中的回滾區段會設為非作用中,因此不會將其指派給新的交易。允許目前使用回滾區段的現有交易完成。
清除系統會透過釋放不再使用的復原日誌來清空回滾區段。
在釋放復原表空間中的所有回滾區段後,截斷作業會執行,並將復原表空間截斷為其初始大小。
由於在作業完成後立即使用,因此截斷作業後的復原表空間大小可能大於初始大小。
變數
innodb_undo_directory
定義了預設復原表空間檔案的位置。如果innodb_undo_directory
變數未定義,則預設復原表空間將駐留在資料目錄中。所有復原表空間檔案的位置,包括使用CREATE UNDO TABLESPACE
語法建立的使用者定義復原表空間,都可以透過查詢資訊綱要FILES
表格來確定。SELECT TABLESPACE_NAME, FILE_NAME FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE LIKE 'UNDO LOG';
回滾段將被重新啟用,以便可以將它們分配給新的交易。
手動截斷
手動截斷復原表空間至少需要三個活動的復原表空間。始終需要兩個活動的復原表空間,以支援啟用自動截斷的可能性。至少三個復原表空間滿足此要求,同時允許手動將一個復原表空間離線。
若要手動啟動復原表空間的截斷,請發出以下陳述式停用復原表空間:
ALTER UNDO TABLESPACE tablespace_name SET INACTIVE;
在復原表空間被標記為非活動狀態後,目前使用復原表空間中回滾段的交易將被允許完成,任何在這些交易完成之前開始的交易也是如此。交易完成後,清除系統會釋放復原表空間中的回滾段,復原表空間將被截斷為其初始大小,且復原表空間的狀態會從 inactive
變更為 empty
。
當 ALTER UNDO TABLESPACE
陳述式停用復原表空間時,清除執行緒會在下一次機會尋找該復原表空間。一旦找到復原表空間並標記為截斷,清除執行緒將以更高的頻率返回,以快速清空和截斷復原表空間。tablespace_name
SET INACTIVE
若要檢查復原表空間的狀態,請查詢資訊綱要 INNODB_TABLESPACES
表格。
SELECT NAME, STATE FROM INFORMATION_SCHEMA.INNODB_TABLESPACES
WHERE NAME LIKE 'tablespace_name';
一旦復原表空間處於 empty
狀態,就可以透過發出以下陳述式重新啟用它:
ALTER UNDO TABLESPACE tablespace_name SET ACTIVE;
處於 empty
狀態的復原表空間也可以被刪除。請參閱刪除復原表空間。
加速自動截斷復原表空間
清除執行緒負責清空和截斷復原表空間。預設情況下,清除執行緒會在每次調用清除操作的 128 次中,尋找要截斷的復原表空間。清除執行緒尋找要截斷的復原表空間的頻率由 innodb_purge_rseg_truncate_frequency
變數控制,該變數的預設設定為 128。
mysql> SELECT @@innodb_purge_rseg_truncate_frequency;
+----------------------------------------+
| @@innodb_purge_rseg_truncate_frequency |
+----------------------------------------+
| 128 |
+----------------------------------------+
若要增加頻率,請降低 innodb_purge_rseg_truncate_frequency
設定。例如,若要讓清除執行緒在每次調用清除操作的 32 次中尋找復原表空間,請將 innodb_purge_rseg_truncate_frequency
設定為 32。
mysql> SET GLOBAL innodb_purge_rseg_truncate_frequency=32;
截斷復原表空間檔案的效能影響
當復原表空間被截斷時,復原表空間中的回滾段將被停用。其他復原表空間中的活動回滾段將承擔整個系統負載的責任,這可能會導致輕微的效能下降。效能受影響的程度取決於許多因素:
復原表空間的數量
復原日誌的數量
復原表空間的大小
I/O 子系統的速度
現有的長期執行交易
系統負載
避免潛在效能影響的最簡單方法是增加復原表空間的數量。
監控復原表空間截斷
提供了 undo
和 purge
子系統計數器,用於監控與復原日誌截斷相關的背景活動。有關計數器名稱和描述,請查詢資訊綱要 INNODB_METRICS
表格。
SELECT NAME, SUBSYSTEM, COMMENT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE '%truncate%';
有關啟用計數器和查詢計數器資料的資訊,請參閱第 17.15.6 節「InnoDB INFORMATION_SCHEMA Metrics Table」。
復原表空間截斷限制
在檢查點之間,對同一個復原表空間的截斷操作次數限制為 64 次。此限制可防止因過多的復原表空間截斷操作而引起的潛在問題,例如,如果繁忙系統上的 innodb_max_undo_log_size
設定過低時,就可能發生這種情況。如果超出限制,復原表空間仍然可以被設為非活動狀態,但直到下一個檢查點之後才會被截斷。在 MySQL 8.4 中,此限制為 50000。
復原表空間截斷復原
復原表空間截斷操作會在伺服器日誌目錄中建立一個暫時的 undo_
檔案。該日誌目錄由 space_number
_trunc.loginnodb_log_group_home_dir
定義。如果在截斷操作期間發生系統故障,則暫時日誌檔案允許啟動程序識別正在被截斷的復原表空間,並繼續執行操作。
以下狀態變數允許追蹤復原表空間總數、隱式 (由 InnoDB
建立) 復原表空間、顯式 (使用者建立) 復原表空間,以及活動復原表空間的數量。
mysql> SHOW STATUS LIKE 'Innodb_undo_tablespaces%';
+----------------------------------+-------+
| Variable_name | Value |
+----------------------------------+-------+
| Innodb_undo_tablespaces_total | 2 |
| Innodb_undo_tablespaces_implicit | 2 |
| Innodb_undo_tablespaces_explicit | 0 |
| Innodb_undo_tablespaces_active | 2 |
+----------------------------------+-------+
有關狀態變數描述,請參閱第 7.1.10 節「伺服器狀態變數」。