环境:
角色 |
机器名 |
操作系统 |
IP |
备注 |
主库 |
db1 |
CentOS 5.11 x86_64 | 192.168.2.241 |
安装Oracle,创建数据库 |
备库 |
db2 |
CentOS 5.11 x86_64 |
192.168.2.242 |
只安装Oracle |
准备工作:
在db1的/etc/hosts里增加
127.0.0.1 db1
192.168.2.242 db2
在db2的/etc/hosts里增加
127.0.0.1 db2
192.168.2.241 db1
目录
-
主库打开归档及强制归档
-
创建3组standby redolog
-
修改参数文件
-
修改监听文件
-
RMAN备份主库
-
复制文件至备库
-
恢复参数文件(db2)
-
修改备库参数文件(db2)
-
准备RMAN恢复工作(db2)
-
生成备库参数文件(db2)
-
恢复数据库(db2)
-
启动备库(db2)
1.主库打开归档及强制归档(db1)
检查Oracle是否开启归档
SQL> archive log list;
Database log mode No Archive Mode
Automatic archival Disabled
Archive destination USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence 6
Current log sequence 8
#可以看到Automatic archival Disabled说明未打开归档
打开归档(打开归档需要先关闭Oracle,然后将数据库启动至mount状态才能修改)
SQL> shutdown immediate;
SQL> startup mount;
SQL> alter database archivelog; #打开归档
SQL> alter database force logging; #打开强制归档也可以在数据库open状态下打开。此操作用于在使用nologging选项不记录redo的请求,用于所有的操作都会记录日志
SQL> alter database open; #打开数据库
SQL> archive log list;
Database log mode Archive Mode
Automatic archival Enabled
Archive destination USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence 6
Next log sequence to archive 8
Current log sequence 8
SQL> alter system set archive_lag_target=1800; //通过30分钟时间限制,强制进行Oracle进行日志切换并归档。默认为0,不启动。不建议该值大于2400或者小于600.(时间过长容易导致数据丢失,时间太短容易引起数据库性能问题)
2.创建多组standby redo log,最少需要多一组,standby redo log是使用Real Time Apply的必要条件
SQL> select group#,member from v$logfile;
GROUP# MEMBER
--------------------------------------------------------------------------------
3 /opt/oracle/oradata/tpy100/redo03.log
2 /opt/oracle/oradata/tpy100/redo02.log
1 /opt/oracle/oradata/tpy100/redo01.log
SQL> alter database add standby logfile ('/opt/oracle/oradata/tpy100/standby04.log') size 50m;
SQL> alter database add standby logfile ('/opt/oracle/oradata/tpy100/standby05.log') size 50m;
SQL> alter database add standby logfile ('/opt/oracle/oradata/tpy100/standby06.log') size 50m;
SQL> alter database add standby logfile ('/opt/oracle/oradata/tpy100/standby07.log') size 50m;
SQL> select group#,member from v$logfile;
GROUP# MEMBER
--------------------------------------------------------------------------------
3 /opt/oracle/oradata/tpy100/redo03.log
2 /opt/oracle/oradata/tpy100/redo02.log
1 /opt/oracle/oradata/tpy100/redo01.log
4 /opt/oracle/oradata/tpy100/standby04.log
5 /opt/oracle/oradata/tpy100/standby05.log
6 /opt/oracle/oradata/tpy100/standby06.log
7 /opt/oracle/oradata/tpy100/standby07.log
3.修改参数文件
修改参数文件前,我们先进行备份
SQL> create pfile='/tmp/tpy100.pfile' from spfile;
在修改前我们需要查看下备份的参数文件,根据具体环境更改下面语句
SQL> alter system set db_unique_name=db1 scope=spfile;
SQL> alter system set log_archive_config='dg_config=(db1,db2)' scope=both;
SQL> alter system set log_archive_dest_1= 'location=/opt/oracle/flash_recovery_area/ valid_for=(all_logfiles,all_roles) db_unique_name=db1' scope=both;
报错:
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-16053: DB_UNIQUE_NAME db1 is not in the Data Guard Configuration
可能会遇上如下报错信息,这个时候需要重启下数据库
SQL> shutdown immediate;
SQL> startup
SQL> alter system set log_archive_dest_1= 'location=/opt/oracle/flash_recovery_area/ valid_for=(all_logfiles,all_roles) db_unique_name=db1' scope=both;
SQL> alter system set log_archive_dest_2= 'service=db2 async valid_for=(online_logfiles,primary_role) db_unique_name=db2' scope=both;
SQL> alter system set log_archive_dest_state_1=enable scope=both;
SQL> alter system set log_archive_dest_state_2=enable scope=both;
SQL> alter system set standby_file_management=auto scope=both;
SQL> alter system set fal_server=db2 scope=both;
SQL> alter system set fal_client=db1 scope=both;
SQL> alter system set db_file_name_convert='/opt/oracle/flash_recovery_area','/opt/oracle/flash_recovery_area' scope=spfile;
SQL> alter system set log_file_name_convert='/opt/oracle/flash_recovery_area','/opt/oracle/flash_recovery_area' scope=spfile;
4.修改监听文件
[oracle@db1 ~]$ vim /opt/oracle/product/11.2.0/network/admin/tnsnames.ora
在后面增加
db1 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = db1)(PORT = 1521))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = db1)
)
)
db2 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = db2)(PORT = 1521))
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = db2)
)
)
5.RMAN备份主库
创建备份存放目录
[oracle@db1 ~]$ mkdir -p /opt/oracle/dbackup
执行备份
rman>run{
allocate channel c1 type disk;
backup format '/opt/oracle/dbackup/tpy100_%T_%s_%p' database;
sql 'alter system archive log current';
backup format '/opt/oracle/dbackup/archive_log_%T_%s_%p' archivelog all;
backup spfile format '/opt/oracle/dbackup/spfile_%u_%T.bak';
release channel c1;
}
rman>copy current controlfile for standby to '/opt/oracle/dbackup/standby.ctl';
6.复制文件至备库
[oracle@db1 ~]$ scp -r /opt/oracle/dbackup/ db2:/opt/oracle
[oracle@db1 ~]$ cd $ORACLE_HOME/dbs
[oracle@db1 dbs]$ scp -r orapwtpy100 db2:$ORACLE_HOME/dbs
[oracle@db1 dbs]$ cd $ORACLE_HOME/network/admin
[oracle@db1 admin]$ scp -r listener.ora tnsnames.ora db2:$ORACLE_HOME/network/admin
7.恢复参数文件(db2)
RMAN> set dbid 2926260986
RMAN> startup nomount;
#这里会报错不用理会即可
RMAN> restore spfile to pfile '/tmp/tpy100.pfile' from '/opt/oracle/dbackup/spfile_04quaekm_20160219.bak';
#我们将参数文件恢复至/tmp/tpy100.pfile,因为这个是主库的参数文件,备库略有不同
8.修改备库参数文件(db2)
[oracle@db2 ~]$ vim /tmp/tpy100.pfile
#将里面的DB1 db1变成相应的DB2 db2,将DB1变成db1
tpy100.__db_cache_size=322961408
tpy100.__java_pool_size=4194304
tpy100.__large_pool_size=4194304
tpy100.__oracle_base='/opt/oracle'#ORACLE_BASE set from environment
tpy100.__pga_aggregate_target=339738624
tpy100.__sga_target=503316480
tpy100.__shared_io_pool_size=0
tpy100.__shared_pool_size=159383552
tpy100.__streams_pool_size=0
*.audit_file_dest='/opt/oracle/admin/tpy100/adump'
*.audit_trail='db'
*.compatible='11.2.0.0.0'
*.control_files='/opt/oracle/oradata/tpy100/control01.ctl','/opt/oracle/flash_recovery_area/tpy100/control02.ctl'
*.db_block_size=8192
*.db_domain=''
*.db_file_name_convert='/opt/oracle/flash_recovery_area','/opt/oracle/flash_recovery_area'
*.db_name='tpy100'
*.db_recovery_file_dest='/opt/oracle/flash_recovery_area'
*.db_recovery_file_dest_size=4070572032
*.db_unique_name='DB2'
*.diagnostic_dest='/opt/oracle'
*.dispatchers='(PROTOCOL=TCP) (SERVICE=tpy100XDB)'
*.fal_client='DB2'
*.fal_server='DB1'
*.log_archive_config='dg_config=(db2,db1)'
*.log_archive_dest_1='location=/opt/oracle/flash_recovery_area/ valid_for=(all_logfiles,all_roles) db_unique_name=db2'
*.log_archive_dest_2='service=db1 async valid_for=(online_logfiles,primary_role) db_unique_name=db1'
*.log_archive_dest_state_1='ENABLE'
*.log_archive_dest_state_2='ENABLE'
*.log_file_name_convert='/opt/oracle/flash_recovery_area','/opt/oracle/flash_recovery_area'
*.memory_target=843055104
*.open_cursors=300
*.processes=150
*.remote_login_passwordfile='EXCLUSIVE'
*.standby_file_management='AUTO'
*.undo_tablespace='UNDOTBS1'
9.准备RMAN恢复工作(db2)
创建相应的目录,复制备库控制文件到相应的位置
[oracle@db2 ~]$ mkdir -p /opt/oracle/admin/tpy100/adump
[oracle@db2 ~]$ mkdir -p /opt/oracle/oradata/tpy100
[oracle@db2 ~]$ mkdir -p /opt/oracle/flash_recovery_area/tpy100
[oracle@db2 ~]$ cp /opt/oracle/dbackup/standby.ctl /opt/oracle/oradata/tpy100/control01.ctl
[oracle@db2 ~]$ cp /opt/oracle/dbackup/standby.ctl /opt/oracle/flash_recovery_area/tpy100/control02.ctl
[oracle@db2 ~]$ lsnrctl start
#启动监听
10.生成备库参数文件(db2)
SQL> shutdown immediate;
SQL> startup nomount pfile='/tmp/tpy100.pfile'
SQL> create spfile from pfile='/tmp/tpy100.pfile';
SQL> alter database mount;
11.恢复数据库(db2)
RMAN> restore database;
12.启动备库(db2)
SQL > alter database open read only;
#在这里启动的时候如果出现
ERROR at line 1:
ORA-10458: standby database requires recovery
ORA-01152: file 1 was not restored from a sufficiently old backup
ORA-01110: data file 1: '/opt/oracle/oradata/tpy100/system01.dbf'
先使用shutdown immediate关闭后再重新启动
SQL> shutdown immediate;
SQL> startup mount;
SQL> alter database recover managed standby database using current logfile disconnect from session;
如果出现
SQL> alter database recover managed standby database using current logfile disconnect from session;
alter database recover managed standby database using current logfile disconnect from session
*
ERROR at line 1:
ORA-38500: USING CURRENT LOGFILE option not available without stand
则可能是在备机没有新建standby log
SQL> select member from v$logfile;
MEMBER
--------------------------------------------------------------------------------
/opt/oracle/oradata/tpy100/redo03.log
/opt/oracle/oradata/tpy100/redo02.log
/opt/oracle/oradata/tpy100/redo01.log
增加standby log:
alter database add standby logfile ('/opt/oracle/oradata/tpy100/standby04.log') size 50m;
alter database add standby logfile ('/opt/oracle/oradata/tpy100/standby05.log') size 50m;
alter database add standby logfile ('/opt/oracle/oradata/tpy100/standby06.log') size 50m;
如果需要重启备库,则需要按如下命令进行重启
SQL> startup;
SQL> alter database recover managed standby database using current logfile disconnect from session;
注意:刚重启完你会发现主库的数据还没过来,但是过段时间就过来了,在生产环境中我们需要快速处理这个问题,以便减少宕机时间。
关闭完备库后,在主库查看
SQL> select dest_name,status,error from v$archive_dest;
DEST_NAME STATUS ERROR
------------------------------ --------
LOG_ARCHIVE_DEST_1 VALID
LOG_ARCHIVE_DEST_2 ERROR ORA-03113: end-of-file on communication channel
可以看到LOG_ARCHIVE_DEST_2是错误的,这个是因为没有连接到备库的归档路径,默认情况下Dataguard会每300秒自动连接,这边为了快读处理
解决办法:在主库执行
SQL> alter system set log_archive_dest_state_2= enable;
再查询,如果依然是如此则需要检查备库的网络及监听
测试有如下语句:
SQL> select sequence#,applied from v$archived_log;
SQL> select process,status from v$managed_standby;
SQL> select sequence# from v$log_history;
查看当前DataGuard角色以及模式
1
2
3
4
5
|
SQL>
select
DATABASE_ROLE,PROTECTION_MODE,PROTECTION_LEVEL from
v
$database;
DATABASE_ROLE PROTECTION_MODE PROTECTION_LEVEL
---------------- -------------------- --------------------
PHYSICAL STANDBY MAXIMUM PERFORMANCE MAXIMUM PERFORMANCE
|
DataGuard启动关闭顺序:
启动顺序:
1.启动从库的监听
1
|
[oracle@db2 ~]$ lsnrctl start
|
2.启动主库的监听
1
|
[oracle@db1 ~]$ lsnrctl start
|
3.启动备库
1
2
3
4
5
6
|
SQL(db2)> startup
mount
;
SQL(db2)> alter database recover managed standby database cancel;
SQL(db2)> alter database
open
read
only;
如果要切换回recover manage模式(启动日志应用或者启动日志实时应用,二选一)
SQL(db2)> alter database recover managed standby database disconnect from session; 启动日志应用
SQL(db2)> alter database recover managed standby database using current logfile disconnect from session; 启动日志实时应用
|
4.启动主库,只有在启动备库之后才能启动
1
|
SQL(db1)> startup
|
关闭顺序:
1.关闭主库:
1
|
SQL(db1)>
shutdown
immediate;
|
2.关闭从库
1
2
|
SQL(db2)> alter database recover managed standby database cancel;
//
停止同步
SQL(db2)>
shutdown
immediate;
|
3.关闭主库监听:
1
|
[oracle@db1 ~]$ lsnrctl stop
|
4.关闭从库监听
1
|
[oracle@db2 ~]$ lsnrctl stop
|