MySQL 8.0 Undo Tablespace管理

1. UNDO 基礎概念

  1. 默認至少初始化2個Undo表空間,最大支持127個Undo表空間,默認表空間名稱爲undo_001,undo_002
  2. 8.0.14 之後UNDO表空間支持在線增加,及在線刪除
  • CREATE UNDO TABLESPACE/DROP UNDO TABLESPACE
    • 不支持指定相對路徑,只支持絕對路徑,且必須是innodb_directories參數定義可識別的路徑或默認的數據目錄下
    • 動態創建的undo表空間必須以.ibu結尾
  1. 8.0.23 之前Undo表空間初始大小依賴innodb_page_size的值配置,默認16K,初始文件大小爲10M,8.0.23 之後Undo表空間初始大小爲16M,默認擴展大小單位爲16M

2. UNDO 相關參數

2.1 參數含義

show variables like '%undo%';
+--------------------------+------------+
| Variable_name            | Value      |
+--------------------------+------------+
| innodb_max_undo_log_size | 8589934592 |   
| innodb_undo_directory    | ./         |  
| innodb_undo_log_encrypt  | OFF        |
| innodb_undo_log_truncate | ON         |
| innodb_undo_tablespaces  | 2          |
+--------------------------+------------+

show variables like '%truncate%';
+--------------------------------------+-------+
| Variable_name                        | Value |
+--------------------------------------+-------+
| innodb_purge_rseg_truncate_frequency | 128   |
| innodb_undo_log_truncate             | ON    |
+--------------------------------------+-------+

show variables like '%segment%';
+-------------------------------+-----------+
| Variable_name                 | Value     |
+-------------------------------+-----------+
| innodb_rollback_segments      | 128       |
| innodb_segment_reserve_factor | 12.500000 |
+-------------------------------+-----------+

innodb_undo_log_truncate			-- 控制是否自動做UNDO的truncate收縮操作,默認爲ON,只有爲ON時,下面2個參數才生效
	innodb_max_undo_log_size		-- 控制UNDO做truncate收縮操作的閾值,當UNDO達到該值時纔出發收縮操作
	innodb_purge_rseg_truncate_frequency 
		-- Batch UNDO清理的次數,默認最大值128,也就是128次後纔會觸發一次UNDO的truncate,而每次清理的undo page由innodb_purge_batch_size參數決定,innodb_purge_batch_size默認爲300,也就是300*128個UNDO小批次清理後纔會觸發UNDO表空間的truncate(也就是UNDO表空間的收縮)操作

innodb_undo_tablespaces 		  -- 控制生成的UNDO表空間的數量,默認2個,在8.0對該參數做了廢棄,但並未提供其他參數控制UNDO數量,當前依舊可以使用該參數做UNDO表空間數量配置,通常建議配置爲3(手工收縮UNDO時需要至少3個UNDO表空間)

innodb_rollback_segments			-- UNDO表空間回滾段的數量,默認爲最大值128

3. UNDO 表空間運維

3.1 查看UNDO的基本信息

-- 可以查看到undo的表空間名稱/文件路徑/初始大小/擴展大小/磁盤文件大小/可用空間及是否啓用的狀態等
SELECT T1.SPACE AS SPACE_ID,
       T1.NAME AS TABLESPACE_NAME,
       T2.FILE_NAME,
       ROUND(T2.INITIAL_SIZE / 1024 / 1024, 2) AS "INITIAL_SIZE(M)",
       ROUND(T2.AUTOEXTEND_SIZE / 1024 / 1024, 2) AS "AUTOEXTEND_SIZE(M)",
       ROUND(T1.FILE_SIZE / 1024 / 1024, 2) AS "FILE_SIZE_DISK(M)",
       ROUND(T2.DATA_FREE / 1024 / 1024, 2) AS "DATA_FREE(M)",
       T2.STATUS,
       T1.STATE
  FROM INFORMATION_SCHEMA.INNODB_TABLESPACES T1,
       INFORMATION_SCHEMA.FILES              T2
 WHERE T1.SPACE = T2.FILE_ID
   AND T1.ROW_FORMAT = 'Undo';

3.2 添加/active/inactive/刪除UNDO表空間

CREATE UNDO TABLESPACE

  • 用來創建新的UNDO 表空間

DROP UNDO TABLESPACE

  • 用來刪除UNDO 表空間

ALTER UNDO TABLESPACE xxxx SET ACTIVE

  • 用來激活UNDO的使用

ALTER UNDO TABLESPACE xxxx SET INACTIVE

  • 用來關閉UNDO的使用(關閉後的UNDO纔可刪除)
-- 創建一個新的UNDO表空間
CREATE UNDO TABLESPACE undo_004 ADD DATAFILE 'undo_004.ibu';

-- 可以用前面的命令查看創建後的狀態

-- 可以將已有的UNDO表示爲inactive(也可理解爲UNDO表空間收縮)
-- PS:設置爲INACTIVE的表空間的STATE爲empty,表示這個表空間不包含任何事務回滾數據,且表空間也收縮爲默認大小
ALTER UNDO TABLESPACE undo_003 SET INACTIVE;

-- 可以將inactive的UNDO轉爲active
ALTER UNDO TABLESPACE innodb_undo_001 SET ACTIVE;

-- 可以將inactive的UNDO表空間進行刪除
-- PS:默認以innodb_開頭初始化的undo表空間不可被刪除
DROP UNDO TABLESPACE innodb_undo_001;
ERROR: 3119 (42000): InnoDB: Tablespace names starting with `innodb_` are reserved.

-- 非系統默認的UNDO在inactive後可被刪除
ALTER UNDO TABLESPACE undo_003 SET ACTIVE;
Query OK, 0 rows affected (0.0030 sec)

3.3 影響UNDO inactive(truncate)性能的因素

  • UNDO 表空間的大小
  • UNDO 表空間的數量
  • UNDO LOGS的數量(實際INSERT/UPDATE/DELETE這類事務回滾段的數據量)
  • 磁盤IO的能力/當前系統的負載
  • 是否存在長事務在使用該UNDO表空間

PS:通常對錶空間做收縮前最簡單避免性能的方式是提前創建一個UNDO表空間,收縮完後再刪除或一直保留均可

4. UNDO 的監控

4.1 UNDO的監控指標

-- 可以使用以下命令開啓對UNDO的監控採集
SET GLOBAL innodb_monitor_enable=module_undo;
SET GLOBAL innodb_monitor_enable=module_purge;

-- 使用該命令查看UNDO truncate的次數及耗時等信息
SELECT NAME,SUBSYSTEM,COUNT,STATUS,COMMENT 
FROM INFORMATION_SCHEMA.INNODB_METRICS 
WHERE NAME LIKE '%truncate%';

4.2 UNDO的狀態值

SHOW STATUS LIKE 'Innodb_undo_tablespaces%';
+----------------------------------+-------+
| Variable_name                    | Value |
+----------------------------------+-------+
| Innodb_undo_tablespaces_total    | 4     |  -- 總共的UNDO表空間數量
| Innodb_undo_tablespaces_implicit | 2     |  -- 這裏implicit其實表示的初始化創建的默認UNDO表空間個數,這種UNDO不可被刪除
| Innodb_undo_tablespaces_explicit | 2     |  -- 這裏explicit其實表示手工顯式創建的UNDO表空間的個數
| Innodb_undo_tablespaces_active   | 4     |	-- 表示處於active的UNDO表空間的個數,可以看到當前和total一樣,說明都在使用
+----------------------------------+-------+

5. UNDO 大小對併發數的限制

5.1 UNDO 記錄的類型及大小

UNDO LOGS包含的是事務最後一次修改的聚簇索引記錄(MySQL是聚簇索引表,也就是包含了一行完整的記錄)

  • 當innodb_page_size 爲16KB默認值時,undo 的slot槽爲1024個
    • 16KB*1024/16=1024個槽

UNDO一共有以下4中日誌類型

  • INSERT 用戶自定義的表
  • UPDATE and DELETE 用戶自定義的表
  • INSERT 自定義的臨時表
  • UPDATE and DELETE 自定義的臨時表

5.2 UNDO各場景下支持的讀寫併發

5.2.1 場景1: 每個事務都執行一個INSERT or UPDATE(DELETE)

併發公式: (innodb_page_size / 16) * innodb_rollback_segments * number of undo tablespaces

select 16*1024/16*128*2;
+------------------+
| 16*1024/16*128*2 |
+------------------+
|      262144.0000 |
+------------------+

5.2.2 場景2: 每個事務都執行一個INSERT and UPDATE(DELETE)

併發公式:(innodb_page_size / 16 / 2) * innodb_rollback_segments * number of undo tablespaces

select 16*1024/16/2*128*2;
+--------------------+
| 16*1024/16/2*128*2 |
+--------------------+
|    131072.00000000 |
+--------------------+

5.2.3 場景3: 每個事務都執行一個INSERT or UPDATE(DELETE) 到臨時表

併發公式: (innodb_page_size / 16) * innodb_rollback_segments

select 16*1024/16*128;
+----------------+
| 16*1024/16*128 |
+----------------+
|    131072.0000 |
+----------------+

5.2.4 場景4: 每個事務都執行一個INSERT and UPDATE(DELETE) 到臨時表

併發公式:(innodb_page_size / 16 / 2) * innodb_rollback_segments

select 16*1024/16/2*128;
+------------------+
| 16*1024/16/2*128 |
+------------------+
|   65536.00000000 |
+------------------+

6. 參考鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章