长事务的理解和预防

  我们常常听说数据库发生了“长事务”而导致很严重的后果。那么何为长事务?长事务是如何产生的?长事务对数据库有什么影响?如何防止长事务的产生?以下对这几方面进行阐述和说明,以加深对SinoDB长事务的理解。

1.什么是长事务

  长事务,顾名思义就是一个事务(transaction)执行了很长时间仍未结束。那么一个事务执行多长时间算是长事务?对于SinoDB数据库来说占用逻辑日志个数的百分比达到长事务高水位线就被定义为一个长事务。

2.事务的控制

  事务的开始和结束,以“begin”为开始,以“commit”或“rollback”结束。“commit”表明事务执行成功,对数据库所做的修改已经生效,“rollback”则说明事务执行失败,对数据库的所有操作均需要撤销,恢复到事务执行之前的状态。为了使事务能被撤销,数据库也必须对所有操作及被修改前的数据进行日志记录,以便撤销时能够执行逆向操作,将数据恢复到以前的状态。

3.对日志的使用和影响

  为了防止数据库因日志资源耗尽发生阻塞,SinoDB设置了长事务高水位线(LTXHWM)和独占的长事务高水位线(LTXEHWM),当一个事务占用日志个数的百分比达到长事务高水位线LTXHWM就被标识为一个长事务,并自动触发回滚操作,当百分比达到独占的长事务高水位线时,其它会话均进入阻塞状态,只进行长事务回滚操作。

4.长事务产生的几种原因

  在SinoDB数据库中,长事务现象发生的原因主要有:

1) 逻辑日志参数设置不合理,日志个数太少或长事务高水位线LTXHWM太低;

2) 数据库并发很高,事务的粒度太粗,长时间不能提交,最终触及长事务高水位线;

3) 事务启动后,未使用commit或rollback来终止事务;

4) 大表连接插入目标表,连接条件不正确产生笛卡尔集,结果集超出预期,长时间不能处理完成;

5) 使用临时表装载大量数据,未指定with no log子句,也未设置TEMPTAB_NOLOG参数。

5.如何避免长事务

  长事务带来的后果是严重的,虽然在长事务发生时可以通过手工添加逻辑日志方式来挽救,但是及时性难以保证。不过长事务也是可以避免的,具体可以从以下几点做起:

1) 根据并发用户数和业务量合理设置逻辑日志大小和个数,保证大部分事务能正常完成;

2) 适当调低长事务高水位线LTXHWM,确保在长事务发生时有足够的日志文件用于回滚;

3) 设置参数DYNAMIC_LOGS为2,当无可用日志文件时会自动增加,需要注意的是日志并不是在事务到达LTXHWM之后就开始增加;

4) 合理控制事务的颗粒度,将大事务分割为小事务进行多次提交批量处理,减少单个事务处理时间,提高逻辑日志资源利用率;

5) 事务操作闭环,事务开始之后必须结束,尽量避免回滚,减少对日志和锁的消耗;

6) 大表进行连接时,尽量保证连接条件唯一,避免产生笛卡尔集,避免产生事务日志;

7) 在创建临时表应加上with no log字句,或将数据库参数TEMPTAB_NOLOG指定为1。