常見Logical Standby異常處理[final]

tolywang發表於2010-07-22


出現Logical Standby不同步現象或SQL APPLY STOP的話,首先是檢視Logical Standby上的
Oracle alert log及dba_logstdby_events(如果sql apply應用失敗,那麼錯誤就會記錄在
logical standby的這個檢視中) .

 

1. 如果出現sql apply stop的現象,可能是不支援的statement或packages. 首先我們
需要檢視 dba_logstdby_events 檢視,檢視最近的statement 。

2. 如果錯誤是資料庫管理方面引起的,比如表空間不足等,那麼我們可以在修復問題後,
重新開啟: alter database start logical standby apply .

3. 如果是因為一個錯誤的statement輸入導致,那麼我們可以先忽略:
alter database stop logical standby apply .
SQL> dbms_logstdby.skip_transaction 
alter database start logical standby apply .

alter database stop logical standby apply .
SQL> dbms_logstdby.skip('TABLE','schema_name','table_name',null)
alter database start logical standby apply .


SQL> alter database stop logical standby apply;
SQL> exec dbms_logstdby.skip('DML','DFMS','WIP_D_SHIP_BIN_DETAIL');
SQL> alter database start logical standby apply;

 


-----------------------------------------------------------------------
例子:

SQL> SET LONG 1000
SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YY HH24:MI:SS';
Session altered.
SQL> SELECT EVENT_TIME, COMMIT_SCN, EVENT, STATUS FROM DBA_LOGSTDBY_EVENTS;

假設logical standby中報tablespace空間不足問題,SQL APPLY已經stop,那麼可以:

SQL> ALTER SESSION DISABLE GUARD; 先停掉standby的保護模式,
加入tablespace 資料檔案 ;
SQL> ALTER SESSION ENABLE GUARD;
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY;  


------------------------------------------------------------------------


不要使用 SKIP_TRANSACTION 處理DML相關的Logical Standby的問題。因為一般DML
導致的failure 只是涉及一個table而已。

 

下面是一個例子: 


Wed Jul 21 12:14:13 2010
LOGSTDBY status: ORA-00001: unique constraint (DFMS.WIP_D_SHIP_BIN_DETAIL_PK) violated
LOGSTDBY Apply process P004 pid=31 OS id=3568 stopped
Wed Jul 21 12:14:13 2010
LOGMINER: End mining logfile: /u01/product/oradata/delll10/arch/1_9086_717422003.arc
Wed Jul 21 12:14:13 2010
LOGMINER: Begin mining logfile for session 1 thread 1 sequence 9087,

/u01/product/oradata/delll10/arch/1_9087_717422003.arc
Wed Jul 21 12:14:15 2010
Errors in file /u01/product/admin/delll10/bdump/delll10_lsp0_3551.trc:
ORA-12801: error signaled in parallel query server P004
ORA-00001: unique constraint (DFMS.WIP_D_SHIP_BIN_DETAIL_PK) violated
LOGSTDBY Analyzer process P003 pid=30 OS id=3564 stopped
LOGSTDBY Apply process P006 pid=34 OS id=3573 stopped
LOGSTDBY Apply process P008 pid=29 OS id=3577 stopped
LOGSTDBY Apply process P005 pid=33 OS id=3571 stopped
LOGSTDBY Apply process P007 pid=35 OS id=3575 stopped
Wed Jul 21 12:16:27 2010
alter database stop logical standby apply
Wed Jul 21 12:16:27 2010
ALTER DATABASE STOP LOGICAL STANDBY APPLY
Completed: alter database stop logical standby apply
Wed Jul 21 12:20:16 2010


明顯的是有人在Production DB上向PK欄位插入的值在Logical Standby上已經存在了,
有可能是有人在Logical Standby中手工插入或修改了值。


一般可以有兩種方式來進行處理:


第一種方法 :忽略這個table上操作,然後應用SQL,然後unskip, 最後初始化有重複值的table
(初始化的過程應該是drop掉table, 然後重新create,因為我們發現它的建立時間已經更改了)。

SQL> alter database stop logical standby apply;
SQL> exec dbms_logstdby.skip('DML','DFMS','WIP_D_SHIP_BIN_DETAIL');
SQL> alter database start logical standby apply;

SQL> alter database stop logical standby apply;
SQL> exec dbms_logstdby.unskip('DML','DFMS','WIP_D_SHIP_BIN_DETAIL');
SQL> EXECUTE DBMS_LOGSTDBY.INSTANTIATE_TABLE ('DFMS','WIP_D_SHIP_BIN_DETAIL','DELLL10');
SQL> alter database start logical standby apply;

 

第二種方式: 關閉SQL APPLY, 使用 trace event 10046 在Logical Standby上對這個
重複值進行跟蹤,在Logical Standby中找到這個重複值後在Standby端刪除,然後啟動
SQL APPLY .

在Logical Standby上操作:

SQL> alter database stop logical standby apply; 
設定10046 event 事件。
SQL> alter database start logical standby apply; 

 

可能避免的方法:

沒有直接的辦法,因為logical standby本身允許在備庫進行寫操作,要是想避免的話,透過trigger,
在logical standby做apply的時候不會觸發trigger,不過人為的對logical standby資料的操作
會觸發trigger, 可以在standby上對關鍵表建trigger,避免dml操作 .

 

 

------------------------------------------------------------------------

 


某些Logical Standby不支援的語句導致sql apply stop .

例子:  grant sysdba to emp ;  會收到錯誤:

LOGSTDBY stmt: grant sysdba to emp 
LOGSTDBY status: ORA-01031: insufficient privileges
然後sql apply stop . 

處理方法: 跳過這個grant DDL.
SQL> alter database stop logical standby apply;
SQL> exec DBMS_LOGSTDBY.SKIP('NON_SCHEMA_DDL');
SQL> alter database start logical standby apply;

不過由於可能後面的正常的DDL都會被跳過,所以我們需要立即執行unskip.
SQL> alter database stop logical standby apply;
SQL> exec DBMS_LOGSTDBY.UNSKIP('NON_SCHEMA_DDL');
SQL> alter database start logical standby apply;

 

------------------------------------------------------------------------


全表掃描導致的長運算也可能導致問題。 可以使用一下語句查出:

SQL> SELECT SAS.SERVER_ID
2 , SS.OWNER
3 , SS.OBJECT_NAME
4 , SS.STATISTIC_NAME
5 , SS.VALUE
6 FROM V$SEGMENT_STATISTICS SS
7 , V$LOCK L
8 , V$STREAMS_APPLY_SERVER SAS
9 WHERE SAS.SERVER_ID = &SLAVE_ID
10 AND L.SID = SAS.SID
11 AND L.TYPE = 'TM'
12 AND SS.OBJ# = L.ID1;


SQL> alter database stop logical standby apply;
SQL> EXECUTE DBMS_LOGSTDBY.SKIP(stmt => 'DML' , -
schema_name => 'SCOTT' , -
object_name => 'FTS');
SQL> alter database start logical standby apply;

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/35489/viewspace-668726/,如需轉載,請註明出處,否則將追究法律責任。