跨库的DB_LINK导致的数据库锁故障的处理

2pc涉及到2个阶段,3个操作
阶段一:“准备提交”,事务协调者向所有操作者发起prepare,所有参与者回答yes/no。
阶段二:“正式提交”,如果所有参与者都回答yes,则向所有参与者发起commit;否则,向所有参与者发起rollback。
因此,要实现2pc,所有参与者都得实现3个操作:prepare/commit/rollback。

2pc的实现
关于2pc,对应的实现层面,也就是XA协议或使用DB_LINK;

2pc的问题
阶段2:其中一个参与者超时或者出错(1、操作异常终止;2、一半事务成功,一半事务失败;3、网络抖动。),那其他参与者,是commit,还是rollback?也不能确定。

1、查看数据库的等待事件
col inst_id for 99;
set lines 2000;
set pages 2000;
select INST_ID,event,count(1) from gv$session where event like ‘enq%’ group by event,INST_ID order by 3;

INST_ID EVENT COUNT(1)

  1 enq: TX - row lock contention                      1

可以看到有一个行锁
2、查找数据库锁:REQUEST等于0的是持有锁者,REQUEST大于0的是持有锁者
set lines 2000;
set pages 2000;
col sess for a20
SELECT /+ rule/DECODE(request,0,'Holder: ',‘Waiter: ‘)||sid||’,Inst:’||inst_id sess,
id1, id2, lmode, request, type
FROM gV L O C K W H E R E ( i d 1 , i d 2 , t y p e ) I N ( S E L E C T i d 1 , i d 2 , t y p e F R O M V LOCK WHERE (id1, id2, type) IN (SELECT id1, id2, type FROM V LOCK WHERE request>0)
ORDER BY id1, request;
SESS ID1 ID2 LMODE REQUEST TY


Holder: 1,Inst:1 589837 887 6 0 TX
Waiter: 43,Inst:1 589837 887 0 6 TX
1是持有者的sid; 43是被锁者的sid

提示:如果锁太多可以用以下命令分别查看持有者和被锁者
查看持有者:
set lines 2000;
set pages 2000;
col sess for a20
SELECT /+ rule/DECODE(request,0,'Holder: ',‘Waiter: ‘)||sid||’,Inst:’||inst_id sess,
id1, id2, lmode, request, type
FROM gV L O C K W H E R E ( i d 1 , i d 2 , t y p e ) I N ( S E L E C T i d 1 , i d 2 , t y p e F R O M V LOCK WHERE (id1, id2, type) IN (SELECT id1, id2, type FROM V LOCK WHERE request>0) and request=0
ORDER BY id1, request;
SESS ID1 ID2 LMODE REQUEST TY


Holder: 1,Inst:1 589837 887 6 0 TX
1是持有者的sid
查看被锁者:
set lines 2000;
set pages 2000;
col sess for a20
SELECT /+ rule/DECODE(request,0,'Holder: ',‘Waiter: ‘)||sid||’,Inst:’||inst_id sess,
id1, id2, lmode, request, type
FROM gV L O C K W H E R E ( i d 1 , i d 2 , t y p e ) I N ( S E L E C T i d 1 , i d 2 , t y p e F R O M V LOCK WHERE (id1, id2, type) IN (SELECT id1, id2, type FROM V LOCK WHERE request>0) and request>0
ORDER BY id1, request;
SESS ID1 ID2 LMODE REQUEST TY


Waiter: 43,Inst:1 589837 887 0 6 TX
43是被锁者的sid
3、查看被锁的语句
set lines 2000;
set pages 2000;
select vn.sid,vn.serial#,vl.sql_text,vl.sql_id from v s q l v l , v sql vl,v session vn
where vl.ADDRESS= decode(vn.SQL_ADDRESS,null,vn.PREV_SQL_ADDR,VN.SQL_ADDRESS)
and vn.sid=&sid;
输入被锁者的sid 43
SID SERIAL# SQL_TEXT SQL_ID


    43         10 update dept_test set deptno=12  where deptno=10                                                                                                        2914fbp7zntwg

4、查看持有锁的语句:
set lines 2000;
set pages 2000;
select a.username, a.sid,b.SQL_TEXT, b.SQL_FULLTEXT from v s e s s i o n a , v session a, v sqlarea b
where a.prev_sql_id=b.sql_id and a.sid=&sid;
输入持有锁的sid 1
USERNAME SID SQL_TEXT SQL_FULLTEXT


SCOTT 1 update dept_test set deptno=11 where deptno=10 update dept_test set deptno=11 where deptno=10

5、查看执行时间长的sql
set pages 2000;
set lines 2000;
col machine for a10
select sid,serial#,username,program,machine,status,LAST_CALL_ET from v$session
where username is not null and username not in(‘SYS’,‘SYSMAN’,‘DBSNMP’) order by last_call_et desc;
SID SERIAL# USERNAME PROGRAM MACHINE STATUS LAST_CALL_ET


     1          7 SCOTT                          sqlplus@rac1 (TNS V1-V3)                         rac1       INACTIVE         4810
    43         10 SCOTT                          sqlplus@rac1 (TNS V1-V3)                         rac1       ACTIVE           4783

查看锁会话详细信息
select c.OBJECT_NAME,a.ROW_WAIT_OBJ#,a.ROW_WAIT_FILE#,a.ROW_WAIT_BLOCK#,a.
ROW_WAIT_ROW#,dbms_rowid.rowid_create(1,c.OBJECT_ID,a.ROW_WAIT_FILE#,a.ROW_WAIT_BLOCK#,a.
ROW_WAIT_ROW#) rid from v s e s s i o n a , v session a , v enqueue_lock b, dba_objects c
where a.sid=b.SID and b.type=‘TX’ and a.ROW_WAIT_OBJ#=object_id(+)

6、处理锁
select
‘kill -9’||’ ‘||spid HOST_COMMAND,
‘alter system kill session ‘’’||A.sid||’,’||A.SERIAL#||’’’’ SQL_COMMAND
from Gv s e s s i o n A , G V session A,GV PROCESS B where A.PADDR=B.ADDR AND SID=&sid;
输出持有锁的sid 1
HOST_COMMAND SQL_COMMAND


kill -9 10609 alter system kill session ‘1,7’

要杀掉持有锁的会话可以执行命令:alter system kill session ‘1,7’ 或者在操作系统中kill -9 10609

select ‘alter system kill session ‘’’||SID|| ‘,’ || SERIAL#||’’’;’ from v$session where blocking_session is not null;

根据事务号查找sid:

假如事务号为:3802.2.3413746
方法一:
select s.sid from v t r a n s a c t i o n t , v transaction t, v session s
where s.saddr=t.ses_addr
and t.xidsqn=‘3413746’
方法二:
select /+ rule/c.sql_text, b.sid
from gv t r a n s a c t i o n a , g v transaction a, gv session b, gv s q l c w h e r e a . x i d u s n = 3802 a n d a . x i d s l o t = 2 a n d a . x i d s q n = 3413746 a n d a . a d d r = b . t a d d r a n d b . s q l a d d r e s s = c . a d d r e s s a n d b . s q l h a s h v a l u e = c . h a s h v a l u e ; s e l e c t x i d u s n , x i d s l o t , x i d s q n f r o m g v sql c where a.xidusn = 3802 and a.xidslot = 2 and a.xidsqn = 3413746 and a.addr = b.taddr and b.sql_address = c.address and b.sql_hash_value = c.hash_value; 方法三: select xidusn, xidslot, xidsqn from gv transaction t, gv$session s where s.saddr=t.ses_addr
and s.osuser=‘root’;

回滚事务:
rollback force ‘3802.2.3413746’;
查看事务回滚的进度:
SELECT timestamp,
session#,
username,
sql_redo
FROM V$LOGMNR_CONTENTS
WHERE xidusn = 3802 AND xidslt = 2 AND xidsqn = 3413746;

查看表的索引:
set linesize 200
select owner,index_name from dba_indexes
where table_name=‘ASYN_BUSINESS_PROCESS’;

select sum(bytes/1024/1024) from dba_segments
where segment_name=‘ASYN_BUSINESS_PROCESS’

在线重建表索引:
alter index ECIQ_OPERATION.pk_asyn_id rebuild online parallel 8;
alter index ECIQ_OPERATION.idx_asyn_bizno rebuild online parallel 8;
alter index ECIQ_OPERATION.idx_asyn_query rebuild online parallel 8;

离线重建表索引:
alter index ECIQ_OPERATION.pk_asyn_id rebuild parallel 8;
alter index ECIQ_OPERATION.idx_asyn_bizno rebuild parallel 8;
alter index ECIQ_OPERATION.idx_asyn_query rebuild parallel 8;

杀掉所有的通过监听连接的数据库会话:
ps -ef|grep LOCAL=NO|awk ‘{print $2}’|xargs kill -9;

查看root操作用户进行的数据库连接:
col osuser for a10
col USERNAME for a15
col MACHINE for a20
col schemaname for a15
col program for a20
set lines 200
set pages 200
select osuser,username,machine,schemaname,program,type,sql_id,client_info from v$session where osuser like ‘%root%’ order by 3;

查看数据库中的坏块:
SQL> select * fromv$database_block_corruption;

no rows selected

猜你喜欢

转载自blog.csdn.net/weixin_44524950/article/details/86483703