有的時候我們做OGG的時候add trandata會出現異常。
這里就剖析一下add trandata到底做了什么
GGSCI (yjfora81 as ggs_admin@testdb) 2> add trandata ppzhu1.test3
2016-03-08 11:47:36 WARNING OGG-00706 Failed to add supplemental log group on table PPZHU1.TEST3 due to ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired SQL ALTER TABLE “PPZHU1″.”TEST3″ ADD SUPPLEMENTAL LOG GROUP “GGS_87926″ (“USER_ID”) ALWAYS /* GOLDENGATE_DDL_REPLICATION */.
然后一直hang住
使用OGG用戶登陸我的用戶GGS_ADMIN
GGSCI (yjfora81) 1> dblogin userid ggs_admin,password test;
Successfully logged into database.
SQL> select SID , SERIAL# ,PADDR from v$session where USERNAME=’GGS_ADMIN';
SID SERIAL# PADDR
———- ———- —————-
145 15 00000001BE185360
SQL> select pid,spid from v$process where addr=’00000001BE185360′;
PID SPID
———- ————————
37 40986
找到SPID和pid OS PID是40986數據庫的pid是37
我們用37 進行ORADEBUG
SQL> oradebug SETORAPID 37
Oracle pid: 37, Unix process pid: 40986, image: oracle@yjfora81 (TNS V1-V3)
SQL> oradebug tracefile_name
/home/oracle/oracle/diag/rdbms/testdb/testdb/trace/testdb_ora_40986.trc
10046事件可以設置以下四個級別:
1 – 啟用標准的SQL_TRACE功能,等價於sql_trace
4 – Level 1 加上綁定值(bind values)
8 – Level 1 + 等待事件跟蹤
12 – Level 1 + Level 4 + Level 8
找到語句使用LEVEL 1即可
SQL> oradebug event 10046 trace name context forever ,level 1;
Statement processed.
在ggsci中
GGSCI (yjfora81 as ggs_admin@testdb) 3> add trandata ppzhu1.test4
Logging of supplemental redo data enabled for table PPZHU1.TEST4.
TRANDATA for scheduling columns has been added on table ‘PPZHU1.TEST4′.
TRANDATA for instantiation CSN has been added on table ‘PPZHU1.TEST4′.
SQL> Oradebug event 10046 trace name context off;
Statement processed.
然后我們查看trace文件
LOCK TABLE “PPZHU1″.”TEST6″ IN SHARE MODE NOWAIT
LOCK TABLE “PPZHU1″.”TEST6″ IN EXCLUSIVE MODE NOWAIT
ALTER TABLE “PPZHU1″.”TES
可以看到是要加鎖的所以add trandata可能造成堵塞
由於ALTER TABLE 看不全,我做了審計發現如下:
ALTER TABLE “PPZHU1″.”TEST8″ ADD SUPPLEMENTAL LOG GROUP “GGS_87937″ (“USER_ID”) ALWAYS /* GOLDENGATE_DDL_REPLICATION */
ALTER TABLE “PPZHU1″.”TEST8″ ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY, UNIQUE, FOREIGN KEY) COLUMNS /* GOLDENGATE_DDL_REPLICATION */
在結合我們的報錯信息
GGSCI (yjfora81 as ggs_admin@testdb) 2> add trandata ppzhu1.test3
2016-03-08 11:47:36 WARNING OGG-00706 Failed to add supplemental log group on table PPZHU1.TEST3 due to ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired SQL ALTER TABLE “PPZHU1″.”TEST3″ ADD SUPPLEMENTAL LOG GROUP “GGS_87926″ (“USER_ID”) ALWAYS /* GOLDENGATE_DDL_REPLICATION */.
2016-03-08 11:53:00 WARNING OGG-00706 Failed to add supplemental log group on table PPZHU1.TEST3 due to ORA-03113: end-of-file on communication channel
Process ID: 23575
Session ID: 80 Serial number: 2709 SQL BEGIN DBMS_CAPTURE_ADM.PREPARE_TABLE_INSTANTIATION(table_name => ‘”PPZHU1″.”TEST3″‘, supplemental_logging => ‘none’); END;.
可以確定 add trandata 至少做了如下操作
1、ALTER TABLE “PPZHU1″.”TEST8″ ADD SUPPLEMENTAL LOG GROUP “GGS_87937″ (“USER_ID”) ALWAYS
2、ALTER TABLE “PPZHU1″.”TEST8″ ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY, UNIQUE, FOREIGN KEY) COLUMNS
3、DBMS_CAPTURE_ADM.PREPARE_TABLE_INSTANTIATION(table_name => ‘”PPZHU1″.”TEST3″‘, supplemental_logging => ‘none’
其中這幾部中第三步會加鎖並且不是NOWAIT的方式,如果表上有事物正在運行,那么這個語句會等待,因為他需要一個MODE 4的鎖在表級S鎖
如下:
SQL> select * from v$lock;
ADDR KADDR SID TYPE ID1 ID2 LMODE REQUEST CTIME BLOCK
—————- —————- ———- —- ———- ———- ———- ———- ———- ———-
00000001BD52BC80 00000001BD52BCF8 80 TX 655363 1685 6 0 122 0
00007F716C65A908 00007F716C65A968 80 TM 87926 0 0 4 122 0
而DML會在表級別上一個SX級別的3級鎖,所以不兼容一直卡着,並且它還會影響隨后的DML因為DML需要表級別的SX鎖,這樣對生產系統的影響
很大。解決方式就是KILL掉OGG登陸的會話。
而1,2兩部都是NOWAIT方式,可以及時報錯出來及ORA-00054: resource busy,不會堵塞
實際上1,2兩部做完后,我們可以再ORACLE數據庫中查看視圖
dba_log_group_columns
dba_log_groups
其中的含義不在給出,可以看看官方手冊。
2.
A:需要! 如果不執行add trandata,insert同步沒有問題(ORACLE數據庫),但是在同步update或delete操作時,就會因為丟失主鍵報同步錯誤。不開啟表級的最小附加日志,update的redo信息不記錄沒有進行更新的字段信息,如主鍵不更新的話主鍵不記錄在redo中,所以會導致同步失敗。
親自實踐過,不信你也可以試試。
SQL> alter session set events '10046 trace name context forever,level 12';
Session altered.
SQL> /
Session altered.
SQL> alter session set events '10046 trace name context off';
Session altered.
SQL>select * from v$diag_info;
案例可以參考 http://blog.mchz.com.cn/?p=4047
->
alter session set statistics_level=all;
select /*+ gathe_plan_statistics */ * from ts.ts_record t where system_name='人員小車閘口' order by pass_datetime desc;
select sql_text,sql_id from v$sql where sql_text like 'select%*%人員小車閘口%';
spool D:\dba\tmp\sql_dev.log
select * from table(dbms_xplan.display_cursor('36tvbv2uth9j9',0,'runstats_last'));
spool off
set pages 100 heading off pause on
select * from table(dbms_xplan.display_cursor(null,0,'allstats last'));
select * from table(dbms_xplan.display_cursor(null,null,'advanced'));
-->
SET LONG 1000000 SET FEEDBACK OFF
spool monitor_sql.html
SELECT DBMS_SQLTUNE.report_sql_monitor(sql_id =>'20wfgydukawbw',type=> 'HTML') AS report FROM dual;
spool off
->
SQL> alter session set events '10046 trace name context forever,level 12';
Session altered.
SQL> /
Session altered.
SQL> alter session set events '10046 trace name context off';
Session altered.
SQL>select * from v$diag_info;