replication

Logic standby delay when query with for update clause

January 11, 2012 oracle, replication, system No comments

今天遇到一个奇怪的问题,3个logic standby 中有一个delay 查看任何日志都没有发现错误,有一个transaction在apply一个SQL,这条SQL没有任何问题,SQL所涉及到的表也没有任何问题
当时的apply情况如下:

SID USERNAME MACHINE EVENT PARAM W WT SQL ST LT LOGON_TIME
—— ———- ———————- —————————— ——————– —- —- —————————- — —— ———-
3222 oracle@db-15 (P000) LogMiner: wakeup event for rea 1/0/0 0 718 / A 1587 1588
3279 oracle@db-15 (P003) LogMiner: wakeup event for pre 1/0/0 0 #### / A 1587 1588
3238 oracle@db-15 (P008) rdbms ipc message 500/0/0 0 #### /404qaurwrsnva A 1587 1588
3237 oracle@db-15 (P011) rdbms ipc message 500/0/0 0 #### /404qaurwrsnva A 1587 1588
3276 oracle@db-15 (P002) LogMiner: wakeup event for pre 1/0/0 0 #### / A 1587 1588
3250 oracle@db-15 (P005) rdbms ipc message 500/0/0 0 #### /05dcutzfrnzmw A 1587 1588
3254 oracle@db-15 (P007) rdbms ipc message 500/0/0 0 #### /404qaurwrsnva A 1587 1588
3256 oracle@db-15 (P010) rdbms ipc message 500/0/0 0 #### /404qaurwrsnva A 1587 1588
3257 oracle@db-15 (P012) rdbms ipc message 500/0/0 0 #### /404qaurwrsnva A 1587 1588
3258 oracle@db-15 (P015) rdbms ipc message 500/0/0 0 #### /404qaurwrsnva A 1587 1588
3262 oracle@db-15 (P014) rdbms ipc message 500/0/0 0 #### /404qaurwrsnva A 1587 1588
3263 oracle@db-15 (P013) rdbms ipc message 500/0/0 0 #### /404qaurwrsnva A 1587 1588
3267 oracle@db-15 (P017) rdbms ipc message 500/0/0 0 #### /404qaurwrsnva A 1587 1588
3269 oracle@db-15 (P016) rdbms ipc message 500/0/0 0 #### /404qaurwrsnva A 1587 1588
3274 oracle@db-15 (P009) rdbms ipc message 500/0/0 0 #### /404qaurwrsnva A 1587 1588
3275 oracle@db-15 (P004) LogMiner: wakeup event for pre 1/0/0 0 #### / A 1587 1588
3246 oracle@db-15 (P006) latch: cache buffers chains 63287313528/124/0 -1 #### bmgkxmt7cybyp/bbjphxukw15ap K 1587 1588
3277 oracle@db-15 (P001) LogMiner: wakeup event for bui 1/0/0 0 814 21wwpjmcv56ds/ A 1587 1588

具体SQL为:
select “PRODUCT_DESCRIPTION”,”SALE_SKILL” from “PROD_DATA2″.”PRO
DUCT” p where(:1=”ID”)for update 我们看到这条SQL带有 for update操作
尝试kill掉这个进程 hang 死:
SQL> alter system kill session ‘3272,4’;
alter system kill session ‘3272,4’
*
ERROR at line 1:
ORA-01013: user requested cancel of current operation

尝试kill掉spid
[oracle@db-15 ~]$ kill -9 8823
-bash: kill: (8823) – No such process

尝试手动停止sql apply:

SQL>alter database stop logical standby apply;

依然hang死

所有的进程都在等待这个回话结束but,it’s for update

尝试强制abort这个transaction:

SQL> ALTER DATABASE ABORT LOGICAL STANDBY APPLY;
SQL>alter database start logical standby apply immediate;

done.3个小时的delay很快被追上

Stopping SQL Apply on a Logical Standby Database

To stop SQL Apply, issue the following statement on the logical standby database:

SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;When you issue this statement, SQL Apply waits until it has committed all complete transactions that were in the process of being applied. Thus, this command may not stop the SQL Apply processes immediately.

If you want to stop SQL Apply immediately, issue the following statement:

SQL> ALTER DATABASE ABORT LOGICAL STANDBY APPLY;

下面做个测试

maybe 仅是个人猜测:备库由PL/SQLDEV 发起的for update查询,但是DBA 没有关闭这个进程:

开启一个新的session:

SQL> update product set id=100000 where id=56;

出现了等待 。也许由于某个DBA 对这个逻辑备库开启了表的for update,但是忘掉了commit 这个操作 it just a guess !

主表缺少主键导致logic standby delay 一例

December 28, 2011 oracle, replication No comments

table缺少primary key 导致logic standby delay 一例

早上在主库做如下操作:


[oracle@racdg1 ~]$ sqlplus ‘/as sysdba’

SQL*Plus: Release 10.2.0.5.0 – Production on Wed Dec 28 11:23:14 2011

Copyright (c) 1982, 2010, Oracle. All Rights Reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 – 64bit Production
With the Partitioning, Real Application Clusters, OLAP, Data Mining
and Real Application Testing options

SQL> DECLARE
2 row_num NUMBER := 0;
BEGIN
FOR c_test IN (SELECT ROWID rid FROM MC_SITE_PRODUCT_PIC t ) LOOP
UPDATE MC_SITE_PRODUCT_PIC t SET t.UPDATE_FLAG = 0 WHERE ROWID = c_test.rid;
row_num := row_num + 1;
IF MOD(row_num,2000) =0 THEN
COMMIT;
dbms_lock.sleep(2);
END IF;
END LOOP;
COMMIT;
END; 3 4 5 6 7 8 9 10 11 12 13
14 /

PL/SQL procedure successfully completed.

SQL>

该表大约有150万行,选择update 2000条 提交一次,导致逻辑备库出现delay


SPID TYPE STATUS
———— ————— —————————————————————————————————-
5798 COORDINATOR ORA-16116: no work available
5665 READER ORA-16127: stalled waiting for additional transactions to be applied
5667 BUILDER ORA-16127: stalled waiting for additional transactions to be applied
5669 PREPARER ORA-16127: stalled waiting for additional transactions to be applied
5671 PREPARER ORA-16127: stalled waiting for additional transactions to be applied
5673 PREPARER ORA-16127: stalled waiting for additional transactions to be applied
5675 ANALYZER ORA-16120: dependencies being computed for transaction at SCN 0x0007.1a92b5a4
5677 APPLIER ORA-16124: transaction 21 33 10269852 is waiting on another transaction
5679 APPLIER ORA-16113: applying change to table or sequence “PROD_DATA2″.”MC_SITE_PRODUCT_PIC”
5681 APPLIER ORA-16124: transaction 21 27 10269698 is waiting on another transaction
5683 APPLIER ORA-16124: transaction 21 6 10269799 is waiting on another transaction
5685 APPLIER ORA-16124: transaction 21 29 10269696 is waiting on another transaction
5687 APPLIER ORA-16124: transaction 10 37 2597623 is waiting on another transaction
5689 APPLIER ORA-16124: transaction 21 40 10269557 is waiting on another transaction
5691 APPLIER ORA-16124: transaction 33 35 358073 is waiting on another transaction
5693 APPLIER ORA-16124: transaction 33 16 357996 is waiting on another transaction
5695 APPLIER ORA-16124: transaction 21 46 10269647 is waiting on another transaction
5697 APPLIER ORA-16124: transaction 10 23 2598005 is waiting on another transaction
5699 APPLIER ORA-16124: transaction 21 13 10269728 is waiting on another transaction

—>5679 APPLIER ORA-16113: applying change to table or sequence “PROD_DATA2”.”MC_SITE_PRODUCT_PIC”更新出现延迟

APPLIED_SCN APPLIED_TIME RESTART_SCN RESTART_TIME LATEST_SCN LATEST_TIME MINING_SCN MINING_TIME
———– ——————- ———– ——————- ———- ——————- ———- ——————-
3.0511E+10 2011-12-28 09:12:06 3.0510E+10 2011-12-28 08:48:07 3.0511E+10 2011-12-28 09:27:28 3.0511E+10 2011-12-28 09:24:01

延迟超过了10分钟,并且有不断加大的趋势

查看5679 apply过程 :

SQL_ID CHILD outline/plan_hash_value Ex DISK_READS bg bg/exec rows LOAD_TIME
————- ———- —————————————————————- ———- ———- ————— ———— ———- ———–
8zy2mm8z8fvpw 0 745000887 109851 24 59862576 544.94 109851 12-28/00:44
TOTAL 109851 24 59862576 544.94 109851

Optimizer Plan:
——————————————————————————————————————————
| Operation | Name | Rows | Bytes| Cost | Pstart| Pstop |
————————————————————————————————————
| UPDATE STATEMENT | | | | 4746 | | |
| UPDATE |MC_SITE_PRODUCT_PIC | | | | | |
| COUNT STOPKEY | | | | | | |
| TABLE ACCESS FULL |MC_SITE_PRODUCT_PIC | 1 | 68 | 4746 | | |
————————————————————————————————————

发现主库已经更新完成150万 ,但是逻辑备库仅仅更新了10万条,执行计划走了 TABLE ACCESS FULL

查看主库的执行计划:

Optimizer Plan:
——————————————————————————————————————————
| Operation | Name | Rows | Bytes| Cost | Pstart| Pstop |
————————————————————————————————————
| UPDATE STATEMENT | | | | 1 | | |
| UPDATE |MC_SITE_PRODUCT_PIC | | | | | |
| TABLE ACCESS BY USER ROWID |MC_SITE_PRODUCT_PIC | 1 | 69 | 1 | | |
————————————————————————————————————

完全不同,查看该表的结构发现此表没有主键,导致logic standby的约束检查,导致logic standby 严重delay

解决方法:

SQL> create public database link xxx connect to xxx IDENTIFIED by xxx using ‘xxx’;

SQL> alter session db_file_multiblock_read_count = 128;

SQL> alter session set sort_area_size = 104857600;

SQL> alter session set workarea_size_policy=manual

SQL> alter database stop logical standby apply;

SQL> EXECUTE DBMS_LOGSTDBY.INSTANTIATE_TABLE (‘xxx’, ‘xxx’, ‘xxx’);

SQL> EXECUTE DBMS_LOGSTDBY.UNSKIP(‘DML’,’xx’,’xxx’);

SQL> alter database start logical standby apply immediate

使用 DBMS_LOGSTDBY.INSTANTIATE_TABLE 将表从pri端 重新同步过来。注意上面的步骤需要在空闲时候做,不然可能导致大量的latch等待:
这次操作产生了大量以下事件,幸运的是table本身不是很大,同步大概花了几十秒而已,对于大表的同步切记小心:


latch: undo global data
latch: undo global data
latch: undo global data
latch: undo global data
latch: undo global data
latcg cache buffers chains
latch: cache buffers chains
latch: cache buffers chains
latch: cache buffers chains
latch: cache buffers chains


临时的解决方法可以先skip掉该表。最后强调一点,表结构最好添加主键,没有主键的表对类似ogg等同步工具的使用都会产生影响。

Down-Stream 配置一例

December 27, 2011 oracle, replication No comments

测试环境:

[oracle@liu ~]$ sqlplus ‘/as sysdba’

SQL*Plus: Release 10.2.0.1.0 – Production on Mon Dec 26 21:53:23 2011

Copyright (c) 1982, 2005, Oracle. All rights reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 – Production
With the Partitioning, OLAP and Data Mining options

在source,destination 分别设置:

创建stream用户的表空间:
create tablespace tbs_stream datafile ‘/oracle/app/oracle/oradata/*xx/tbs_stream02.dbf’ size 200M;

将logmnr的默认表空间转到刚刚建立的表空间:
SQL> execute dbms_logmnr_d.set_tablespace(‘tbs_stream’);

PL/SQL procedure successfully completed.

创建stream user和授权:
SQL> CREATE USER strmadmin IDENTIFIED BY strmadmin
2 DEFAULT TABLESPACE tbs_stream
3 QUOTA UNLIMITED ON tbs_stream;

SQL> grant dba to strmadmin;

Grant succeeded.

SQL>
SQL>
SQL> BEGIN
2 DBMS_STREAMS_AUTH.GRANT_ADMIN_PRIVILEGE(
3 grantee => ‘strmadmin’,
4 grant_privileges => true);
END;
/ 5 6

设置tnsname

[oracle@yang admin]$ cat tnsnames.ora
# tnsnames.ora Network Configuration File: /u01/app/oracle/product/10.2.0/db_1/network/admin/tnsnames.ora
# Generated by Oracle configuration tools.

LIU =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.200)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = liu)
)
)

STANDBY =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.201)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = standby)
)
)

CXX =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = yang)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = cxx)
)
)

EXTPROC_CONNECTION_DATA =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0))
)
(CONNECT_DATA =
(SID = PLSExtProc)
(PRESENTATION = RO)
)
)

AXX =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = liu)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = axx)
)
)

设置global_names
SQL> Alter system set global_names=TRUE scope=BOTH;

设置stream需要的初始化参数:


alter system set aq_tm_processes=2 scope=both;
alter system set global_names=true scope=both;
alter system set job_queue_processes=10 scope=both;
alter system set parallel_max_servers=20 scope=both;
alter system set undo_retention=3600 scope=both;
alter system set streams_pool_size=25M scope=spfile;
alter system set utl_file_dir=’*’ scope=spfile;
alter system set open_links=4 scope=spfile;

建立dblink。
在source机:
create database link cxx connect to strmadmin identified by strmadmin using ‘cxx’;
在destination机:
create database link axx connect to strmadmin identified by strmadmin using ‘axx’;

在source数据库启用Database 追加日志
alter database add supplemental log data;

在downstream site设置:

ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_1=ENABLE SCOPE=SPFILE;

alter system set log_archive_dest_1 = ‘LOCATION=/u01/arch’ scope=both;

注意创建standby redo时,大小要和source site的redo大小一致,数量上要比source site的redo多一个。

在downstream site:

ALTER DATABASE ADD STANDBY LOGFILE GROUP 4
(‘/u01/app/oracle/oradata/cxx/stdy_redo04.log’) SIZE 150M;

ALTER DATABASE ADD STANDBY LOGFILE GROUP 5
(‘/u01/app/oracle/oradata/cxx/stdy_redo05.log’) SIZE 150M;

ALTER DATABASE ADD STANDBY LOGFILE GROUP 6
(‘/u01/app/oracle/oradata/cxx/stdy_redo06.log’) SIZE 150M;

ALTER DATABASE ADD STANDBY LOGFILE GROUP 7
(‘/u01/app/oracle/oradata/cxx/stdy_redo07.log’) SIZE 150M;

准备source site的参数:

ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_2=ENABLE SCOPE=SPFILE;

ALTER SYSTEM SET LOG_ARCHIVE_DEST_2=’SERVICE=cxx LGWR SYNC NOREGISTER
VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE)
DB_UNIQUE_NAME=cxx’
SCOPE=SPFILE;

在source site创建需要复制的schema:

SQL> create user liu identified by liu default tablespace users;

User created.

SQL> grant connect, resource, create table to liu;

Grant succeeded.

SQL>create table liu(id int);

SQL>begin

for i in 1..20001 loop
insert into liu.liu values (i);
commit;
end loop;
end;
/

PL/SQL procedure successfully completed.

在downstream site设置stream queue:

conn strmadmin/strmadmin

BEGIN
DBMS_STREAMS_ADM.SET_UP_QUEUE(
queue_table => ‘strmadmin.DOWNSTREAM_Q_TABLE’,
queue_name => ‘strmadmin.DOWNSTREAM_Q’,
queue_user => ‘STRMADMIN’);
END;
/

在downstream site创建apply进程:

conn strmadmin/strmadmin

BEGIN
DBMS_APPLY_ADM.CREATE_APPLY(
queue_name => ‘strmadmin.DOWNSTREAM_Q’,
apply_name => ‘DOWNSTREAM_APPLY’,
apply_captured => TRUE
);
END;
/

在downstream site创建capture进程:

conn strmadmin/strmadmin

BEGIN
DBMS_CAPTURE_ADM.CREATE_CAPTURE(
queue_name => ‘strmadmin.DOWNSTREAM_Q’,
capture_name => ‘DOWNSTREAM_CAPTURE’,
rule_set_name => NULL,
start_scn => NULL,
source_database => ‘axx’,
use_database_link => true,
first_scn => NULL,
logfile_assignment => ‘implicit’);
END;
/

在downstream site:

conn strmadmin/strmadmin

SQL> BEGIN
2 DBMS_CAPTURE_ADM.SET_PARAMETER(
3 capture_name => ‘DOWNSTREAM_CAPTURE’,
4 parameter => ‘downstream_real_time_mine’,
5 value => ‘y’);
6 END;
7 /

PL/SQL procedure successfully completed.

在downstream site设置rule规则:

BEGIN
DBMS_STREAMS_ADM.ADD_table_RULES(
table_name => ‘LIU.LIU’,
streams_type => ‘capture’,
streams_name => ‘downstream_capture’,
queue_name => ‘strmadmin.downstream_q’,
include_dml => true,
include_ddl => true,
include_tagged_lcr => false,
source_database => ‘axx’,
inclusion_rule => TRUE);
END;
/

导出测试表:

SQL> select DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER() from dual;

DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER()
—————————————–
618212

[oracle@liu ~]$ exp system/oracle tables=liu.liu file=liu.dump log=liu.log object_consistent=Y

Export: Release 10.2.0.1.0 – Production on Mon Dec 26 21:47:31 2011

Copyright (c) 1982, 2005, Oracle. All rights reserved.

Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 – Production
With the Partitioning, OLAP and Data Mining options
Export done in US7ASCII character set and AL16UTF16 NCHAR character set
server uses WE8ISO8859P1 character set (possible charset conversion)

About to export specified tables via Conventional Path …
Current user changed to LIU
. . exporting table LIU 20001 rows exported
Export terminated successfully without warnings.
[oracle@liu ~]$ imp system/oracle@cxx file=liu.dump full=y ignore=y STREAMS_INSTANTIATION=Y

Import: Release 10.2.0.1.0 – Production on Mon Dec 26 21:50:36 2011

Copyright (c) 1982, 2005, Oracle. All rights reserved.

Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 – Production
With the Partitioning, OLAP and Data Mining options

Export file created by EXPORT:V10.02.01 via conventional path
import done in US7ASCII character set and AL16UTF16 NCHAR character set
import server uses WE8ISO8859P1 character set (possible charset conversion)
. importing SYSTEM’s objects into SYSTEM
. importing LIU’s objects into LIU
. . importing table “LIU” 20001 rows imported
Import terminated successfully without warnings.

destination:设置apply scn

conn strmadmin/strmadmin

begin
DBMS_APPLY_ADM.SET_TABLE_INSTANTIATION_SCN(
source_object_name =>’liu.liu’,
source_database_name =>’axx’,
instantiation_scn =>618212);
end;
/

在downstream site开始启动apply进程:

conn strmadmin/strmadmin

SQL> exec DBMS_APPLY_ADM.START_APPLY(apply_name => ‘DOWNSTREAM_APPLY’);

PL/SQL procedure successfully completed.

在downstream site启动capture进程:

conn strmadmin/strmadmin

SQL> exec DBMS_CAPTURE_ADM.START_CAPTURE(capture_name => ‘DOWNSTREAM_CAPTURE’);

PL/SQL procedure successfully completed.

测试结果:

SQL> conn liu/liu
Connected.
SQL>
SQL> begin
2 for i in 1..10000 loop
3 insert into liu values (i);
4 commit;
5 end loop;
6 end;
7 /

PL/SQL procedure successfully completed.

SQL> alter system switch logfile;

[oracle@yang bdump]$ tail -f alert_cxx.log

RFS[8]: Successfully opened standby log 5: ‘/u01/app/slog5.log’
Mon Dec 26 21:53:58 2011
RFS LogMiner: Registered logfile [/u01/arch/1_30_770906800.dbf] to LogMiner session id [41]
Mon Dec 26 21:54:04 2011
LOGMINER: Archived logfile found, transition to mining logfile: /u01/arch/1_30_770906800.dbf
Mon Dec 26 21:54:04 2011
LOGMINER: End mining logfile: /u01/arch/1_30_770906800.dbf
Mon Dec 26 21:54:04 2011
LOGMINER: Begin mining logfile: /u01/app/slog5.log

SQL> select count(*) from liu;

COUNT(*)
———-
28935

SQL> /

COUNT(*)
———-
29432

SQL> /

COUNT(*)
———-
29566

SQL> /

COUNT(*)
———-
29703

SQL> /

COUNT(*)
———-
29798

SQL> /

COUNT(*)
———-
29927

SQL> /

COUNT(*)
———-
30001

SQL> /

COUNT(*)
———-
30001

复制完成

Physical-standby standbylogfile checksum error

December 23, 2011 oracle, replication No comments

总结下今天DG碰到的问题,本来一个很简单的问题,被我们复杂化衍生出很多问题。

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 – 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> show parameter check

NAME TYPE VALUE
———————————— ———– ——————————
db_block_checking string FALSE
db_block_checksum string TRUE
log_checkpoint_interval integer 0
log_checkpoint_timeout integer 1800
log_checkpoints_to_alert boolean FALSE
SQL> show parameter filesystem

通过filesystemio_options设置DIO和ASYNC模式

NAME TYPE VALUE
———————————— ———– ——————————
filesystemio_options string SETALL
SQL>

SQL>alter database recover managed standby database disconnect from session using current logfile;

以下是alert.log信息:

Thu Dec 22 18:23:57 CST 2011
Waiting for all non-current ORLs to be archived…
Media Recovery Log /data/oracle/oradata/paystd/arch/1_3_770564180.dbf
MRP0: Background Media Recovery terminated with error 368
Thu Dec 22 18:23:57 CST 2011
Errors in file /data/oracle/oradata/paystd/bdump/paystd_mrp0_2983.trc:
ORA-00368: checksum error in redo log block
ORA-00353: log corruption near block 6144 change 175261 time 12/22/2011 17:00:09
ORA-00334: archived log: ‘/data/oracle/oradata/paystd/arch/1_3_770564180.dbf’

checksum检查发现错误,同事以前是做SUN的,认为是DIO导致的,修改filesystemio_options=async,之后我也没管,今天早上来问说正常了,我检查了下依然发现问题:

Errors in file /data/oracle/oradata/paystd/udump/paystd_rfs_5428.trc:
ORA-00367: checksum error in log file header
ORA-00315: log 5 of thread 0, wrong thread # 1 in header
ORA-00312: online log 5 thread 0: ‘/data/oracle/oradata/paystd/std1.log’

改成async依然不行?

检查system 设置:

[oracle@db57 bdump]$ cat /proc/slabinfo |grep kio
kioctx 43 72 320 12 1 : tunables 54 27 8 : slabdata 6 6 0
kiocb 11 30 256 15 1 : tunables 120 60 8 : slabdata 2 2 0
[oracle@db57 bdump]$

系统没有问题 async使用正常,至此 我认为filesystemio_options并不是问题的根源,查看相关metalink文档:

Oracle Linux, Filesystem & I/O Type Supportability [ID 279069.1]

此图明确的指出了Oracle在linux5下所支持的IOtype(async sync dio) 并不会因为DG的原因所改变,在测试环境做了如下测试。


session1:

SQL> alter system set filesystemio_options = directio scope=spfile;

System altered.

SQL> shutdown abort;
ORACLE instance shut down.
SQL> startup
ORACLE instance started.

Total System Global Area 218103808 bytes
Fixed Size 1218580 bytes
Variable Size 88082412 bytes
Database Buffers 121634816 bytes
Redo Buffers 7168000 bytes
Database mounted.
Database opened.

SQL> begin
2 for i in 1..10000 loop
3 insert into t1 values (i);
4 commit;
5 end loop;
6 end;
7 /

PL/SQL procedure successfully completed.

SQL> alter system switch logfile;

System altered.

SQL> alter system checkpoint;

System altered.

SQL>
SQL>
SQL> begin
2 for i in 1..1000 loop
3 insert into t1 values (i);
4 commit;
5 end loop;
6 end;
7 /

PL/SQL procedure successfully completed.

SQL> commit;

Commit complete.

SQL>
SQL>
SQL> alter system checkpoint;

System altered.

SQL>

session2:

[root@liu u01]# strace -o /u01/dbwn.log -p 18671
Process 18671 attached – interrupt to quit

pwrite64(20, “\6\242\0\0\323\21@\0\321\350\24\0\0\0\1\6\345v\0\0\2\0\’\0@\2\0\0\320\350\24\0″…, 8192, 37380096) = 8192
times(NULL) = 431759580
times(NULL) = 431759580
pwrite64(20, “\6\242\0\0\326\21@\0\321\350\24\0\0\0\1\6\31g\0\0\2\0\0\0@\2\0\0\320\350\24\0″…, 8192, 37404672) = 8192
times(NULL) = 431759581
times(NULL) = 431759581
pwrite64(20, “\6\242\0\0\333\21@\0\321\350\24\0\0\0\1\6\3624\0\0\2\0\0\0A\2\0\0\320\350\24\0″…, 8192, 37445632) = 8192
times(NULL) = 431759581
times(NULL) = 431759581
pwrite64(20, “\6\242\0\0\336\21@\0\321\350\24\0\0\0\1\6\302\221\0\0\2\0\0\0A\2\0\0\320\350\24\0″…, 8192, 37470208) = 8192
times(NULL) = 431759581
times(NULL) = 431759581
pwrite64(20, “\6\242\0\0\”+@\0\300\343\24\0\0\0\1\6\2358\0\0\1\0\0\0\351\23\0\0\277\343\24\0″…, 8192, 90456064) = 8192
times(NULL) = 431759581
times(NULL) = 431759581
pwrite64(20, “\6\242\0\0002+@\0\300\343\24\0\0\0\1\6|Z\0\0\2\0\5\0\353\23\0\0\277\343\24\0″…, 8192, 90587136) = 8192

证明了此观点。OK 那么这种现象只能定义为block corrupt–>对应 checksum error in redo log block,这么简单的现象,因为一个filesystemio设置,引申出如此多的疑虑。

解决方法:clear or drop logfile;

我们采取 clear logfile的方法:

SQL> alter database clear logfile ‘/data/oracle/oradata/paystd/std5.log’
Clearing online log 9 of thread 0 sequence number 0
Completed: alter database clear logfile ‘/data/oracle/oradata/paystd/std5.log’

SQL> alter system set filesystemio_options=setall scope=spfile;

System altered.

SQL> shutdown abort;
ORACLE instance shut down.
SQL> startup mount;
ORACLE instance started.

Total System Global Area 1.2885E+10 bytes
Fixed Size 2118256 bytes
Variable Size 1744833936 bytes
Database Buffers 1.1123E+10 bytes
Redo Buffers 14655488 bytes
Database mounted.
SQL> alter database recover managed standby database disconnect from session using current logfile;

Database altered.

SQL>

查看alert:

Recovery of Online Redo Log: Thread 1 Group 5 Seq 44 Reading mem 0
Mem# 0: /data/oracle/oradata/paystd/std1.log
Fri Dec 23 12:52:09 CST 2011
Completed: ALTER DATABASE RECOVER managed standby database using current logfile disconnect
Redo Shipping Client Connected as PUBLIC
— Connected User is Valid
RFS[2]: Assigned to RFS process 5942
RFS[2]: Identified database type as ‘physical standby’
Primary database is in MAXIMUM PERFORMANCE mode
Primary database is in MAXIMUM PERFORMANCE mode
RFS[2]: Successfully opened standby log 6: ‘/data/oracle/oradata/paystd/std2.log’
Fri Dec 23 13:31:15 CST 2011
RFS[1]: Successfully opened standby log 5: ‘/data/oracle/oradata/paystd/std1.log’
Fri Dec 23 13:31:16 CST 2011
Media Recovery Waiting for thread 1 sequence 45 (in transit)
Fri Dec 23 13:31:16 CST 2011
Recovery of Online Redo Log: Thread 1 Group 6 Seq 45 Reading mem 0
Mem# 0: /data/oracle/oradata/paystd/std2.log

APPLY 正常 问题解决

总结: 一个比较简单的问题,因为同事的一句话:设置filesystemio为ASYNC解决了,导致后面一连串的认证工作,以至于怀疑DG是否允许DIO特性,看来自己对待问题的态度还不够严谨,但是由此延伸到filesystemio问题也不失为一件好事,以此记之。

Physical standby ORA-01274

December 16, 2011 oracle, replication No comments

今天新上线的系统物理备库出现以下错误:

[oracle@db-15 ~]$ sqlplus ‘/as sysdba’

SQL*Plus: Release 10.2.0.5.0 – Production on Fri Dec 16 20:37:38 2011

Copyright (c) 1982, 2010, Oracle. All Rights Reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 – 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL>

查看alertlog 发现

ORA-01274: cannot add datafile ‘+DATA/item/datafile/undotbs3.dbf’ – file could not be created
Fri Dec 16 11:33:37 CST 2011
alter database recover managed standby database cancel
Fri Dec 16 11:33:37 CST 2011
MRP0: Background Media Recovery cancelled with status 16037
Fri Dec 16 11:33:37 CST 2011
Errors in file /home/oracle/admin/item/bdump/item_mrp0_13039.trc:
ORA-16037: user requested cancel of managed recovery operation
Managed Standby Recovery not using Real Time Apply
Recovery interrupted!
Some recovered datafiles maybe left media fuzzy
Media recovery may continue but open resetlogs may fail
Fri Dec 16 11:33:39 CST 2011
Errors in file /home/oracle/admin/item/bdump/item_mrp0_13039.trc:
ORA-16037: user requested cancel of managed recovery operation
Fri Dec 16 11:33:39 CST 2011
MRP0: Background Media Recovery process shutdown (item)
Fri Dec 16 11:33:39 CST 2011

查看操作日志发现主库在早上添加过undotbs datafile;

Managed Standby Recovery not using Real Time Apply
Fri Dec 16 11:17:46 CST 2011
Errors in file /home/oracle/admin/item/bdump/item_mrp0_12997.trc:
ORA-01111: name for data file 21 is unknown – rename to correct file
ORA-01110: data file 21: ‘/data/oracle/product/10205/db1/dbs/UNNAMED00021’
ORA-01157: cannot identify/lock data file 21 – see DBWR trace file
ORA-01111: name for data file 21 is unknown – rename to correct file
ORA-01110: data file 21: ‘/data/oracle/product/10205/db1/dbs/UNNAMED00021’

ORA-01110: data file 21: ‘/data/oracle/product/10205/db1/dbs/UNNAMED00021’

出现了convert转换错误,查看备库发现standby_file_managemtn=manual;

File #22 added to control file as ‘UNNAMED00021’ because
the parameter STANDBY_FILE_MANAGEMENT is set to MANUAL
The file should be manually created to continue.
MRP0: Background Media Recovery terminated with error 1274

处理方法:

SQL> alter system set standby_file_management=MANUAL;

System altered.

alter database create datafile ‘/data/oracle/product/10205/db1/dbs/UNNAMED00021’ as ‘/data/f-io/disk0/data/oracle/oradata/item/undotbs3.dbf’ size 10240M
Database altered.

SQL> alter system set standby_file_management=auto scope=both;

System altered.

这里的10240M 要对应主库的undo datafile size

继续开启redo apply

SQL> alter database recover managed standby database disconnect from session using current logfile;

Database altered.

SQL> select * from v$dataguard_stats;

NAME VALUE UNIT TIME_COMPUTED
—————————— —————————— —————————— ————————–
apply finish time +00 00:00:02.6 day(2) to second(1) interval 16-DEC-2011 20:58:48
apply lag +00 00:00:16 day(2) to second(0) interval 16-DEC-2011 20:58:48
estimated startup time 11 second 16-DEC-2011 20:58:48
standby has been open N 16-DEC-2011 20:58:48
transport lag +00 00:00:06 day(2) to second(0) interval 16-DEC-2011 20:58:48

后续日志apply 正常

ORA-01555 on Active Physical standby and patchset issue without Central Inventory

December 7, 2011 maintain, oracle, replication 2 comments

今天在生产库解决一个ORA-01555 on Active Physical standby问题:
Applies to:

Oracle Server – Enterprise Edition – Version: 11.2.0.2.0 and later [Release: 11.2 and later ]
Information in this document applies to any platform.
Primary and Standby databases at 11.2.0.2
Symptoms

After upgrading to 11.2.0.2 we see this ORA-1555 on the Standby Database. It is not possible to logon with system, dbsnmp or other db-users. Only sys as sysdba is working.
It’s like we are running on system’s undo Tablespace, – and not the one which has been restored..

查看系统alert日志发现:
ORA-01555 caused by SQL statement below (SQL ID: 1f9apznp767fc, Query Duration=0 sec, SCN: 0x0006.62ab3687):
select object_name synonym_name, object_name, owner object_owner, status, object_type
from sys.all_objects o
where o.owner = object_owner
and o.object_type in (‘TABLE’, ‘VIEW’, ‘MATERIALIZED VIEW’, ‘SEQUENCE’, ‘FUNCTION’, ‘PROCEDURE’, ‘PACKAGE’, ‘TYPE’)
and o.object_name not like ‘BIN$%’

order by o.object_type, o.object_name

一个简单的查询 都导致了ora-01555 undo回滚段出现严重问题,同时出现如下问题:

ORA-00313: open failed for members of log group 15 of thread 1
ORA-00312: online log 15 thread 1: ‘/data/oracle/oradata/edw1/redo15.log’
ORA-27037: unable to obtain file status

客户端报如下错误:

同时发现mutex 等待 以及大量library cache lock 等待

通过查找metalink 发现与以下描述极其相似

This problem is introduced in 11.2.0.2 by the fix for bug 9214531

A self-hang / spin can occur when getting a library cache lock
leading to a wider hang scenario with other sessions waiting
for the blocked lock.

Rediscovery Notes:
A process spins in kglLock(),
other processes waiting for the spinning session
ORA-1555 on Active data Guard

解决方案:通过打p10018789_112020_Linux-x86-64解决此问题

打patch 过程过遇到很多问题,下面一一阐述:

opatch lsinventory raise error code 104

OPatch cannot find a valid oraInst.loc file to locate Central Inventory.
OPatch failed with error code 104

通过了解发现此RDBMS是通过tar包过来直接relink的,缺少全局的 Inventory 所以我们需要手动创建Inventory
首先要编辑一个oraInst.loc文件,使之指向我们要创建全局inventory的目录

inventory_loc=/data/oracle/oraInventory
inst_group=oinstall

cd $ORACLE_HOME/oui/bin
./runInstaller -silent -ignoreSysPrereqs -attachHome ORACLE_HOME=”” ORACLE_HOME_NAME=”

我们这里采用的是 ./runInstaller -silent -ignoreSysPrereqs -attachHome ORACLE_HOME=”/data/oracle/product/11.2.0/db1″ ORACLE_HOME_NAME=”oracle11g”

The inventory pointer is located at /etc/oraInst.loc

The inventory is located at /data/oracle/oraInventory

‘AttachHome’ was successful.

针对rac的Inventory重建 我们需要指定crs_home 和oracle_home

./runInstaller -silent -ignoreSysPrereqs -attachHome ORACLE_HOME=”<10g Ora_Crs_Home Path>” ORACLE_HOME_NAME=”” LOCAL_NODE=’node1′ CLUSTER_NODES=node1,node2 CRS=true

./runInstaller -silent -ignoreSysPrereqs -attachHome ORACLE_HOME=”<10g Oracle_Home Path>” ORACLE_HOME_NAME=”” LOCAL_NODE=’node1′ CLUSTER_NODES=node1,node2

下面的过程就显得很简单了:

解压缩补丁文件

unzip p10018789_112020_Linux-x86-64.zip

重新生成oraInventory

./runInstaller -silent -ignoreSysPrereqs -attachHome ORACLE_HOME=”/data/oracle/product/11.2.0/db1″ ORACLE_HOME_NAME=”oracle11g”

设置环境变量

export PATH=$ORACLE_HOME/OPatch:$PATH

停止redo apply

alter database recover managed standby database cancel;

关闭数据库

shutdownn immediate

打补丁

cd 10018789

opatch apply

打开数据库并开始redo应用

startup mount

alter database open read only

alter database recover managed standby database disconnect from session using current logfile;

观察日志 发现问题解决

关于 Logic standby 的相关操作

December 4, 2011 oracle, replication No comments

一. 确认操作的对象和语句是否能被逻辑Standby支持

1.1 由于逻辑Standby是通过SQL应用来保持与Primary数据库的同步。SQL应用与REDO应用是有很大的区别,REDO应用实际上是在物理Standby端进行RECOVER;SQL应用则是分析重做日志文件中的REDO信息,并将其转换为SQL语句,在逻辑Standby端执行,因此,需要注意以下几点:

(1)并非所有的数据类型都能被逻辑Standby支持,
逻辑Standby支持的数据类型有:
BINARY_DOUBLE、BINARY_FLOAT、BLOB、CHAR、CLOB and NCLOB、 DATE、INTERVAL YEAR TO MONTH、INTERVAL DAY TO SECOND、 LONG、LONG RAW、NCHAR、NUMBER、NVARCHAR2、RAW、TIMESTAMP、
TIMESTAMP WITH LOCAL TIMEZONE、TIMESTAMP WITH TIMEZONE、VARCHAR2 and VARCHAR

说明:下列类型在获取Standby支持时需要注意兼容性:
CLOB,需要Primary数据库的兼容级别运行于10.1或更高。
含LOB字段的索引组织表(IOT),需要Primary数据库的兼容级别运行于10.2或更高。
不含LOB字段的索引组织表(IOT),需要Primary数据库的兼容级别运行于10.1或更高。

不支持的数据类型有:
BFILE、Encrypted Columns、ROWID, UROWID、XMLType、对象类型、VARRAYS、嵌套表、自定义类型。

也可以通过查询DBA_LOGSTDBY_UNSUPPORTED来确定主数据库中是否含有不支持的对象
SQL> select * from dba_logstdby_unsupported;
注意:该视图的ATTRIBUTES列,显示对象不被SQL应用支持的原因。

(2)并非所有的存储类型都能被逻辑Standby支持。
逻辑Standby能够支持簇表(Cluster Tables)、索引组织表(Index-Organized Tables)、堆组织表(Heap-Organized Tables),但不支持段压缩(Segment Compression)存储类型。

(3)并非所有的PL/SQL包都能被SQL应用支持。
通常那些不会修改系统元数据(Metadata)的Package在实际应用时不会有问题,如DBMS_OUTPUT、DBMS_RANDOM、DBMS_METADATA之类的包。
那些可能修改系统元数据的Package不会被SQL应用支持,即使它们在Primary执行过,并且被成功传输到逻辑Standby端,也不会执行。如DBMS_JAVA、DBMS_REGISTRY、DBMS_ALERT、DBMS_SPACE_ADMIN、DBMS_REFRESH、DBMS_REDEFINITION、DBMS_SCHEDULER及DBMS_AQ等。只有DBMS_JOB例外,Primary数据库的jobs会被复制到逻辑Standby,不过在逻辑Standby数据库不会执行这些job。

说明:元数据,直接理解成对象的物理定义。举例来说,对于某表而言,元数据就是表结构,或表的存储属性等。

(4)并非所有的SQL语句都能在逻辑Standby端执行。
在默认情况下,下列SQL语句在逻辑Standby端会被SQL应用自动跳过:
ALTER DATABASE。
ALTER MATERIALIZED VIEW。
ALTER MATERIALIZED VIEW LOG。
ALTER SESSION。
ALTER SYSTEM。
CREATE CONTROL FILE。
CREATE DATABASE。
CREATE DATABASE LINK。
CREATE PFILE FROM SPFILE。
CREATE MATERIALIZED VIEW。
CREATE MATERIALIZED VIEW LOG。
CREATE SCHEMA AUTHORIZATION。
CREATE SPFILE FROM PFILE。
DROP DATABASE LINK。
DROP MATERIALIZED VIEW。
DROP MATERIALIZED VIEW LOG。
EXPLAIN。
LOCK TABLE。
SET CONSTRAINTS。
SET ROLE。
SET TRANSACTION。

另外,由于SQL语句非常灵活,即使是那些能被SQL应用支持的DDL语句,可能在附加了某些特别的参数后,也不会在逻辑Standby端执行,由于数目较多,此处不再一一列举,感兴趣的话请查阅官方文档。

(5)并非所有的DML操作都能在逻辑Standby端实面SQL应用。
维护逻辑Standby与Primary的数据库同步是通过SQL应用实现,SQL应用转换的SQL语句在执行时,对于INSERT还好说,对于UPDATE、DELETE操作则必须能够唯一定位到数据库待更新的那条记录。问题就在这里,如果Primary库中表设置不当,可能就无法确认唯一条件。
你可能会说可以通过ROWID唯一嘛!千万要谨记啊,逻辑Standby,为啥叫逻辑Standby,就是因为它只是逻辑上与Primary数据库相同,物理上可能与Primary数据库存在相当大差异。一定要认识到,逻辑Standby的物理结构与Primary是不相同的(即使初始逻辑Standby是通过Primary的备份创建)。
因此想通过ROWID更新显然是不好使的,当然也就不能再将其作为唯一条件。下面来看这个问题。

1.2 确保Primary库中各表的行可被唯一标识
Oracle通过主键、唯一索引/约束的补充日志(Supplemental Logging)来确定待更新逻辑Standby数据库中的行。当数据库启用了补充日志,每一条UPDATE语句写REDO的时候会附加列值唯一信息,比如:
如果表定义了主键,则主键列会随同被更新列一起作为UPDATE语句的一部分,以便执行时区分哪些列应该被更新。
如果没有主键,则非空的唯一索引/约束会随同被更新列作为UPDATE语句的一部分,以便执行时区分哪些列应该被更新,如果该表有多个唯一索引/约束,则Oracle自动选择长度最短的那个,以降低生成的重做日志大小。
如果表既无主键,也没有定义唯一索引/约束,所有可定长度的列,连同被更新列同时作为UPDATE语句的一部分。更明确些,可定长度的列是指除LONG、LOB、LONG RAW、OBJECT TYPE、COLLECTION类型外的列。
Oracle 建议你为表创建一个主键或非空的唯一索引/约束,以尽可能确保SQL应用能够有效应用REDO数据,更新逻辑Standby数据库。

下列语句可以用来检查SQL应用能否唯一识别表列,并找出不被支持的表:
SQL> SELECT OWNER, TABLE_NAME FROM DBA_LOGSTDBY_NOT_UNIQUE WHERE (OWNER, TABLE_N
AME) NOT IN (SELECT DISTINCT OWNER, TABLE_NAME FROM DBA_LOGSTDBY_UNSUPPORTED)
AND BAD_COLUMN = ‘Y’;

OWNER TABLE_NAME
—– —————
TSMSY SRS$

提 示: 关于DBA_LOGSTDBY_NOT_UNIQUE, 该视图显示所有既没主键也没唯一索引的表。如果表中的列包括足够多的信息,通常也可支持在逻辑Standby端的更新,不被支持的表通常是由于列的定义包含了不支持的数据类型。

注意BAD_COLUMN列值,该列有两个值:
Y:表示该表中有采用大数据类型的字段,比如LONG、CLOB。如果表中除LOG列某些行记录完全匹配,则该表无法成功应用于逻辑Standby。Standby会尝试维护这些表,不过你必须保证应用不允许。
N:表示该表拥有足够的信息,能够支持在逻辑Standby的更新,不过仍然建议你为该表创建一个主键或者唯一索引/约束,以提高LOG应用效率。

假设在某张表中你可以确认数据是唯一的,但是基于效率方面的考虑,不想为其创建主键或唯一约束,怎么办呢?没关系,Oracle早想到了这一点,你可以创建一个DISABLE的Primary-Key Rely约束:

提 示: 关于Primary-Key Rely约束。
如果DBA能够确认表中的行是唯一的,那么可以为该表创建Rely的主键,Rely约束并不会造成系统维护主键的开销,如你对一个表创建了RELY约束,系统则会假定该表中的行是唯一的,这样能够提高SQL应用时的性能。但是需要注意,由于Rely的主键约束只是假定唯一,如果实际并不唯一的话,有可能会造成错误的更新哟。
创建Rely的主键约束非常简单,只要在标准的创建语句后加上RELY DISABLE即可,例如:
SQL> ALTER TABLE USER ADD PRIMARY KEY (ID) RELY DISABLE;
表已更改。

注 意: 创建了Rely约束后,Oracle会假定该列是唯一的(给DBA足够的信任),不过并不会对该列的值进行唯一性的验证,因此该列是否唯一只能由DBA来主动维护。

二. 管理逻辑Standby的相关视图
1.DBA_LOGSTDBY_EVENTS
可以把该视图看成逻辑Standby操作日志,因此如果发生了错误,可以通过该视图查看近期逻辑Standby都做了些什么。默认情况下,该视图只保留最近100条事件的记录(可以通过相关过程修改保存的记录条数)。
例如:
SQL> SELECT EVENT_TIME,STATUS,EVENT FROM DBA_LOGSTDBY_EVENTS
ORDER BY EVENT_TIMESTAMP;
EVENT_TIM STATUS EVENT
——— ————————————————– ——————-
05-MAY-10 ORA-16111: log mining and apply setting up
05-MAY-10 ORA-16257: Switchover initiated stop apply success

2.DBA_LOGSTDBY_LOG
该视图用来记录当前的重做日志的应用情况,功能类似于物理Standby中的V$ARCHIVED_LOG。
多数情况下,你只需要关注SEQUENCE#、APPLIED等有限的几个列,即查看日志序号和是否应用,当然该视图还能提供更多信息,如应用的SCN、应用时间等,例如:
SQL> SELECT SEQUENCE#,FIRST_CHANGE#,NEXT_CHANGE#,
TIMESTAMP,APPLIED FROM DBA_LOGSTDBY_LOG;
SEQUENCE# FIRST_CHANGE# NEXT_CHANGE# TIMESTAMP APPLIED
———- ————- ———— ——— ——–
110 572160 572171 05-MAY-10 CURRENT
111 572171 572175 05-MAY-10 NO

通常情况下,该查询只会返回几条记录,如果说你的数据库操作非常频繁,可能记录数会稍多一些,但如果记录数非常多,那你就需要关注一下,是不是出了什么问题,难道SQL应用没有启动?

3.V$LOGSTDBY_STATS
该视图就是用来显示LogMiner的状态等相关信息,例如:
SQL> SELECT *FROM V$LOGSTDBY_STATS;
NAME VALUE
—————————— ————————————————-
number of preparers 1
number of appliers 5
maximum SGA for LCR cache 30
parallel servers in use 9
maximum events recorded 100
preserve commit order TRUE
transaction consistency FULL
record skip errors Y
record skip DDL Y
record applied DDL N
record unsupported operations N

4.V$LOGSTDBY_PROCESS
该视图显示当前日志应用服务的相关信息。常用于诊断归档日志逻辑应用的性能问题(后面优化部分会涉及),包含的信息也很广,包括:
身份信息:SID、SERIAL#、SPID。
SQL应用进程:COORDINATOR、READER、BUILDER、PREPARER、ANALYZER、或APPLIER。
进程当前的状态:见STATUS_CODE或STATUS列。
该进程当前操作REDO记录最大SCN:HIGH_SCN列。
例如:
SQL> SELECT SID,SERIAL#,SPID,TYPE,STATUS,HIGH_SCN FROM V$LOGSTDBY_PROCESS;
SID SERIAL# SPID TYPE STATUS
———- ———- ———— ————— —————————–
139 303 6831 COORDINATOR ORA-16116: no work available
153 292 6833 READER ORA-16240: Waiting for logfil
136 5 6835 BUILDER ORA-16116: no work available
137 5 6837 PREPARER ORA-16116: no work available
128 1 6841 ANALYZER ORA-16116: no work available
132 1 6843 APPLIER ORA-16116: no work available
133 2 6845 APPLIER ORA-16116: no work available
130 1 6847 APPLIER ORA-16116: no work available
129 1 6849 APPLIER ORA-16116: no work available
131 1 6851 APPLIER ORA-16116: no work available

5.V$LOGSTDBY_PROGRESS
该视图显示LOG应用服务当前进展状况,如当前应用到逻辑Standby的SCN及时间,SQL应用开始应用的SCN及时间,最后接收及应用的SCN和时间等。

例如,查看当前应用的SCN信息:
SQL> SELECT APPLIED_SCN, LATEST_SCN, MINING_SCN, RESTART_SCN FROM V$LOGSTDBY_PROGRESS;

APPLIED_SCN LATEST_SCN MINING_SCN RESTART_SCN
———– ———- ———- ———–
572164 572232 572166

6.V$LOGSTDBY_STATE
该视图显示SQL应用的大致状态,如Primary数据库的DBID,是否实时应用,当前SQL应用的状态。需要注意的是该视图的STATE列,该列可能有下述的几种状态。应用日志的过程,也是这几种状态相互转换的过程。

1) INITIALIZING初始化状态。
执行ALTER DATABASE START LOGICAL STANDBY APPLY语句,启动SQL应用时,首先就会进入初始化状态,例如:
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;
Database altered.
SQL> SELECT SESSION_ID, STATE FROM V$LOGSTDBY_STATE;
SESSION_ID STATE
———- ——————————
21 INITIALIZING
这个状态存在的时间非常短暂,多数情况下只有当ALTER DATABASE START LOGICAL STANDBY APPLY执行时查看V$LOGSTDBY_STATE视图,会看到初始化状态,一旦该命令执行完,状态就被切换为等待字典日志或应用中的状态了。

2) WAITING FOR DICTIONARY LOGS等待数据字典日志。
指第一次初始化时的状态,如刚从物理Standby转换成逻辑Standby,需要首先应用来自Primary端生成的数据字典,在等待Primary数据字典信息时,就会处于这一状态。例如:
SQL> SELECT SESSION_ID, STATE FROM V$LOGSTDBY_STATE;
SESSION_ID STATE
———- ——————————
21 WAITING FOR DICTIONARY LOGS
这个过程也非常短暂。

3) LOADING DICTIONARY加载并分析。
当查询V$LOGSTDBY_STATE视图,显示下列状态时,说明处于加载数据字典的状态:
SQL> SELECT SESSION_ID, STATE FROM V$LOGSTDBY_STATE;
SESSION_ID STATE
———- ——————————
21 LOADING DICTIONARY

对于比较大型的数据库系统,加载数据字典需要一些时间。此时还可以查询V$lOGMNR_DICTIONARY_LOAD视图获取关于加载的更详细的信息,例如:

SQL>SELECT PERCENT_DONE, COMMAND FROM V$LOGMNR_DICTIONARY_LOAD
WHERE SESSION_ID =(SELECT SESSION_ID FROM V$LOGSTDBY_STATE);
APPLYING应用REDO数据。
SQL应用正在处理中,如果要查看当前的处理进度,可以通过V$LOGSTDBY_PROGRESS视图完成。

4) WAITING ON GAP中断等待状态。
SQL应用挖掘并应用了所有可用的REDO数据,正等待新的日志文件,也有可能是由于归档文件有中断造成的。如果查询V$LOGSTDBY_STATE视图时发现处于这一状态,应该同时查询V$ARCHIVE_GAP视图,检查是否有中断的归档。

5) IDLE空闲状态。
处于这一状态也有可能不是好现象,一方面可能是逻辑Standby处理能力优秀,所有活都干完了;也可能是Primary数据库发送日志或逻辑Standby日志出现了问题,导致SQL应用无活可干,因此处于空闲状态。
如果你发现你的逻辑Standby数据库长期处于这一状态,建议查询DBA_LOGSTDBY_LOG视图,确认Primary端产生的日志文件能被逻辑Standby数据库正常接收。

6) SQL APPLY NOT ON。
如果你查询V$LOGSTDBY_STATE视图时发现提示这一状态,说明逻辑Standby数据库根本没启动SQL应用。

三.逻辑Standby数据库的自定义配置
3.1 取消自动删除归档文件
逻辑Standby应用完归档后会自动删除该归档文件,这一极具体贴意味的特性,是由逻辑Standby中的一项参数控制的,如果希望禁用自动删除的功能,可以执行下列语句:
SQL> EXEC DBMS_LOGSTDBY.APPLY_SET(‘LOG_AUTO_DELETE’, ‘FALSE’);
PL/SQL procedure successfully completed.

在某些情况下确实需要禁用归档文件的自动删除功能,如逻辑Standby需要执行Flashback Database操作,如果你想恢复到之前的某个时间点,然后再接着应用,就必须要有该时间点后对应的归档,假如LOG_AUTO_DELETE为TRUE的话,应用过的归档已经被删除,想回都回不去。

提 示: 如何知道当前逻辑Standby的参数设置呢?Oracle专门提供了一个数据字典DBA_LOGSTDBY_PARAMETERS,用于查询逻辑Standby当前的参数,例如:
SQL> SELECT * FROM DBA_LOGSTDBY_PARAMETERS;

NAME VALUE
—————————— ————————————————-
FIRST_SCN 580428
PREP_DICT_RECEIVED
PRIMARY 3409053734
LMNR_SID 1
GUARD_STANDBY READY
LOG_AUTO_DELETE FALSE
APPLY_SCN 581410

需要注意的是,如果禁止了Standby归档文件的自动删除功能,一定要有相应的其他解决方案,不能说取消了自动删除功能,之后逻辑Standby数据库接收到的Standby归档文件就不再管它,这肯定会产生问题,最起码要考虑到逻辑Standby数据库的存储空间是有限的。

逻辑Standby数据库接收到的归档文件并不会显示在V$ARCHIVED_LOG视图中,因此以为通过RMAN中的配置自动删除这些文件的希望也是会落空的。对于这类文件的删除,正确的删除方法通常会按照如下步骤操作:
首先执行DBMS_LOGSTDBY.PURGE_SESSION,该过程会检查当前所有接收到的归档日志文件,对于那些已经应用过,不再需要的文件进行标记,例如:
SQL> EXECUTE DBMS_LOGSTDBY.PURGE_SESSION;
PL/SQL procedure successfully completed.

然后,查询数据字典DBA_LOGMNR_PURGED_LOG,所有被DBMS_LOGSTDBY. PURGE_SESSION标记不再需要的日志都会记录在这里,例如:
SQL>SELECT * FROM DBA_LOGMNR_PURGED_LOG;
FILE_NAME
————————————————-
/U01/STD/ARC00109_0680477835.001
该字典只有一列,即归档文件的实际路径。最后根据显示的路径找到这些文件,然后在操作系统中删除即可。

3.2 启动实时应用
在默认情况下,逻辑Standby会等待单个归档文件全部接收之后再启动REDO应用,如果Standby数据库配置了Standby Redologs,就可以打开实时应用(Real-Time Apply),这样逻辑Standby端就不再需要等待接收完归档文件,只要有REDO数据写入本地的Standby Redologs,即可通过相应的进程实时写向逻辑Standby数据库。
启动逻辑Standby数据库的实时应用非常简单,只需要在逻辑Standby启动SQL应用时加上IMMEDIATE子句即可,例如:
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;
Database altered.

3.3 定义DBA_LOGSTDBY_EVENTS记录的事件
要查看逻辑Standby执行REDO应用时的操作信息,一般有两种方式:
一种是查看Oracle数据库的警告日志文件Alert(当然该文件不仅仅包括REDO应用的信息),
另一种是直接查询数据字典DBA_LOGSTDBY_EVENTS。

如果只是想查看日志应用信息的话,数据字典DBA_LOGSTDBY_EVENTS实用性更高,毕竟术业有专攻嘛。不过默认情况下该字典中只保留最近的100条消息(可以通过V$LOGSTDBY_STATS视图查看保留的记录数),这个数量过于偏小,如果要修改该字典中记录的事件数量,也是通过DBMS_LOGSTDBY.APPLY_SET过程完成。例如,设置该字典保留最近999条事件,执行语句如下:
JSSLDG> EXEC DBMS_LOGSTDBY.APPLY_SET(‘MAX_EVENTS_RECORDED’,’999′);
PL/SQL procedure successfully completed.

注 意: 执行DBMS_LOGSTDBY.APPLY_SET过程时,REDO应用必须处于停止状态。
SQL> alter database stop logical standby apply;
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;

另外,还可以通过DBMS_LOGSTDBY.APPLY_SET过程设置是否记录DDL应用的事件,例如:
SQL> EXEC DBMS_LOGSTDBY.APPLY_SET(‘RECORD_APPLIED_DDL’,’TRUE’);
PL/SQL procedure successfully completed.

注:该过程同样要停REDO.

然后启动REDO应用,查看当前的最大保存记录数及是否记录DDL应用的事件:
SQL>ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;
Database altered.
SQL> select * from v$logstdby_stats where name in (‘maximum events recorded’,’record applied DDL’);

NAME VALUE
—————————— ————————————————-
maximum events recorded 999
record applied DDL N

四.修改逻辑Standby端数据
相对物理Standby,逻辑Standby的管理要复杂一点点。这个就是管理一个半数据库和管理两个数据库的差异(假设Data Guard环境为一主一备的情况下),毕竟逻辑Standby只是逻辑上,仿佛与Primary数据库一致,其实它是一个独立运行的,甚至可能与Primary数据库完全不同的数据库系统,对于这种配置环境,管理上多花点工夫想想也是应该的。

4.1 指定对象跳过应用
在默认情况下,接收自Primary的REDO数据中,所有能够被逻辑Standby数据库支持的操作都会在逻辑Standby端执行。如果你希望跳过对某些对象的某些操作的话,DBMS_LOGSTDBY.SKIP就能派上用场了。

先来看看DBMS_LOGSTDBY.SKIP的语法:
DBMS_LOGSTDBY.SKIP (
stmt IN VARCHAR2,
schema_name IN VARCHAR2 DEFAULT NULL,
object_name IN VARCHAR2 DEFAULT NULL,
proc_name IN VARCHAR2 DEFAULT NULL,
use_like IN BOOLEAN DEFAULT TRUE,
esc IN CHAR1 DEFAULT NULL);
除stmt外,其他都是可选参数,并且看字面意义就能明白其所指。例如,你想跳过SCOTT用户下对dept表的DML操作,可以通过执行下列语句实现(执行该过程前需要先停止REDO应用):
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;
Database altered.
SQL> EXEC DBMS_LOGSTDBY.SKIP(‘DML’, ‘SCOTT’, ‘DEPT’);
PL/SQL procedure successfully completed.
SQL>ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;
Database altered.

4.2 恢复对象同步
如果逻辑Standby中的某些表取消了与Primary的同步维护,现在希望再恢复同步,没问题,DBMS_LOGSTDBY家大业大,它还有个叫UNSKIP的门生专干这个。
我们来看一下DBMS_LOGSTDBY.UNSKIP的语法:
DBMS_LOGSTDBY.UNSKIP (
stmt IN VARCHAR2,
schema_name IN VARCHAR2,
object_name IN VARCHAR2);
三项均为必选参数,各参数的定义与SKIP过程相同。

下面演示恢复tmp1表的同步。
首先查看当前逻辑Standby都有哪些对象处于不同步状态,可以通过DBA_LOGSTDBY_SKIP视图查看,例如:
SQL> select * from dba_logstdby_skip;
ERROR STATEMENT_OPT OWNER NAME U E PROC
—– —————————— ———- —– – – ———-
N DML SCOTT DEPT Y
N INTERNAL SCHEMA SYSTEM % Y
N INTERNAL SCHEMA SYS % Y
N INTERNAL SCHEMA OLAPSYS % Y
N INTERNAL SCHEMA SI_INFORMT % Y
N INTERNAL SCHEMA MGMT_VIEW % Y
N INTERNAL SCHEMA ORDPLUGINS % Y
N INTERNAL SCHEMA XDB % Y
N INTERNAL SCHEMA SYSMAN % Y
N INTERNAL SCHEMA WMSYS % Y
N INTERNAL SCHEMA DBSNMP % Y

注意在执行DBMS_LOGSTDBY.UNSKIP过程前,要停止当前的SQL应用状态:
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;
Database altered.
执行DBMS_LOGSTDBY.UNSKIP过程,恢复前面停止的scott.tmp1表的应用:
SQL> execute dbms_logstdby.unskip(‘DML’, ‘SCOTT’, ‘dept’);
PL/SQL procedure successfully completed.

4.3 添加或重建对象
指定对象跳过应用虽然被取消,但是有可能在此期间由于Primary数据库做过数据修改,两端此时已经不同步,如果Standby端继续应用极有可能导致应用错误的数据。
对于这类情况,Oracle也早有预见,DBMS_LOGSTDBY包中还有一个过程叫INSTANTIATE_TABLE,专门用来同步一下跳过的对象,以保持与Primary数据库的一致。

DBMS_LOGSTDBY.INSTANTIATE_TABLE的调用语法如下:
DBMS_LOGSTDBY.INSTANTIATE_TABLE (
schema_name IN VARCHAR2,
table_name IN VARCHAR2,
dblink IN VARCHAR2);
除了SCHEMA名称和表名称外,还需要提供一个数据库链,因此这里我们首先在逻辑Standby端创建一个连接Primary数据库的数据库链:
SQL> CREATE DATABASE LINK PRE_TBL_DATA CONNECT TO SYSTEM IDENTIFIED BY ADMIN
USING ‘ORCL_PD’;
Database link created.
执行使用DBMS_LOGSTDBY.INSTANTIATE_TABLE过程,重新同步SCOTT.TMP1表(注意执行该过程前别忘了暂停当前的SQL应用):
SQL>EXEC DBMS_LOGSTDBY.INSTANTIATE_TABLE(‘SCOTT’, ‘DEPT’, ‘PRE_TBL_DATA’);
PL/SQL procedure successfully completed.
SQL> SELECT * FROM SCOTT.DEPT;

对象已被重建,然后重新启动SQL应用即可:
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;
Database altered.

4.4 逻辑Standby端修改数据
逻辑Standby的一个极具实用价值的特性就是可以边查询边应用,因此将其作为报表服务器专供查询是个很不错的想法,而且逻辑Standby相对于物理Standby而言更具灵活性,如我们可以在逻辑Standby上,对一些表创建Primary数据库并不方便创建的索引、约束,甚至可以做DML/DDL操作(当然,需要注意不要破坏了与Primary数据库之间同步的逻辑关系)。
不过由于此时Data Guard仍然控制着对逻辑Standby数据库中表的读写操作,因此,如果你想对逻辑Standby中的数据做些什么的话,ALTER SESSION DISABLE|ENABLE GUARD语句就必须牢记在心了,它拥有像”芝麻开门”一样神奇的能力。 下面我们就来感受一下吧。

在逻辑Standby端启动SQL应用的情况下,执行DDL操作:
SQL> GRANT DBA TO SCOTT;
Grant succeeded.
SQL> CONN SCOTT/TIGER;
Connected.
SQL> CREATE TABLE DAVE AS SELECT * FROM USER_OBJECTS;
CREATE TABLE DAVE AS SELECT * FROM USER_OBJECTS
*
ERROR at line 1:
ORA-01031: insufficient privileges

出错了,提示权限不足,实际上SCOTT被授予了DBA角色,肯定拥有CREATE TABLE权限的,因此此处与用户的权限无关,而是有其他因素制约了SCOTT无法进行修改。
下面禁用Data Guard保护之后,再次尝试操作数据:
SQL> ALTER SESSION DISABLE GUARD;
Session altered.
SQL> CREATE TABLE DAVE AS SELECT * FROM USER_OBJECTS;
Table created.
这下可以了,这就是Data Guard的作用。
注 意: 数据修改完之后,别忘了再次启用Data Guard,以避免不经意的误操作对逻辑Standby的配置造成影响(你说不手动启用Data Guard保护,直接退出行不行,当然也可以,ALTER SESSION所做修改仅对当前会话有效,退出重新登录,原会话设置自然就失效了)。
SQL> ALTER SESSION ENABLE GUARD;
Session altered.

按照Oracle的建议,还是尽可能不要在逻辑Standby端执行DML之类操作,以免破解其与Primary之间同步的逻辑关系,

也可以通过下列语句查看当前数据库是否处于Data Guard保护状态:
SQL> SELECT GUARD_STATUS FROM V$DATABASE;
GUARD_S
——-
ALL

该参数对应三个值:
ALL:表示对数据库中所有对象启动修改保护,除SYS用户外,其他用户均不能直接修改数据。
STANDBY:表示对处于逻辑Standby维护关系的对象启动修改保护,除SYS用户外,其他用户均不能直接修改数据。
NONE:不启动数据保护。

如果要永久设置数据库的Data Guard保护模式,则是通过ALTER DATABASE命令来完成,可指定的值也正是上述的三种,例如:
SQL> ALTER DATABASE GUARD STANDBY;
Database altered.

执行完上述语句后,Data Guard仅对处于逻辑Standby维护关系的对象进行防止修改操作的保护。

考虑到逻辑Standby中也有可能对数据进行修改(正如上例演示),因此这里引申谈一谈在逻辑Standby数据库中,约束和触发器的执行模式。默认情况下,约束和触发器都能在逻辑Standby端正常运行。约束和触发器在逻辑Standby端的执行可以分成两种情况:
对于SQL应用维护的约束和触发器,由于在Primary数据库已经检查过约束,因此Standby端不需要再次检查;触发器的情况也是这样,Primary端操作时结果已经被记录,因此逻辑Standby端将直接被应用,而不会二次触发。
对于没有SQL应用维护的约束和触发器,其执行情况与普通的Oracle数据库环境相同。

4.5 重定义REDO应用执行的操作
对于逻辑Standby数据库,你甚至可以通过编写自定义的PROCEDURE,来重新定义SQL应用时执行的操作。
如逻辑Standby数据库的文件路径与Primary数据库路径不同,如果是物理Standby,可以通过*_FILE_NAME_CONVERT之类的参数处理,在逻辑Standby环境中这几个参数无效,应该如何处理呢?答案就是通过编写自定义的过程,修改SQL应用时执行的操作。

下面通过示例,演示通过编写自定义的PROCEDURE,修改创建表空间时逻辑Standby端数据文件的路径。
首先当然是创建一个过程,建议创建在SYS下,因为在这个用户下的操作肯定不会有同步的问题,如下所示:
SQL> CREATE OR REPLACE PROCEDURE SYS.HANDLE_TBS_DDL (
2 OLD_STMT IN VARCHAR2,
3 STMT_TYP IN VARCHAR2,
4 SCHEMA IN VARCHAR2,
5 NAME IN VARCHAR2,
6 XIDUSN IN NUMBER,
7 XIDSLT IN NUMBER,
8 XIDSQN IN NUMBER,
9 ACTION OUT NUMBER,
10 NEW_STMT OUT VARCHAR2
11 ) AS
12 BEGIN
13
14 NEW_STMT := REPLACE(OLD_STMT, ‘/u01/oradata/orcl_pd/’, ‘/u01/oradata/orcl_st’);
15 ACTION := DBMS_LOGSTDBY.SKIP_ACTION_REPLACE;
16
17 EXCEPTION
18 WHEN OTHERS THEN
19 ACTION := DBMS_LOGSTDBY.SKIP_ACTION_ERROR;
20 NEW_STMT := NULL;
21 END HANDLE_TBS_DDL;
22 /
Procedure created.
逻辑非常简单,基本上就是一个REPLACE,不过PROCEDURE中声明的变量看起来很多,这个是固定格式,不建议修改。

停止逻辑Standby的SQL应用:
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;
Database altered.

如果不停,PROCEDURE不能生效。

执行DBMS_LOGSTDBY.SKIP过程,将编写的过程注册到表空间处理的SQL应用中:
SQL> EXEC DBMS_LOGSTDBY.SKIP (stmt => ‘TABLESPACE’,proc_name => ‘sys.handle_tbs_ddl’);
PL/SQL procedure successfully completed.

这里也要借助DBMS_LOGSTDBY.SKIP过程实现。该过程功能非常强大,而且操作非常灵活。

重启SQL应用:
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;
Database altered.

测试一下,在Primary端创建一个新的表空间:
SQL> CREATE TABLESPACE BOOKS DATAFILE ‘/u01/oradata/orcl_pd/books01.dbf’ SIZE 20m;
Tablespace created.
SQL> SELECT FILE_NAME FROM DBA_DATA_FILES WHERE TABLESPACE_NAME=’BOOKS’;
FILE_NAME
—————————————————————————–
/u01/oradata/orcl_pd/books01.dbf

转向逻辑Standby数据库查看:
SQL> SELECT FILE_NAME FROM DBA_DATA_FILES WHERE TABLESPACE_NAME=’BOOKS’;
FILE_NAME
—————————————————————————-
/u01/oradata/orcl_st/books01.dbf
表空间成功创建,并且数据文件路径也被转换为我们指定的路径。

此时如果你查看Alert日志文件,会发现其中记录下了类似这样的信息:
LOGSTDBY stmt: create tablespace books datafile ‘/u01/oradata/orcl_pd/books01.dbf’ size 20m
LOGSTDBY status: ORA-16110: 逻辑备用应用 DDL 的用户过程处理
LOGSTDBY id: XID 0x0001.009.000000d1, hSCN 0x0000.0012ec41,
lSCN 0x0000.0012ec41, Thread 1, RBA 0x007f.0000079a.80,
txnCscn 0x0000.0012ec43, PID 5816, ORACLE.EXE (P004)
LOGSTDBY stmt: create tablespace books datafile ‘/u01/oradata/orcl_st/books01.dbf’ size 20m
LOGSTDBY status: ORA-16202: 跳过过程已请求替换语句
LOGSTDBY id: XID 0x0001.009.000000d1, hSCN 0x0000.0012ec41,
lSCN 0x0000.0012ec41, Thread 1, RBA 0x007f.0000079a.80,
txnCscn 0x0000.0012ec43, PID 5816, ORACLE.EXE (P004)
create tablespace books datafile ‘/u01/oradata/orcl_st/books01.dbf’ size 20m
Completed: create tablespace books datafile ‘/u01/oradata/orcl_st/books01.dbf’ size 20m
LOGSTDBY stmt: create tablespace books datafile ‘/u01/oradata/orcl_st/books01.dbf’ size 20m
LOGSTDBY status: ORA-16204: 成功应用了 DDL

五.优化逻辑Standby数据同步性能

5.1 调整APPLIER进程数
APPLIER进程就是执行应用操作的进程。在默认情况下逻辑Standby会启动5个APPLIER进程,如果日志应用任务繁重(或者说Primary数据库修改量较大),则适当多启动几个APPLIER进程有助于提高应用的效率。

先查看当前空闲的APPLIER进程数:
SQL> SELECT COUNT(*) AS IDLE_APPLIER FROM V$LOGSTDBY_PROCESS WHERE TYPE = ‘APPLIER’ and status_code = 16166;

IDLE_APPLIER
————
0
返回结果为0,难道都在忙?这个真不一定,空闲的APPLIER进程数为0不一定代表应用非常繁忙,也有可能是因为当前没什么需要应用的日志,甚至都没启动应用进程。

说 明: status_code=16166表示进程是空闲状态,因为stats_code=16166对应的状态说明列STATS为ORA-16116: no work available。

检查事务的应用情况:
SQL> SELECT NAME,VALUE FROM V$LOGSTDBY_STATS WHERE NAME LIKE ‘transactions%’;
NAME VALUE
—– —————————
trans 358
trans 358

如果ready-applied的值比APPLIER进程数的两倍还要大,则说明DBA有必要考虑增加APPLIER进程的数目了,反之如果applied与ready的值差不多大,或者其差比APPLIER进程数还小,则说明APPLIER进程数偏多,DBA有必要考虑适当减小进程的数目。

如果确认当前APPLIER进程都非常繁忙,要增加APPLIER进程,可按如下步骤操作:

1) 停止逻辑Standby端的SQL应用:
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;
Database altered.

2) 执行下列语句,调整APPLIER进程数为10:
SQL> EXECUTE DBMS_LOGSTDBY.APPLY_SET(‘APPLY_SERVERS’,10);
PL/SQL procedure successfully completed.

3) 重新启动SQL应用:
JSSLDG> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;
Database altered.

4) 查出的就是当前运行的APPLIER进程数:
SQL> SELECT COUNT(0) FROM V$LOGSTDBY_PROCESS WHERE TYPE=’APPLIER’;
COUNT(0)
———-
10

也可以通过V$LOGSTDBY_STATS视图查询,例如:
SQL> SELECT * FROM V$LOGSTDBY_STATS WHERE NAME=’number of appliers’;

NAME VALUE
—– —————————————————————-
numbe 10

5.2 调整PREPARER进程数
PREPAPER进程将接收到的REDO数据中的块修改转换成LCRs(Logical Change Records)。一般需要调整PREPAPER进程数的机会不多,通常只有一种情况:APPLIER进程有空闲,Transactions Ready还很多,但没有空闲的PREPAPER进程,这时候DBA可能就需要增加一些PREPAPER进程。

先检查空闲PREPAPER进程数量:
SQL> SELECT COUNT(*) AS IDLE_PREPARER FROM V$LOGSTDBY_PROCESS
WHERE TYPE = ‘PREPARER’ and status_code = 16166;

IDLE_PREPARER
————-
0
说 明:如果显示为0,别怕,也有可能是因为当前没什么新的REDO数据需要处理。
如果确实需要调整PREPAPER进程数量,可以按照下列步骤进行。

首先停止SQL应用:
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;
Database altered.

调整PREPAPER进程数量为4(默认只有1个PREPAPER进程):
SQL> EXECUTE DBMS_LOGSTDBY.APPLY_SET(‘PREPARE_SERVERS’,4);
PL/SQL procedure successfully completed.

重新启动SQL应用即可:
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;
Database altered.

查看当前启动的PREPAPER进程数, 查询V$LOGSTDBY_STATS视图,例如:
SQL> SELECT * FROM V$LOGSTDBY_STATS WHERE NAME=’number of preparers’;
NAME VALUE
—– —————————————————————-
numbe 4

5.3 调整LCR使用的内存
LCR中保存的是转换后的块修改的记录,这部分数据保存在SGA中.

查询当前LCR可用的最大内存:
SQL> SELECT * FROM V$LOGSTDBY_STATS WHERE NAME=’maximum SGA for LCR cache’;
NAME VALUE
———————————— ——————–
maximum SGA for LCR cache 30

显示的参数值默认单位为M,当前结果显示LCR内存区可用空间为30M。

要增加LCR可用的内存,可按照下列步骤操作。

1) 首先还是需要停止SQL应用:
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;
Database altered.

2) 调整内存大小为100M:
SQL> EXEC DBMS_LOGSTDBY.APPLY_SET(‘MAX_SGA’,100);
PL/SQL procedure successfully completed.

3)最后重启SQL应用即可
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;
Database altered.

5.4 调整事务应用方式
在默认情况下逻辑Standby端事务应用顺序与Primary数据库提交顺序相同。如果DBA希望逻辑Standby端事务应用不按照Primary数据库顺序执行的话,可以按照下列步骤操作:

1)停止SQL应用:
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;

2)允许事务不按照Primary的提交顺序应用:
SQL> EXECUTE DBMS_LOGSTDBY.APPLY_SET(‘PRESERVE_COMMIT_ORDER’, ‘FALSE’);

3)重新启动SQL应用:
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;

恢复逻辑Standby按照事务提交顺序应用的话,可按照下列步骤操作:

1)先停止SQL应用:
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;

2)重置参数PRESERVE_COMMIT_ORDER的初始值:
SQL> EXECUTE DBMS_LOGSTDBY.APPLY_UNSET(‘PRESERVE_COMMIT_ORDER’);

3)重新启动SQL应用:
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;

六.应用REDO数据到Standby数据库
1.物理Standby应用REDO数据
物理Standby启动REDO应用,数据库要处于MOUNT状态或是OPEN READ ONLY状态,启动REDO应用的命令相信大家已经非常熟悉了。

前台应用:
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE;
语句执行完成后,不会将控制权返回到命令行窗口,除非你手动中止应用。在这种情况下如果还需要对数据库进行操作,只能新开一个命令行连接,在Oracle 8i刚推出Standby特性时(那时不叫Data Guard),只提供了这种方式。

后台应用:
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT;
这是现在比较通用的方式,语句执行完后,控制权自动返回到当前的命令行模式,REDO应用以后台进程运行。

启动实时应用,附加USING CURRENT LOGFILE子句即可:
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE;

如果要停止REDO应用,执行下列语句即可:
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;

2.逻辑Standby应用REDO数据
SQL应用的原理是将接收到的REDO数据转换成SQL语句在逻辑Standby数据库端执行,因此逻辑Standby需要启动至OPEN状态。
(1)启动SQL应用。逻辑Standby数据库启动SQL应用没有前、后台运行之说,语句执行完之后,控制权就会自动返回当前命令行窗口。要启动SQL应用,直接执行下列语句即可:
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY;

如果要启动实时应用,附加IMMEDIATE子句即可,例如:
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;

(2)停止SQL应用,如:
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;
由于是执行SQL语句的方式应用REDO数据,因此上述语句的执行需要等待当前执行的SQL触发的事务结束,才能真正停止REDO应用的状态。

如果不考虑事务执行情况,马上停止REDO应用,可以通过下列的语句来完成:
SQL> ALTER DATABASE ABORT LOGICAL STANDBY APPLY;

continuing ……

reference:http://blog.csdn.net/tianlesoftware/article/details/5564208

ORA-16009 in alert log with standby and LGWR ASYNC

December 2, 2011 oracle, replication No comments

今天用10.2.0.1的一套物理DG 转 逻辑 standby 出现大量错误:

primary 端:

— Connected User is Valid
RFS[2]: Assigned to RFS process 30286
RFS[2]: Database mount ID mismatch [0x9a9ac2b3:0x9a9a1a16]
RFS[2]: Destination database ID mismatch [0x2593781616:0x2592975883]
RFS[2]: Not using real application clusters
Fri Dec 2 19:27:39 2011
Errors in file /u01/app/oracle/admin/liu/udump/liu_rfs_30286.trc:
ORA-16009: remote archive log destination must be a STANDBY database
Fri Dec 2 19:30:16 2011
Thread 1 advanced to log sequence 24
Current log# 2 seq# 24 mem# 0: /u01/app/oracle/oradata/liu/redo02.log
Fri Dec 2 19:30:17 2011
LNS: Standby redo logfile selected for thread 1 sequence 24 for destination LOG_ARCHIVE_DEST_2

standby 端:

0x0000.000a997d, PID 29187, oracle@yang (P005)
Fri Dec 2 19:11:29 2011
LOGMINER: Log Auto Delete – deleting: /u01/arch/1_21_767998669.dbf
Deleted file /u01/arch/1_21_767998669.dbf
LNS1 started with pid=33, OS id=30088
Fri Dec 2 19:28:22 2011
Thread 1 advanced to log sequence 4
Current log# 3 seq# 4 mem# 0: /u01/app/oracle/oradata/liu/redo03.log
Fri Dec 2 19:28:23 2011
Errors in file /u01/app/oracle/admin/liu/bdump/liu_lns1_30088.trc:
ORA-16009: remote archive log destination must be a STANDBY database
Fri Dec 2 19:28:23 2011
LGWR: Error 16009 creating archivelog file ‘liu’
LNS: Failed to archive log 3 thread 1 sequence 4 (16009)

但是日志apply 正常 查找metalink

Bug 4676659 – ORA-16009 in alert log with standby and LGWR ASYNC [ID 4676659.8]
Modified 24-SEP-2008 Type PATCH Status PUBLISHED
Bug 4676659 ORA-16009 in alert log with standby and LGWR ASYNC

This note gives a brief overview of bug 4676659.
The content was last updated on: 03-APR-2008
Click here for details of each of the sections below.
Affects:

Product (Component) Oracle Server (Rdbms)
Range of versions believed to be affected Versions >= 10.2 but < 11 Versions confirmed as being affected 10.2.0.2 Platforms affected Generic (all / most platforms affected) Fixed: This issue is fixed in 10.2.0.3 (Server Patch Set) 11.1.0.6 (Base Release)

解决方法:升级数据库到10.2.0.5