阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

分布式事务故障处理暨ORA-24756: transaction does not exist处理

142次阅读
没有评论

共计 3808 个字符,预计需要花费 10 分钟才能阅读完成。

ORA-24756 处理

看到警告日志一直报 ORA-24756 错误

Errors in file /Oracle/admin/NHMIX01/bdump/nhmix01_reco_4959.trc:
ORA-24756: transaction does not exist
但是去找 trace 文件的时候却没有

想到了事务的问题,查 dba_2pc_pending

select local_tran_id,state from dba_2pc_pending;
LOCAL_TRAN_IDSTATE
6.22.290635commited

通过该视图我去到远端的数据库查询该是视图

select local_tran_id,state from dba_2pc_pending;
no rows selected.

我尝试

commit force ‘6.22.290635’  却发现被 hang 住了,其实此时不需要 commit force 了,此时是分布式事务的第三个阶段即 forget phase 发生错误,需要做的是在本地清除分布式事务信息。

exec DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(‘6.22.290635’);

再 kill 了那个 commit force 动作。再去查询 dba_2pc_pending 的时候就找不到这个事务了。

分佈式事务总结

分布式事务,简单来说,是指一个事务在本地和远程执行,本地需要等待确认远程的事务结束后,进行下一步本地的操作。如通过 dblink update 远程数据库的一行记录,如果在执行过程中网络异常,或者其他事件导致本地数据库无法得知远程数据库的执行情况,此时就会发生 in doubt 的报错。此时需要 dba 介入,且需要分多种情况进行处理。

分布式事务在 commit 提交时候,会经历 3 个阶段:
1.PREPARE PHASE:
  1.1 决定哪个数据库为 commit point site。(注,参数文件中 commit_point_strength 值 [默认值为 1] 高的那个数据库为 commit point site)
  1.2 全局协调者(Global Coordinator)要求所有的点(除 commit point site 外)做好 commit 或者 rollback 的准备。此时,对分布式事务的表加锁。
  1.3 所有分布式事务的节点将它的 scn 告知全局协调者。
  1.4 全局协调者取各个点的最大的 scn 作为分布式事务的 scn。(eygle 在这篇文章中也测试过)
至此,所有的点都完成了准备工作,我们开始进入 COMMIT PHASE 阶段,此时除 commit point site 点外所有点的事务均为 in doubt 状态,直到 COMMIT PHASE 阶段结束。

如果数据库在此阶段出现问题,我们查询(假设远程数据库为 commit point site,且本地数据库为 Global Coordinator):

Scenario 1 collecting:

select local_tran_id,state from dba_2pc_pending;
LOCAL_TRAN_IDSTATE
6.22.290635collecting

remote DB

select local_tran_id,state from dba_2pc_pending;
no rows selected.

即表示本地数据库要求做好 commit 或者 rollback 准备,现在正在收集其他点的数据库返回信息,但是远程数据库状态未知(in doubt),我们需要手动的将本地的 Global Coordinator 信息清除掉:

SQL> exec DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(‘6.22.290635’);

PL/SQL procedure successfully completed.

Scenario2:prepared

select local_tran_id,state from dba_2pc_pending;
LOCAL_TRAN_IDSTATE
6.22.290635prepared

remote DB

select local_tran_id,state from dba_2pc_pending;
no rows selected.

即表示本地 Global Coordinator 已做好准备,已将分布式锁放到各个事务表上,但远程数据库的状态再次未知(in doubt), 我们需要手动的将本地的 transaction rollback 掉,并且清除分布式事务信息:

rollback force ‘6.22.290635’;

exec DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(‘6.22.290635’);

2.COMMIT PHASE:
    2.1 Global Coordinator 将最大 scn 传到 commit point site,要求其 commit。
    2.2 commit point 尝试 commit 或者 rollback。分布式事务锁释放。
    2.3 commit point 通知 Global Coordinator 已经 commit。
    2.4 Global Coordinator 通知分布式事务的所有点进行 commit。

Scenario 1 local prepared ,remote commited

local:
select local_tran_id,state from dba_2pc_pending;
LOCAL_TRAN_IDSTATE
6.22.290635prepared

 

remote DB:
select local_tran_id,state from dba_2pc_pending;
LOCAL_TRAN_IDSTATE
1.92.66874commited

即表示远程数据库可能已经 commit,但是本地数据库未知远程数据库的状态,还是处于 prepared 状态。我们需要如下处理:

local:
commit force ‘6.22.290635’;

exec DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(‘6.22.290635’);

remote DB:

exec DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(‘1.92.66874‘);

Scenario2  local commited,remote commited

local:
select local_tran_id,state from dba_2pc_pending;
LOCAL_TRAN_IDSTATE
6.22.290635commited
remote DB:
select local_tran_id,state from dba_2pc_pending;
LOCAL_TRAN_IDSTATE
1.92.66874commited

即表示本地和远程数据库均完成 commit,但未清除分布式事务信息,我们需要如下处理:

local:

exec DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(‘6.22.290635’);

remote DB:

exec DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(‘1.92.66874‘);

3.FORGET PHASE:
  3.1 参与的点通知 commit point site 他们已经完成 commit,commit point site 就能忘记(forget)这个事务。
  3.2 commit point site 在远程数据库上清除分布式事务信息。
  3.3 commit point site 通知 Global Coordinator 可以清除本地的分布式事务信息。
  3.4 Global Coordinator 清除分布式事务信息。

local:

select local_tran_id,state from dba_2pc_pending;
LOCAL_TRAN_IDSTATE
6.22.290635commited

remote DB

select local_tran_id,state from dba_2pc_pending;
no rows selected.

即表示远端已完成 commit,通知 Global Coordinator 清除分布式事务信息,但是本地没有收到该信息,我们改如下处理:

local

exec DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY(‘6.22.290635’);

总结分佈式事务的状态依次如下:

phaselocal_stateremote_stateaction
preparecollecting
prepared
/
/
本地 DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY
本地 rollback force 后 PURGE_LOST_DB_ENTRY
commitprepared
commited
commited
commited
本地 commit force 后本地和远程均 PURGE
本地和远程均 PURGE_LOST_DB_ENTRY
forgetcommited/本地 PURGE_LOST_DB_ENTRY

更多 Oracle 相关信息见Oracle 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=12

本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-09/135023.htm

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-22发表,共计3808字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中