1. 前言
目前接触的项目是有对以oracle数据库的服务跨机房灾备/读压力分载这样的需求。从成本、需求等方面考虑,暂定为用oracle企业版免费提供的data guard(下称DG)操作实现跨机房灾备。
上有业务层的切换这里不做说明,仅说明DG作为灾备的方案如何选择合适的冷备方案。
另外,对于oracle11g版本的DG,可在备份数据的同时提供只读服务。
下面对DG说明它的工作方式,并附上简单部署实例。
2. Data Guide 用来做什么
提及Oracle数据同步、复制、备份等等这些关键字,其实Oracle本身作为商业型数据库就提供了很多的工具。但是侧重点不同,这里结合查询的资料大概说下,也可以作为实际环境中解决问题时一点参考。
RAC(real application clusters):实时应用集群,强项在于解决单点故障和负载均衡,因此RAC方案常用于7*24的核心系统,但RAC方案中的数据只有一份,尽管可以通过RAID等机制可以避免存储故障,但是数据本身是没有冗余的,容易形成单点故障。,比较适合短距离(单机房)内保障应用可用性。
DG:通过冗余数据来提供数据保护,通过日志同步机制保证冗余数据和主数据之前的同步,这种同步可以是实时,延时,同步,异步多种形式。Data Gurad常用于异地容灾和小企业的高可用性方案. Oracle 11g版本中增强物理Standby的应用功能,在11g版本中,物理Standby可以在OPEN READ ONLY模式下继续应用REDO数据,这就极大地提升了物理Standby数据库的应用场合。+
3. Data Guide 如何工作
名词解释:
Primary Database 主库
Standy Database 备库
Redo Log Oracle Redo Log 实时日志
3.1 架构
日志就是数据库操作的记录
DG架构按功能可分为3部分:
- 日志发送(Redo Send)
- 日志接收(Redo Receive)
- 日志应用 (Redo Apply)
3.1.1 日志发送
Primary Database运行过程中,会源源不断地产生Redo日志,这些日志需要发送到Standy Database。
DG支持2种方式发送,一种通过ARCH进程发送归档日志,一种通过LGWR发送实时日志。
可以看到都会占用数据库额外的一部分资源完成这项工作。
3.1.1.1 使用ARCH进程
这是默认方式,即主库日志归档时通过ARCH进程发送归档日志给备库。基本流程如下:
Primary Database不断产生Redo Log,这些日志被LGWR进程写到联机日志- 当一组联机日志被写满后,会发生日志切换
(Log Switch)并且会触发本地归档,本地归档位置是采用LOG_ARCHIVE_DEST_1='LOCATION=/path'这种格式定义的 - 完成本地归档后,联机日志就可以被覆盖重用
ARCH进程通过Net把归档日志发送给Standby Database的RFS(Remote File Server)进程Standby Database端的RFS进程把接收的日志写入到归档日志Standby Database端的MRP(Managed Recovery Process)进程(Redo Apply)或者LSP进程(SQL Apply)在Standby Database上应用这些日志,进而同步数据
可以看到,Primary Database只有在发生归档时才会发送日志到Standby Database,而且不写入备机的重做日志(Standby Redologs)。所以,如果Primary Database异常宕机,联机日志中的Redo内容就会丢失,因此使用ARCH进程无法避免数据丢失的问题。
要想避免数据丢失,就必须使用LGWR。
3.1.1.2 使用LGWR线程1
使用LGWR 又分SYNC(同步)和ASYNC(异步)两种方式。
3.1.1.2.1 SYNC同步方式
同步方式即主库的事务得确认日志写入成功才会提交。它的流程如下:
Primary Database产生的Redo日志要同时写到联机日志文件和本地的LNSn进程(LGWR Network Server Process),再由LNSn(LGWR Network Server process)进程把日志通过网络发送给远程的目的地,每个远程目的地对应一个LNS进程,多个LNS进程能够并行工作LGWR必须等待写入本地日志文件操作和通过LNSn进程的网络传送都成功,Primary Database上的事务才能提交,这也是SYNC的含义所在。Standby Database的RFS进程把接收到的日志写入到Standby Redo Log日志中。Primary Database的日志切换也会触发Standby Database上的日志切换,即Standby Database对Standby RedoLog的归档,然后触发Standby Database的MRP或者LSP进程恢复归档日志。
使用LGWR SYNC方式时,还可以同时使用NET_TIMEOUT参数,这个参数单位是秒,代表如果多长时间内网络发送没有响应,LGWR 进程会抛出错误。示例如下:(抛出错误不意味着失败,可以设置重试发送或者等待下一次归档时再次发送 2)
alter system set log_archive_dest_2 = 'SERVICE=ST LGWR SYNC NET_TIMEOUT=30' scope=both;
Question: 这里主库日志切换是redo日志组满了,备库那边的日志组是什么情况,和主库一样?
如果某次同步挂了,理论上备库的日志组大小要大于主库的日志组文件大小?另外下一次归档发送时主库日志一部分已归档,如何发送?
Reply:备库是用主库生成的standby controlfile建立实例的,日志组和主库一样。如何发送待测试:先停掉备库,主库操作不断归档日志,再开启备库看看同步情况
对于归档失败的处理,LOG_ARCHIVE_DEST_n参数有几个属性,可以用来控制归档过程中出现故障时应该采取的措施。
REOPEN
指定时间后再次尝试归档,默认300s
MAX_FAILURE
控制失败尝试次数
LOG_ARCHIVE_DEST_1='LOCATION=E:/ora10g/oradata/jsspdg/ REOPEN=100 MAX_FAILURE=3'
ALTERNATE
指定替补的归档目的地
LOG_ARCHIVE_DEST_1='LOCATION=/disk1 ALTERNATE=LOG_ARCHIVE_DEST_2'
// REOPEN优先级更高,先重试再替补
3.1.1.2.2 ASYNC异步方式
显然同步方式受网络影响,而且比较影响主库性能。超时时间设置也要考虑网络延迟的影响。不过同步方式能有效的保证数据准确性。
异步方式不要求网络日志写入成功,基本流程如下:
Primary Database一段产生Redo日志后,LGWR把日志同时提交给日志文件和本地LNS进程,但是LGWR进程只需成功写入日志文件就可以,不必等待LNSn进程的网络传送成功LNSn进程异步地把日志内容发送到Standby Database。多个LNSn进程可以并发发送Primary Database的Online Redo Log写满后发生Log Switch触发归档操作,也触发Standby Database对Standby Redo Log的归档;然后触发MRP或者LSP进程恢复归档日志
3.1.2 日志接收
Standby Database的RFS(Remote File Server)进程接收到日志后,就把日志写到Standby Redo Log或者Archived Log文件中。具体写入哪个文件,取决于Primary的日志传送方式和Standby database的位置。
3.1.3 日志应用
日志应用服务,就是在Standby Database上重演Primary Database日志,从而实现两个数据库的数据同步。
根据Standby Database重演日志方式的不同,可分为物理Standby(Physical Standby)和逻辑Standby(Logical Standby)。
根据Redo Apply发生的时间可以分成两种: 实时应用(Real-Time Apply)和归档时应用。
物理Standby:
接收完Primary数据库生成的REDO数据后,以介质恢复的方式实现同步,这种方式也叫Redo Apply。没有数据类型的限制,可以保证两个数据库完全一致。只能在Mount 状态下进行恢复,11g版本后可以以同时只读方式打开。
逻辑Standby:
接收后将其转换成SQL语句,在Standby数据库上执行SQL语句实现同步,这种方式叫SQL Apply。不支持所有数据类型,可以在视图DBA_LOGSTDBY_UNSUPPORTED 中查看不支持的数据类型,如果使用了这种数据类型,则不能保证数据库完全一致。可以在恢复的同时进行读写操作。
创建
逻辑Standby数据库要先创建一个物理Standby数据库,然后再将其转换成逻辑Standby数据库。
实时应用(Real-Time Apply),:
这种方式必须Standby Redo Log,每当日志被写入Standby Redo Log时,就会触发恢复,使用这种方式的好处在与可以减少数据库切换(Switchover 或者Failover)的时间,因为切换时间主要用在剩余日志的恢复上。
归档时应用:
这种方式在Primary Database发生日志切换,触发Standby Database 归档操作,归档完成后触发恢复。 这也是默认的恢复方式。
-- Physical Standby启用Real-Time:
Alter database recover managed standby database using current logfile;
-- Logical Standby启用Real-Time:
Alter database start logical standby apply immediate;
-- 查看是否使用Real-Time apply:
Select recovery_mode from v$archive_dest_status;
某些情况下你可能不希望Standby数据库与Primary太过同步,那就可以在Primary数据库端发送REDO数据的相应LOG_ARCHIVE_DEST_n参数中指定DELAY属性(单位为分钟,如果指定了DELAY属性,但没有指定值,则默认是30分钟)。
ALTER SYSTEM SET LOG_ARCHIVE_DEST_3='SERVICE=DavePrimary ARCH VALID_ FOR=
(ONLINE_LOGFILES, PRIMARY_ROLE) DB_UNIQUE_NAME=Dave DELAY=15';
-- 物理Standby可以通过下列语句取消延迟应用:
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE NODELAY;
-- 逻辑Standby可以通过下列语句取消延迟应用:
ALTER DATABASE START LOGICAL STANDBY APPLY NODELAY;
3.2 数据保护模式
Data Guard 允许定义3钟数据保护模式:
- 最大保护(Maximum Protection)
- 最大可用(Maximum Availability)
- 最大性能(Maximum Performance)
3.2.1 最大保护
要求所有的事务在提交前其REDO不仅被写入到本地的Online Redologs,还要同时写入到Standby数据库的Standby Redologs,并确认REDO数据至少在一个Standby数据库中可用(如果有多个的话),然后才会在Primary数据库上提交。如果出现了什么故障导致Standby数据库不可用的话(比如网络中断),Primary数据库会被Shutdown,以防止数据丢失。
可以看到,必须有一个备库同步成功,主库事务才提交。如果只有一个备库,是完全保证主备库数据一致的。
结合前面我们知道这种方式也就是使用LGWR线程同步发送并且AFFIRM。
3.2.2 最高可用
与最大保护模式类似,也是要求本地事务在提交前必须至少写入一台Standby数据库的Standby Redologs中,不过与最大保护模式不同的是,如果出现故障导致Standby数据库无法访问,Primary数据库并不会被Shutdown,而是自动转为最高性能模式,等Standby数据库恢复正常之后,Primary数据库又会自动转换成最高可用性模式。
结合前面我们知道这种方式也是使用LGWR线程同步发送并且AFFIRM 3。
Question: 这里怎么设置的?和最大保护如何区别,如果不设置超时时间,怎么判定备库不可用,而此时主库如何做?设置超时时间也是类似,超时是shutdown还是commit?
参见[设置保护模式](#3.2.4 设置保护模式)
3.2.3 最高性能
默认方式,归档方式或异步方式发送日志,事务的提交不依赖于网络日志的写入 4。
可以LGWR ASYNC 或者ARCH。
Question:这里事务提交会确认本地日志写成功吗?应该是的,否则就很容易出问题
3.2.4 设置保护模式
上面的疑问可以取消了,数据库有参数设置的。
-
关闭数据库,重启到Mount 状态,如果是RAC,需要关闭所有实例,然后只启动一个实例到mount状态。
-
修改模式:
-- {PROTECTION | AVAILABILITY | PERFORMANCE} ALTER DATABASE SET STANDBY DATABASE TO MAXIMIZE PERFORMANCE; -
打开数据库: alter database open;
-
确认修改数据保护模式
select protection_mode,protection_level from v$database;
3.3 裂缝检测和解决
当Primary Database的某些日志没有成功发送到Standby Database,这时候发生了归档裂缝(Archive Gap)。缺失的日志就是Gap。
3.3.1 自动检测解决
Data Guard能够自动检测,解决归档裂缝,不需要DBA的介入。这需要备库配置FAL_CLIENT,FAL_SERVER 这两个参数。
FAL_CLIENT和FAL_SERVER两个参数都是Oracle Net Name。FAL_CLIENT 通过网络向FAL_SERVER发送请求,FAL_SERVER通过网络向FAL_CLIENT发送缺失的日志。FAL_CLIENT向FAL_SERVER发送请求时,会携带FAL_CLIENT参数值,用来告诉FAL_SERVER应该向哪里发送缺少的日志。 这个参数值也是一个Oracle Net Name,这个Name是在FAL_SERVER上定义的,用来指向FAL_CLIENT.
3.3.2 手工检测解决
-
查看是否有日志GAP:
SELECT UNIQUE THREAD#, MAX(SEQUENCE#) OVER(PARTITION BY THREAD#) LAST FROM V$ARCHIVED_LOG; SELECT THREAD#, LOW_SEQUENCE#, HIGH_SEQUENCE# FROM V$ARCHIVE_GAP; -
如果有,则拷贝过来
-
手工的注册这些日志:
ALTER DATABASE REGISTER LOGFILE '路径';
3.4 指定日志发送对象
3.4.1 VALID_FOR
LOG_ARCHIVE_DEST_n参数中的VALID_FOR属性,用来指定传输的内容,该属性有两个参数值需要指定:REDO_LOG_TYPE和DATABASE_ROLE。该参数的主要目的是为了确保,一旦发生角色切换操作后数据库的正常运转。
REDO_LOG_TYPE:
ONLINE_LOGFILE、STANDBY_LOGFILE、ALL_LOGFILES。
DATABASE_ROLE:
PRIMARY_ROLE、STANDBY_ROLE、ALL_ROLES。
3.4.2 DB_UNIQUE_NAME
DB_UNIQUE_NAME作用是指定唯一的Oracle数据库名称,保证REDO数据在传输过程中才能确认传输到DBA希望被传输到的数据库上。
要确保REDO数据被传输到指定服务器,除了在LOG_ARCHIVE_DEST_n参数中指定正确DB_UNIQUE_NAME属性之外,还有一个初始化参数LOG_ARCHIVE_CONFIG也需要进行正确的配置。该参数除了指定Data Guard环境中的唯一数据库名外,还包括几个属性,用来控制REDO数据的传输和接收:
-- SEND:允许数据库发送数据到远端。
-- RECEIVE:允许Standby接收来自其他数据库的数据。
-- NOSEND,NORECEIVE:自然就是禁止喽。
LOG_ARCHIVE_CONFIG='NORECEIVE,DG_CONFIG= (PRI,ST) '
4. 示例
本机使用docker完成实例,后面尽可能复现些异常情况。
借助与docker容器占用轻量资源以及容器间暴露的端口默认互通,数据库之间的网络是连通的。
这里把整个操作流程总结下。
4.1 资源准备
| hostname | ip | db_name | db_unique_name | net service name |
|---|---|---|---|---|
| db1 | 172.17.0.2 | orcl | primary | orcl |
| db2 | 172.17.0.3 | orcl | standby | orcl |
4.1.1 安装oracle
4.1.1.1 下载oracle11g镜像
docker pull registry.cn-hangzhou.aliyuncs.com/jydsun/oracle11g_ssg:1.04
登陆账号:root/install oracle/install
实例密码:sys/oracle
其实都用不着,在docker里直接获取到root权限,切换oracle用户就有sysdba权限
4.1.1.2 启动容器
# primary
docker run -d --name db1 -p 15211:1521 -v /mnt/hgfs/E/Workspace/Database/Oracle/data/db1:/data/oracle_data -e oracle_allow_remote=true registry.cn-hangzhou.aliyuncs.com/jydsun/oracle11g_ssg:1.04
# standby
docker run -d --name db2 -p 15212:1521 -v /mnt/hgfs/E/Workspace/Database/Oracle/data/db2:/data/oracle_data -e oracle_allow_remote=true registry.cn-hangzhou.aliyuncs.com/jydsun/oracle11g_ssg:1.04
4.2 DG部署
另外了解到oracle对dg也是有个管理工具DG_Broker的,可以帮助dba快速部署dg,这里给个链接了解下 DG_Broker配置。
以下是手工部署的过程,使用broker更简单点,但其实最终也是帮助生成以下过程中的参数设置等等,所以这里展示下手工的全过程,帮助了解每个细节点。(其实是之前根本不知道db_broker,后来才知道有这玩意,不然我也想先用broker啊…后面再补充个文档吧,o(╥﹏╥)o)
4.2.1 开启主库归档并设置强制日志
--干净的关闭数据库
SQL> shutdown immediate
--以mount模式启动
SQL> startup mount
--切换到归档模式
SQL> alter database archivelog;
--开启强制日志
SQL> alter database force logging;
--打开数据库
SQL> alter database open;
--查看归档
SQL> archive log list;
--查看是否为强制日志
SQL> select force_logging from v$database;
4.2.2 添加主库Standby Redo Log
--查看Redo和Standby Redo
SQL> select * from v$logfile;

最低0.47元/天 解锁文章
5683

被折叠的 条评论
为什么被折叠?



