关键字:
KingbaseES、prepared transactions、人大金仓、KingbaseES
一、事务简介
在数据库系统中,事务是一组操作序列,包含了至少一条对数据库的操作。在提交整个块之前,该块中语句的结果对其他事务不可见。为了将事务与其他的数据库语句区分开来,通常事务以BEGIN开始,以COMMIT或ROLLBACK结束。如果事务失败或回滚,则对数据库完全没有影响。
二、prepared transactions
2.1 prepared transactions简介及相关参数
事务依附于会话的,但是prepared transaction是一种独立于会话的事务。prepared transaction为两阶段提交准备了一个事务,当开启prepared transaction之后,该事务不再与当前会话关联,事务的状态存储在磁盘上,这使得数据库服务器即使在从崩溃中重新启动后也可以恢复事务。在对prepared transaction执行回滚或提交操作之前,将一直维护该事务。
在KES的kingbase.conf文件中,默认max_prepared_transaction=0,即默认不启用prepared transaction。如果需要启用prepared transaction,建议将max_prepared_transaction设置成max_connections的值。在同步的流复制standby库上,最好将其设置的比max_connections大一点,以免standby不能接收查询。参数设置完毕后,需要重启数据库才可生效。
2.2 pg_prepared_xacts视图及参数解释
通过查看视图pg_prepared_xacts,可以查看活跃状态的prepared transactions。
select * from pg_prepared_xacts;
注意事项:
1.transaction:事务id
2.gid:用户为prepared transaction定义的名称
3.prepared:prepared日期,创建事务时带有时区的时间戳
4.owner:创建该prepared transaction的事务
5.database:数据库名
2.3创建prepared transaction
知道什么是prepared transaction之后,现在来看看如何创建一个prepared transaction。创建一个该事务通常需要四个步骤:
1.begin(或start transaction)
2.执行需要的操作
3. prepare transaction ‘transaction_id’
4.commit prepared (或rollback prepared)
prepare transaction、commit prepared、或rollback prepared后面加上一个gid,可以唯一标识prepared transaction。
2.4 commit prepared
2.5 rollback prepared
2.6异常场景
三、孤儿prepared transactions
当含有prepared transactions的KES关闭或者中断时,会为每个prepared transaction创建一个文件,保存在data目录下的sys_twophase中。
比如有个prepared transaction,没有提交事务就停止了server。KES就会在sys_twophase下创建一个文件,名字对应的是被中断的prepared transaction事务id。
在KES被重启后,在启动日志会报如下信息:
如果不希望恢复该prepared transaction,删除sys_twophase目录下的相应文件即可。此时该prepared transaction没有完成,这种没有完成的prepared transaction就被叫做孤儿prepared transaction,继续持有可能包含锁的关键系统资源,或者使事务ID保持活动状态。
当事务A处于prepared状态,并且在提交事务A之前,如果另一个事务B试图更改事务A所占用的表,事务B将无法获取所需的锁并挂起,直到解决了prepared事务A为止,否则事务B会无限期挂起。但是由于事务A使一个孤儿prepared transaction,因此事务B最终必须发出CTRL + C来停止。
该孤儿prepared transaction事务A可能会阻止vacuum清除只对该事务可见、对其它事务不可见的死元组。在极端情况下,会导致数据库关闭,因为孤儿prepared transaction会阻止事务id的wrap around。