Oracle 透過多版本並發控制(MVCC)實現「讀不阻塞寫、寫不阻塞讀」的同時,以 UNDO 段構建陳述式級讀一致性,並利用系統變更號(SCN)實現精準的時間點恢復。本文通過實測案例,演示一致性讀構建、事務回滾、提交後基於 SCN 的閃回恢復全流程。
| 組件 | 角色 | 關鍵特性 |
|---|---|---|
| UNDO 表空間 | 儲存舊映像(Before Image) | 自動管理(UNDO_MANAGEMENT=AUTO)、保留時間 UNDO_RETENTION、保證保留 RETENTION GUARANTEE |
| UNDO 區段 | 交易專用 UNDO 儲存單元 | 循環使用、延伸/縮減、支援並發交易 |
| SCN (System Change Number) | 資料庫全域邏輯時鐘 | 單調遞增、提交時分配、檢查點/備份/複製同步錨點 |
| 交易表 (Transaction Table) | UNDO 區段頭部槽位 | 記錄交易狀態(ACTIVE/COMMITTED)、最後 SCN、UNDO 串鏈指標 |
-- Session 1 (SYS)
CREATE TABLE t_consistency (a NUMBER, b NUMBER);
INSERT INTO t_consistency VALUES (1,2);
INSERT INTO t_consistency VALUES (3,4);
COMMIT;
-- Session 2 查詢確認初始狀態
SELECT * FROM t_consistency;
-- A=1,B=2 / A=3,B=4
-- Session 1 修改但不提交
UPDATE t_consistency SET b = 10 WHERE a = 1; -- 1 row updated
-- Session 2 查詢(看到舊值 2,非 10)
SELECT * FROM t_consistency;
-- A=1,B=2 / A=3,B=4
-- Session 1 提交
COMMIT;
-- Session 2 再次查詢(看到新值 10)
SELECT * FROM t_consistency;
-- A=1,B=10 / A=3,B=4
機制:Session 2 查詢啟動時取得 SCNquery,讀取資料塊時發現 ITL 指向活躍交易,順著 UNDO 串鏈回溯到 SCNquery 之前的版本,構建 CR(Consistent Read)塊返回。
-- 當前狀態:A=1,B=10 / A=3,B=4 (已提交)
-- Session 1 再次修改
UPDATE t_consistency SET b = 2 WHERE a = 1; -- 1 row updated
SELECT * FROM t_consistency; -- Session 1 看到 B=2
-- Session 1 後悔,回滾
ROLLBACK;
-- Session 1 再次查詢(恢復到提交前狀態 B=10)
SELECT * FROM t_consistency;
-- A=1,B=10 / A=3,B=4
機制:ROLLBACK 將交易表槽位標記為 COMMITTED(但實際是回滾),釋放鎖,後續讀取依 SCN 邏輯看到提交前版本。UNDO 記錄保留供其他活躍查詢使用,直到 UNDO_RETENTION 過期。
SELECT current_scn FROM v$database;
-- CURRENT_SCN = 693636
DELETE FROM t_consistency; -- 2 rows deleted
COMMIT;
-- 確認資料消失
SELECT * FROM t_consistency; -- no rows selected
SELECT * FROM t_consistency AS OF SCN 693636;
-- A=1,B=10 / A=3,B=4 (恢復到刪除前狀態)
INSERT INTO t_consistency
SELECT * FROM t_consistency AS OF SCN 693636; -- 2 rows created
COMMIT;
-- 驗證恢復
SELECT * FROM t_consistency;
-- A=1,B=10 / A=3,B=4
-- SCN 轉時間
SELECT scn_to_timestamp(693636) FROM dual;
-- 2024-03-15 14:30:45.000000000
-- 時間轉 SCN (近似)
SELECT timestamp_to_scn(TIMESTAMP '2024-03-15 14:30:00') FROM dual;
應用層可記錄關鍵業務時間點對應 SCN,實現「業務時間點恢復」。
| 故障類型 | 恢復技術 | RPO | RTO | 前提條件 |
|---|---|---|---|---|
| 單筆/少量誤刪/誤改(未提交) | ROLLBACK | 0 | 秒級 | 同一 Session、未提交 |
| 單筆/少量誤刪/誤改(已提交) | 閃回查詢 + INSERT ... AS OF SCN | 0 | 分鐘級 | UNDO 保留未過期、知 SCN/時間 |
| 整表/大量資料誤操作 | 閃回表 FLASHBACK TABLE t TO SCN ... | 0 | 分鐘級 | 啟用 ROW MOVEMENT、UNDO 充足 |
| Schema 級邏輯錯誤 | 閃回資料庫 FLASHBACK DATABASE TO SCN ... | 0 | 小時級 | 啟用 FRA、FLASHBACK ON、備份控制檔 |
| 物理損壞/存儲故障 | RMAN 備份恢復 + 歸檔重做應用 | 備份頻率 | 視資料量 | 有效備份策略、歸檔完整 |
| 邏輯錯誤發現延遲超過 UNDO 保留 | 邏輯備份 / GoldenGate 異構複製 / 時間點恢復 (TSPITR) | 備份/複製延遲 | 視方案 | 額外授權、架構規劃 |
-- 1. UNDO 保留設定(至少覆蓋最長業務查詢 + 緩衝)
ALTER SYSTEM SET UNDO_RETENTION = 3600 SCOPE=BOTH; -- 1 小時
ALTER TABLESPACE undotbs1 RETENTION GUARANTEE; -- 強制保留,寧可 DML 失敗不覆寫 UNDO
-- 2. 監控 UNDO 使用壓力
SELECT BEGIN_TIME, END_TIME, UNDOBLKS, TXNCOUNT, MAXQUERYLEN,
(UNDOBLKS * 8192 / 1024 / 1024) AS UNDO_MB
FROM v$undostat
ORDER BY BEGIN_TIME DESC;
-- 3. 閃回資料庫狀態
SELECT FLASHBACK_ON, OLDEST_FLASHBACK_SCN, OLDEST_FLASHBACK_TIME
FROM v$database;
-- 4. 確保 ROW MOVEMENT 啟用(閃回表前提)
ALTER TABLE critical_table ENABLE ROW MOVEMENT;
UNDO_RETENTIONFLASHBACK TABLE/DATABASE 流程與時效ORA_ROWSCN(近似 SCN),支援行級歷史追溯Oracle 的一致性與恢復能力,建立在 SCN 全域時序 + UNDO 版本鏈 + 智慧型快取 三位一體架構之上。掌握 SCN 與 UNDO 的互動邏輯,才能在災難發生時,從容執行精準恢復,而非盲目恢復全庫備份。