首页 » ORACLE 9i-23c » Manually create Oracle 11g physical standby DG ,Switchover, Convert to Logical standby(Scripts and Short Descriptions)

Manually create Oracle 11g physical standby DG ,Switchover, Convert to Logical standby(Scripts and Short Descriptions)

oracle datagraud是数据库的容灾方案, 简单记录oracle 11g 单实例的安装配置dataguard和switch over及转换逻辑standby操作,章节以下顺序:
1. Manually create physical standby with rman;
2. Primary role and Primary standby role switchover;
3. Converting Physical Standby to Logical Standby ;

1.Manually create physical standby with rman

Enable archivelog mode

SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE ARCHIVELOG;
ALTER DATABASE OPEN;

Enable Forced Logging

ALTER DATABASE FORCE LOGGING;

Create a Password File

orapwd file=orapwicme password=oracle entries=10 ignorecase=y

Static listener configuration(primary and standby)

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = xxxxx)
      (ORACLE_HOME = /u01/app/oracle/product/11.2.0/db_1)
      (SID_NAME = xxx)
    )
  )

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = xxxxx)(PORT = 1521))
    )
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
    )
  )

ADR_BASE_LISTENER = /u01/app/oracle


Configure tnsnames on primary and standby both.

vi $ORACLE_HOME/network/admin/tnsnames.ora

In my case primary db IP is 192.168.168.230 and standby db IP 192.168.168.231. (tnsnames can be different service_name,tnsnames will be used in log_archive_dest_N SERVICE AND fal_client or fal_server)

primarydb =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.168.230)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = pora230)
)
)

standbydb =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.168.231)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = sora231)
)
)

Set Primary Database Initialization Parameters

alter system set log_archive_config='DG_CONFIG=(pora230,sora231)';
alter system set log_archive_dest_1='LOCATION=/data/oracle/pora230/archivelog/ VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=pora230';
alter system set log_archive_dest_2='SERVICE=standbydb LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=sora231';

alter system set fal_client=primarydb;
alter system set fal_server=standbydb;
alter system set log_archive_format='%d_%t_%s_%r.arc' scope=spfile;
alter system set DB_FILE_NAME_CONVERT='/oradata/sora231/','/oracle/oradata/pora230/' scope=spfile;
alter system set LOG_FILE_NAME_CONVERT='/oradata/sora231/','/oracle/oradata/pora230/' scope=spfile;

alter system set  STANDBY_FILE_MANAGEMENT=AUTO;

Configure a Standby Redo Log

A standby redo log is required for the maximum protection and maximum availability modes and the LGWR ASYNC transport mode is recommended for all databases. Data Guard can recover and apply more redo data from a standby redo log than from archived redo log files alone.

The synchronous and asynchronous redo transport modes require that a redo transport destination have a standby redo log. A standby redo log is used to store redo received from another Oracle database.Each standby redo log file must be at least as large as the largest redo log file in the redo log of the redo source database.The standby redo log must have at least one more redo log group than the redo log at the redo source database, for each redo thread at the redo source database.

for example.

ALTER DATABASE ADD STANDBY LOGFILE ('/oracle/oradata/icme/slog1.rdo') SIZE 100M;

CREATE Standby Controlfile

alter database CREATE STANDBY CONTROLFILE AS '/tmp/control01.ctl';

CREATE Standby init file;

SQL> create pfile from spfile;

BACKUP DATABASE ON Primary DB

rman target /
rman> backup database format '/oradata/oracle/full_%d_%T_%s'  PLUS ARCHIVELOG;

scp control ,pfile ,rman backup to standby db

scp xxx  xx…..

Config archivelog delete policy on primary db

rman target / <<eof
show all;
configure archivelog deletion policy to shipped to all standby;
exit
eof

#################Summary of PRIMARY db site############################

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_file_name_convert string /oradata/sora231/, /oracle/oradata/pora230/
db_name string pora230
db_unique_name string PORA230
global_names boolean FALSE
instance_name string pora230
lock_name_space string
log_file_name_convert string /oradata/sora231/, /oracle/oradata/pora230/
service_names string PORA230
log_archive_dest_1 string LOCATION=/data/oracle/pora230/archivelog/ VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=pora230
log_archive_dest_10 string
log_archive_dest_2 string SERVICE=standbydb LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=sora231
log_archive_dest_3 string LOCATION=/data/oracle/pora230/
lgarchivelog/ VALID_FOR=(STAND
BY_LOGFILES,STANDBY_ROLE) DB_U
NIQUE_NAME=pora230

####################Summary of standby db site############################
#modify pfile

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_file_name_convert string /oracle/oradata/pora230/, /oradata/sora231/
db_name string STDB
db_unique_name string sora231
global_names boolean FALSE
instance_name string sora231
lock_name_space string
log_file_name_convert string /oracle/oradata/pora230/, /oradata/sora231/
service_names string sora231
log_archive_dest_1 string LOCATION=/oradata/sora231/archlog/ VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=sora231
log_archive_dest_10 string
log_archive_dest_2 string SERVICE=primarydb LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=pora230
log_archive_dest_3 string LOCATION=/oradata/sora231/stbarchlog/ VALID_FOR=(STANDBY_LOGFILES,STANDBY_ROLE) DB_UNIQUE_NAME=sora231

 

##########################################################

ON standby db:

create pfile from spfile;

— or manual create pfile just add “db_name=xxx” ,startup nomount ,create pfile from memory;

move standby control file to specified path in standby spfile or pfile

startup mount;

#restore standby database from rman backupset of primary db

rman target /
catalog backuppiece '/home/oracle/full_PORA230_20130521_1';
catalog backuppiece '/home/oracle/full_PORA230_20130521_2';

RMAN> restore database;

Starting restore at 2013-05-22 03:32:43
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid=158 devtype=DISK

channel ORA_DISK_1: starting datafile backupset restore
channel ORA_DISK_1: specifying datafile(s) to restore from backup set
restoring datafile 00001 to /oradata/sora231/system01.dbf
restoring datafile 00002 to /oradata/sora231/undotbs01.dbf
restoring datafile 00003 to /oradata/sora231/sysaux01.dbf
restoring datafile 00004 to /oradata/sora231/users01.dbf
channel ORA_DISK_1: reading from backup piece /home/oracle/full_PORA230_20130521_1
channel ORA_DISK_1: restored backup piece 1
piece handle=/home/oracle/full_PORA230_20130521_1 tag=TAG20130521T164617
channel ORA_DISK_1: restore complete, elapsed time: 00:00:07
Finished restore at 2013-05-22 03:32:51

— if hava backup archivelog backupset

restore archivelog all;

alter database recover managed standby database disconnect from session;

############# some manage commands about redo apply #####

– start redo apply
alter database recover managed standby database disconnect from session;

– start real-time redo apply
alter database recover managed standby database using current logfile disconnect from session;

--stop redo apply
alter database recover managed standby database cancel;

-- start delay apply standby
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DELAY 30 DISCONNECT FROM SESSION;

如果创建备库使用duplicate就更简单, 备份密码文件,pfile文件。

startup nomount pfile ='/home/oracle/ora.pfile'
$ rman TARGET sys/password@DB11G AUXILIARY sys/password@DB11G_STBY

DUPLICATE TARGET DATABASE
  FOR STANDBY
  FROM ACTIVE DATABASE
  DORECOVER
  SPFILE
    SET db_unique_name='DB11G_STBY' COMMENT 'Is standby'
    SET LOG_ARCHIVE_DEST_2='SERVICE=db11g ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=DB11G'
    SET FAL_SERVER='DB11G' COMMENT 'Is primary'
  NOFILENAMECHECK;

2 Primary role and Primary standby role switchover;

# PRIMARY SWITCH TO PRIMARY STANDBY

select db_unique_name,switchover_status,database_role from v$database;

DB_UNIQUE_NAME SWITCHOVER_STATUS DATABASE_ROLE
------------------------------ -------------------- ----------------
pora230 TO STANDBY PRIMARY

alter database commit to switchover to physical standby;
Database altered.

# PHYSICAL STANDBY SWITCH TO PRIMARY (Make Sure SWITCHOVER_STATUS is "TO PRIMARY")

select db_unique_name,switchover_status,database_role from v$database;
DB_UNIQUE_NAME SWITCHOVER_STATUS DATABASE_ROLE
------------------------------ -------------------- ----------------
sora231 SESSIONS ACTIVE PHYSICAL STANDBY

select db_unique_name,switchover_status,database_role from v$database;
DB_UNIQUE_NAME SWITCHOVER_STATUS DATABASE_ROLE
------------------------------ -------------------- ----------------
sora231 TO PRIMARY PHYSICAL STANDBY

alter database commit to switchover to primary;

select db_unique_name,switchover_status,database_role ,open_mode from v$database;
DB_UNIQUE_NAME SWITCHOVER_STATUS DATABASE_ROLE OPEN_MODE
------------------------------ -------------------- ---------------- ----------
sora231 TO STANDBY PRIMARY MOUNTED

alter database open;
Database altered.

select db_unique_name,switchover_status,database_role ,open_mode from v$database;
DB_UNIQUE_NAME SWITCHOVER_STATUS DATABASE_ROLE OPEN_MODE
------------------------------ -------------------- ---------------- ----------
sora231 NOT ALLOWED PRIMARY READ WRITE

#Switch back method same above.

3 Converting Physical Standby to Logical Standby

# some check UNSUPPORTED with logical standby

SELECT OWNER, TABLE_NAME FROM DBA_LOGSTDBY_NOT_UNIQUE
WHERE (OWNER, TABLE_NAME) NOT IN (SELECT DISTINCT OWNER, TABLE_NAME FROM DBA_LOGSTDBY_UNSUPPORTED) AND BAD_COLUMN = 'Y';

select * from DBA_LOGSTDBY_UNSUPPORTED;

# ON PRIMARY DB(Modify some initialization paramters ,Do not need to restart the database)

alter system SET log_archive_dest_3='LOCATION=/data/oracle/pora230/lgarchivelog/ VALID_FOR=(STANDBY_LOGFILES,STANDBY_ROLE) DB_UNIQUE_NAME=pora230';

ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY, UNIQUE INDEX) COLUMNS;

ALTER SYSTEM SWITCH LOGFILE;

create tablespace tbs_logidg datafile '/oracle/oradata/pora230/tbs_logidg01.dbf' size 20m autoextend on maxsize 5g;
EXECUTE DBMS_LOGMNR_D.SET_TABLESPACE('TBS_LOGIDG');
EXECUTE DBMS_LOGSTDBY.BUILD;

# ON Physical standby db

alter database recover managed standby database cancel;

#Converting Physical Standby to Logical Standby

ALTER DATABASE RECOVER TO LOGICAL STANDBY stdb;

tip:
if the step is hang ,try do EXECUTE DBMS_LOGSTDBY.BUILD again on primary database

# re-create password

[oracle@db231 dbs]$ orapwd file=orapwsora231 entries=5 password=oracle

SQL> SHUTDOWN;
SQL> STARTUP MOUNT;

alter system set log_archive_dest_1='LOCATION=/oradata/sora231/archlog/ VALID_FOR=(ONLINE_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=sora231';
alter system set log_archive_dest_3='LOCATION=/oradata/sora231/stbarchlog/ VALID_FOR=(STANDBY_LOGFILES,STANDBY_ROLE) DB_UNIQUE_NAME=sora231';

idle>ALTER DATABASE OPEN RESETLOGS;

# Stop or Start the SQL apply on logical standby

alter database stop logical standby apply;
alter database start logical standby apply immediate;

sys@STDB>select db_unique_name,switchover_status,database_role ,open_mode from v$database;

DB_UNIQUE_NAME SWITCHOVER_STATUS DATABASE_ROLE OPEN_MODE
------------------------------ -------------------- ---------------- ----------
sora231 NOT ALLOWED LOGICAL STANDBY READ WRITE

##################### know issue ##########

1,DB_FILE_NAME_CONVERT

Note:
The DB_FILE_NAME_CONVERT initialization parameter is not honored once a physical standby database is converted to a logical standby database. If necessary, you should register a

skip handler and provide SQL Apply with a replacement DDL string to execute by converting the path names of the primary database datafiles to the standby datafile path names.

See theDBMS_LOGSTDBYpackage inOracle Database PL/SQL Packages and Types Reference. for information about the SKIP procedure.

SQL> alter database stop logical standby apply;
SQL> EXECUTE DBMS_LOGSTDBY.SKIP(stmt=>'CREATE TABLESPACE', schema_name=>'SYS', object_name=>'%');
SQL> EXECUTE DBMS_LOGSTDBY.SKIP(stmt=>'DROP TABLESPACE', schema_name=>'SYS', object_name=>'%');
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;

or

SQL> alter database stop logical standby apply;
SQL> alter session disable guard;
SQL> create tablespace ts_test1 datafile '/orahome/oradata/LOGSTDBY/ts_test1.dbf' size 10m reuse;
SQL> drop tablespace ts_test2 including contents and datafiles cascade constraints;
SQL> alter session enable guard;

SQL> alter database start logical standby apply immediate skip failed transaction;

or

SQL> alter database start logical standby apply immediate;

2,Privileges

# Apply fails with ORA-01031: Insufficient Privileges

# ON STANDBY CREATE TABLE

ALTER DATABASE STOP LOGICAL STANDBY APPLY;
ALTER SESSION DISABLE GUARD;
create table xxx
ALTER SESSION ENABLE GUARD;
ALTER DATABASE START LOGICAL STANDBY APPLY;

OR

SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;
Database altered.
SQL> EXECUTE DBMS_LOGSTDBY.SKIP(stmt => 'SCHEMA_DDL',-
schema_name => 'HR', -
object_name => 'TESTEMP%');
PL/SQL procedure successfully completed.
SQL> EXECUTE DBMS_LOGSTDBY.SKIP('DML','HR','TESTEMP%');
PL/SQL procedure successfully completed.
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;
Database altered.

# modify guard_status

sys@STDB>select db_unique_name,switchover_status,database_role ,open_mode, guard_status from v$database;

DB_UNIQUE_NAME SWITCHOVER_STATUS DATABASE_ROLE OPEN_MODE GUARD_S
------------------------------ -------------------- ---------------- ---------- -------
sora231 NOT ALLOWED LOGICAL STANDBY READ WRITE ALL

sys@STDB>alter database guard standby;
Database altered.

sys@STDB>select db_unique_name,switchover_status,database_role ,open_mode, guard_status from v$database;

DB_UNIQUE_NAME SWITCHOVER_STATUS DATABASE_ROLE OPEN_MODE GUARD_S
------------------------------ -------------------- ---------------- ---------- -------
sora231 NOT ALLOWED LOGICAL STANDBY READ WRITE STANDBY

3,Materialized view

New materialized views that are created, altered, or dropped on the primary database after the logical standby database has been created will not be created on the logical standby database. However, materialized views created on the primary database prior to the logical standby database being created will be present on the logical standby database.

Logical Standby supports the creation and maintenance of new materialized views locally on the logical standby database in addition to other kinds of auxiliary data structure.

IF An ON-DEMAND fast refreshe MView in logical standby database has been created before physical standby convert to logical standby, when primary db has DML On had mview table,on logical standby Materialized view logs are synchronized, but exec dbms_mview.refresh Mview on primary db , Materialized view is not refreshed on standby side. you need to manually refresh the standby side or create a job.

## Some frequently used check commands about Logical standby db #####

SELECT FILE_NAME, SEQUENCE# AS SEQ#, FIRST_CHANGE# AS FCHANGE#, -
     NEXT_CHANGE# AS NCHANGE#, TIMESTAMP, -
     DICT_BEGIN AS BEG, DICT_END AS END, -
     THREAD# AS THR# ,applied FROM DBA_LOGSTDBY_LOG -
     ORDER BY SEQUENCE#;

COLUMN LID FORMAT 9999
COLUMN SERIAL# FORMAT 9999
COLUMN SID FORMAT 9999
SELECT SID, SERIAL#, LOGSTDBY_ID AS LID, SPID, TYPE, HIGH_SCN FROM V$LOGSTDBY_PROCESS;

SELECT TYPE, STATUS_CODE, STATUS FROM V$LOGSTDBY_PROCESS;
select * from v$logstdby_state;

#related views

    DBA_LOGSTDBY_EVENTS View
    DBA_LOGSTDBY_LOG View
    V$LOGSTDBY_STATS View
    V$LOGSTDBY_PROCESS View
    V$LOGSTDBY_PROGRESS View
    V$LOGSTDBY_STATE View
    V$LOGSTDBY_STATS View

# to check if redo apply enabled use “v$archive_dest_status” On standby

select DEST_ID,dest_name,status,type,srl,recovery_mode from v$archive_dest_status where dest_id=1;

— update 20180823 —
for example to fix archivelog miss

RMAN> run{
allocate channel ch1 type 'SBT_TAPE';
restore archivelog from sequence 268797  until sequence 268803 thread 2;
release channel ch1;
}

RMAN> list backup of archivelog sequence between 268795  and 268803 thread 2;

RMAN> backup as copy archivelog sequence between 202430  and 202440 format '+datadg' delete input;	

RMAN> delete archivelog sequence between 202430  and 202440 backed up 1 times to device type SBT_TAPE;

SQL> select t.*,arched-applied gap,sysdate etime  from (select thread#,max(sequence#) arched, max(decode(applied,'YES',sequence#,1)) applied from v$archived_log group by thread#) t;

   THREAD#     ARCHED    APPLIED        GAP ETIME
---------- ---------- ---------- ---------- -----------------
         1     202571     202326        245 20180821 20:02:41
         2     269297     268835        462 20180821 20:02:41

RMAN> delete archivelog sequence between 202306  and 202326 thread 1;
RMAN> delete archivelog sequence between 268790  and 268835 thread 2;
		 
SQL>select t.*,arched-applied gap,sysdate etime  from (select thread#,max(sequence#) arched, max(decode(applied,'YES',sequence#,1)) applied, max(decode(DELETED,'YES',sequence#,1)) DELETED from v$archived_log group by thread#) t;	

打赏

,

对不起,这篇文章暂时关闭评论。