关于优先事务(Priority Transaction)
n 如果低优先级事务阻塞了高优先级事务,Oracle数据库将自动中止低优先级事务,以便高优先级事务能够继续进行务优先获取锁资源,这就是优先事务的功能。
n 该功能保持高事务吞吐量的同时,也减轻了数据库维护工作。
n 从 Oracle Database 23ai 开始,数据库提供了用于控制何时以及哪些持有行锁的事务可以自动回滚。
n 低优先级事务根据策略自动回滚,但会话仍然保持活动状态。
1. 优先级
Oracle 数据库提供了会话设置,用于控制事务优先级,所有在该会话下的事务均保持该事务优先级配置,使用语法:
ALTER SESSION SET "txn_priority" = "HIGH";
参数 txn_priority 用于配置事务优先级:
n LOW :持有LOW低优先级行锁, 事务管理器不会rollback阻塞源holder行锁持有者事务
n MEDIUM: 持有MEDIUM中优先级行锁,事务管理器rollback阻塞源holder低级(LOW)行锁持有者事务
n HIGH: 持有HIGH高优先级行锁,事务管理器rollback阻塞源holder低级(LOW|MEDIUM)行锁持有者事务
2. 等待目标
2.1 等待目标参数
Oracle 数据库提供了系统级参数,用于控制事务row lock holder在什么时间自动回滚事务释放row lock:
n priority_txns_high_wait_target
n priority_txns_medium_wait_target
ü 参数priority_txns_high _wait_target/ priority_txns_medium_wait_target用于设置高/中优先级事务等待事务低优先级事务ROLLBACK最大时间,单位为秒(默认值2147483647)
ü 超过超时阈值的低优先级事务会被强制回滚ROLLBACK,但事务所在会话保持活跃
ü LOW低优先级事务无等待目标参数设置( priority_txns_low_wait_target )
注意事项:
ü 应用程序捕获 ORA-63300 错误后,需发起ROLLBACK SQL 语句确认自动回滚;否则该会话所SQL语句将继续收到 ORA-63302 错误
ü 只有同时设置事务优先级/等待目标参数,优先级事务功能才会被启用,两者缺一不可
2.2 配置示例
使用 ALTER SYSTEM 命令设置参数,单位为秒(s),例如设置高优先级目标等待位20秒:
ALTER SYSTEM SET priority_txns_high_wait_target = 20 scope=both;
ü 当优先级较高事务被优先级较低事务阻塞时,高优先级事务等待系统达到阈值的低优先级事务回滚阻;
ü 当有多个被阻塞事务试图获取同一行锁时,等待时间可能会比指定的目标时间更长,例如(假设高优先级等待目标时间为20秒):
1) 在T1时刻,事务1(低优先级事务:sid40)锁定了特定的一行:
2) 在T1时刻,事务2(另一低优先级事务:sid48)尝试锁定同一行并等待:
3) 在T3时刻,事务3(高优先级事务,sid208)尝试更新同一行等待:
4) 行锁事务阻塞:
说明:
ü 假设所有事务未提交,高优先级事务(sid208)先等待阈值20秒(从T3开始计算),直至事务管理器将第一个事务s(sid40)回滚:
ü 之后,事务2获得行锁(enqueue锁),事务3将继续从事务2T2时刻继续等待20秒,事务2被回滚:
ü 可以看到,设置了高优先级事务等待事件并不等于设定最大等待阈值,而是并发会话的累计值:
5) alert日志记录
当事务被终止时,Alert警报日志中会显示警报。例如:
3. 手动回滚
当低优先级事务被自动回滚时,在手动发出rollback指令前,后续 SQL 语句将抛出 ORA-63302 错误。因此,应用程序逻辑必须设计捕获这两个错误 ORA-63300/ORA-63302,然后发出rollback指令:
下表列出了确认回滚可用方法:
4. 事务模式
优先事务支持2种模式,TRACK以及ROLLBACK模式,默认模式是回滚(ROLLBACK):
n TRACK模式:数据库在V$SYSSTAT中增加统计信息,记录优先事务可以回滚的事务数量,而不是实际回滚任何事务;应用程序借助统计值来调整合适的等待目标值,然后再切换到回滚模式使用,类似dry run模式
n ROLLBACK模式:在这种模式下,如果正确配置了优先级( txn_priority )及等待目标(priority_txns_high _wait_target/ priority_txns_medium_wait_target),那么就可以实优先事务功能
更改事务模式语法:
ALTER SYSTEM SET "priority_txns_mode"="ROLLBACK";
5. 实践探索
优先事务关键点在于设置等待目标阈值,如何设置priority_txns_high _wait_target/ priority_txns_medium_wait_target,可以参考以下步骤探索:
1) 将PRIORITY_TXNS_MODE设置为TRACK,并监控行锁竞争等待事件时间
2) 在TRACK模式下运行工作负载,监控优先级事务行锁等待时间
例如,如果HIGH优先级事务行锁最多等待10秒,那么建议将priority_txns_high _wait_target设置为超过90秒,以便Oracle数据库在对数据库执行有意义的操作时,不会回滚任何合法持有行锁的事务
3) 在粗略评估目标参数值后,关闭TRACK模式/切换ROLLBACK模式,开始使用优先事务
4) 业务运行巡检,根据运行状态再调试:
ü 当出现行锁竞争时,等待行锁的事务会在一个共同的等待事件enq: TX - row lock contention上等待:
优先事务相关等待事件见下表:
通过txn_priority/wait_target启用优先事务后,等待的事务将根据等待事务的优先级在相应的等待事件上等待。如下示例:会话(会话ID为204)持有一个高优先级事务,该事务持有了某一行的锁。你可以看到其他想要同一行锁的事务,根据它们的优先级在不同的等待事件上等待
SELECT TO_CHAR(xidusn) || '.' || TO_CHAR(xidslot) || '.' || TO_CHAR(xidsqn) AS xid, sid, event, seconds_in_wait, blocking_session
FROM v$session, v$transaction
WHERE event LIKE '%enq%' AND v$session.saddr = v$transaction.ses_addr;
TRANSACTION_ID SID EVENT SECONDS_IN_WAIT BLOCKING_SESSION
--------------- ------ ----------------------------------- --------------- ----------------
2.17.1619 187 enq: TX - row lock (HIGH priority) 361 204
5.32.1557 51 enq: TX - row lock (LOW priority) 359 204