Skip to content

OceanBase 事务超时与死锁

事务超时原理与配置

事务超时类型

  1. 语句执行超时:单个 SQL 语句的执行时间超过设定阈值
  2. 事务执行超时:整个事务的执行时间超过设定阈值
  3. 锁等待超时:事务等待锁的时间超过设定阈值

事务超时配置

sql
-- 设置语句执行超时时间(毫秒)
ALTER SYSTEM SET ob_query_timeout = 10000;

-- 设置事务执行超时时间(毫秒)
ALTER SYSTEM SET ob_trx_timeout = 300000;

-- 设置锁等待超时时间(毫秒)
ALTER SYSTEM SET ob_trx_lock_timeout = 5000;

-- 设置租户级别的超时时间
ALTER TENANT tenant_name SET ob_query_timeout = 15000;
ALTER TENANT tenant_name SET ob_trx_timeout = 600000;
ALTER TENANT tenant_name SET ob_trx_lock_timeout = 10000;

事务超时参数说明

参数名描述默认值建议值
ob_query_timeout语句执行超时时间(毫秒)1000010000-30000
ob_trx_timeout事务执行超时时间(毫秒)300000300000-600000
ob_trx_lock_timeout锁等待超时时间(毫秒)50005000-10000
ob_trx_idle_timeout事务空闲超时时间(毫秒)8640000086400000
ob_trx_retry_timeout事务重试超时时间(毫秒)120000120000

死锁原理与检测

死锁产生条件

  1. 互斥条件:资源不能被共享,只能被一个进程使用
  2. 请求与保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求
  3. 不剥夺条件:进程已获得的资源,在未使用完之前,不能被强行剥夺
  4. 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系

死锁检测机制

OceanBase 采用主动检测和被动检测相结合的方式处理死锁:

  1. 主动检测:定期扫描事务等待图,检测是否存在环
  2. 被动检测:当事务等待锁超时,检查是否存在死锁
  3. 死锁解除:选择一个代价最小的事务进行回滚,解除死锁

死锁检测配置

sql
-- 启用死锁检测
ALTER SYSTEM SET enable_deadlock_detection = 'true';

-- 设置死锁检测间隔(毫秒)
ALTER SYSTEM SET deadlock_detection_interval = 1000;

-- 设置死锁检测超时时间(毫秒)
ALTER SYSTEM SET deadlock_detection_timeout = 5000;

事务超时与死锁处理

查看事务超时与死锁信息

sql
-- 查看当前活跃事务
SELECT * FROM oceanbase.GV$OB_TRX WHERE state = 'RUNNING';

-- 查看事务锁等待情况
SELECT * FROM oceanbase.GV$OB_LOCK_WAITSTAT;

-- 查看死锁历史记录
SELECT * FROM oceanbase.DBA_OB_DEADLOCK_HISTORY ORDER BY gmt_create DESC;

-- 查看超时事件
SELECT * FROM oceanbase.DBA_OB_EVENT_HISTORY WHERE event_type = 'timeout' ORDER BY gmt_create DESC;

手动处理事务超时与死锁

sql
-- 终止长时间运行的事务
KILL SESSION 'session_id';

-- 查看会话信息
SELECT * FROM oceanbase.GV$OB_SESSIONS WHERE sessid = 'session_id';

-- 强制提交或回滚事务
ALTER SYSTEM KILL TRANSACTION 'trx_id';

优化事务超时与死锁的 SQL

  1. 优化长事务:将长事务拆分为多个短事务
  2. 优化锁竞争:减少锁持有时间,避免全表锁
  3. 优化索引:确保查询使用索引,减少扫描范围
  4. 调整事务隔离级别:根据业务需求选择合适的隔离级别
sql
-- 查看 SQL 执行计划
EXPLAIN SELECT * FROM table_name WHERE condition;

-- 优化索引
CREATE INDEX idx_column ON table_name(column);

-- 调整事务隔离级别
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

事务超时与死锁最佳实践

配置建议

  1. 合理设置超时参数:根据业务需求和系统性能,设置合适的超时时间
  2. 启用死锁检测:确保死锁检测功能已启用
  3. 调整检测间隔:根据系统负载调整死锁检测间隔
  4. 设置合理的隔离级别:根据业务需求选择合适的事务隔离级别

开发建议

  1. 避免长事务:尽量将事务拆分为多个短事务
  2. 减少锁持有时间:在事务中尽量减少不必要的操作,尽快提交或回滚
  3. 避免热点数据竞争:合理设计表结构和索引,减少热点数据的竞争
  4. 使用批量操作:对于大量数据的操作,使用批量操作减少事务数量
  5. 合理使用锁粒度:尽量使用行级锁,避免表级锁

监控与告警

  1. 监控事务超时:设置事务超时告警,及时发现长时间运行的事务
  2. 监控死锁事件:设置死锁告警,及时处理死锁问题
  3. 监控锁等待:监控锁等待时间和数量,及时发现锁竞争问题
  4. 定期分析:定期分析事务超时和死锁记录,找出根本原因

常见问题(FAQ)

Q1: 事务超时会导致数据不一致吗?

A1: 不会。OceanBase 会自动回滚超时的事务,确保数据一致性。当事务超时发生时,系统会终止事务并释放所有已获得的资源和锁。

Q2: 如何查看导致死锁的 SQL 语句?

A2: 可以通过以下方式查看导致死锁的 SQL 语句:

sql
-- 查看死锁历史记录,包含导致死锁的 SQL
SELECT * FROM oceanbase.DBA_OB_DEADLOCK_HISTORY ORDER BY gmt_create DESC;

-- 查看当前活跃事务的 SQL
SELECT s.sessid, t.trx_id, s.sql_text 
FROM oceanbase.GV$OB_SESSIONS s 
JOIN oceanbase.GV$OB_TRX t ON s.sessid = t.sessid 
WHERE t.state = 'RUNNING';

Q3: 死锁发生时,OceanBase 会如何处理?

A3: OceanBase 会自动检测死锁,并选择一个代价最小的事务进行回滚,解除死锁。被回滚的事务会收到一个死锁错误,应用程序需要处理这个错误并决定是否重试。

Q4: 如何避免事务超时?

A4: 可以通过以下方式避免事务超时:

  1. 优化 SQL 语句,提高执行效率
  2. 减少事务中的操作数量,缩短事务执行时间
  3. 合理设置超时参数
  4. 避免在事务中执行耗时的外部操作

Q5: 如何处理频繁发生的死锁?

A5: 对于频繁发生的死锁,可以采取以下措施:

  1. 分析死锁日志,找出导致死锁的根本原因
  2. 优化表结构和索引,减少锁竞争
  3. 调整事务执行顺序,避免循环等待
  4. 降低事务隔离级别
  5. 增加锁等待超时时间
sql
-- 查看死锁详细信息
SELECT * FROM oceanbase.DBA_OB_DEADLOCK_HISTORY WHERE trx_id1 = 'trx_id' OR trx_id2 = 'trx_id';

-- 优化索引
CREATE INDEX idx_new ON table_name(column1, column2);