如何处理IN_DOUBT的分布事物

什么是分布事物?

在一个事物中,包含对多个数据库数据进行处理的DML语句。


在分布事物中,为了保证全局数据的一致性,采用两阶段提交。如下图:

global coordinator Commit point site

commit_point_strength = 5 commit_point_strength = 10

RemoteLocal

Insert into table @ remote

Insert into table

Commit;

两阶段提交保证分布事物全部提交或全部回滚

系统参数commit_point_strength 定义了分布数据库的提交顺序,commit_point_strength值较高的数据库为commit point site,在分布事物中最先提交,分布事物的状态信息也存在该数据库中。一般将关键的数据库作为commit point site 本地数据库为Global Coordinator

分布事物的两阶段提交分三个过程:

1. 准备阶段(PREPARE PHASE

·本地数据库Global Coordinator向其它数据库发出COMMIT通知

·比较所有数据库的SCN号,将最高的SCN号作为分布事物的全局SCN

·所有数据库写在线日志

·对分布事物修改的表加分布锁,防止被读写

·各数据库向Global Coordinator发出已经准备好的通知

所有参与分布事物的数据库必须经过上述准备,才能进入下一阶段。

2. 提交阶段(COMMIT PHASE

·本地数据库Global Coordinator通知commit point site首先提交。commit point site提交后,释放其占有的资源,通知Global Coordinator完成提交

·本地数据库Global Coordinator通知其它数据库提交

·提交节点在日志中追加一条信息,表示分布事物已经完成提交,并通知Global Coordinator。此时所有数据库的数据保持了一致性。

3. 注销阶段(FORGET PHASE

·本地数据库Global Coordinator通知commit point site所有数据库已经完成提交

·commit point site清除分布事物的记录和状态信息,并通知Global Coordinator

·Global Coordinator清除本地分布事物的记录和状态信息

此时分布事物的两阶段提交全部完成。

如果两阶段提交完成之前,数据库或网络出现异常,应用就会报错,分布事物处于IN_DOUBT状态。一旦数据库或网络恢复正常,系统(RECO PROCESS)会自动处理IN_DOUBT状态的分布事物。有些情况需要管理员手工处理IN_DOUBT状态的分布事物:

·IN_DOUBT状态的分布事物,将关键表锁住,造成应用不能正常工作

·分布数据库需要重建

下面举例说明不同情况下,手工处理IN_DOUBT状态分布事物的详细过程:

本地数据库Global Coordinator

local.oracle.com

commit_point_strength=5

远端数据库commit point site:

remote.oracle.com

commit_point_strength=10

分布事物:

/* DML remote -> remote.oracle.com */

insert into s_dept@remote values ();

/* DML local -> v817rep.be.oracle.com */

insert into emp values ();

commit;

1. 准备阶段没有完成时出现异常

ALERT FILE LOCAL.ORACLE.COM:

ORA-02050: transaction 3.4.270 rolled back, some REMOTE DBs may be in-doubt

ORA-02059: ORA-2PC-CRASH-TEST-2 in commit comment

DISTRIB TRAN LOCAL.ORACLE.COM.89f6eafb.3.4.270

is LOCAL tran 3.4.270 (hex=03.04.10e)

insert pending collecting tran, scn=196918 (hex=0.00030136)

ALERT FILE REMOTE.ORACLE.COM:

No entries

DBA_2PC_PENDING@LOCAL.oracle.com:

LOCAL_TRAN_ID|GLOBAL_TRAN_ID |STATE |MIX|HOST |COMMIT#

-------------|------------------------------|--------|---|----------|----------

3.4.270 |LOCAL.ORACLE.COM.89f6eafb |collecti|no |BE-ORACLE-|196918

|.3.4.270 |ng | |NTbel449 |

DBA_2PC_NEIGHBORS@LOCAL.oracle.com:

LOCAL_TRAN_ID|IN_OUT|DATABASE |DBUSER_OWNER |INT

-------------|------|-------------------------|---------------|---

3.4.270 |in | |SCOTT |N

3.4.270 |out |REMOTE.ORACLE.COM |SCOTT |C

DBA_2PC_PENDING@REMOTE.oracle.com:

no rows selected

DBA_2PC_NEIGHBORS@REMOTE.oracle.com:

no rows selected

由上边信息我们可以得知:

本地数据库Global Coordinator

处于COLLECTING阶段,等待所有数据库返回已准备好的通知

远端数据库commit point site:什么也没发生(系统自动回退)

解决方法:

清除本地数据库中IN_DOUBT状态分布事物的记录

execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('3.4.270');

你使用了9iaum(auto undo management)

要先屏蔽掉对undo操作的错误提示:
sql>alter system set UNDO_SUPPRESS_ERRORS = TRUE
sql>EXECUTE DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('1.29.81672')
sql>alter system set UNDO_SUPPRESS_ERRORS = false

看看dba_2pc_pending中是否还有该记录

2. 准备阶段完成时出现异常

ALERT FILE LOCAL.ORACLE.COM:

ORA-02054: transaction 1.8.238 in-doubt

ORA-02059: ORA-2PC-CRASH-TEST-1 in commit comment

ORA-02063: preceding line from V817

DISTRIB TRAN LOCAL.ORACLE.COM.89f6eafb.1.8.238

is LOCAL tran 1.8.238 (hex=01.08.ee)

insert pending prepared tran, scn=194671 (hex=0.0002f86f)

ALERT FILE REMOTE.ORACLE.COM:

ORA-02059: ORA-2PC-CRASH-TEST-1 in commit comment

DBA_2PC_PENDING@LOCAL.oracle.com:

LOCAL_TRAN_ID|GLOBAL_TRAN_ID |STATE |MIX|HOST |COMMIT#

-------------|------------------------------|--------|---|----------|----------

1.8.238 |LOCAL.ORACLE.COM.89f6eafb |prepared|no |BE-ORACLE-|194671

|.1.8.238 | | |NTbel449 |

DBA_2PC_NEIGHBORS@LOCAL.oracle.com:

LOCAL_TRAN_ID|IN_OUT|DATABASE |DBUSER_OWNER |INT

-------------|------|-------------------------|---------------|---

1.8.238 |in | |SCOTT |N

1.8.238 |out |REMOTE.ORACLE.COM |SCOTT |C

DBA_2PC_PENDING@REMOTE.oracle.com:

no rows selected

DBA_2PC_NEIGHBORS@REMOTE.oracle.com:

no rows selected

由上边信息我们可以得知:

本地数据库Global Coordinator:处于PREPARE阶段,占有分布锁,等待提交

远端数据库commit point site:什么也没发生(系统自动回退)

解决方法:

rollback force 'LOCAL.ORACLE.COM.89f6eafb.1.8.238';

-OR-

rollback force '1.8.238';

DBA_2PC_PENDING@LOCAL.oracle.com:

LOCAL_TRAN_ID|GLOBAL_TRAN_ID |STATE |MIX|HOST |COMMIT#

-------------|------------------------------|--------|---|----------|----------

1.8.238 |LOCAL.ORACLE.COM.89f6eafb |forced r|no |BE-ORACLE-|194671

|.1.8.238 |ollback | |NTbel449 |

清除本地数据库中IN_DOUBT状态分布事物的记录

execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('3.4.270');

3. 提交阶段出现异常

·COMMIT POINT SITE 完成提交

ALERT FILE LOCAL.ORACLE.COM:

ORA-02054: transaction 3.38.281 in-doubt

ORA-02053: transaction 2.39.179 committed, some REMOTE DBs may be in-doubt

ORA-02059: ORA-2PC-CRASH-TEST-6 in commit comment

ORA-02063: preceding 2 lines from V817

ALERT FILE REMOTE.ORACLE.COM:

ORA-02053: transaction 2.39.179 committed, some REMOTE DBs may be in-doubt

ORA-02059: ORA-2PC-CRASH-TEST-6 in commit comment

DBA_2PC_PENDING@LOCAL.oracle.com:

LOCAL_TRAN_ID|GLOBAL_TRAN_ID |STATE |MIX|HOST |COMMIT#

-------------|------------------------------|--------|---|----------|----------

3.38.281 |LOCAL.ORACLE.COM.89f6eafb |prepared|no |BE-ORACLE-|201050

|.3.38.281 | | |NTbel449 |

DBA_2PC_NEIGHBORS@LOCAL.oracle.com:

LOCAL_TRAN_ID|IN_OUT|DATABASE |DBUSER_OWNER |INT

-------------|------|-------------------------|---------------|---

3.38.281 |in | |SCOTT |N

3.38.281 |out |REMOTE.ORACLE.COM |SCOTT |C

DBA_2PC_PENDING@REMOTE.oracle.com:

LOCAL_TRAN_ID|GLOBAL_TRAN_ID |STATE |MIX|HOST |COMMIT#

-------------|------------------------------|--------|---|----------|----------

2.39.179 |LOCAL.ORACLE.COM.89f6eafb |committe|no |BE-ORACLE-|201052

|.3.38.281 |d | |NTbel449 |

DBA_2PC_NEIGHBORS@REMOTE.oracle.com:

LOCAL_TRAN_ID|IN_OUT|DATABASE |DBUSER_OWNER |INT

-------------|------|-------------------------|---------------|---

2.39.179 |in |LOCAL.ORACLE.COM |SCOTT |C

由上边信息我们可以得知:

本地数据库Global Coordinator:处于PREPARE阶段,占有分布锁,等待提交

远端数据库commit point site: 已经完成提交

解决方法:

commit force 'LOCAL.ORACLE.COM.89f6eafb.3.38.281','201052';

-OR-

commit force '3.38.281','201052';

注意使用较高的SCN号,保证数据的全局一致性

DBA_2PC_PENDING@LOCAL.oracle.com:

LOCAL_TRAN_ID|GLOBAL_TRAN_ID |STATE |MIX|HOST |COMMIT#

-------------|------------------------------|--------|---|----------|----------

3.38.281 |LOCAL.ORACLE.COM.89f6eafb |forced c|no |BE-ORACLE-|201052

|.3.38.281 |ommit | |NTbel449 |

清除本地数据库中IN_DOUBT状态分布事物的记录

execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('3.38.281');

清除REMOTE数据库中IN_DOUBT状态分布事物的记录

execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('2.39.179');

·所有数据库完成提交,但没有进入注销阶段

ALERT FILE LOCAL.ORACLE.COM:

ORA-02053: transaction 3.16.283 committed, some REMOTE DBs may be in-doubt

ORA-02059: ORA-2PC-CRASH-TEST-8 in commit comment

ALERT FILE REMOTE.ORACLE.COM:

DISTRIB TRAN LOCAL.ORACLE.COM.89f6eafb.3.16.283

is LOCAL tran 2.44.179 (hex=02.2c.b3)

insert pending committed tran, scn=201607 (hex=0.00031387)

DBA_2PC_PENDING@LOCAL.oracle.com:

LOCAL_TRAN_ID|GLOBAL_TRAN_ID |STATE |MIX|HOST |COMMIT#

-------------|------------------------------|--------|---|----------|----------

3.16.283 |LOCAL.ORACLE.COM.89f6eafb |committe|no |BE-ORACLE-|201607

|.3.16.283 |d | |NTbel449 |

DBA_2PC_NEIGHBORS@LOCAL.oracle.com:

LOCAL_TRAN_ID|IN_OUT|DATABASE |DBUSER_OWNER |INT

-------------|------|-------------------------|---------------|---

3.16.283 |in | |SCOTT |N

3.16.283 |out |REMOTE.ORACLE.COM |SCOTT |C

DBA_2PC_PENDING@REMOTE.oracle.com:

LOCAL_TRAN_ID|GLOBAL_TRAN_ID |STATE |MIX|HOST |COMMIT#

-------------|------------------------------|--------|---|----------|----------

2.44.179 |LOCAL.ORACLE.COM.89f6eafb |committe|no |BE-ORACLE-|201607

|.3.16.283 |d | |NTbel449 |

DBA_2PC_NEIGHBORS@REMOTE.oracle.com:

LOCAL_TRAN_ID|IN_OUT|DATABASE |DBUSER_OWNER |INT

-------------|------|-------------------------|---------------|---

2.44.179 |in |LOCAL.ORACLE.COM |SCOTT |C

由上边信息我们可以得知:

本地数据库Global Coordinator:完成提交

远端数据库commit point site: 完成提交

清除本地数据库中IN_DOUBT状态分布事物的记录

execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('3.16.283');

清除REMOTE数据库中IN_DOUBT状态分布事物的记录

execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('2.44.179');

4. 注销阶段出现异常

ALERT FILE LOCAL.ORACLE.COM:

ORA-02053: transaction 1.10.255 committed, some REMOTE DBs may be in-doubt

ORA-02059: ORA-2PC-CRASH-TEST-10 in commit comment

ALERT FILE REMOTE.ORACLE.COM:

No entries

DBA_2PC_PENDING@LOCAL.oracle.com:

LOCAL_TRAN_ID|GLOBAL_TRAN_ID |STATE |MIX|HOST |COMMIT#

-------------|------------------------------|--------|---|----------|----------

1.10.255 |LOCAL.ORACLE.COM.89f6eafb |committe|no |BE-ORACLE-|202241

|.1.10.255 |d | |NTbel449 |

DBA_2PC_NEIGHBORS@LOCAL.oracle.com:

LOCAL_TRAN_ID|IN_OUT|DATABASE |DBUSER_OWNER |INT

-------------|------|-------------------------|---------------|---

1.10.255 |in | |SCOTT |N

1.10.255 |out |REMOTE.ORACLE.COM |SCOTT |C

DBA_2PC_PENDING@REMOTE.oracle.com:

no rows selected

DBA_2PC_NEIGHBORS@REMOTE.oracle.com:

no rows selected

由上边信息我们可以得知:

本地数据库Global Coordinator:完成提交

远端数据库commit point site: 完成FORGET

解决方法:

清除本地数据库中IN_DOUBT状态分布事物的记录

execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('1.10.255');

2pc

2 phase commit
未决两阶段提交事务
也就是具有分布式数据库的概念所谓两阶段提交,就是同一个事务分布在2个以上的数据库上需要所有的数据库上的操作成功才算成功
若其中有一个数据库上的操作不成功则该事务属于未完成事务
通过这个view,能把这些事务找出来,然后做出相应的处理通常数据库是由 RECO 进程来处理这些事务的:在操作已经成功的那部分数据库上回退操作!

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/35489/viewspace-84485/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/35489/viewspace-84485/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值