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
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
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
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
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
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
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
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
session s
where s.saddr=t.ses_addr
and t.xidsqn=‘3413746’
方法二:
select /+ rule/c.sql_text, b.sid
from gv
session b, 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