一、DG介绍
1、什么是DG
Oracle Data Guard 是 Oracle 数据库内置的高可用性(HA)和灾难恢复(DR)解决方案,通过对主数据库的实时同步和监控,提供数据保护、故障恢复及负载均衡能力。
2、组成
(1)主数据库(Primary):处理生产事务的读写。
(2)备用数据库(Standby):从主库接收并应用重做日志,保持数据同步。
(3)Data Guard Broker:自动化管理集群配置、监控和故障切换。
3、原理
(1)日志传输与应用
主库将在线重做日志(Online Redo Logs)或归档日志(Archived Logs)传输到备用库。
备用库接收后,通过 Redo Apply 或 SQL Apply(仅逻辑备用)重放日志,保持数据一致性。
(2)三种模式
DG有种数据同步模式
最大性能(Maximum Performance)
异步传输日志,主库性能优先,可能丢失少量数据。
最大可用性(Maximum Availability)
同步传输,但允许主库在备用不可用时降级为异步模式。
最大保护(Maximum Protection)
强制同步传输,主库事务提交需等待备用确认,确保零数据丢失(若备用宕机,主库自动关闭)。
二、环境准备
1、环境信息
192.168.184.183
192.168.184.164
这些值在备库上暂时没有,等部署完再进行查看。
su - oracle
echo $ORACLE_SID
sqlplus / as sysdba
SELECT instance_name FROM v$instance;
SELECT value FROM v$parameter WHERE name = 'db_unique_name';
SELECT name FROM v$database;
SELECT value FROM v$parameter WHERE name='service_names';
2、主库环境准备
(1)主库基础环境安装
主库正常安装Oracle19c单机数据库即可。
可参考:
CentOS系统静默安装Oracle19c数据库
或者
CentOS系统下图形化界面安装Oracle19c数据库
(2)修改db_unique_name
这里我将db_unique_name改为orcl
SELECT value FROM v$parameter WHERE name='db_unique_name';
修改db_unique_name可参考:
如何修改DB_UNIQUE_NAME
(3)修改hostname
主库所在主机名修改为oracle19c
hostnamectl set-hostname oracle19c
hostname oracle19c
su -
(4)修改/etc/hosts
vim /etc/hosts
添加如下内容:
192.168.184.163 oracle19c
192.168.184.164 oracle19c-dg
3、备库环境准备
备库只需要安装数据库软件和监听,之后主库的所有参数、控制、数据文件都用ram的方式物理拷贝过来。
(1)修改主机名
hostnamectl set-hostname oracle19c-dg
hostname oracle19c-dg
su -
(2)修改/etc/hosts
vim /etc/hosts
添加如下内容:
192.168.184.163 oracle19c
192.168.184.164 oracle19c-dg
(3)配置network
vim /etc/sysconfig/network
添加如下内容:
NOZEROCONF=yes
HOSTNAME=oracle19c-dg
(4)备库安装Oracle和监听
注意!!这里只需要安装Oracle和监听,这个文档里的静默建库,不需要操作。
4、主库、备库修改监听配置
(1)主库修改listener.ora
su - oracle
vim /u01/app/oracle/product/19c/db_1/network/admin/listener.ora
新增如下内容:
# 新增主库静态监听
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = orcl) # 与 db_unique_name 一致
(ORACLE_HOME = /u01/app/oracle/product/19c/db_1)
(SID_NAME = orcl)
)
)
(2)备库库修改listener.ora
su - oracle
vim /u01/app/oracle/product/19c/db_1/network/admin/listener.ora
(3)主库修改tnsnames.ora
su - oracle
vim /u01/app/oracle/product/19c/db_1/network/admin/tnsnames.ora
(4)备库修改tnsnames.ora
su - oracle
vim /u01/app/oracle/product/19c/db_1/network/admin/tnsnames.ora
(5)测试主备tns监听
tnsping orcl
tnsping stddb
5、主库开启归档
主库开启归档,并重新设置归档目录,我这里已经设置好了,如果没设置的话,可参考:
如何开启数据库的归档模式
archive log list
6、打开数据库强制日志
alter database force logging;
7、查看归档模式和保护模式
select log_mode,force_logging from v$database;
8、开启数据库保护模式
这里根据需求进行选择,这里我选择最大性能
(1)最大保护模式
alter database set standby database to MAXIMIZE PROTECTION;
(2)最大性能
alter database set standby database to MAXIMIZE PERFORMANCE;
(3)最大可用
该模式需在mount下修改,并且备库已经做好了配置,否者主库检测不到可用备库会自动挂掉。
alter database set standby database to MAXIMIZE AVAILABILITY;
9、进行查看数据库同步模式
SELECT DATABASE_ROLE, OPEN_MODE, PROTECTION_MODE, DATAGUARD_BROKER FROM V$DATABASE;
10、增加redo log日志文件
(1)查询当前redo log日志文件数量以及目录
默认只有3个,但是redo在还没有传完备库的时候,3个文件都写满了,会导致无法归档,事务卡死等情况,所以这个尽量多点好。
SELECT GROUP#, MEMBER FROM V$LOGFILE;
(2)新增redo log文件
alter database add standby logfile group 4 ('/u01/app/oracle/oradata/ORCL/redo04.log') size 200M;
alter database add standby logfile group 5 ('/u01/app/oracle/oradata/ORCL/redo05.log') size 200M;
alter database add standby logfile group 6 ('/u01/app/oracle/oradata/ORCL/redo06.log') size 200M;
alter database add standby logfile group 7 ('/u01/app/oracle/oradata/ORCL/redo07.log') size 200M;
alter database add standby logfile group 8 ('/u01/app/oracle/oradata/ORCL/redo08.log') size 200M;
alter database add standby logfile group 9 ('/u01/app/oracle/oradata/ORCL/redo09.log') size 200M;
(3)再次查询
SELECT GROUP#, MEMBER FROM V$LOGFILE;
三、修改主库参数
1、LOG_ARCHIVE_CONFIG
这里的orcl和stddb是主备库的unique_name唯一名称 用来区分数据库
alter system set LOG_ARCHIVE_CONFIG='DG_CONFIG=(orcl,stddb)' scope=both sid='*';
2、LOG_ARCHIVE_DEST_1
这里填写主库本地归档日志路径 主库唯一名
alter system set LOG_ARCHIVE_DEST_1='LOCATION=/u01/app/arc_log VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=orcl' scope=both sid='*';
3、LOG_ARCHIVE_DEST_2
这里的service是备库的tns文件中的名称 后面的db_unique_name是备库的唯一名称,但这里备库的db_unique_name我们还未设置,后面我们会在备份的pflie文件中进行修改并设置的。
alter system set LOG_ARCHIVE_DEST_2='SERVICE=stddb LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=stddb'scope=both sid='*';
4、fal_client和fal_server
主库上fal_client指向自己,也就是orcl
主库上fal_server指向备库,也就是stddb
fal_client:
指定主库(Primary Database)向备库发送归档日志请求时使用的标识。
fal_server:
指定备库(Standby Database)在需要获取缺失的归档日志时,向主库(Primary Database)或其他中间服务器发起请求的目标地址。
alter system set fal_server='stddb' scope=both sid='*';
alter system set fal_client='orcl' scope=both sid='*';
5、DB_FILE_NAME_CONVERT
alter system set DB_FILE_NAME_CONVERT='/u01/app/oracle/oradata/ORCL','/u01/app/oracle/oradata/ORCL' scope=spfile sid='*';
6、LOG_FILE_NAME_CONVERT
alter system set LOG_FILE_NAME_CONVERT='/u01/app/oracle/oradata/ORCL','/u01/app/oracle/oradata/ORCL' scope=spfile sid='*';
四、主库进行备份
1、创建备份目录
su - oracle
mkdir -p /u01/app/oracle/oradata/rman_backup
2、拷贝密码文件
cp $ORACLE_HOME/dbs/orapworcl /u01/app/oracle/oradata/rman_backup
ll /u01/app/oracle/oradata/rman_backup
3、生成pfile文件
创建pfile文件并生成到备份目录中
create pfile='/u01/app/oracle/oradata/rman_backup/pfile.ora.1bak' from spfile;
查看生成的pfile文件
cd /u01/app/oracle/oradata/rman_backup/
ll
4、生成控制文件
创建当前主库的控制文件并生成到备份目录中
alter database create standby controlfile as '/u01/app/oracle/oradata/rman_backup/standby.ctl';
查看生成的控制文件
cd /u01/app/oracle/oradata/rman_backup/
ll
5、使用rman进行备份
(1)连接到rman
rman target /
(2)进行备份
进行备份操作
run{
allocate channel c1 type disk maxpiecesize=100m;
allocate channel c2 type disk maxpiecesize=100m;
backup database filesperset 4 format '/u01/app/oracle/oradata/rman_backup/ora_L0_%d_%T_%s_%p';
sql 'alter system archive log current';
sql 'alter system archive log current';
sql 'alter system archive log current';
backup archivelog all format '/u01/app/oracle/oradata/rman_backup/arch_L0_%d_%T_%s_%p' delete input; crosscheck backup;
crosscheck archivelog all;
}
五、备库进行恢复
1、创建目录
参照主库备份pfile文件中的路径进行创建目录
cd /u01/app/oracle/oradata/rman_backup
cat pfile.ora.1bak
在备库创建目录
su - oracle
mkdir -p /u01/app/oracle/oradata/ORCL/
mkdir /u01/app/arc_log
mkdir -p /u01/app/oracle/admin/orcl/adump
2、传输备份文件
主库将将备份文件都传到备库
scp -r /u01/app/oracle/oradata/rman_backup/ oracle@192.168.184.164:/u01/app/oracle/oradata/
3、查看备份文件
备库查看备份文件
cd /u01/app/oracle/oradata/
ll
ll rman_backup
4、拷贝密码文件
备库将备份的密码文件拷贝到$ORACLE_HOME/dbs目录下
(1)查看备份文件中的密码文件
su - oracle
cd /u01/app/oracle/oradata/rman_backup
ll
(2)拷贝并查看
cp orapworcl $ORACLE_HOME/dbs
ll $ORACLE_HOME/dbs
5、恢复控制文件
(1)主库查看控制文件路径
/u01/app/oracle/oradata/ORCL/control01.ctl
/u01/app/oracle/oradata/ORCL/control02.ctl
show parameter control
(2)将备份的控制文件按原路径进行拷贝
备库拷贝到相应路径,并将文件名称改为原来的样子
cp /u01/app/oracle/oradata/rman_backup/standby.ctl /u01/app/oracle/oradata/ORCL/control01.ctl
cp /u01/app/oracle/oradata/rman_backup/standby.ctl /u01/app/oracle/oradata/ORCL/control02.ctl
(3)查看备库的控制文件
cd /u01/app/oracle/oradata/ORCL/
ll
6、修改pfile文件
su - oracle
cd /u01/app/oracle/oradata/rman_backup/
vim pfile.ora.1bak
(1)db_unique_name 改为 stddb
(2)diagnostic_dest改为/u01/app/oracle
(3)fal_client改为stddb
备库上fal_client指向自己,也就是stddb,这个和主库的配置是正好是反着的
(4)fal_server改为orcl
备库上fal_server指向主库,也就是orcl,这个和主库的配置是正好是反着的
(5)local_listener
一般不用改,默认就是LISTENER_ORCL
(6)log_archive_config
指定切换对象 写主库tns文件中的名称,这个也不用改,和主库配置的一样即可。
(7)log_archive_dest_1改成备库的信息
这里写备库的归档日志存放路径和备库的唯一名
log_archive_dest_1='LOCATION=/u01/app/arc_log VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=stddb'
(8)log_archive_dest_2改成主库的信息
这里写tns文件中主库的名称和唯一名
log_archive_dest_2='SERVICE=orcl LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=orcl'
(9)db_file_name_convert
数据文件路径转换,前面是主库的路径 后面是备库的路径,一般不用改,这些目录都创建好了
(10)log_file_name_convert
日志文件转换路径,前面是主库的路径 后面是备库的路径,一般不用改,这些目录都创建好了
(11)audit_file_dest
审计日志路径,一般不用改,这些目录都创建好了
(12)db_name
默认不需要改
如下是整个配置:
orcl.__data_transfer_cache_size=0
orcl.__db_cache_size=2600468480
orcl.__inmemory_ext_roarea=0
orcl.__inmemory_ext_rwarea=0
orcl.__java_pool_size=0
orcl.__large_pool_size=16777216
orcl.__oracle_base='/u01/app/oracle'#ORACLE_BASE set from environment
orcl.__pga_aggregate_target=872415232
orcl.__sga_target=3439329280
orcl.__shared_io_pool_size=134217728
orcl.__shared_pool_size=671088640
orcl.__streams_pool_size=0
orcl.__unified_pga_pool_size=0
*.audit_file_dest='/u01/app/oracle/admin/orcl/adump'
*.audit_trail='db'
*.compatible='19.0.0'
*.control_files='/u01/app/oracle/oradata/ORCL/control01.ctl','/u01/app/oracle/oradata/ORCL/control02.ctl'
*.db_block_size=8192
*.db_file_name_convert='/u01/app/oracle/oradata/ORCL','/u01/app/oracle/oradata/ORCL'
*.db_name='orcl'
*.db_unique_name='stddb'
*.diagnostic_dest='/u01/app/oracle'
*.dispatchers='(PROTOCOL=TCP) (SERVICE=orclXDB)'
*.fal_client='stddb'
*.fal_server='orcl'
*.local_listener='LISTENER_ORCL'
*.log_archive_config='DG_CONFIG=(orcl,stddb)'
*.log_archive_dest_1='LOCATION=/u01/app/arc_log VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=stddb'
*.log_archive_dest_2='SERVICE=orcl LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=orcl'
*.log_archive_dest_state_1='ENABLE'
*.log_file_name_convert='/u01/app/oracle/oradata/ORCL','/u01/app/oracle/oradata/ORCL'
*.nls_language='AMERICAN'
*.nls_territory='AMERICA'
*.open_cursors=300
*.pga_aggregate_target=820m
*.processes=300
*.remote_login_passwordfile='EXCLUSIVE'
*.sga_target=3276m
*.undo_tablespace='UNDOTBS1'
7、备库使用pfile启动到nomount模式
su - oracle
sqlplus / as sysdba
startup pfile='/u01/app/oracle/oradata/rman_backup/pfile.ora.1bak' nomount;
8、创建spfile文件
备库使用pfile创建spfile文件
create spfile from pfile='/u01/app/oracle/oradata/rman_backup/pfile.ora.1bak';
备库查看spfile文件
cd /u01/app/oracle/product/19c/db_1/dbs/
ll
9、恢复控制文件
(1)进入rman
su - oracle
rman target /
(2)恢复控制文件
restore controlfile from '/u01/app/oracle/oradata/ORCL/control01.ctl';
restore controlfile from '/u01/app/oracle/oradata/ORCL/control02.ctl';
10、恢复数据文件
(1)备库启动数据到mount模式
之前这里使用pfile文件启动到nomout了,后又创建了spfile文件了,
我们关闭数据库,然后启动到mount
shutdown immediate;
startup mount;
(2)连接到rman
su - oracle
rman target /
(3)扫描备份文件
catalog start with '/u01/app/oracle/oradata/rman_backup';
下面哪个报错不影响,因为密码文件和备份的pfile文件不是数据的备份文件。
(4)恢复数据
run {
allocate channel c1 type disk maxpiecesize=100m;
allocate channel c2 type disk maxpiecesize=100m;
restore database ;
}
11、查看数据文件
查看数据文件恢复,现在所有的文件都跟主库一致了
ll /u01/app/oracle/oradata/ORCL
12、打开数据库
之前启动到数据到mount状态了
下面打开数据库
alter database open;
13、配置检查
(1)查看主备库的归档目录
archive log list
(2)查看主备库的归档路径参数
show parameter LOG_ARCHIVE_DEST_1;
show parameter LOG_ARCHIVE_DEST_2;
(3)查看数据一些名称
14、测试连接
(1)主库连备库
sqlplus sys/oracle@stddb as sysdba
(2)备库连主库
sqlplus sys/oracle@orcl as sysdba
六、进行配置DG
1、备库关闭数据库
shutdown immediate
2、备库启动到nomount
startup nomount;
3、以standby的方式启动备库到mount
alter database mount standby database;
4、更新会话,开启MRP0进程
此命令用于在 物理备用数据库(Physical Standby Database) 上启动 托管恢复(Managed Recovery),使备用库自动应用来自主库的归档日志或在线重做日志,保持与主库的数据同步。执行后会断开当前会话,恢复过程在后台持续运行。首次启动备用库时应用归档日志。
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;
5、关闭MRP0进程
alter database recover managed standby database cancel;
6、启动MRP0进程
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;
7、查看DG状态
查看DG状态,VALID代表正常
select dest_name,
status,
target,
ARCHIVER,
destination,
log_sequence,
valid_type,
valid_role
from V$ARCHIVE_DEST;
8、查看两台数据的状态,以及保护模式
select dest_name,
type,
database_mode,
recovery_mode,
protection_mode,
destination,
SRL,
GAP_STATUS
from V$ARCHIVE_DEST_STATUS;
9、查看redo log日志状态
select * from v$log;
select * from v$logfile;
七、进行测试
1、 Data Guard 角色验证
SELECT DATABASE_ROLE, PROTECTION_MODE FROM V$DATABASE;
2、主库切换日志组
(1)手动触发日志切换
SELECT * FROM V$LOGFILE;
(2)验证日志切换
在主库查询当前日志组状态
ALTER SYSTEM SWITCH LOGFILE;
3、备库应用日志查看
(1)查询托管恢复进程状态
SELECT PROCESS, STATUS, THREAD#, SEQUENCE#, BLOCK#, BLOCKS
FROM V$MANAGED_STANDBY;
(2)检查归档日志应用进度
SELECT MAX(SEQUENCE#) FROM V$ARCHIVED_LOG WHERE APPLIED = 'YES';
(3)查看未应用日志
SELECT SEQUENCE#, FIRST_CHANGE#, FIRST_TIME
FROM V$ARCHIVED_LOG
WHERE APPLIED = 'NO'
ORDER BY SEQUENCE#;
4、主库创建数据查看是否同步
(1)主库创建数据
CREATE TABLE student_info (
student_id NUMBER(10) PRIMARY KEY,
name VARCHAR2(50) NOT NULL,
gender CHAR(1) CHECK (gender IN ('M', 'F')),
birth_date DATE,
email VARCHAR2(100) UNIQUE,
create_time TIMESTAMP DEFAULT SYSTIMESTAMP
);
-- 单条记录插入
INSERT INTO student_info VALUES
(1, '张三', 'M', TO_DATE('2000-01-15', 'YYYY-MM-DD'), 'zhangsan@edu.cn', DEFAULT);
-- 多条记录插入
INSERT ALL
INTO student_info VALUES (2, '李四', 'M', DATE '2001-03-22', 'lisi@example.com', SYSTIMESTAMP)
INTO student_info VALUES (3, '王芳', 'F', TO_DATE('1999-12-05', 'YYYY-MM-DD'), 'wangfang@mail.com', DEFAULT)
SELECT * FROM DUAL;
commit;
SELECT * FROM student_info;
(2)备库进行查询
SELECT * FROM student_info;
八、常见问题
1、备库未应用最新日志
(1)现象:V$MANAGED_STANDBY 中 SEQUENCE# 未更新
select * from V$MANAGED_STANDBY
(2)解决办法
检查备库监听状态
lsnrctl status
验证备库的 LOG_ARCHIVE_DEST_2
SHOW PARAMETER LOG_ARCHIVE_DEST_2;
2、日志应用延迟
(1)现象:主库已切换日志,但备库未及时应用
(2)解决办法
主库手动刷新日志传输
ALTER SYSTEM ARCHIVE LOG CURRENT;
3、主库更新数据、从库未更新
(1)查询托管恢复进程状态
SELECT PROCESS, STATUS, THREAD#, SEQUENCE#, BLOCK#, BLOCKS
FROM V$MANAGED_STANDBY;
主库:
从库:
(2)重启MRP0进程
如果数据库重启过的话,要启动MRP0进程
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;