合 Oracle中的分布式事务介绍
Tags: 故障处理分布式数据库分布式事务ORA-01591
什么是分布式事务
现代数据库系统往往伴随着复杂的结构和环境,其中,分布式数据库组成是一个重要方面。系统后台的数据库系统不再是由单个数据库构成,而是由多台独立数据库、甚至是多台异构数据库构成。
分布式事务是指一个事务在本地和远程执行,本地需要等待确认远程的事务结束后,进行下一步本地的操作。如通过DBLINK更新远程数据库的一行记录,如果在执行过程中网络异常,或者其它事件导致本地数据库无法得知远程数据库的执行情况,那么此时就会发生IN-DOUBT的报错。此时需要DBA介入,且需要分多种情况进行处理。
Oracle会自动处理分布式事务,保证分布式事务的一致性,所有站点全部提交或全部回滚。一般情况下,处理过程在很短的时间内完成,根本无法察觉到。但是,如果在COMMIT或ROLLBACK的时候,出现了连接中断或某个数据库站点Crash的情况,那么提交操作可能会无法继续,此时DBA_2PC_PENDING
和DBA_2PC_NEIGHBORS
中会包含尚未解决的分布事务。对于绝大多数情况,当恢复连接或Crash的数据库重新启动后,会自动解决分布式事务,不需要人工干预。只有分布事务锁住的对象急需被访问,锁住的回滚段阻止了其它事务的使用,网络故障或Crash的数据库的恢复需要很长的时间等情况出现时,才使用人工操作的方式来维护分布式事务。手工强制提交或回滚将失去二层提交的特性,Oracle无法继续保证事务的一致性,事务的一致性应由手工操作者保证。
使用“ALTER SYSTEM DISABLE DISTRIBUTED RECOVERY;
”可以使Oracle不再自动解决分布事务,即使网络恢复连接或者CRASH的数据库重新启动。使用“ALTER SYSTEM ENABLE DISTRIBUTED RECOVERY;
”恢复自动解决分布事务。
有关分布式事务有两个重要的视图,分别是DBA_2PC_PENDING和DBA_2PC_NEIGHBORS。DBA_2PC_PENDING视图列出所有的悬而未决的事务,此视图在未填入悬而未决的事务之前是空的,解决之后也被清空。如下所示:
表 3-26 DBA_2PC_PENDING解释
列名 | 说明 |
---|---|
LOCAL_TRAN_ID | 本地事务标识,格式为INTEGER.INTEGER.INGEGER。当一个连接的LOCAL_TRAN_ID和GLOBAL_TRAN_ID相同时,该节点是该事务的全局协调器。 |
GLOBAL_TRAN_ID | 全局事务标识,格式为:GLOBAL_DB_NAME.DB_HEX_ID.LOCAL_TRAN_ID,其中DB_HEX_ID是用来标识数据库八字符的十六进制数,全局事务各ID在分布式事务的每个节点都是相同的。 |
STATE | 见表 3-27 DBA_2PC_PENDING的STATE列的说明 |
MIXED | “YES”意味着一部分事务已经在一个节点上提交,而在另一个节点上被回滚。 |
TRAN_COMMENT | 事务的注释,或者如果使用了事务命名,当事各被提交时,那么事务的名字就会出现在此处 |
HOST | 主机名 |
COMMIT# | 已提交的事务的全局提交数 |
表 3-27 DBA_2PC_PENDING的STATE列的说明
列值 | 说明 |
---|---|
Connecting | 通常情况下,只有全局协调器和本地协调器才使用这个条目,节点在能够决定它是否能够准备好之前,要收集来自于其它数据库服务的信息。 |
Prepared | 节点已准好,可能或者也可能没有将已准备好的消息通知本地协调器,但此时,该节点还没有接收到提交的请求,仍保持着准许备好的状态,控制着提交事务所必需的任何本地资源。 |
Commited | 节点(任何类型)已经提交了事务,但该事务所包含的其它节点可能并没有提交,也就是该事务在一个个或多个其它节点上仍然是悬而未决。 |
Forced commit | DBA进行判断后,可以强行提交未决的事务,如果一个事务由DBA在本地节点进行手动提交时,产生此项目。 |
Forced abor(rollback) | DBA进行判断后,可以强行回滚未决的事务,如果一个事务由DBA在本地节点进行手动回滚时,产生此项目。 |
另一个视图是DBA_2PC_NEIGHBORS,该视图列出所有获得的(从远程客户)和送出的(给远程服务器)悬而未决的事务,也表示该本地节点是不是事务的提交点站点。
表 3-28 DBA_2PC_NEIGHBORS
列名 | 说明 |
---|---|
LOCAL_TRAN_ID | 同上。 |
IN_OUT | 获得事务为IN,送出事务为OUT。 |
Database | 对获得事务来说指本地节点信息的客户数据库的名称;对送出的事务来说指用于访问远程服务器上信息的数据库链接的名称。 |
DBuser_owner | 对获得事务来说指远程数据库链接用于连接的本地账户;对于送出事务来说指该数据库链接的拥有者。 |
INTERFACE | “C”代表提交信息,“N”表示已准备好状态的一条消息或是一条请求只读提交的请求。当“IN_OUT”为OUT时,“C”表示该连接的远程的站点是提交点站点,并且知道是提交还是中断。“N”表示本地节点正在通知远程节点,说它已准备好。当“IN_OUT”为IN时,“C”表示本地节点或送出的远程的一个数据库是提交点站点,“N”表示本地节点正在通知远程节点,说它已准备好。 |
后台进程:RECO(Recoverer Process,分布式事务恢复)
RECO(Recoverer Process,分布式事务恢复) 主要用于分布式数据库的恢复(Distributed Database Recovery),适用于两阶段提交的应用场景。该进程可以保证分布式事务的一致性,在分布式事务中,所有数据库要么同时COMMIT,要么同时ROLLBACK。在分布式数据库中,reco进程可以自动的解决分布式事务发生错误的情况。一个节点上的reco进程自动的连接到没有被正确处理事务相关的数据库上面。当reco建立了数据库之间的连接,它会自动的解决没有办法处理的事务,删除与该事务相关的待定的事务表中的行(清理事务表)。
分布式事务ORA-01591错误解决
1、故障环境介绍
项目 | 数据库 |
---|---|
DB类型 | RAC |
DB版本 | 11.2.0.3 |
DB存储 | ASM |
OS版本及kernel版本 | AIX 64位 6.1.0.0 |
2、故障发生现象及报错信息
执行一个UPDATE语句的时候报ORA-01591的错误。
3、故障分析及解决过程
这个错误是由于分布式事务引起,而不是普通的锁引起的。若检查一般对象数据表锁定,则只需要检查V$LOCKED_OBJECT和V$TRANSACTION视图,就可以定位到具体的SQL语句和操作人等信息,但是检查之后的结果如下:
1 2 3 4 5 6 7 | SYS@oraLHR12> SELECT * FROM GV$LOCKED_OBJECT; no rows selected SYS@oraLHR12> SELECT * FROM GV$TRANSACTION; no rows selected |