1 DG物理架构
- 主库
有oracle软件,database(datafile、control、redo等)共同构成了数据库。如果主机坏了,数据库就不能访问了。 - 备库
只有操作系统os和一个oracle软件。把主库的database通过rman备份,然后将备份片传到备库上。它们的一切信息都是一样的,所以db_name等都是一样的。(在rman备份前要确定数据库是归档模式,因为rman必须在归档模式下进行操作。)
DG是一项Oracle自带的功能,利用它设立一个备用数据库,备用数据库可达到与主库数据实时同步的左右。当主库发生故障时,备库的存在可以保证数据不会丢失多于一个事务所造成的影响(网络条件理想的状态下)。
ADG的作用则是当主库故障或因其他原因无法使用时,备库可以几乎无缝承担起主库的事务。
2 准备工作
2.1 相关名字
db_unique_name
备份完的数据文件,数据文件头部记录的信息都是属于主库的,所以它们的db_name
是相同的,所以需要用db_unique_name
加以区分。instance_name
就是SID,可以和db_name
不一样service_names
提供服务的数据库的名字
除了db_name
后三个名字都可以修改
2.1.1 节点及实例名
主库 primary | 备库 standby | |
---|---|---|
hostname | yr | YAORAO |
db_name | orcl | orcl |
db_unique_name | orcl_pri | orcl_std |
service_names | oradb_pri | orcadb_std |
global_name | orcl_pri | orcl_std |
2.1.2 网络配置
主库 primary | 备库 standby | |
---|---|---|
OS_version | Oracle Linux 5.7 | Oracle Linux 5.7 |
IP_ADDRESS | 192.168.233.250 | 192.168.233.2 |
2.2 OS network
- 配置网络环境和host文件
vi /etc/hosts
需要分别在主库和备库的/etc/hosts文件里添加主库和备库的host的IP和name(注意是在root用户下更改)
主库primary 192.168.233.250
备库standby 192.168.233.2
- 验证主、备库是否连通
# 主库--->备库
ping 192.168.233.250
# 备库--->主库
ping 192.168.233.2
3 主库准备工作
3.1 修改数据库的name参数
- 查看数据库的name参数
- 设置主库的
service_names
是orcl_pri
SQL>alter system set service_names='orcl_pri';
- 设置主库的
db_unique_name
为orcl_pri
SQL>alter system set db_unique_name='orcl_pri' scope=spfile;
DB_UNIQUE_NAME是一个静态参数,不能马上生效,需要重启后生效。
- 重新启动数据库后再次查看name参数
SQL> show parameter name
3.2 配置主库TNS
TNS的作用是表明备库的各类地址信息,系统需要通过访问这个文件准确的与备库取得联系。所以不论是主机还是备机,SCN当中的内容都是对方的信息。
1.listener.ora
由于主库的监听在安装Oracle时就已经安装了,所以不用单独配置,可以直接开启监听。
- 查看主库监听状态
使用oracle用户
文件listener.ora记录了IP ADDRESS、port、db_name/service_name等信息,监听相当于“发射塔”,公布了自己的坐标、名字等。
其中,
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=yr)(PORT=1521)))
# tcp 网络协议
# host 主机名
# port 端口号
# TNS-12541: TNS:no listener 表示当前没有监听者
- 打开主库监听
[oracle@yr ~]$ lsnrctl start
- 再次查看主库监听信息
status是READY表示监听为开启状态。其中,orclXDB是数据库自己的一个。
2.配置主库的tnsname.ora
[oracle@yr admin]$ cd $ORACLE_HOME/network/admin
[oracle@yr admin]$ vi tnsnames.ora
3.3 配置主库归档模式
主备数据库实现数据同步的基础是主库的归档日志可以实时共享给备库,而这个功能就是通过修改的主库的归档日志位置信息,将备库的位置添加到主库当中去。
- 查看主库是否为归档模式
SQL> archive log list;
- 在mount状态下,打开主库的归档
SQL> shutdown immediate
SQL> startup mount;
SQL> alter database archivelog;
- 设置数据库强制归档,强制数据库记录log,记录在redo里
SQL>alter database force logging;
- 配置闪回区
1.设置dest_1为本地
SQL> alter system set log_archive_dest_1='location=/u01/app/oracle/fast_recovery_area valid_for=(all_logfiles,all_roles) db_unique_name=orcl_pri';
2.设置dest_2为备库
SQL> alter system set log_archive_dest_2='service=orcl_std lgwr async valid_for=(online_logfiles,primary_role) db_unique_name=orcl_std';
通过lgwr来写,async是异步。
也就是说,所有的业务都访问主库,备库只能read only。要写数据就是往主库里写,传输是通过数据块。
主库接收到备库的信息,就是同步,在主库没有接收到备库的收到信息之前,不进行其他操作,但这样会影响主库的工作效率。
异步就是即使没收到备库的信息,也不影响自己的工作。
- 添加所有成员
列出所有的主备库
SQL> alter system set log_archive_config='dg_config=(orcl_pri,orcl_std)';
3.4 FAL参数
FAL是fetch archived log指获取归档日志。
fal_server
指定一个service name,standby数据库使用。
SQL> alter system set fal_server=orcl_std;
fal_client
是方便fal server引用standby库。
SQL> alter system set fal_client=orcl_pri;
如果在传输中,中断了,只有配置了这个参数,备库才可以主动从主库要东西,把缺少的内容要来,所以这个时候,备库才相当于一个服务端,向它的“客户”——主库去要东西。
- 设置备库的文件管理方式是自动的
SQL> alter system set standby_file_management=auto;
为什么要在主库配置的时候去配置备库的文件管理方式呢?
因为如果主库坏了,备库还在备份,是实时传输的,所以最少丢失的数据单位是一个事务。
因此,这时备库出来服务的时候,切换成了failover,备库脱离了这个环境,就成为了一个独立的库了。在测试两个库是否一样,能否独立工作,是用switchover,这个时候,备库就成了主库,主库便成了备库,所以这个时候,备库就要standby了。
3.5 备份主库文件
主库文件的备份包括数据文件、控制文件、归档文件、密码文件、初始化参数文件的备份。
- 创建备份片存放目录
mkdir /u01/oracle/rman_bak/
- 备份数据文件和归档日志文件
rman target /
run{
allocate channel c1 type disk;
allocate channel c2 type disk;
allocate channel c3 type disk;
allocate channel c4 type disk;
backup as compressed backupset database include current controlfile format '/u01/oracle/rman_bak/full_%U_%t.bak'
backup as compressed backupset archivelog all format '/u01/oracle/rman_bak/arch_%U_%t.bak'
release channel c1;
release channel c2;
release channel c3;
release channel c4;
}
- 备份控制文件
SQL> alter database create standby controlfile as '/u01/oracle/rman_bak/control.ctl.std';
因为是给备库创建的,所以叫standby controlfile
- 备份初始化参数文件
SQL>create pfile='/u01/oracle/rman_bak/initorcl.ora' from spfile;
- 通过scp传输给备库
SQL> scp *1001* oracle@192.168.233.2:/u01/oracle/rman_bak/
SQL> scp control.ctl.std initorcl.ora orapworcl oracle@192.168.233.2:/u01/oracle/rman_bak/
- 在备库的/u01/oracle/rman_bak/路径下查看:
4 备库准备工作
开始配置备库之前,首先需要再次确认备库的Oracle数据库版本是否与主库相同,且service_name、unique_name和hostname主备库不能相同。
备库的准备工作包括配置TNS、监听与测试备库与主库的连接。
4.1 配置备库TNS
备库的TNS内容均为主库的信息
- 修改备库tnsnames.ora
tnsnames.ora文件记录了服务器名和其对应的信息。包括要连谁的IP、端口号、以及service name的所有信息
[oracle@YAORAO admin]$ cd $ORACLE_HOME/network/admin
[oracle@YAORAO admin]$ vi tnsnames.ora
oradb_pri = # 主库的service_name
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.233.250)(PORT = 1521)) # HOST是主库的IP PORT端口号一般是默认的
)
(CONNECT_DATA =
(SERVICE_NAME =orcl_pri) # 主库的service_name
)
)
4.2 配置备库监听
vi $ORACLE_HOME/network/admin/listener.ora
# 文件内容
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.233.2)(PORT = 1521))
) # 备库的HOST
)
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = /u01/app/oracle/product/11204/db_1) # 备库的ORACLE_HOME
(PROGRAM = extproc)
)
(SID_DESC =
(GLOBAL_DBNAME = orcl_std)
(SERVICE_NAME = orcl_std)
(ORACLE_HOME = /u01/app/oracle/product/11204/db_1) # 备库的ORACLE_HOME
(SID_NAME = orcl)
)
)
必须重启后这个文件才生效
可以先看下状态
[oracle@YAORAO admin]$ lsnrctl stat
如果是启动状态就要先通过lsnrctl stop
命令关掉监听,再通过lsnrctl start
命令打开监听。现在再查看lsnrctl stat
监听状态,可以看到orcl_std
有一个实例orcl
。
注意,如果再在编辑listener.ora时,global_dbname和service_name不同,那么下面的service会显示为“orcl”
4.3 测试备库与主库的连接
1.检查主库和备库的监听是否正常,tnsname能否ping
- 备库的监听文件
- 主库的监听文件
2.使用tnsping测试主库与备库是否连接 - 备库ping主库
5 备库数据恢复
目前已经准备好了回复所需的全部文件,现在需要一步一步的利用主库传输过来的数据恢复备库,并建立主库与备库的实时共享。
5.1 修改初始化参数
cp /u01/oracle/rman_bak/initorcl.ora $OEACLE_HOME/dbs/
vi initorcl.ora
orcl.__db_cache_size=352321536
orcl.__java_pool_size=4194304
orcl.__large_pool_size=8388608
orcl.__oracle_base='/u01/app/oracle'#ORACLE_BASE
set from environment # 备库的oracle_base
orcl.__pga_aggregate_target=335544320
orcl.__sga_target=499122176
orcl.__shared_io_pool_size=0
orcl.__shared_pool_size=125829120
orcl.__streams_pool_size=0
*.audit_file_dest='/u01/app/oracle/admin/orcl/adump' # 数据库审计时候的默认地址
*.audit_trail='db'
*.compatible='11.2.0.4.0'
*.control_files='/u01/app/oracle/oradata/orcl/control01.ctl','/u01/app/oracle/oradat
a/orcl/control02.ctl'
*.db_block_size=8192
*.db_domain=''
*.db_name='orcl'
*.db_recovery_file_dest_size=42949672960
*.db_recovery_file_dest='/u01/app/oracle/fast_recovery_area' # 闪回区地址,可以随意创建
*.db_unique_name='orcl_std' # 由orcl_pri改成orcl_std
*.diagnostic_dest='/u01/app/oracle' # $ORACLE_BASE目录
*.dispatchers='(PROTOCOL=TCP) (SERVICE=orclXDB)'
*.fal_client='ORCL_STD' # 这里和主库对调
*.fal_server='ORCL_PRI'
*.log_archive_config='dg_config=(orcl_pri,orcl_std)'
*.log_archive_dest_1='location=/u01/app/oracle/fast_recovery_area
valid_for=(all_logfiles,all_roles) db_unique_name=orcl_std' # 归档日志存放在本地的位置,由orcl_pri改成orcl_std
*.log_archive_dest_2='service=orcl_std lgwr async valid_for=(online_logfiles,primary_role) db_unique_name=orcl_std' # 由orcl_pri改成orcl_std
*.log_archive_format='%t_%s_%r.dbf'
*.memory_target=833617920
*.open_cursors=300
*.processes=150
*.remote_login_passwordfile='EXCLUSIVE'
*.service_names='orcl_std'
*.standby_file_management='AUTO'
*.undo_tablespace='UNDOTBS1'
注意复制粘贴的时候,要看行号,以前一行的一定还要在一行。
5.2 将口令文件放到默认目录
cp /u01/oracle/rman_bak/orapworcl $OEACLE_HOME/dbs/
5.3 恢复控制文件
- 先在nomount状态下打开数据库
SQL>startup nomount pfile='/u01/oracle/rman_bak/initorcl.ora'
- 通过rman恢复控制文件
[oracle@YAORAO rman_bak]$ rman target /
RMAN> restore controlfile from '/u01/oracle/rman_bak/control.ctl.std';
注意,要先在参数文件里找到控制文件的存放地址
*.control_files='/u01/oracle/rman_bak/control.ctl.std'
- 通过standby的控制文件mount数据库
SQL> alter database mount standby database;
现在数据库是mount状态。
5.4 恢复数据文件
-
主库的数据文件地址:
/u01/app/oracle/oradata/orcl
-
备库的数据文件地址:
/u01/oracle/rman_bak/
-
通知控制文件备份片位置
RMAN>catalog start with '/u01/oracle/rman_bak/';
目标端存储备份片的地址和源端不同,但是控制文件记录的信息是源端存储备份片的位置,所以要通知控制文件备份片的地址在哪里
- 恢复数据文件先去主库找datafile的地址,一一建在备库上。
- 恢复数据文件
RMAN> restore database;
- 查看告警日志
[oracle@YAORAO trace]$ pwd
/u01/app/oracle/diag/rdbms/orcl_std/oradb/trace
[oracle@YAORAO trace]$ tail -f alert_orcl.log
根据告警日志中的报错信息,进行更改
5.5 创建spfile参数文件
创建spfile文件:
SQL> create spfile from pfile='/u01/app/oracle/product/11204/db_1/dbs/initorcl.orc';
5.6 开启备库实时
备份的文件恢复的数据库是之前备份的那一时刻,因此需要用归档日志去追从过去到现在,所以要去读归档日志的条目。
- 备库进行日志恢复
SQL> recover managed standby database disconnect from session;
recover文件,并且管理数据库
disconnect from session:把recover的动作放到后台去自己执行,和前端断开
- 在备库停止日志恢复
SQL>alter database recover managed standby database cancel;
备库停掉recover的动作,但是对于主库来说,依旧还在传送日志条目和归档文件,只要网络通,就会一直传
- 恢复主库到备份的日志传输
alter system set log_archive_dest_state_2=enable;
恢复主库到备份的日志传输,暂停日志传输后的归档日志会全部传输到备库,不会导致备库的归档日志 gap
- 手动启动日志应用,备库:
SQL> alter database recover managed standby database disconnect from session;
这时如果在主库手动切换日志,备库存归档日志文件的相应地址有内容时,就是连好了。
6 ADG
- 打开备库
备库打开后,它的open_mode打开模式依旧是read only。因为DG只能read only,也可以实时接收,但不能recover。
ADG(Active Data Guard)是活跃的,数据能同步的备库。并且ADG可以读写分离。其中,读的地址连在备库,写的地址连在主库。
6.1 Standby redo log
1.SRL只有在数据库是standby角色是才起作用,建议为primary也配置SRL只是为了以后主库备库切换时不用再次设置
2. standby上SRL完全等同于primary上的ORL(Online redo log),在primary发生日志切换时,Remote File System(RFS)进程把primary上的ORL写到standby的SRL,同时standby归档上一个SRL
3. standby通过应用并归档SRL以达到与primary一致。主库如果有n组,那么备库要建立n+1组,bytes要一样大
- 查看主库有多少日志组
SQL> select * from v$log;
- 查看主库log的大小
SQL> select bytes/1024/1024 from v$log;
因为主库有5组,那么备库需要创建5+1组(不考虑成员)
SQL> alter database add standby logfile group 6 ('/u01/app/oracle/oradata/log_member1/stby_redo06.log') size 70m;
6.2 打开备库实时同步
SQL> alter database open read only;
SQL> alter database recover managed standby database using current logfile disconnect from session;
SQL> select open_mode from v$database;
此时备库的打开状态发生了变化:可以应用了
此时备库已经是ADG状态了,在主库修改文件,并提交,备库就能实现实时同步了。
- 在主库的test表插入两行数据并提交
- 在备库查看test表的内容
如果主库不commit,备库就看到的是提交前的状态。
配置好standby redo log的话,就可以达到事务级的保护。
7 主备库切换
7.1 查看自己的身份
SQL> select database_role from v$database;
- 主库
- 备库
7.2 查看当前状态
SQL> select switchover_status from v$database;
-
主库
查询结果是TO STANDBY 或 SESSIONS ACTIVE表明可以进行切换; -
备库
查看备库的状态,查询结果为TO PRIMARY 或 SESSIONS ACTIVE表明可以切换成主库;
7.3 将主库切换为备库
- 将数据库切换为standby(备库)状态,此sql执行后,数据库默认关闭,需重启数据库
SQL> alter database commit to switchover to physical standby;
- 将主库启动之mount状态
SQL> startup mount;
- 查看数据库状态,结果为PHYSICAL STANDBY 说明切换成功
SQL> select database_role from v$database;
- 将数据库开启至open
SQL> alter database open;
7.4 将备库切换为主库
- 将数据库切换为primary(主库)状态,此sql执行之后,数据库默认跳到mount状态,需再次open数据库
SQL> alter database commit to switchover to primary with session shutdown;
- 开启数据库
SQL> alter database open;
- 查询数据库状态,结果为FAILED DESTINATION,PRIMARY,READ WRITE说明切换主库成功
SQL> select switchover_status,database_role,open_mode from v$database;
7.5 验证数据同步
- 打开备库应用日志功能,在新备库(之前的主库)执行
SQL> alter database recover managed standby database using current logfile disconnect from session;
- 验证主备库数据是否同步:在主库切换logfile,多次切换验证 Current log sequence 是否同步
SQL> alter system switch logfile;
- 在主备库分别查看归档日志序列号是否一致,多次切换后主备库的Current log sequence相同,则DG无异常
- 此时在新主库修改内容,备库实时变化
新主库
新备库
没有和主库同步是因为主库没有提交事务,这是事务级保护 - 主库提交事务
- 备库实时同步