Oracle AskTOM Commit 提交机制详解

Oracle AskTOM Commit 提交机制详解

来源:AskTOM (asktom.oracle.com) 适用版本:Oracle Database 全版本 文档版本:v1.0 / 2026-07-22


1. 概述

Commit 机制是 Tom Kyte 反复强调的话题[1]。

详细见:Oracle Redo Log 机制详解Oracle 事务 ACID 深度解析


2. Commit 做了什么

2.1 LGWR 写 Redo

- Redo Buffer → Redo Log
- 保证持久性
- 同步

2.2 释放锁

- 行锁释放
- 资源释放
- 其他会话可继续

2.3 清理 Undo

- Undo 段标记
- 提交 SCN
- 后续读一致性

2.4 通知

- 提交完成
- 后台清理

3. COMMIT 选项

3.1 默认

- WAIT:等待 LGWR
- 同步
- 持久

3.2 NOWAIT

COMMIT WRITE WAIT;     -- 默认
COMMIT WRITE NOWAIT;   -- 不等待 LGWR

3.3 BATCH

COMMIT WRITE BATCH;    -- 批量写
COMMIT WRITE IMMEDIATE; -- 立即写

3.4 选项对比

选项性能持久性风险
WAIT
NOWAIT实例故障丢
BATCH批量丢
IMMEDIATE

4. 频繁 COMMIT 问题

4.1 Tom Kyte 观点

- 不要在循环里 COMMIT
- 每次提交:
  - LGWR 同步写
  - 性能差
- 应该事务级

4.2 反例

CREATE OR REPLACE PROCEDURE bad_commit IS
BEGIN
  FOR i IN 1..100000 LOOP
    INSERT INTO emp VALUES (i, 'Name'||i);
    COMMIT;  -- 错误!
  END LOOP;
END;
/

4.3 正例

CREATE OR REPLACE PROCEDURE good_commit IS
BEGIN
  FOR i IN 1..100000 LOOP
    INSERT INTO emp VALUES (i, 'Name'||i);
  END LOOP;
  COMMIT;  -- 事务级
END;
/

4.4 性能对比

- bad_commit: 10 分钟
- good_commit: 1 分钟
- 差距 10 倍

5. LOG_BUFFER

5.1 作用

- Redo 缓存
- LGWR 异步写
- 减少磁盘 I/O

5.2 大小

ALTER SYSTEM SET log_buffer=64M SCOPE=SPFILE;

5.3 触发 LGWR

- 1/3 满
- 1MB
- COMMIT
- 3 秒

6. SCN

6.1 提交 SCN

- COMMIT 时分配
- 系统变更号
- 一致性基础

6.2 查询

SELECT current_scn FROM v$database;

6.3 依赖

- 事务依赖
- 一致性读
- MVCC

7. FAST=TRUE 神话

7.1 Tom Kyte 名言

"COMMIT = FAST=TRUE 是神话"

7.2 真相

- COMMIT 有代价
- LGWR 同步写
- 不能消除

8. 长事务

8.1 问题

- Undo 增长
- ORA-01555
- 性能下降

8.2 监控

SELECT sid, serial#, used_ublk 
FROM v$transaction t, v$session s 
WHERE t.addr = s.taddr 
ORDER BY used_ublk DESC;

8.3 优化

- 分批 commit
- 10k-100k 行
- 平衡

9. 分布式事务

9.1 两阶段

- Prepare
- Commit
- 协调者

9.2 2PC

- 一致性
- 性能差
- 慎用

9.3 XA

- 跨资源
- 协议
- 风险

10. COMMIT 性能优化

10.1 Redo Log

- 大小足够
- 多组
- 高速磁盘

10.2 LOG_BUFFER

- 适当大小
- 64M+

10.3 NOWAIT/BATCH

- 评估风险
- 性能
- 一致性

10.4 应用

- 事务级 COMMIT
- 批量
- 不要循环 COMMIT

11. 监控

11.1 Redo 速率

SELECT value FROM v$sysstat WHERE name='redo writes';
SELECT value FROM v$sysstat WHERE name='redo sync time';

11.2 Commit 等待

SELECT event, time_waited 
FROM v$system_event 
WHERE event IN ('log file sync', 'log file parallel write');

11.3 LGWR

SELECT * FROM v$bgprocess WHERE name='LGWR';

12. 常见问题

12.1 log file sync

- COMMIT 等待
- LGWR 慢
- Redo Log 优化

12.2 ORA-01555

- 长事务
- Undo 不足
- 分批 commit

12.3 数据丢失

- NOWAIT/BATCH
- 实例故障
- 评估风险

13. 最佳实践

  1. 事务级:COMMIT
  2. 不要循环:COMMIT
  3. Redo Log:足够大
  4. LOG_BUFFER:适当
  5. 高速磁盘:Redo
  6. 监控:log file sync
  7. NOWAIT:慎用
  8. 长事务:分批
  9. 测试:性能
  10. 原理:理解

14. 参考资料

[1] AskTOM, “Commit Frequency”, https://asktom.oracle.com [2] Tom Kyte, “Expert Oracle Database Architecture”, Chapter 9