Loading... # 一、高可用产品对比 ## 1.1 什么是高可用 > HA 是 High Availability可以叫做高可用,或高可用性,高可用(环境), 是分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计减少系统不能提供服务的时间。 > 如果系统每运行100个时间单位,会有1个时间单位无法提供服务,我们说系统的可用性是99%。很多公司的高可用目标是4个9,也就是99.99%,这就意味着,系统的年停机时间为8.76个小时。百度的搜索首页,是业内公认高可用保障非常出色的系统,甚至人们会通过baidu能不能访问来判断“网络的连通性”,百度高可用的服务让人留下啦“网络通畅,百度就能访问”,“百度打不开,应该是网络连不上”的印象,这其实是对百度HA最高的褒奖。 > 众所周知,单点是系统高可用的最大的风险和敌人,应该尽量在系统设计的过程中避免单点。在方法论上高可用保证的原则是“集群化”,或者叫“冗余”。只有一个单点,挂了服务会受影响;如果有冗余备份,那么挂了还有其它备份能够继续提供服务。 > RAC提供了实例级别的冗余,DG提供了数据存储级别的冗余。若要保证系统高可用,则架构设计的核心准则是:冗余。有了冗余之后,还不够,毎次岀现故障需要人工介入恢复势必会增加系统的不可服务实践。所以,又往往是通过“自动故障转栘″来实现系统的高可用 > Oracle failsafe、Data Guard 和 RAC 均为 ORACLE 公司提供的高可靠性(HA)解决方案.然而之三者之间却存在着很大区别.,但是这几种方案之间却存在着很大区别. ## 1.2 FAILSAFE 和RAC的区别 **1).操作系统** > failsafe 系统局限于 WINDOWS 平台,必须配合 MSCS(microsoft cluster server),而 RAC 最早是在 UNIX 平台推出的,目前已扩展至 LINUX 和 WINDOWS 平台,通过 OSD(operating system dependent)与系统交互.对于高端的 RAC 应用,UNIX 依然是首选的平台. **2).系统结构** > FAILSAFE 采用的是 SHARE NOTHING 结构,即采用若干台服务器组成集群,共同连接到一个共享磁盘系统,在同一时刻,只有一台服务器能够访问共享磁盘,能够对外提供服务.只要当此服务器失效时,才有另一台接管共享磁盘.RAC 则是采用 SHARE EVERYTHING,组成集群的每一台服务器都可以访问共享磁盘,都能对外提供服务.也就是说 FAILSAFE 只能利用一台服务器资源,RAC 可以并行利用多台服务器资源. **3).运行机理** > 组成 FAILSAFE 集群的每台 SERVER 有独立的 IP,整个集群又有一个 IP,另外还为 FAILSAFE GROUP 分配一个单独的 IP(后两个 IP 为虚拟 IP,对于客户来说,只需知道集群 IP,就可以透明访问数据库).工作期间,只有一台服务器(preferred or owner or manager)对外提供服务,其余服务器(operator)成待命状,当前者失效时,另一服务器就会接管前者,包括FAILSAFE GROUP IP与CLUSTER IP,同时FAILSAFE会启动上面的DATABASE SERVICE,LISTENER 和其他服务.客户只要重新连接即可,不需要做任何改动.对于 RAC 组成的集群,每台服务器都分别有自已的 IP,INSTANCE 等,可以单独对外提供服务,只不过它们都是操作位于共享磁盘上的同一个数据库.当某台服务器失效后,用户只要修改网络配置,如(TNSNAMES.ORA),即可重新连接到仍在正常运行的服务器上.但和 TAF 结合使用时,甚至网络也可配置成透明的. **4).集群容量** > 前者通常为两台,后者在一些平台上能扩展至 8 台. **5).分区** > FAILSAFE 数据库所在的磁盘必须是 NTFS 格式的,RAC 则相对灵活,通常要求是 RAW,然而若干 OS 已操作出了 CLUSTER 文件系统可以供 RAC 直接使用.综上所述,FAILSAFE 比较适合一个可靠性要求很高,应用相对较小,对高性能要求相对不高的系统,而 RAC则更适合可靠性、扩展性、性能要求都相对较高的较大型的应用. ## 1.3 RAC和OPS区别 > RAC 是 OPS 的后继版本,继承了 OPS 的概念,但是 RAC 是全新的,CACHE 机制和 OPS 完全不同.RAC 解决了 OPS 中 2 个节点同时写同一个 BLOCK 引起的冲突问题. 从产品上来说 RAC 和 OPS 是完全不同的产品,但是我们可以认为是相同产品的不同版本. ## 1.4 双机热备、RAC、DG、OGG的区别 > RAC和DG是高可用体系中的常用的两种工具,每个工具既可以独立应用,也可以相互配合使用。但是它们各自的侧重点不同,适用场景也不同。 > RAC是本地的高可用集群,每个节点用来分担不同或相同的应用,以解决运算效率低下、单点故障这样的问题,它是几台硬件相同或不相同的服务器加一个共享存储来构成的。RAC的强项在于解决单点故障和负载均衡,所以,RAC方案常用于7*24的核心系统,但RAC方案中的数据只有一份,尽管可以通过RAID等机制避免存储故障,但是数据本身是没有冗余的,因此需要加强备份。 > DG是Oracle的远程复制技术,它有物理和逻辑之分,但是总的来说,它需要在异地有一套独立的系统,是一种异地容灾的解决方案。DG通过冗余数据的方式来提供数据保护,通过日志同步机制保证冗余数据和主库之间的同步,这种同步可以是实时、延时、同步或异步等多种形式。DG常用于异地容灾和小企业的高可用性方案,可以在备库上执行只读地查询操作,从而分散主库的性能压力。 > OGG软件是一种基于日志的结构化数据复制备份软件,它通过解析源数据库在线日志或归档日志获得数据的增量变化,再将这些变化应用到目标数据库,从而实现源数据库与目标数据库的同步。OGG可以实现一对一、广播(一对多)、聚合(多对一)、双向复制、层叠、点对点、级联等多种灵活的拓扑结构,可以实现只复制某几个表的功能。 | | 双机热备 | OPS | RAC | Dataguard | OGG | | ------------------ | ---------------------------------------------------- | ------------------------------- | ---------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | ------------------------------------ | | 共享存储 | 不是 | 有 | 有 | 有 | 不是 | | 高可用 | 有 | 有 | 有 | 有 | | | 保护类型 | 热备只是一个实例,一个数据库,做不了并发和负载均衡 | 实例冗余,负载均衡 | 实力层冗余 | 数据库层冗余 | Schema或表级别冗余 | | 需要的软硬件资源 | 只有两台机器和磁盘整列,有一个漂移的IP,不能共享存储 | 两台机器和磁盘阵列,两个虚拟IP | 可有多台机器和磁盘阵列,一个节点有一个虚拟IP | 有独立的机器和独立的磁盘 | 有独立机器和独立存储 | | 优缺点 | Failsafe是免费的,一台服务器闲置硬件浪费较大 | 在并发读写性能上较差 | 读写并发性能较好,但是对维护人员的技能和专业要求较高,要单独购买Oracle Cluster软件 | 是一个轻量级的容灾系统,在10g以上的版本中还能在备用节点上提供,读写功能和自动进行故障转移功能 | 可以在表或者schema级别实现实时复制 | ### 1.4.1 双机热备份方式 这种方式的主要缺点在于: > 由于需要重新启动数据库在双机热备份方式下, **数据库系统平时只能在一台服务器** (例如服务器A上运行,另一台服务器无法直接访问数据库,自然也无法进行负载分担.当服务器A由于故障失效时,由相应的操作系统软件控制,将服务器A管理的存储设备(如硬盘)转交给服务器B控制,同时在服务器B上启动另一个数据库实例,管理数据库.这种切换并启动新的数据库核心的过程一般需要几十秒到几分钟. > Ø核心进程,无法保证数据库系统连续不间断地运行; > Ø在系统切换的过程中,客户端与服务器之间的数据库连接会中断,需要重新进行数据库的连接和登录工作; > Ø由于数据库系统只能在一台服务器上运行,另一台服务器无法分担系统的负载,实际上造成了客户投资的浪费.在有些系统中,为了解决双机负载分担的问题,将应用系统人为分割为两个数据库系统分别在两台服务器上运行.这种方式在一定程度上解决了负载分担的问题,但给系统管理、统计分析等业务处理带来了很多额外的复杂性 ### 1.4.2 RAC方式 > RAC 是 real application cluster 的简称,它是在多个主机上运行一个数据库的技术,即是一个 db 多个 instance.它的好处是可以由多个性能较差的机器构建出一个整体性能很好的集群,并且实现了负载均衡,那么当一个节点出现故障时,其上的服务会自动转到另外的节点去执行,用户甚 至感觉不到什么. > 在并行服务器方式下,两台(或多台)服务器上各自运行一个数据库核心进程,但共同管理、操作一个数据库.客户端无论连接到哪个服务器都可以在数据库中进行操作.当服务器A由于故障失效时,数据库系统本身并未停止工作,连接在服务器B上的客户端还可以继续进行正常工作.同时,服务器B上也不需要再启动新的数据库服务器进程,因此也没有“切换时间″.对于一些特殊应用中严格要求前端应用不能中断的情况,orac1e并行服务器还提供了一种“预连接(pre-connect)"方式,以这种方式连接的客户端当服务器端发生故障时,客户端与数据库服务器的连接不会中断,会被orac1e并行服务器软件自动转接到还在正常工作的其它服务器上,不需要重新输入用户名及口令. ##### 1.4.2.1 相对于双机热备份方式 同样有许多操作系统平台支持并行服务器方式的高可用性方案,例如HP MC Service Guard OPS Edition与双机热备份方式相比,Orac1e Real Application cluster并行服务器方式有以下优点 > 1).各服务器共享—个数据库,在正常运行时可以进行负载分担,无需考虑应用数据的人为分割 > 2).并行服务器方式对应用完全透明,在应用程序设计和开发的过程中也不需要进行特殊编程,简化了开发的复杂程度,同时今后系统扩展也无需修改应用程序 > 3).不需要重新启动数据库核心进程,缩短了故障造成的停机时间 ##### 1.4.2.2 RAC的好处 具有 Cache fusion体系结构的 Oracle Real Application Clusters为企业应用开发提供了以下好处 > 1).应用系统灵活和毫不费力的伸缩性;应用用户可以登录到单独的虛拟高性能集群服务器.向数据库切加节点非常容易,并且当需要添加处理器节点或者业务需求变化时,不用手工对数据进行分区.对于所有的应用即时提供集群的可伸缩性--不用修改应用程序 > 2).较之传统集群数据库体系结构的高可用性解決方案;该体系结枃为客户提供了几乎连续的数据访可,使硬件和软件故障导致的业务中断最小化.系统具备对多个节点失败的容错能力,使部件失败屏蔽开最终用户 > 3).单独的管理实体;为了进行所有管理操作,在集群中保持一个单独的系统映像.DBA一次性地进行安装、配置、备份、升级以及监控等功能,然后σ racle将管理功能自动分配到适宜的节点.这意味着DBA只管理着一个虚拟服务器. > 4).Cache fusion保存了所有orac1e客户在他们应用中学习和开发orac1e的投资.所有单节点数据库功能都保留下来,并且应用程序使用相同标准的σ racle接口连接到数据库上. #### 1.4.2.3 可伸缩性 > 基于RAC应用的用户或者中间层应用服务器客户,可以通过虚拟数据库服务连接到数据库上.Oracle在集群中多个节点之间自动平衡用户负载.不同节点上的 Real Application Clusters数据库实例预订所有数据库服务或者部分子集数据库服务.这使得DBA高度灵活地选定,连接到特定数据库服务的特定应用程序客户是否可以连接到某些或者全部的数据库节点.虽然毎一个节点有一个不同的物理IP地址时,应用客户仍可以在一个逻辑数据库服务名的水平上进行连接.因此客户端对于不相关的事情如多服务器的多个地址可以毫不关心.随着业务的增长,应用系统可以从容地增加处理能力.Cache fusion体系结构直接地利用新节点的CPU和内存资源.DBA无需用手工对数据重新分区.这个优点是这种体系结构的副产品,因为有透明度的数据存取是 Cache fusion的一项基本功能.Cache fusion体系机构自动适应快速变化的应用需求及随之而来的工作负荷的改变.DBA也不必因为工作负荷变化而对数据进行手工的重新分区.Real Application Clusters通过动态地重新分配数据库资源,从而在节点之间用最小化的磁盘I/O和低的延迟通信来优化利用集群系统资源.这使得Real Application Clusters可以从容实现增加的应用吞吐量和优化的响应时间 #### 1.4.2.4 高可用 > Real Application Clusters提供了真正的高可用性解决方案,关键的突破是在大多数数据库恢复期间能提供完整的数据库访问,这使得Real Application Clusters成为应用所要求的24x7可用性的最佳平台. > Real Application clusters在高可用性上在三个关键领域胜出 > 1).提供了数据库恢复期间的数据块访问 > 2).透明的失效转移对最终用户屏蔽了系统失效 > 3).N-1节点失效的容错能力,只要有一个数据库节点幸存,Real Application Clusters就能够提供完全的数据库访问和相对不间断的操作. #### 1.4.2.5 可管理性 > Real Application cluster实现了真正意义上的一个单系统访问数据库,它提供了从任何节点到所有磁盘设备和远程高速缓存进行无缝数据访问的能力.此单系统映像延伸到所有数据库管理操作.安装、配置、备份、升级以及监控等操作只需进行一次,然后会自动发布到集群中所有节点上去.各种race工具(如Oracle Universal Installer、Database Configuration Assistant以及Recovery Manager)将发现集群数据块中所有不同的节点并以它们为目标分配给想得到的任务.通过为特定的管理操作选择多个目标节点,管理任务在数据库集群中多个节点上执行.这为应用系统管理其环境带来了极大的可伸缩性上的经济实惠.例如,向数据库集群添加一个节点只会增加最小的管理任务.这样,Real Application Clusters支持在线商务应用和决策支持之类的应用,并且为数据访问和管理提供了单一的虚拟高性能服务器. #### 1.4.2.6 总结 > 1).对于硬件来说基本上一样,共享存储、光纤线(也有还用SCSI线的)、多台小型机(可以做多节点的相互热备,也可以做多节点的RAC)、光纤交换机(如果是用光纤卡的话);但做RAC,在主机之间,最好使用高带宽网络交换机(虽然不用也可以做成),硬件成本相差不大. > 2).软件如果是双机热备,必须买操作系统級的双机管理软件;如果是RλC目前还是建议购买双机管理软件(尽管10g的εrs+asm可以摆脱双机软件了,但ASM目前实在太难伺候了),当然还得买RAC License. # 二、Dataguard综述 ## 2.1 DG原理 > Oracle DataGuard是Oracle自带的数据同步功能,基本原理是将日志文件从原数据库(主库)传输到目标数据库(备库),然后在目标数据库上应用这些日志文件,从而使目标数据库与源数据库保持同步,是一种数据库级别的高可用性方案. > DG(Data Guard,数据卫士)不是一个备份恢复的工具,然而DG却拥有备份的功能,在物理DG下它可以和主库一模一,但是它存在的目的井不仅仅是为了备份恢复数据,应该说它的存在是为了确保企业数据的高可用性,数据保护以及灾难恢复DBA可以通过将一些操作(例如查询报表)转移到备库执行的方式来减小主库的压力,构建高可用的企业数据库应用环境. > 在DG环境中,至少有两个数据库,一个处于OPEN状态对外提供服务,这个数据库叫作主库(Primary Database). 第二个处于恢复状态,叫作备库(standby Database). 通常情况下,主库对外提供服务,用户在主库上进行操作,操作被记在联机日志和归档日志中,这些日志通过网络传递给备库,然后在备库上被应用,从而实现主库和备库的对这过程进一步地优化设计,使得日志的传递、恢复工作更加自动化、智能化,并且提供一系列参数和命令DBA工作. 如果软硬件升级,那么可以把备库切换为主库继续对外服务,这样既减少了服务停止时间,并且娄常原因导致主库不可用,那么也可以把备库强制切换为主库继续对外服务,这时数据损失都和配置的数据保护级别有关系,所以,Primar和Standby只是一个角色概念,并不固定在某个数据库中. > 主备库既可以是单实例数据库,也可以是RAC. > DataGuard可以提供Oracle数据库的冗灾、数据保护、故障恢复等,实现数据库快速切换与灾难性恢复. 在生产数据库的保证"事务一致性"时,使用生产库的物理全备份创建备库,备库会通过生产库传输过来的归档日志或重做条目自动维护备用数据库. ## 2.2 DG优缺点 **DG的优点** > 1).灾难恢复及高可用性 > 2).全面的数据保护 > 3).有效利用系统资源 > 4).在高可用及高性能之间更加灵活的平衡机制 > 5).故障检查及解决方案 > 6).集中的、易用的管理模式 > 7).自动化的的角色转换 **DG的缺点** > 1).由于传输整个日志文件,所以需要较高的网络传输带宽 > 2).在 Oracle 11g之前的物理备库虽然可以只读方式打开,然后执行查询、报表等操作,但需要停止应用日志,这将使目标库与源数据不能保持同步,如果在此期间源数据库发生故障,那么将延长切换的时间,从11g开始,ADG可以在数据库打开的情况下应用日志,这极大地提高了DG的应用范围. > 3).逻辑备库不能支持某些特定的数据对象和数据类型 > 4).不支持双向复制,所以,无法应用于信息集成的场合 > 5).只能复制整个数据库,不能选择某个 SCHEMA或表空间或表进行单独复制. > 6).不支持异构的系统环境,需要相同的操作系统版本和数据库版本(Oracle 11g支持部分异构平台) ## 2.3 DG架构 ### 2.3.1 架构 DG架构按照功能可以分成3个部分: > 日志发送 Redo send > 日志接收 Redo Receive > 日志应用 Redo Apply ### 2.3.2 日志发送 > 主库在运行过程中,会源源不断地产生Redo日志,这些日志需要发送到备库. 这个发送动作可以由主库的LGR或者ARCn进程完成,不同的归档目的地可以使用不同的方法,但是对于一个目的地,只能选用一种方法. 选择不同的进程在数据保护能力和系统可用性方面有很大区别. > 如果使用LGNR进程来传递日志,但是由于某些原因,LGwR进程变得无法归档到目的地了,那么重做传输将会使用ARCn进程来完成归档操作. > 若不配置传输进程和模式的话,在Oracle 11g下则默认为LGWR ASYNC方式,在orac1e10g下则默认为ARCH模式. DG传输进程及其模式的关系 | **版本** | **10g** | **11g** | | ----------------------------------------------------------------------------------------------- | -------------------------------------------------- | ------------------------- | | 传输模式 | LGWR ASYNC(异步) | LGWR SYNC(同步) | | 后台进程表现 ps -ef | grep -v grep | grep -E | | "ora_lns | ora_nsa | ora_nss" | | 视图GV$MANAGED_STANDBY | LNS | LGWR | | 切换日志的时候告警日志 | 出现过一次,LNS: Standby redo logfile | | | selected for thread 1 sequence 13 for destination LOG_ARCHIVE_DEST_2,但再切换的时候就不出现了 | 无 | 无 | | sequence 98 for destination LOG_ARCHIVE_DEST_2 | LNS: Standby redo logfile selected for thread 1 | | | sequence 98 for destination LOG_ARCHIVE_DEST_2 | ARC0: Standby redo logfile selected for thread 1 | | | sequence 102 for destination LOG_ARCHIVE_DEST_2 | | | | **是否默认** | 否 | 是,默认采用归档进程传送 | #### 2.3.2.1 使用ARCH进程 > 1).主库(Primary Database)不断产生Redo日志,这些日志被LGWR进程写到联机日志. > 2).当一组联机日志被写满后,会发生日志切换(Log Switch),并且会触发本地归档,本地归档位置是采用“LOG_ARCHIVE_DEST_1='LOCATION=/path'”格式定义的. 例如,修改本地归档的SQL语句可以是:“ALTER SYSTEM SET LOG_ARCHIVE_DEST_1='LOCATION=/u01/arch' SCOPE=BOTH;”. > 3).完成本地归档后,联机日志就可以被覆盖重用. > 4).ARCH进程通过网络把归档日志发送给备库(Standby Database)的RFS(Remote File Server)进程. > 5).备库端的RFS进程把接收的日志写入到归档路径中. > 6).若是物理DG的话,则备库的MRP(Managed Recovery Process)进程进行Redo Apply;若是逻辑DG的话,则备库的LSP(logical standby process)进程进行SQL Apply进而同步数据. > 用ARCH模式传输不写Standby Redo Logs,直接保存成归档文件存放于Standby端. > 逻辑备库接收日志后将日志转换成SQL语句,然后逻辑备库上的LSP进程执行这些SQL语句进而实现主备库的数据同步,这种方式叫SQL Apply. 物理备库接收完主库生成的Redo数据后,MRP进程以介质恢复的方式实现同步,这种方式也叫Redo Apply. > 使用ARCH进程传递最大问题在于:主库只有在发生归档时才会发送日志到备库. 如果主库异常宕机,那么联机日志中的Redo内容就会丢失,所以,使用ARCH进程无法避免数据丢失的问题,要想避免数据丢失,就必须使用LGWR,而使用LGWR又分SYNC(同步)和ASYNC(异步)两种方式. #### 2.3.2.2 使用LGWR进程的SYNC方式 > 1).主库产生的Redo日志要同时写到日志文件和网络,也就是说LGWR进程把日志写到本地日志文件的同时还要发送给本地的LNSn进程(LGWR Network Server Process),再由LNSn进程把日志通过网络发送给远程的目的地,每个远程目的地对应一个LNS进程,多个LNS进程能够并行工作. > 2).LGWR必须等待写入本地日志文件操作和通过LNSn进程的网络传送都成功,主库上的事务才能提交,这也是SYNC的含义所在. > 3).备库的RFS进程把接收到的日志写入到Standby Redo Log日志中. > 4).主库的日志切换也会触发备库上的日志切换,即主库对Standby Redo Log的归档,然后触发备库的MRP或者LSP进程应用归档日志. #### 2.3.2.3 使用LGWR进程的ASYNC方式 > 使用LGWR SYNC方法的可能问题在于,如果日志发送给备库过程失败,那么LGWR进程就会报错. 也就是说主库的LGWR进程依赖于网络状况,有时这种要求可能过于苛刻,这时就可以使用LGWR ASYNC方式. 它的工作机制如下所示: > 1).主库一旦产生Redo日志,LGWR就把日志同时提交给日志文件和本地LNS进程,但是LGWR进程只需成功写入日志文件就可以,不必等待LNSn进程的网络传送成功. > 2).LNSn进程异步地把日志内容发送到备库,多个LNSn进程可以并发发送. > 3).主库的联机Redo日志文件写满后发生Log Switch,触发归档操作,也触发备库对Standby Redo Log的归档;然后触发MRP或者LSP进程恢复归档日志. ### 2.3.3 日志接收 > 备库的RFS(Remote File Server)进程接收到日志后,就把日志写到Standby Redo Log或者Archived Log文件中,具体写入哪个文件,取决于主库的日志传送方式. 如果写到Standby Redo Log文件中,那么当主库发生日志切换时,也会触发备库上的Standby Redo Log的日志切换,并把这个Standby Redo Log归档;如果是写到Archived Log,那么这个动作本身也可以看作是个归档操作. 在日志接收中归档日志会被放在LOG_ARCHIVE_DEST_n指定的位置. ### 2.3.4 日志应用 > 日志应用服务,就是在备库上重演主库的日志,从而实现两个数据库的数据同步. > 根据Redo Apply发生的时间不同可以分成两种:一种是实时应用(Real-Time Apply),这种方式必须包含Standby Redo Log,每当日志被写入Standby Redo Log时,就会触发恢复,使用这种方式的好处在于可以减少数据库切换(Switchover或者Failover)的时间,因为切换时间主要用在剩余日志的恢复上. 另一种是归档应用,这种方式在主库上发生日志切换,会触发备库的归档操作,归档完成后触发恢复. 这也是默认的恢复方式. > 根据备库重演日志方式的不同,可分为Redo Apply和SQL Apply:若是物理DG的话,则备库的MRP(Managed Recovery Process)进程进行Redo Apply. 物理备库接收完主库生成的Redo数据后,MRP进程以介质恢复的方式实现同步,这种方式叫Redo Apply. 若是逻辑DG的话,则备库的LSP(logical standby process)进程进行SQL Apply进而同步数据. 逻辑备库接收日志后将日志转换成SQL语句,然后逻辑备库上的LSP进程执行这些SQL语句进而实现主备库的数据同步,这种方式叫SQL Apply. ## 2.4 DG中的进程 > 这几个进程是DG结构中日志传输、接受和应用的关键性进程,下面分别介绍这几个进程. ### 2.4.1 RFS进程 > RFS(Remote File Server)进程主要用来**接受从主库传送过来的日志信息**. 对于物理备库而言,RFS进程可以直接将日志写进Standby Redo logs,也可以直接将日志信息写到归档日志中. 一般可以在主备库的告警日志中看到如下的信息: 主库: ```powershell LNS1 started with pid=21, OS id=11222 ``` 备库: ````bash RFS[2]: Successfully opened standby log5:'/opt/oracle/oradata/lhrdb/std_redo5a.log' ```` 在数据库中查询: ```sql_more SELECT PROCESS,PID,STATUS FROM V$MANAGED_STANDBY; ``` > 对于Oracle 11g而言,该进程一般会自动启动,但是,对于Oracle 10g而言,由于某些特殊原因,该进程可能不会自动启动,那么可以使用如下的步骤来手动启动该进程: > > ```sql_more > --启动实时应用 > --物理:ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION; > --逻辑:ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE; > alter system set log_archive_dest_state_2='defer'; > alter system switch logfile; > alter system set log_archive_dest_state_2='enable'; > alter system switch logfile; > --重启备库 > ``` ### 2.4.2 LNSn进程 > (LGWR Network Server process) > DG可以使用ARCn、LGWR来传送日志,但它们都是把日志发送给本地的LNSn(如果有多个目标备库,那么会启动相应数量的LNSn进程,同时发送数据)进程,然后备库的RFS进程接收数据,接收到的数据可以存储在备库的备用Redo日志文件中或备库的归档日志中,然后再应用到备库中. > 一般情况下,主库切换(ALTER SYSTEM SWITCH LOGFILE;)日志可以启动LNSn进程,若不能正常启动则可以按照如下的步骤来处理: > > ```sql_more > --ALTER SYSTEM SWITCH LOGFILE; > --备库启动实时应用后,主库: > ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_2='DEFER'; > ALTER SYSTEM SWITCH LOGFILE; > ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_2='ENABLE'; > ALTER SYSTEM SWITCH LOGFILE; > --重启备库、主库 > ``` > 进程查询 > > ```sql_more > # ps -ef|grep -v grep|grep -E "ora_lns|ora_nsa|ora_nss" > oracle 8090 1 0 03:57 ? 00:01:40 ora_lns1_oradg10g > oracle 8092 1 0 03:57 ? 00:01:40 ora_nsa2_oradg11g > oracle 8095 1 0 03:57 ? 00:01:40 ora_nss2_orawl11g > ``` > 需要注意的是,若在Oracle 10g中采用LGWR传输日志的时候,则进程表现为LNSn,但在Oracle 11g中,若采用LGWR ASYNC(异步方式)来传输日志的时候,则进程表现为nsa,若采用LGWR SYNC(同步方式)来传输日志的时候,则进程表现为nss,且通过视图GV$MANAGED_STANDBY查询的结果不尽相同 ### 2.4.3 MRP进程 > (Managed Recovery Process) > 该进程只针对物理备库,作用为应用从主库传递过来的Redo日志到物理备库,称为Redo Apply. 如果使用SQL语句“ALTER DATABASE > RECOVER MANAGED STANDBY DATABASE”启用该进程,那么前台进程将会做恢复. 如果加上DISCONNECT语句,那么恢复过程将在后台进程,发出该语句的进程可以继续做其它的事情,进程如下所示: > > ```bash > $ ps -ef | grep ora_mrp > oracle 4794 1 0 10:33 ? 00:00:00 ora_mrp0_orawldg > ``` ### 2.4.4 LSP进程 > (logical standby process) > 只有逻辑备库才会有该进程. LSP进程控应用Redo日志到逻辑备库. 进程如下所示: ````bash $ ps -ef | grep ora_lsp oracle 4683 1 0 10:31 ? 00:00:01 ora_lsp0_oraljdg ```` > 对于DG配置,可以通过Grid Control来完成,也可以通过Data Guard Broker以及SQL*Plus来完成. 对于前两者方式可以在图形界面完成,操作简单. 而对于使用SQL*Plus ## 2.5 DG的三种保护模式 > DG提供了3种数据保护模式(Protection Mode): > 最大保护(Maximum Protection) > 最高性能(Maximum Performance) > 最高可用(Maximum Availability) | 比较项目 | 最大保护模式 (Maximum Protection) | 最高可用 (Maximum Availablility) | 最高性能 (Maximum Performance) | | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 简介 | 最大保护模式能够确保绝无数据丢失,该模式要求主库所有的事务在提交前其Redo不仅被写入到本地的online Redo Logs,要同时写入到备库的standby Redo Logs,并确认Redo数据至少在一个备库中可用(如果有多个的话),然后才会在主库上提交. 如果出现了导致备库不可用故障(例如网络中断),那么主库会被关闭.因此,在该保护模式下,数据库必须配置SYNC传输模式,且必须和备库连通,否则会导致主库不能启动. | 最高可用模式在不影响主库可用地前提下,提供最高级别的数据保护.其实现方式与最大保护模式类似,也是要求本地事务在提交前必须至少写入台备库的standby Redo Logs中,不过与最大保护模式不同的是,如果出现故障导致备库无法访问,那么主库并不会被关闭,而是自动转为最高性能模式,等备库恢复正常之后,主库又会自动转换成最高可用模式.最高可用模式适用于想要确保获得零数据丢失保护,但不想让生产数据库受网络/备用服务器故障影响的企业. | 在最高性能模式下,事务可以随时提交.如果网络条件理想的话,那么这种模式能够提供类似最高可用性的数据保护,而仅对主库的性能有轻微影响.这也是在创建备库时,系统的默认保护模式.最高性模式区别于最大保护模式的地方是,它并不需要将日志信息实时的传递到备库上,也不需要确保日志在其中的至少一台备库上应用. | | 切换命令 | alter database | | | | set standby database to maximize protection; | alter database | | | | set standby database to maximize availablility; | alter database | | | | set standby database to maximize performance; | | | | | 数据丢失 | 零数据丢失 | 零数据丢失 | 最小数据丢失 | | 主库事务<br/> 完成情况 | 主库Redo需要同时写入主库、至少一个备库,主库事务才能完成. | 主库Redo需要同时写入主库,至少一个备库,主库事务才能完成. | 主库事务可以随时提交 | | 默认模式 | 否 | 否 | 是 | | 性能影响 | 最大 | 介于两者之间 | 最小 | | 网络传输 | 同步(SYNC) | 同步(SYNC) | 使用LGWR进程传递归档时采用同步(SYNC)或异步(ASYNC)<br/> 使用ARCH进程归档时,采用同步(SYNC) | | 需要Standby Redo Log | 是 | 是 | 推荐有 | | Redo写进程 | LGWR | LGWR | LGWR或ARCH | | 磁盘写操作 | AFFIRM | AFFIRM | AFFIRM或NOAFFIRM | | 优点 | 数据零丢失 | 在没有问题出现的情况下,保证没有数据丢失 | 避免备库对主库的性能可用性影响 | | 缺点 | 要求网络高度稳定可靠,如果出现了导致备库不可用故障(比如网中断),那么主库会被关闭.备库的自动关闭会影响到主库的可用性,同时需要备库恢复后才能提交,对网络等客观条件要求非常的高,主库的性能会因此受到非常大的冲击.最大保护模式损害了系的可用性. | 在正常运行的过程中缺点是主库的性能受到诸多因素的影响. 要求备库必须配置Standby Redo Logs,而主库必须使用GWR | | | SYNC AFFIRM方式归档到备库. | 如果与主库提交的事务相关的恢复数据没有发送到备库,那么这些事务数据将被丢失,不能保数据无损失. 如果主库发生灾难性故障,日志全部损失,那么备库和主库可能会出现一个左右的日志信息差异.当然,在这种方式下,可以通过设置主库增加归档频率来缩小可能的数据损失.最高性能模式损害了系统的数据安全性 | | | | 当前数据库保护模式查询SQL | | | | | select | | | | | protection_mode from v$database; | | | | # 三、DG的必要设置 ## 3.1 主库添加Standby log > 确保Standby redo log的大小与主库online redo log的大小一致 > 如果主库为单实例数据库:Standby redo log组数=主库日志总数+1 > 如果主库是RAC数据库:Standby redo log组数=(每个线程的日志数+1)*最大线程数,线程数即thread# > 不建议复用Standby redo log,避免增加额外的I/O以及延缓重做传输 ```sql_more # 如果是CDB环境,先检查处于CDB根容器中,PDB下是不允许的; # 在Oracle 12c的架构里,online redo log 和控制文件是保存在CDB中的,PDB中只有运行需要的数据文件; # 所以如果是CDB下,就在CDB中加 Standby redo log. # 1、查看组数=2,每组2个线程THREAD SYS@orcl1> select count(group#),thread# from v$log group by thread#; COUNT(GROUP#) THREAD# ------------- ---------- 2 1 2 2 # 2、大小=50M SYS@orcl1> select group#,bytes/1024/1024 from v$log; GROUP# BYTES/1024/1024 ---------- --------------- 1 50 2 50 3 50 4 50 # 3、创建standby logfile(3+1组、每组50M) # 视图v$standby_log还没有创建standby log col MEMBER for a50 SYS@orcl1> select * from v$standby_log; no rows selected # 查看logfile,将standby log也放在该目录 SYS@orcl1> select group#,status,type,member from v$logfile order by member; GROUP# STATUS TYPE MEMBER ---------- ------- ------- -------------------------------------------------- 1 ONLINE +DATA/ORCL/ONLINELOG/group_1.262.1062286541 2 ONLINE +DATA/ORCL/ONLINELOG/group_2.263.1062286543 3 ONLINE +DATA/ORCL/ONLINELOG/group_3.266.1062286795 4 ONLINE +DATA/ORCL/ONLINELOG/group_4.267.1062286795 1 ONLINE +FRA/ORCL/ONLINELOG/group_1.257.1062286543 2 ONLINE +FRA/ORCL/ONLINELOG/group_2.258.1062286543 3 ONLINE +FRA/ORCL/ONLINELOG/group_3.259.1062286795 4 ONLINE +FRA/ORCL/ONLINELOG/group_4.260.1062286795 # === RAC下添加standby log ===================== # 上面查出组数=2,每组2个THREAD,根据规则需要(2+1)*2=6组【(每组线程数2+1)最大线程数2】,大小50M alter database add standby logfile thread 1 group 5 '+DATA' size 50m; alter database add standby logfile thread 1 group 6 '+DATA' size 50m; alter database add standby logfile thread 1 group 7 '+DATA' size 50m; alter database add standby logfile thread 2 group 8 '+DATA' size 50m; alter database add standby logfile thread 2 group 9 '+DATA' size 50m; alter database add standby logfile thread 2 group 10 '+DATA' size 50m; # 4、节点2上验证查看 SYS@orcl2> select group#,bytes/1024/1024 from v$standby_log; GROUP# BYTES/1024/1024 ---------- --------------- 5 50 6 50 7 50 8 50 9 50 10 50 6 rows selected. SYS@orcl2> select group#,status,type,member from v$logfile; GROUP# STATUS TYPE MEMBER ---------- ------- ------- -------------------------------------------------- 2 ONLINE +DATA/ORCL/ONLINELOG/group_2.263.1062286543 2 ONLINE +FRA/ORCL/ONLINELOG/group_2.258.1062286543 1 ONLINE +DATA/ORCL/ONLINELOG/group_1.262.1062286541 1 ONLINE +FRA/ORCL/ONLINELOG/group_1.257.1062286543 3 ONLINE +DATA/ORCL/ONLINELOG/group_3.266.1062286795 3 ONLINE +FRA/ORCL/ONLINELOG/group_3.259.1062286795 4 ONLINE +DATA/ORCL/ONLINELOG/group_4.267.1062286795 4 ONLINE +FRA/ORCL/ONLINELOG/group_4.260.1062286795 5 STANDBY +DATA/ORCL/ONLINELOG/group_5.269.1081897411 6 STANDBY +DATA/ORCL/ONLINELOG/group_6.270.1081897411 7 STANDBY +DATA/ORCL/ONLINELOG/group_7.271.1081897411 8 STANDBY +DATA/ORCL/ONLINELOG/group_8.272.1081897411 9 STANDBY +DATA/ORCL/ONLINELOG/group_9.273.1081897411 10 STANDBY +DATA/ORCL/ONLINELOG/group_10.274.1081897411 14 rows selected. ``` ## 3.2 搭建物理DG注意点 > 具体操作参考部署手册 > 1).主库需要设置为FORCE LOGGING模式 > 2).主库需要设置为归档模式 > 3).主库必须添加Standby Redo Log Files,其大小应该和Online Redo Log Files的大小(size)一致. > >> 另外,Standby日志组的个数应满足以下条件: >> 如果主库是单实例数据库 :standby redo log组数=主库日志组总数+1 >> 如果主库是RAC数据库 :standby redo log组数=(每线程的日志组数+1)x最大线程数 >> > > 4).如果主库为RAC,那么应该将控制文件的快照备份位置设置到共享磁盘中,只在节点一执行:CONFIGURE SNAPSHOT CONTROLFILE NAME TO '+DATA/snapcf_TESTDGPRI.f'; > 5).主库和备库的监听需要设置静态监听 > 6).主备库的密码文件应该采用复制的方式生成 > 7).连接rman时,建议都使用tns连接,例如:rman target sys/prssword@TNS_TESTDGPRI auxiliary sys/password@TNS_TESTDGPHY > >> 在以上输出结果中, >> 这2行输出中的TESTDG是DB_NAME,但主备库必须保持一致; >> 第一行是主库,所以必须有DBID输出,即主库必须是open的状态,而备库是nomount状态. >> > > 8).如果是ASM管理的数据库,那么应该将数据库添加到集群资源中. 以下是将物理备库添加到集群资源的命令: > > ```bash > srvctl add db -d TESTDGPHY -c RAC -o /u01/app/oracle/product/11.2.0/dbhome_1 -p '+datadg/TESTDGPHY/PARAMETERFILE/spfile.278.976878603' -r physical_standby -n TESTDG > srvctl add instance -d TESTDGPHY -i DGPHY1 -n raclhr-11gR2-N1 > srvctl add instance -d TESTDGPHY -i DGPHY2 -n raclhr-11gR2-N2 > srvctl status db -d TESTDGPHY > srvctl start db -d TESTDGPHY > crsctl stat res -t > srvctl config db -d TESTDGPHY -a > ``` ## 3.3 DG的一些参数说明 | **下列参数为****Primary****角色相关的初始化参数** | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | DB_NAME | | DB_UNIQUE_NAME | | LOG_ARCHIVE_CONFIG | | LOG_ARCHIVE_DEST_n | | LOG_ARCHIVE_DEST_STATE_n | | REMOTE_LOGIN_PASSWORDFILE | | **以下参数为与****Standby****角色相关的参数** **(** **建议在****Primary** **数据库的初始化参数中也进行设置** **,** **这样即使发** **生角色切换** **,** **新的****Standby** **也能直接正常运行** **)** | | FAL_SERVER | | FAL_CLIENT | | DB_FILE_NAME_CONVERT | | LOG_FILE_NAME_CONVERT | | STANDBY_FILE_MANAGEMENT | > 其中,上表中的LOG_ARCHIVE_DEST_n各个参数的含义如下所示: > Ø AFFIRM(磁盘写操作): > 保证Redo日志被写进物理备用数据库. 默认是NOAFFIRM. 当使用LGWR SYNC AFFIRM属性的时候需要等待I/O全部完成时,主库事务才能提交. 该参数对数据库性能是有影响的. > Ø NOAFFIRM:LGWR的I/O > 操作是异步的,该参数是默认值. ### 3.3.1 DELAY:指明备库应用日志的延迟时间(Redo数据延迟应用) > 注意:该属性并不是说延迟发送Redo数据到Standby,而是指明归档到Standby后,延迟应用的时间,单位为分钟. 如果没有指定DELAY属性,那么表示没有延迟. 如果指定了DELAY属性,但没有指定值,那么默认是30分钟. 不过,如果DBA在备库启动Redo应用时指定了实时应用,那么即使在LOG_ARCHIVE_DEST_n参数中指定了DELAY属性,Standby数据库也会忽略DELAY属性. ```sql --如下所示的命令会忽略DELAY属性: ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION; --而以下命令不会忽略DELAY属性: ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION; ``` > 另外,Standby端还可以在启动Redo应用时,通过附加NODELAY子句的方式,取消延迟应用. 物理Standby可以通过下列语句取消延迟应用: > > ```sql > ALTER DATABASE RECOVER MANAGED STANDBY DATABASE NODELAY; > ``` > 逻辑Standby可以通过下列语句取消延迟应用: > > ````sql > ALTER DATABASESTART LOGICAL STANDBY APPLY NODELAY; > ```` > 一般设置延迟应用的需求都是基于容错方面的考虑,如Primary数据库端由于误操作,数据被意外修改或删除,只要Standby数据库尚未应用这些修改,那么就可以快速从Standby数据库中恢复这部分数据. 不过Oracle自从9i版本开始提供FLASHBACK特性之后,对于误操作使用FLASHBACK特性进行恢复,显然更加方便快捷,因此DELAY方式延迟应用已经非常少见了. > Ø SERIVCE > 用于指定备用数据库的TNSNAMES描述符,Oracle会将Redo日志传送到这个TNSNAMES指定的备库. > Ø SYNC > 用于指定使用同步传输方式到备库. 即LGWR进程需要等待来自LNS的确认消息后,然后告知客户端事务已提交. 最高可用性及最大保护模式下,至少有一个备用目标应指定为SYNC. > Ø ASYNC > 与SYNC相反,指定使用异步传输模式,此为默认的传输方法. > Ø NET_TIMEOUT > 指定LGWR进程等待LNS进程的最大时间数,缺省为30s. 如果超出该值,那么主库放弃备库,继续执行主库上的事务. > Ø REOPEN > 主库遇到备库故障后尝试重新连接备库所需等待的时间,缺省为300s. > Ø DB_UNIQUE_NAME > 主库与备库连接时会发送自己的唯一名称,同时要求备库返回其唯一名称,并结合LOG_ARCHIVE_CONFIG验证其存在性. > Ø VALID_FOR > 定义何时使用LOG_ARCHIVE_DEST_n参数以及应该在哪类Redo日志文件上运行. 可用日志文件类型:ONLINE_LOGFILE、STANDBY_LOGFILE、ALL_LOGFILES. 可用的角色类型:PRIMARY_ROLE、STANDBY_ROLE、ALL_ROLES. > > ```bash > ONLINE_LOGFIL :表示归档联机Redo日志; > STANDBY_LOGFILE :表示归档备库的Redo日志/接受的Redo日志; > ALL_LOGFILES :表示所有的在线和归档日志; > PRIMARY_ROLE :仅当数据库角色为主库时候归档生效; > STANDBY_ROLE :仅当数据库角色为备库时候归档生效; > ALL_ROLES :任意角色归档均生效. > ``` # 四、DG的分类和转换 > DG根据备库(Standby Database)重演日志方式的不同,可以分为物理DG(Physical DG)、逻辑DG(Logical DG)和快照DG(Snapshot DG),它们对应的数据库分别可以称为Physical Standby、Logical Standby和Snapshot Standby. > 创建物理备库的方法很多. 对于Oracle 11g而言,可以直接从Active Database来创建,也可以基于10g的RMAN备份方式来创建. 对于Oracle 10g而言,只能基于RMAN来创建. 对于12c的数据库,可以通过dbca -createDuplicateDB的方式来创建一个物理DG,但是前提条件是主库必须是一个单机且非CDB的环境. ## 4.1 物理DG(Physical DG) > 物理DG使用的是Media Recovery技术,在数据块级别进行恢复,这种方式没有数据类型的限制,可以保证两个数据库完全一致. 在Oracle 11g之前的物理DG只能在MOUNT状态下进行恢复,虽然可以以只读方式打开备库,但是不能应用日志,而到了Oracle 11g时备库可以在打开的情况下执行恢复操作了,这称为ADG(Active Data Guard). > 物理DG实时应用进程为MRP进程. 需要注意的是,主库在开启闪回数据库功能后,物理备库并不会开启闪回数据库的功能. ## 4.2 逻辑DG(Logical DG) > 逻辑DG使用的是LogMiner技术,通过把日志内容还原成SQL语句,然后通过SQL引擎执行这些SQL语句. 逻辑DG不支持所有的数据类型,这些不支持的数据类型可以在视图DBA_LOGSTDBY_UNSUPPORTED中查看. 如果使用了这些数据类型,那么不能保证主备库完全一致. Logical Standby可以在恢复的同时进行读写操作. 逻辑DG实时应用进程为LSP进程. 需要注意的是,在逻辑DG中,SYS用户下的对象不会同步. 要想创建一个逻辑备库需要先创建一个物理备库,然后再将其转换成逻辑备库. ## 4.3 快照DG(Snapshot DG) > 当Physical Standby转换为Snapshot Standby时,它是一个完全可更新的Standby数据库. Snapshot > Standby依然会接收来自主库的归档文件,但是它不会应用. 当Snapshot Standby转换为Physical Standby时,所有在Snapshot Standby数据库的操作被丢弃之后,Physical Standby数据库才会应用Primary数据库的Redo数据. > 最后需要说明的一点是,物理DG可以转换为逻辑DG,但是逻辑DG不能转换为物理DG. 快照DG和物理DG可以相互转换. > 通过V$DATABASE视图的DATABASE_ROLE列可以查询DG的类型: > > ```sql > select db_unique_name,database_role,open_mode from v$database; > ``` ## 4.4 物理DG转换逻辑DG步骤 > 具体操作参考部署手册 > >> 1).停用备库MRP进程 >> 2).主库构建LogMiner字典 >> 3).物理备库恢复为逻辑备库 >> 4).修改备库参数,打开逻辑备库 >> ## 4.5 物理DG和快照DG相互转换 > 具体操作参考部署手册 # 五、DG中常用的视图和SQL ## 5.1 视图 ```bash V$MANAGED_STANDBY :包含与物理备库相关的数据库进程(例如:LGWR、RFS、LNS、ARCH、MRP等)的信息. V$ARCHIVED_LOG :在备库执行此查询时,显示该备库接收到的日志. V$LOG_HISTORY :包含归档历史的详细信息. V$DATAGUARD_STATUS :包含DG生成的消息,这些消息被写入该特定数据库(主库或备库)的告警日志或跟踪文件中. V$RECOVERY_PROGRESS :包含与备库恢复相关的统计信息. V$STANDBY_EVENT_HISTOGRAM :包含某个物理备库的应用滞后的直方图. DBA_LOGSTDBY_LOG :包含关于已经被或正在被SQL Apply处理的归档日志的信息. DBA_LOGSTDBY_EVENTS :包含最近的SQL Apply事件(例如异常终止)的记录,这些事件也存在于告警日志中. V$LOGSTDBY_PROCESS :包含每个SQL Apply进程的当前状态. ``` ## 5.2 物理DG中的SQL ### 5.2.1 启用日志应用 ```sql ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION; ``` ### 5.2.2 启用实时的日志应用 ```sql ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION; ``` > 子句DISCONNECT FROM SESSION并非必需,该子句的作用是指定启动完应用后自动退出到命令操作符前.如果不指定该子句的话,那么当前SESSION就会一直停留处理Redo应用,如果想做其它操作,那么就只能新建一个连接. ### 5.2.3 停止日志应用服务 ```sql ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL; ``` ### 5.2.4 查看DG备机是否启用了日志应用 > 有两种办法可以判断: > 1).可以查看是否有mrp进程,如果看不到mrp进程,那么说明没有启用日志应用. > 2).查看V$ARCHIVE_DEST_STATUS的RECOVERY_MODE列,若启用了实时应用,则在Oracle 11g显示MANAGED REAL TIME APPLY,在Oracle 10g显示MANAGED. ```sql [oracle@dg ~]$ ps -ef|grep ora_mrp oracle 19592 1 0 10:15 ? 00:00:01 ora_mrp0_phydb ``` ### 5.2.5 DG总体情况查询(主备库) > 以下的SQL是一个非常有用的SQL语句,可以查询出当前DG的运行和配置的总体情况: ```sql SET LINE 9999 COL DEST_NAME FORMAT A20 COL DESTINATION FORMAT A15 COL GAP_STATUS FORMAT A10 COL DB_UNIQUE_NAME FORMAT A15 COL ERROR FORMAT A10 COL APPLIED_SCN FOR 999999999999999 SELECT AL.THREAD#, ADS.DEST_ID, ADS.DEST_NAME, (SELECT ADS.TYPE || ' ' || AD.TARGET FROM V$ARCHIVE_DEST AD WHERE AD.DEST_ID = ADS.DEST_ID) TARGET, ADS.DATABASE_MODE, ADS.STATUS, ADS.ERROR, ADS.RECOVERY_MODE, ADS.DB_UNIQUE_NAME, ADS.DESTINATION, ADS.GAP_STATUS, (SELECT MAX(SEQUENCE#) FROM V$LOG NA WHERE NA.THREAD# = AL.THREAD#) CURRENT_SEQ#, MAX(SEQUENCE#) LAST_ARCHIVED, MAX(CASE WHEN AL.APPLIED = 'YES' AND ADS.TYPE <> 'LOCAL' THEN AL.SEQUENCE# END) APPLIED_SEQ#, (SELECT AD.APPLIED_SCN FROM V$ARCHIVE_DEST AD WHERE AD.DEST_ID = ADS.DEST_ID) APPLIED_SCN FROM (SELECT * FROM V$ARCHIVED_LOG V WHERE V.RESETLOGS_CHANGE# = (SELECT D.RESETLOGS_CHANGE# FROM V$DATABASE D)) AL, V$ARCHIVE_DEST_STATUS ADS WHERE AL.DEST_ID(+) = ADS.DEST_ID AND ADS.STATUS != 'INACTIVE' GROUP BY AL.THREAD#, ADS.DEST_ID, ADS.DEST_NAME, ADS.STATUS, ADS.ERROR, ADS.TYPE, ADS.DATABASE_MODE, ADS.RECOVERY_MODE, ADS.DB_UNIQUE_NAME, ADS.DESTINATION, ADS.GAP_STATUS ORDER BY ADS.DEST_ID,AL.THREAD#; ``` ### 5.2.6 日志应用情况 > 检查是否存在GAP的SQL语句: ```sql SELECT THREAD#,LOW_SEQUENCE#,HIGH_SEQUENCE# FROM V$ARCHIVE_GAP; ``` > 物理DG日志应用情况: ```sql COL NAME FOR A100 SET LINESIZE 9999 PAGESIZE 9999 COL NEXT_CHANGE# FOR 999999999999999 SELECT THREAD#, NAME, SEQUENCE#, ARCHIVED, APPLIED, A.NEXT_CHANGE# FROM V$ARCHIVED_LOG A WHERE A.SEQUENCE# >= (SELECT MAX(B.SEQUENCE#) - 3 FROM V$ARCHIVED_LOG B WHERE B.THREAD# = A.THREAD# AND B.RESETLOGS_CHANGE# = A.RESETLOGS_CHANGE# AND B.RESETLOGS_CHANGE# = (SELECT D.RESETLOGS_CHANGE# FROM V$DATABASE D) AND B.APPLIED = 'YES' GROUP BY B.THREAD#) ORDER BY A.THREAD#, A.SEQUENCE#; 5.2.7 物理备库进程信息 COL GROUP_# FORMAT A5 COL CLIENT_PID FORMAT A8 SET LINE 9999 PAGESIZE 9999 SELECT A.INST_ID, A.PROCESS, A.CLIENT_PROCESS, A.CLIENT_PID, A.STATUS, A.GROUP# GROUP_#, A.THREAD#, A.SEQUENCE#, A.DELAY_MINS, A.RESETLOG_ID, C.SID, C.SERIAL#, A.PID SPID, B.PNAME FROM GV$MANAGED_STANDBY A, GV$PROCESS B, GV$SESSION C WHERE A.PID = B.SPID AND B.ADDR = C.PADDR AND A.INST_ID = B.INST_ID AND B.INST_ID = C.INST_ID ORDER BY A.INST_ID,B.PNAME; ``` ```bash 1). PROCESS :进程名称,如ARCH、RFS、MRP0等 2). CLIENT_PID :在备库查询时对应的Primary数据库中的进程,如ARCH、LGWR等,在主库查询时就是后台进程 3). SEQUENCE# :归档序号 4). STATUS :进程的当前状态,值较多,常见的有: ALLOCATED :正准备连接Primary数据库 ATTACHED :正在连接Primary数据库 CONNECTED :已连接至Primary数据库 IDLE :空闲中 RECEIVING :归档文件接收中 OPENING :归档文件处理中 CLOSING :归档文件处理完,收尾中 WRITING :Redo数据库写向归档文件中 WAIT_FOR_LOG :等待新的Redo数据中 WAIT_FOR_GAP :归档有中断,正等待中断的那部分Redo数据 APPLYING_LOG :应用Redo数据中 ``` ### 5.2.8 手动注册日志 > 如果有日志文件未被传输或未被注册到备库,那么可以使用如下命令手工注册到备库. 下面的SQL语句可以生成物理和逻辑DG注册的SQL语句,日志号从1980到2000: ```sql SELECT 'alter database register or replace logical logfile ''/arch/log_1_' || A || ' _666200636.arc'';' LOGICAL_DG, 'alter database register or replace logfile ''/arch/log_1_' || A || ' _666200636.arc'';' PHYSICAL_DG FROM (SELECT LEVEL A FROM DUAL CONNECT BY LEVEL <= 2000) WHERE A >= 1980; ``` ## 5.3 逻辑DG](中的SQL ### 5.3.1 日志应用的启动和关闭 ```sql ALTER DATABASE STOP LOGICAL STANDBY APPLY; ---停止应用,等待事务完成 ALTER DATABASE ABORT LOGICAL STANDBY APPLY; --不等待事务完成就停止 ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE; ---实时 ALTER DATABASE START LOGICAL STANDBY APPLY; --非实时 ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE SKIP FAILED TRANSACTION; --实时应用并跳过失败的事务 ``` > 如何知道是否开启了实时应用呢?可以查询V$LOGSTDBY_STATE视图或查询是否有lsp进程. ```sql SQL> SELECT * FROM V$LOGSTDBY_STATE; PRIMARY_DBID SESSION_ID REALTIME_APPLY STATE ------------ ---------- ------------------ ----------------------------------------- 1480747539 1 Y APPLYING [oracle@rac01~]$ ps -ef|grep -i ora_lsp oracle 20450 1 0 15:22 ? 00:00:00 ora_lsp0_oraljdg ``` ### 5.3.2 查看日志文件的应用情况 ```sql COLUMN DICT_BEGIN FORMAT A15; COLUMN FILE_NAME FORMAT A50; SET NUMF 9999999; COL FCHANGE# FORMAT 9999999999999; COL NCHANGE# FOR 999999999999999999999; SET LINE 200 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 THREAD#,SEQUENCE#; ---------------------------------------------- SET LINE 9999 PAGESIZE 9999 COL FILE_NAME FORMAT A120 SELECT THREAD#,SEQUENCE#, FILE_NAME, APPLIED, TIMESTAMP FROM DBA_LOGSTDBY_LOG D WHERE D.SEQUENCE# >=(SELECT MAX(SEQUENCE#)-3 FROM DBA_LOGSTDBY_LOG NB WHERE NB.THREAD#=D.THREAD# AND NB.APPLIED='YES' ) ORDER BY THREAD#,D.SEQUENCE#; ``` ### 5.3.3 查看备库SQL Apply的进度 ```sql SQL> SELECT LATEST_SCN,MINING_SCN,APPLIED_SCN,LATEST_TIME,MINING_TIME,APPLIED_TIME FROM V$LOGSTDBY_PROGRESS; LATEST_SCN MINING_SCN APPLIED_SCN LATEST_TIME MINING_TIME APPLIED_TIME ---------- ---------- ----------- ------------------- ------------------- ------------------- 8895794846 8895316681 8895316680 2010-05-18 16:27:08 2010-05-18 16:03:54 2010-05-18 16:03:54 ``` ### 5.3.4 查看备库是否有任何DDL/DML语句未成功应用 > 如果物理DG没有实时应用,或者说物理DG的mrp进程已经启动了,但是在很长时间后依然没有应用归档日志,那么可以通过查询物理DG的告警日志来找到原因. > 如果逻辑DG没有实时应用,或者说逻辑DG的lsp进程已经启动了,但是在很长时间后依然没有应用归档日志,那么可以使用如下的SQL查询原因 ```sql_more COL EVENT_TIMESTAMP FORMAT A30 COL EVENT FORMAT A40 COL EVENT_STATUS FORMAT A80 SELECT A.EVENT_TIME, A.CURRENT_SCN, A.COMMIT_SCN, XIDUSN, XIDSLT, XIDSQN, TO_CHAR(EVENT) EVENT, A.STATUS_CODE, STATUS EVENT_STATUS FROM DBA_LOGSTDBY_EVENTS A WHERE A.EVENT_TIME >= SYSDATE - 10 / 1660 ``` ### 5.3.5 查看备库SQL Apply的状态 ```sql_more COL REALTIME_APPLY FORMAT A15 COL STATE FORMAT A20 SELECT * FROM V$LOGSTDBY_STATE; PRIMARY_DBID SESSION_ID REALTIME_APPLY STATE ------------ ---------- --------------- --------------- 262089084 1 Y APPLYING ``` > 注意STATE列,该列可能有下述的几种状态: ```bash INITIALIZING :LogMiner SESSION已创建并初始化 LOADING DICTIONARY :SQL应用调用LogMiner字典 WAITING ON GAP :SQL应用正在等待日志文件,可能有中断 APPLYING :SQL应用正在工作 WAITING FOR DICTIONARY LOGS :SQL应用正在等待LogMiner字典信息 IDLE :SQL应用工作非常出色,处于空闲状态 SQL APPLY NOT ON :没有开启应用 ``` ### 5.3.6 取消部分对象或事务的同步 > 可以利用DBMS_LOGSTDBY.SKIP存储过程跳过特定表或特定用户的DML事务或部分DDL语句. 这些跳过的对象或事务可以通过视图DBA_LOGSTDBY_SKIP和DBA_LOGSTDBY_SKIP_TRANSACTION查看. ```sql_more EXECUTE DBMS_LOGSTDBY.SKIP(STMT => 'VIEW'); EXECUTE DBMS_LOGSTDBY.SKIP(STMT => 'PROFILE'); EXECUTE DBMS_LOGSTDBY.SKIP(STMT => 'DATABASE LINK'); EXECUTE DBMS_LOGSTDBY.SKIP(STMT => 'CREATE VIEW'); EXECUTE DBMS_LOGSTDBY.SKIP(STMT => 'DROP VIEW'); EXECUTE DBMS_LOGSTDBY.SKIP(STMT=>'SCHEMA_DDL', SCHEMA_NAME=>'%', OBJECT_NAME=>'%', PROC_NAME=>NULL); EXECUTE DBMS_LOGSTDBY.SKIP(STMT=>'SCHEMA_DDL', SCHEMA_NAME=>'LHR', OBJECT_NAME=>'%', PROC_NAME=>NULL); EXECUTE DBMS_LOGSTDBY.SKIP(STMT=>'SCHEMA_DDL', SCHEMA_NAME=>'MDSYS', OBJECT_NAME=>'%', PROC_NAME=>NULL); EXEC DBMS_LOGSTDBY.SKIP_TRANSACTION (3, 3, 827); --(XIDUSN = 3, XIDSLT = 3, XIDSQN = 827) SELECT EVENT, STATUS,'EXEC DBMS_LOGSTDBY.SKIP_TRANSACTION ('||XIDUSN||', '||XIDSLT||', '||XIDSQN||');' FROM DBA_LOGSTDBY_EVENTS A WHERE XIDUSN IS NOT NULL AND A.EVENT_TIME >= SYSDATE - 60 / 1660; SELECT 'EXEC DBMS_LOGSTDBY.SKIP_TRANSACTION ('||XIDUSN||', '||XIDSLT||', '||XIDSQN||');' FROM DBA_LOGSTDBY_EVENTS A WHERE XIDUSN IS NOT NULL AND A.EVENT_TIME >= SYSDATE - 10 / 1660; SELECT * FROM DBA_LOGSTDBY_SKIP; SELECT * FROM DBA_LOGSTDBY_SKIP_TRANSACTION; ``` ### 5.3.7 备库相关SQL #### 5.3.7.1 增加apply进程个数 > 首先查看当前空闲的applier进程数 ```sql_more SELECT COUNT(*) IDLE_APPLIER FROM V$LOGSTDBY_PROCESS WHERE TYPE='applier' AND STATUS_CODE=16166; --STATUS_CODE=16166表示进程是空闲状态,当然空闲的applier进程数为0不一定代表应用非常繁忙,也有可能是因为当前没有什么需要应用的日志,甚至应用进程都没启动 ``` > 检查事务的应用情况: ```sql_more select name,value from v$logstdby_stats where name like'TRANSACTION%'; ``` > 如果 ready-applied的值比 applier进程数的兩倍还要大,则说明有必要考虑增加app1ier进程的数目了,反之如果applied与 ready的值差不多大,或者其差比 applier进程数还小,则说明app1ier进程数偏多,有必要考虑适当减小进程的数目. > 如果确认当前 applier进程都非常繁忙,要增加 applier进程,可按如下步骤操作: > 如果Ap1y进程过于繁忙,那么可以增加 Appl进程个数以下命令调整为20,默认为5个: ```sql_more SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY; SQL> EXECUTE DBMS_LOGSTDBY.APPLY_SET('APPLY_SERVERS',20); SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE; ``` #### 5.3.7.2 处理从主库接收到的归档文件 > 逻辑DG在应用完归档日志后会自动删除该归档文件,这一特性是由逻辑DG中的2个参数控制的,它们分别为<span style='color:green'>LOG_AUTO_DELETE</span>和<span style='color:green'>LOG_AUTO_DEL_RETENTION_TARGET</span>. > **LOG_AUTO_DELETE** > > 值默认为TRUE,表示逻辑DG在应用完归档日志后会自动删除该归档文件,默认24小时之后删除(由参数LOG_AUTO_DEL_RETENTION_TARGET控制). 如果希望禁用自动删除的功能,那么可以执行下列语句: sql_more> 在告警日志中会有类似如下的记录: ```sql_more Fri Jul 27 13:48:53 2018 LOGMINER: Log Auto Delete - deleting: /u01/app/oracle/flash_recovery_area/ORADGLG/1_202_886695024.dbf Deleted file /u01/app/oracle/flash_recovery_area/ORADGLG/1_202_886695024.dbf ``` > 在某些情况下确实需要禁用归档文件的自动删除功能,例如逻辑DG需要执行Flashback Database操作,如果你想恢复到之前的某个时间点,然后再接着应用,那么就必须要有该时间点后对应的归档. 假如LOG_AUTO_DELETE为TRUE的话,应用过的归档已经被删除,想回都回不去. > **LOG_AUTO_DEL_RETENTION_TARGET** > > 表示逻辑DG在应用完归档日志后的多长时间之后再自动删除该归档文件. 该参数仅在LOG_AUTO_DELETE设置为TRUE之后才起作用,默认值为1440分钟,即24小时,可以通过以下命令修改该值的大小: ```sql_more EXECUTE DBMS_LOGSTDBY.APPLY_SET('LOG_AUTO_DEL_RETENTION_TARGET',1); ``` > 以上命令表示归档日志被应用完之后,再过1分钟才会自动删除该归档日志. 需要注意的是,<span style='color:green'>这些设置仅适用于从主库传递过来的归档文件归档到的位置不是闪回恢复区. 如果正在使用闪回恢复区,那么这些从主库传递过来的归档文件将不再根据参数LOG_AUTO_DELETE和LOG_AUTO_DEL_RETENTION_TARGET的值做处理.</span> > 如果禁止了逻辑DG归档文件的自动删除功能,那么一定要有相应的其他解决方案,不能说取消了自动删除功能,之后逻辑Standby数据库接收到的Standby归档文件就不再管它,这肯定会产生问题,最起码要考虑到逻辑Standby数据库的存储空间是有限的. > 逻辑Standby数据库接收到的归档文件并不会显示在V$ARCHIVED_LOG视图中,因此以为通过RMAN中的配置自动删除这些文件的希望也是会落空的. 对于这类文件的删除,正确的删除方法通常会按照如下步骤操作: > 首先执行DBMS_LOGSTDBY.PURGE_SESSION,该过程会检查当前所有接收到的归档日志文件,对于那些已经应用过,不再需要(这里是当前不再需求,未来是否有可能需要就得由DBA来决定了)的文件进行标记,例如: ```sql_more EXECUTE DBMS_LOGSTDBY.PURGE_SESSION; ``` > 然后,查询数据字典DBA_LOGMNR_PURGED_LOG,所有被DBMS_LOGSTDBY.PURGE_SESSION标记不再需要的日志都会记录在这里,例如: ```sql_more SELECT*FROM DBA_LOGMNR_PURGED_LOG; ``` > 该字典只有一列,即归档文件的实际路径. 最后根据显示的路径找到这些文件,然后在操作系统中删除即可. #### 5.3.7.3 调整PREPARER(调制机)的进程数 > 如果备库上有很多事务在等待Apply,但是还有空闲的Applier进程,且已经没有idle状态的PREPARER(调制机)进程,这时需要增加PREPARER的进程数. 以下命令调整为4个,默认为1个: ```sql_more --查看空闲preparer进程数 SELECT COUNT(*) IDLE_APPLIER FROM V$LOGSTDBY_PROCESS WHERE TYPE='PREPARER' AND STATUS_CODE=16166; --检查事务应用情况 select name,value from v$logstdby_stats where name like 'TRANSACTION%'; --查看当前空闲的applier进程数 SELECT COUNT(*) IDLE_APPLIER FROM V$LOGSTDBY_PROCESS WHERE TYPE='APPLIER' AND STATUS_CODE=16166; ``` > 如果备库有很多事务在等待apply,但是还有空闲的applier进程,切已经没有idle状态的PREPARER(调制机)进程,这是需要增加PREPARER进程数. 以下是命令调整为4个,默认为1个 ```sql_more SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY; SQL> EXECUTE DBMS_LOGSTDBY.APPLY_SET('PREPARE_SERVERS',4); SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE; ``` #### 5.3.7.4 调整MAX_SGA,防止Paged out ```sql_more --通过以下SQL可以查询到是否发生了Paged out: SQL> select value bytes from v$logstdby_stats where name='bytes paged out'; --如果以上查询结果在增长,那么查看当前MAX_SGA的大小: SQL> select value from v$logstdby_stats where name like 'maximum SGA for LCR cache%'; VALUE --------------------------------------------------------------- 30 --可以增大MAX_SGA: SQL> alter database stop logical standby apply; SQL> execute dbms_logstdby.apply_set('MAX_SGA',1000); SQL> alter database start logical standby apply immediate; ``` > 逻辑备库需要将Redo记录解析成LCR(Logical Change Records),会在Shared Pool里分配一部分空间来作为LCR Cache,如果Cache太小,就会像OS的虚拟内存管理一样,需要做page out,这会严重影响应用日志的性能. 在默认情况下,LCR Cache为Shared Pool的四分之一,最少不少于30M(默认为30M,最大可以设置到4096M),否则SQL Apply不能启动. 如果机器的内存足够,建议将LCR Cache尽量设大一点,当然,同时Share Pool也要足够大. 如果机器内存有限,那么可以考虑将Buffer Cache减少一点来给LCR Cache腾出空间. #### 5.3.7.5 调整事务应用方式 > 默认情况下逻辑Standby端事务应用顺序与Primary端提交顺序相同. 如果希望逻辑Standby端的事务应用不要按照顺序的话,那么可以按照下列的步骤操作: ```sql_more --1、停止SQL应用: SQL>ALTER DATABASE STOP LOGICAL STANDBYAPPLY; --2、允许事务不按照Primary的提交顺序应用: SQL>EXECUTE DBMS_LOGSTDBY.APPLY_SET('PRESERVE_COMMIT_ORDER','FALSE'); --3、重新启动SQL应用 SQL>ALTER DATABASE START LOGICAL STANDBYAPPLY IMMEDIATE; ``` > 恢复逻辑Standby按照事务提交顺序应用的话,按照下列步骤: ```sql_more --1、停止SQL应用: SQL>ALTER DATABASE STOP LOGICAL STANDBYAPPLY; --2、重置参数PRESERVE_COMMIT_ORDER的初始值: SQL>EXECUTE DBMS_LOGSTDBY.APPLY_UNSET('PRESERVE_COMMIT_ORDER'); --3、重新启动SQL应用: SQL>ALTER DATABASE START LOGICAL STANDBYAPPLY IMMEDIATE; ``` # 六、主备库归档日志清理 ## 6.1 概述 > 在11g里面,随着ASM、RAC、Data Guard(包括Active Data Guard)的成熟,使用RAC+ASM+Data Guard越来越成为一种可靠的、维护简单、稳定的高可用性和容灾保护方案. 这篇文章谈谈如何管理Oracle 11g > Data Guard环境中的归档日志. > 归档日志是重要的,备份恢复需要它,而Data Guard也需要它. 在早期版本的Data Guard环境中,常常面临着归档日志管理问题. 在Data Guard环境里面,对归档日志管理需要达到以下几个方面的要求或者说是需求: > >> **不能够随意删除掉归档日志,归档日志丢失会导致Data Guard需要重新搭建. >> **不能随意使用RMAN删除归档日志,否则同样会导致Data Guard需要重新搭建. >> **在使用RMAN备份后,如果归档没有被传送或应用到备库上,那么RMAN不应该删除归档日志,否则Data Guard需要的归档就必须从备份里面还原出来,增加了维护工作量. >> **对RMAN的备份脚本没有特别的要求,否则脚本意外改动,可能会导致Data Guard需要的归档日志被删除. >> **归档应尽量保存在磁盘上,以避免Data Guard长时间维护时归档被删除. >> **备库的归档日志不需要花精力去维护,自动删除已经应用过的归档日志. >> **幸运的是,在11g环境里面,上述的几点很容易就满足,那就是只需要做到以下几点.** >> **使用快速恢复区(fast recovery area),在10g版本的文档中称为闪回恢复区(flash recovery area),老实说,一直不太明白为什么取名叫闪回恢复区,难道是因为10g有了数据库闪回功能?在RAC中,毫无疑问快速恢复区最好是置放在ASM上. >> **为快速恢复区指定合适的空间. 首先我们需要预估一个合理的归档保留时间长. 比如由于备份系统问题或Data Guard备库问题、维护等,需要归档保留的时间长度. 假设是24小时,再评估一下在归档量最大的24小时之内,会有多少量的归档?一般来说是在批量数据处理的时候归档量最大,假设这24小时之内归档最大为200G. 注意对于RAC来说是所有节点在这24小时的归档量之和. 最后为快速恢复区指定需要的空间量,比通过参数db_recovery_file_dest_size指定快速恢复区的大小. 这里同样假设快速恢复区们存放归档日志. >> **在备库上指定快速恢复区以及为快速恢复区指定合适的大小,在备库上指定快速恢复区的大小主要考虑的是:切换成为主库后归档日志容量;如果主库归档容量压力大,备库能否存储更多的归档日志以便可以通过备库来备份归档日志. >> **对主库和备份使用RMAN配置归档删除策略:CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON ALL STANDBY; >> **完成了上述几个步骤,那么归档管理的要求基本上就达到了. 通过这样的设置,实现的效果如下:** >> **归档日志如果没有应用到备库,那么在RMAN中使用backup …. delete inputs all和delete archivelog all不会将归档日志删除. 但但是请注意如果是使用delete force命令则会删除掉归档,不管归档有没有被应用到备库. >> **如果归档日志已经应用到了备库,那么在RMAN中使用backup …. delete inputs all和delete archivelog all可以删除归档日志,在正常情况下,由于归档日志可能很快应用到Data Guard,所以在RMAN备份之后可以正常删除归档日志. RMAN也不需要使用特别的备份脚本,也不必担心人为不小心使用. delete archivelog all命令删除了归档. >> **备库的归档日志存储到快速恢复区中,备库的快速恢复区空间紧张时,会自动删除已经应用过的较早的归档日志以释放空间,这样便可以实现备库的归档日志完全自动管理. >> **如果由于备份异常或Data Guard异常,在快速恢复区空间紧张时,Oracle在切换日志时,会自动删除掉已经应用过的归档日志,以释放空间. 但是如果归档日志没有应用到Data Guard,那么归档日志不会被删除. 这种情况下,快速恢复区的归档可能会增加到空间耗尽,最后就会出现数据库不能归档,数据库挂起的问题. >> > 注意上面最后一点,当快速恢复区空间紧张时,Oracle开始删除归档日志,删除的条件还包括归档日志已经应用到备库,这种情况下如果归档日志还没有备份,也会被删除掉. 这里的问题是,文档中描述的快速恢复区空间紧张,具体是指什么时间?也就是快速恢复区的空间消耗多少百分比的时候才算是空间紧张?在MOS文章《Files being deleted in the flash recovery area, messagesin the alert log Deleted Oracle managed file <filename> (Doc ID1369341.1)》里面有提到,空间使用率达到80%以后就开始删除文件(归档日志). > Oracle在往快速恢复区存储文件时,其步骤大概是这样的:Oracle估计需要的空间大小(切换日志时就是归档日志大小),然后将这个大小与当前的占用空间大小相加,看是否超过了80%,如果超过了,那么就回收空间(回收的空间应大于等于新建文件需要的空间大小,也就是回收的空间以够用为原则). 如果不能回收空间(比如归档日志没有被应用到备库),那就只能继续占用新的空间,直到空间耗尽. > 这里的问题是,假设快速恢复区设定了200G空间,那么在使用到80%,也就是160G的时候就开始回收空间. 那么我们在估算空间时,就应该上浮20%. 比如我们要求保留24小时归档,这24小时之内归档量最大是200G,那么我们应该为快速恢复区设置240G左右的容量. > 那么,这个80%的比率能够更改吗以便延迟Oracle删除归档日志的时间吗?答案是肯定的. 没有相应的数据库参数来设定,但是可以通过事件来设置,事件号是19823: ## 6.2 查询应用到备库的归档日志 ### 6.2.1 主库查询 ```sql_more SELECT THREAD#, NAME, SEQUENCE#, ARCHIVED, APPLIED, A.NEXT_CHANGE#, A.COMPLETION_TIME, 'delete archivelog sequence ' || A.SEQUENCE# || ' thread ' ||A.THREAD# || ';' EXEC_SQL FROM V$ARCHIVED_LOG A WHERE (A.THREAD#, A.SEQUENCE#, a.RESETLOGS_CHANGE#) IN (SELECT b.THREAD#, b.SEQUENCE#, b.RESETLOGS_CHANGE# FROM V$ARCHIVED_LOG B WHERE B.APPLIED = 'YES' AND b.COMPLETION_TIME <= SYSDATE - 3) AND a.NAME NOT IN (SELECT b.DESTINATION FROM v$archive_dest b WHERE b.DESTINATION IS NOT NULL) AND A.COMPLETION_TIME <= SYSDATE - 3 ORDER BY A.THREAD#, A.SEQUENCE#; ``` ### 6.2.2 备库查询 ```sql_more COL NAME FOR A100 SET LINESIZE 9999 PAGESIZE 9999 COL NEXT_CHANGE# FOR 999999999999999 SELECT THREAD#, NAME, SEQUENCE#, ARCHIVED, APPLIED, A.NEXT_CHANGE# FROM V$ARCHIVED_LOG A WHERE A.SEQUENCE# >= (SELECT MAX(B.SEQUENCE#)-3 FROM V$ARCHIVED_LOG B WHERE B.THREAD# = A.THREAD# AND B.RESETLOGS_CHANGE# = A.RESETLOGS_CHANGE# AND B.RESETLOGS_CHANGE# = (SELECT D.RESETLOGS_CHANGE# FROM V$DATABASE D) AND B.APPLIED = 'YES' GROUP BY B.THREAD#) ORDER BY A.THREAD#, A.SEQUENCE#; ``` ## 6.3 DG环境删除归档日志范例 ```bash chmod +x /home/oracle/delarch/deldgarch.sh crontab -e 0 17 * * * /home/oracle/delarch/deldgarch.sh mkdir -p /home/oracle/lhr/log more /home/oracle/delarch/deladgarc.sh #!/bin/bash export ORACLE_HOME=/u01/app/oracle/product/18.3.0/dbhome_1 export ORACLE_SID=htzxdb1 export NLS_DATE_FORMAT="YYYY-MM-DD HH24:Mi:SS" LOG_DIR=/home/oracle/lhr/log DATEL=`date '+%Y-%m-%d'` LOG_NAME=${LOG_DIR}/deladgarc_${ORACLE_SID}_${DATEL}".log" SQL_NAME=${LOG_DIR}/deladgarc_${ORACLE_SID}_${DATEL}".sql" LINK_NAME=tns_htzxdbphy $ORACLE_HOME/bin/sqlplus -S sys/oracle@${LINK_NAME} as sysdba <<EOF set feedback off heading off pagesize 0 linesize 100 col exec_sql format a50 spool ${SQL_NAME} SELECT 'delete archivelog sequence ' || A.SEQUENCE# || ' thread ' || A.THREAD# || ';' EXEC_SQL FROM V\$ARCHIVED_LOG A WHERE (A.THREAD#, A.SEQUENCE#, a.RESETLOGS_CHANGE#) IN( SELECT b.THREAD#, b.SEQUENCE#, b.RESETLOGS_CHANGE# FROM V\$ARCHIVED_LOG B WHERE B.APPLIED = 'YES' AND b.COMPLETION_TIME <= SYSDATE - 8 ) AND a.NAME NOT IN (SELECT b.DESTINATION FROM v\$archive_dest b WHERE b.DESTINATION IS NOT NULL) AND A.COMPLETION_TIME <= SYSDATE - 8 ORDER BY A.THREAD#,A.SEQUENCE#; spool off exit EOF $ORACLE_HOME/bin/rman log=$LOG_NAME target sys/oracle@${LINK_NAME} <<EOF crosscheck archivelog all; delete noprompt expired archivelog all; @${SQL_NAME} exit; EOF ``` # 七、DG中GAP的解决方案 > 当主库的某些日志没有成功传送到备库,那么这时候就发生了归档裂缝(Archive Gap). 目前Oracle提供了两种日志GAP的检测和处理机制,分别是自动GAP处理(Automatic Gap Resolution)和FAL进程GAP处理(FAL Gap Resolution). 自动GAP处理即主库上的ARCn进程会每分钟检查备库上的日志GAP情况并做相应处理. FAL(Fetch Archive Log)是通过配置FAL_SERVER和FAL_CLIENT实现GAP检测的一种机制,它是备库主动发起的“取”日志的过程. 备库就是FAL_CLIENT,它从FAL_SERVER中取这些GAP. Oracle会首先尝试使用FAL进程处理GAP,当发现FAL机制并没有配置生效的时候,进而尝试使用自动GAP处理. > FAL进程只在物理备库存在. FAL进程提供了一个CLIENT/SERVER的机制,用来解决检测在主库产生的连续的归档日志,而在备库接受的归档日志不连续的问题. 该进程只有在需要的时候才会启动,而当工作完成后就关闭了,因此在正常情况下,该进程是无法看见的. ## 7.1 物理DG手动解决GAP > 在一些特殊情况下,如果GAP不能自动解决,那么就需要手工执行中断恢复. 通过查询视图V$ARCHIVE_GAP可以确定断档的是哪些日志. ```sql_more SQL> SELECT * FROM V$ARCHIVE_GAP; THREAD# LOW_SEQUENCE# HIGH_SEQUENCE# ----------- ------------- -------------- 1 10 12 ``` > 可以看到,当前物理备库丢失日志文件从线程1的序号10到序号12. 接下来确定归档日志文件的路径:(假设在主数据库上的本地归档目的地是LOG_ARCHIVE_DEST_1): ```sql SQL> SELECT NAME FROM V$ARCHIVED_LOG WHERE THREAD#=1 AND DEST_ID=1 AND SEQUENCE# BETWEEN 10 AND 12; NAME ----------------------------------------------------------------- /arch/thread1_dest/arch_1_10.arc /arch/thread1_dest/arch_1_11.arc /arch/thread1_dest/arch_1_12.arc ``` > 接下来,复制这些日志文件到物理备库,然后在物理备库上使用“ALTER DATABASE REGISTER LOGFILE”语句来注册这些归档日志,如下所示: ```sql_more SQL> ALTER DATABASE REGISTER LOGFILE '/arch/thread1_dest/arch_1_10.arc'; ``` > 也可以使用如下的SQL语句: ```sql ALTER DATABASE REGISTER OR REPLACE LOGFILE '/arch/thread1_dest/arch_1_10.arc'; ALTER DATABASE REGISTER OR REPLACE PHYSICAL LOGFILE '/arch/thread1_dest/arch_1_11.arc'; ``` > 在物理备库上注册这些日志文件之后,重新打开重做应用进程. 如果断档的归档日志较多,那么可以使用如下的SQL语句来生成要执行的SQL语句(如下的SQL也适用于逻辑DG): ```sql SELECT 'ALTER DATABASE REGISTER OR REPLACE LOGICAL LOGFILE ''/arch/thread1_dest/arch_1_' || a ||'.arc'';' LOGICAL_DG, 'ALTER DATABASE REGISTER OR REPLACE LOGFILE ''/arch/thread1_dest/arch_1_' || a ||'.arc'';' PHYSICAL_DG FROM (SELECT LEVEL A FROM DUAL CONNECT BY LEVEL <= 12) ``` > 需要注意的是,视图ARCHIVE_GAP只返回当前妨碍重做应用继续的下一个中断. 在解决中断并重启重做应用进程后,再次在物理备库上查询V$ARCHIVE_GAP视图来确定下一个中断序号,如果有的话,重复这个过程直到没有更多的中断. ## 7.2 逻辑DG手动解决GAP > 在逻辑备库上查询DBA_LOGSTDBY_LOG视图可以确定是否有归档中断. 例如,下面的查询指出断档号为16至18: ```sql COLUMN FILE_NAME FORMAT a60 SELECT THREAD#, SEQUENCE#, FILE_NAME FROM DBA_LOGSTDBY_LOG L WHERE NEXT_CHANGE# NOT IN (SELECT FIRST_CHANGE# FROM DBA_LOGSTDBY_LOG WHERE L.THREAD# = THREAD#) ORDER BY THREAD#, SEQUENCE#; THREAD# SEQUENCE# FILE_NAME --------- ---------- --------------------------------------------- 1 16 /arch/oracle/arch_1_16.arc ``` > 接下来复制丢失的日志文件到逻辑备库,并在逻辑备库上使用“ALTER DATABASE REGISTER LOGICAL LOGFILE”来注册这些日志文件. 例如: ```sql ALTER DATABASE REGISTER LOGICAL LOGFILE '/arch/oracle/arch_1_16.arc'; ``` > 在逻辑备库上注册这些日志文件之后,重启SQL应用. 和物理DG一样,在逻辑备库上的DBA_LOGSTDBY_LOG视图只返回当前妨碍SQL应用继续的下一个中断. 在解决指定的中断并重启SQL应用之后,再次在逻辑备库上查询DBA_LOGSTDBY_LOG视图,以确定下一个中断序号,如果有的话,重复这个过程直到没有更多的中断. > <span style='color:green'>需要注意的是,如果需要的归档日志已经不在主库上了,但是有归档日志的RMAN备份,那么可以通过RMAN恢复把缺少的归档日志进行还原,如下所示:</span> ```sql SET ARCHIVELOG DESTINATION TO '/arch'; RESTORE ARCHIVELOG FROM LOGSEQ 7; ``` > 如果断档的归档日志已经丢失,且RMAN又没有备份,那么在Oracle 10g之前没有办法修复了,只能重建DG,但是从Oracle 11g开始可以采用主库基于SCN的增量备份来恢复DG,详见【主库丢失归档的物理DG恢复】 ## 7.3 主库丢失归档的物理之拷贝备份恢复 > 面试DBA岗位,面试官对于DG环境常常会问到,若是主库丢失了归档文件,而这些归档文件还未来得及传递到备库,则物理备库是否只能通过重建的方式来恢复呢?这道面试题是作者亲身经历,当时以为只能重建备库,但最后经过查找文档找到了解决办法,可以通过对主库进行基于SCN的增量备份来恢复物理DG. > 全过程简单有如下几个步骤: > 1、备库查询当前SCN号 > 2、主库根据SCN号进行增量备份 > 3、将备份集传输至备库 > 4、备库应用备份集恢复 ### 7.3.1 第一步,主库创建基于SCN的增量备份: > 首先要知道误删除或者丢失的归档日志是从哪个SCN开始的. 视图V$ARCHIVED_LOG的FIRST_CHANGE#列能够查到归档日志对应的起始SCN. 可以使用如下SQL查询最小的SCN: ```sql SELECT (SELECT MIN(D.CHECKPOINT_CHANGE#) FROM V$DATAFILE D) DATAFILE_SCN, (SELECT MIN(D.CHECKPOINT_CHANGE#) FROM V$DATAFILE_HEADER D WHERE ROWNUM = 1) DATAFILE_HEADER_SCN, (SELECT CURRENT_SCN FROM V$DATABASE) CURRENT_SCN, (SELECT MIN(B.NEXT_CHANGE#) FROM V$ARCHIVED_LOG B WHERE B.SEQUENCE# IN (968,644)--这里修改成丢失的归档号 AND RESETLOGS_CHANGE# =(SELECT D.RESETLOGS_CHANGE# FROM V$DATABASE D)) NEXT_CHANGE# FROM DUAL; ``` > 若最小的SCN为750983,则在主库上使用BACKUP ... INCREMENTAL FROM SCN为主库做一个增量备份,这个操作会将整个库中SCN大于750983的BLOCK全备份出来,SQL如下: ```sql RUN { ALLOCATE CHANNEL D1 TYPE DISK; ALLOCATE CHANNEL D2 TYPE DISK; ALLOCATE CHANNEL D3 TYPE DISK; ALLOCATE CHANNEL D4 TYPE DISK; BACKUP AS COMPRESSED BACKUPSET INCREMENTAL FROM SCN 750983 DATABASE FORMAT '/ARCHIVE/STANDBY_NEW_%D_%T_%U.BAK' INCLUDE CURRENT CONTROLFILE FOR STANDBY FILESPERSET=5 TAG 'FOR STANDBY NEW'; RELEASE CHANNEL D1; RELEASE CHANNEL D2; RELEASE CHANNEL D3; RELEASE CHANNEL D4; } list backupset of controlfile;--找到控制文件的备份集文件名 ``` ### 7.3.2 第二步,将备份的文件复制到备库端的空目录下 ### 7.3.3 第三步,恢复备库的控制文件 > 在使用RMAN恢复备库的控制文件之前,需要将原来的控制文件进行手工的冷备并且记录下原来的控制文件中记录的数据文件的名称: ```sql SELECT ''''||NAME||''' ;' FROM V$DATAFILE; --记录备库数据文件原名称及路径 startup force nomount cp +DATA/oranlhr/controlfile/control01.ctl +DATA/oranlhr/controlfile/control01.ctl_bk restore standby controlfile from '/home/oracle/bak/standby_TESTDG_20180525_19t3q9sb_1_1.bak'; select 'alter database rename file '''||NAME ||''' TO ' FROM V$datafile; --查询恢复控制文件后备库数据文件的名称 ``` ### 7.3.4 第四步,在备库执行RECOVER操作: ```sql ALTER DATABASE MOUNT; CATALOG START WITH '/ARCHIVE/'; list incarnation of database; reset database to incarnation 1;--应该和主库保持一致 --重命名备库的数据文件 alter system set standby_file_management=manual sid='*'; alter database rename file '+DATADG/testdg/datafile/system.274.976812987' TO '+DATADG/testdgphy/datafile/system.261.976877439'; ...... alter database rename file '+DATADG/testdg/datafile/undotbs2.286.976813901' TO '+DATADG/testdgphy/datafile/undotbs2.257.976877619'; alter system set standby_file_management=auto sid='*'; --最后执行恢复操作 RECOVER DATABASE NOREDO; ``` > 最后开启备库的实时应用进程,并且查询备库的日志应用情况: ```sql ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION; COL NAME FOR A100 SET LINESIZE 9999 PAGESIZE 9999 COL NEXT_CHANGE# FOR 999999999999999 SELECT THREAD#, NAME, SEQUENCE#, ARCHIVED, APPLIED, A.NEXT_CHANGE# FROM V$ARCHIVED_LOG A WHERE A.SEQUENCE# >= (SELECT MAX(B.SEQUENCE#) - 3 FROM V$ARCHIVED_LOG B WHERE B.THREAD# = A.THREAD# AND B.RESETLOGS_CHANGE# = A.RESETLOGS_CHANGE# AND B.RESETLOGS_CHANGE# = (SELECT D.RESETLOGS_CHANGE# FROM V$DATABASE D) AND B.APPLIED = 'YES' GROUP BY B.THREAD#) ORDER BY A.THREAD#, A.SEQUENCE#; ``` > 若需要恢复的文件比较多,则可以使用如下的SQL来查询恢复的进度: ```sql SELECT A.USERNAME, (SELECT UPPER(NB.OSUSER) FROM V$SESSION NB WHERE NB.SID = A.SID) OSUSER, (SELECT NB.SID || ',' || NB.SERIAL# || ',' || PR.SPID FROM V$PROCESS PR, V$SESSION NB WHERE NB.PADDR = PR.ADDR AND NB.SID = A.SID AND NB.SERIAL# = A.SERIAL#) SESSION_INFO, A.TARGET, A.OPNAME, TO_CHAR(A.START_TIME, 'YYYY-MM-DD HH24:MI:SS') START_TIME, ROUND(A.SOFAR * 100 / A.TOTALWORK, 2) || '%' AS PROGRESS, (A.TIME_REMAINING) TIME_REMAINING, (A.SOFAR || ':' || A.TOTALWORK) SOFAR_TOTALWORK, (A.ELAPSED_SECONDS) ELAPSED_SECONDS, MESSAGE MESSAGE, (SELECT NB.EVENT FROM V$SESSION_WAIT NB WHERE NB.SID = A.SID) WAIT_EVENT, (SELECT NB.STATUS FROM V$SESSION NB WHERE NB.SID = A.SID) STATUS FROM V$SESSION_LONGOPS A WHERE A.TIME_REMAINING <> 0 ORDER BY STATUS, A.TIME_REMAINING DESC, A.SQL_ID, A.SID; ``` > 在主库归档日志丢失无法同步到备库时,可以利用增量scn来备份主库的方式,从而避免重建standby. 由于丢失了归档,所以最后需要对数据库进行一次全备. > 在整个恢复过程中需要注意的几点: > 1).若备库是rac,或者asm存储,则在还原控制文件后需要把控制文件中的数据文件重命名为备库的原数据文件名称才可以执行恢复操作. > 2).在执行RECOVER DATABASE NOREDO前,应该让备库和主库都处于同一个incarnation,否则会报如下的错误,并且不能启用备库的实时日志应用功能: ```sql SYS@DGPHY1> alter database open; alter database open * 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: '+DATADG/testdgphy/datafile/system.261.976877439' ``` ## 7.4 主库丢失归档的物理DG之12c RMAN新特性通过网络远程恢复数据库 实验模拟 > 在Dataguard环境中遇到过主库丢失归档日志,而备库也没有及时接收,导致备库出现了GAP的现象. 因为日志的中断,备库无法再去应用之后的日志,就无法起到容灾的效果. > 遇到这种故障,往往主库如果数据很大的时候,大家都不会去选择重新搭建来恢复备库,而会去选择更轻的增量恢复来解决问题. > 即使如此,一旦主库数据量过大,每日变化量也极多,进行一次增量恢复其实也需要大量的时间以及备份集所需要的空间. 甚至,在GAP期间,如果主库新增了数据文件,那么也会增加任务量. > 在12cR1开始,RMAN提供了一个 from service 的子句让备库可以通过网络来执行recover和restore命令. > The FROM SERVICE clause provides the service name of the physical standby database from which the files must be restored. During the restore operation, RMAN creates backup sets, on the physical standby database, of the files that need to be restored and then transfers these backup sets to the target database over the network. > 那在哪些情况下可以使用这个新特性呢 > 1).当备库出现GAP,而主库丢失归档需要做增量备份的时候 > 2).当备库丢失数据文件、控制文件以及表空间的需要restore的时候 > 这个特性其实大大缩减了备库在一些丢失归档需要做增量备份的情况下的工作量,将需要在主备库来回切换的操作简化为只需要在备库进行操作就可以完成. > 关于如何运用这一特性,用些简单的例子来试验下. > 备库增量恢复演示 > 模拟一个拥有GAP的备库的环境: ```sql SQL> select * from v$archive_gap; THREAD# LOW_SEQUENCE# HIGH_SEQUENCE# CON_ID ---------- ------------- -------------- ---------- 1 1231 1234 1 2 762 765 1 SQL> show parameter fal NAME TYPE VALUE ------------------------------------ ---------------------- ------------------------------ fal_client string slave_db fal_server string primary_db ``` > 查询可知主库tnsname连接串名为primary_db ### 7.4.1 step 1 查询备库当前SCN ```sql RMAN> select current_scn from v$database; CURRENT_SCN ----------- 37537287 ``` > 这里提一下,12c 开始,RMAN可以直接执行很多命令,而不需要去使用sql 'sql'的句式去执行. > 然后起至nomount状态 ```sql RMAN> startup force nomount ``` ### 7.4.2 step 2 备库通过from service子句进行增量恢复 ```sql RMAN> restore standby controlfile from service primary_db; RMAN> alter database mount; ``` > 为防止在GAP期间有新增的数据文件 > 可以在主库查询断档之后主库新增的数据文件 ```sql SQL> select file# from v$datafile where creation_change# > =37537287; FILE# ---------- 47 ``` > 通过from service恢复命令将新增的数据文件通过网络在备库恢复. ```sql RMAN>run { SET NEWNAME FOR DATABASE TO '/data/data1/AXTEST/datafile/%f_%U'; RESTORE DATAFILE 47 FROM SERVICE primary_db; } ``` > 因为主备库数据文件路径不一致,需要使用catalog与copy将数据名更新一致. ```sql RMAN> catalog start with '/data/data1'; RMAN> switch database to copy; ``` ### 7.4.3 step 3 增量恢复 > 至此,可以进行增量恢复了 > 在from service句式中还是可以使用常规备份时候使用的参数 > SECTION SIZE (在传输时使用并发备份集传输) > USING COMPRESSED BACKUPSET (在传输时使用压缩,减轻网络压力) ```sql RMAN> recover databasefrom service primary_db noredo SECTIONSIZE1G USING COMPRESSED BACKUPSET; ``` > #接下来就是正常的起库开启实时日志恢复了 > 通过这种方式可以很快的去解决一些备库需要做增量恢复或者数据文件丢失的故障. > 当然,需要使用from service句式时有些必要的条件: > 1).两个数据库之间tns必须保持可以连接的状态 > 2).两个数据库密码文件必须保持一致 > 3).两个数据库的COMPATIBLE参数必须为12.0 ## 7.5 备库数据文件移异常的物理DG之手动恢复 > 有的时候由于备库空间不足,在主库添加了数据文件后,导致备库数据文件的缺失,可能很久之后才发现,但是由于归档的缺失等其它原因而导致备库不能正常应用Redo日志. 还有其它情况可能导致备库的数据文件不能正常ONLINE,在这种情况下,可以在主库上利用CONVERT命令备份一个数据文件然后拷贝到备库即可. 若是备库归档文件比较全,则可以直接在备库创建数据文件后应用Redo日志即可,而不需要从主库拷贝数据文件. > 恢复过程中的一些关键性的命令如下所示: ```sql --主库备份相关文件 CONVERT DATAFILE '+DATA1/oralhrs/datafile/tbs101.262.923139373' FORMAT '/tmp/tbs101.dbf_bk'; --备库修改从主库拷贝过来的文件为ASM格式 CONVERT DATAFILE '/tmp/tbs101.dbf_bk' FORMAT '+DATA1'; --备库修改文件管理模式为手动 ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT='MANUAL' SID='*'; --备库若数据文件丢失可以先创建一个数据文件 ALTER DATABASE CREATE DATAFILE 64 AS '+DATA1'; --重命名刚新建的数据文件为从主库拷贝过来的数据文件 ALTER DATABASE RENAME FILE '+DATA1/oralhrsg/datafile/tbs101.483.923151901' TO '+DATA1/oralhrsg/datafile/tbs101.382.923151215'; --启用Redo恢复 ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION; ``` > 接下来演示整个恢复过程. ### 7.5.1 检查备库异常文件 > 首先查看备库的文件情况,发现64号文件处于OFFLINE状态. ```sql SYS> SELECT A.FILE#,A.NAME,A.RECOVER,A.CHECKPOINT_CHANGE#,STATUS FROM V$DATAFILE_HEADER A WHERE A.FILE# IN (1,2,64); FILE# NAME REC CHECKPOINT_CHANGE# STATUS ---------- ---------------------------------------------------- --- ------------------ ------- 1 +DATA1/oralhrsg/datafile/system.358.869055401 1.5760E+10 ONLINE 2 +DATA1/oralhrsg/datafile/sysaux.354.869047985 1.5760E+10 ONLINE 64 +DATA1/oralhrsg/datafile/tbs101.382.875442343 1764555149 OFFLINE SYS@oraLHRDG2> RECOVER DATAFILE 64; ORA-00283: recovery session canceled due to errors ORA-01153: an incompatible media recovery is active SYS@oraLHRDG2> RECOVER MANAGED STANDBY DATABASE CANCEL; Media recovery complete. SYS@oraLHRDG2> RECOVER DATAFILE 64; ORA-00283: recovery session canceled due to errors ORA-01610: recovery using the BACKUP CONTROLFILE option must be done SYS@oraLHRDG2> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION; Database altered. SYS@oraLHRDG2> ALTER DATABASE DATAFILE 64 ONLINE; alter database datafile 64 online * ERROR at line 1: ORA-01113: file 64 needs media recovery ORA-01110: data file 64: '+DATA1/oralhrsg/datafile/tbs101.382.875442343' ``` ### 7.5.2 主库用CONVERT命令备份异常文件 > 虽然可以开启实时应用进程,但是64号文件依然不能ONLINE,因为现在的系统SCN号和64号文件头的SCN号相差很大了,归档日志必然不存在了,所以使用日志来恢复文件的方法自然不可行了. 那么,接下来在主库用CONVERT命令备份64号文件: ```sql [ZFLHRSDB1:oracle]:/oracle>rman target / Recovery Manager: Release 11.2.0.3.0 - Production on Wed Sep 21 14:49:56 2016 Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved. connected to target database: ORAIPPS (DBID=1344172889) RMAN> CONVERT DATAFILE '+DATA1/oralhrs/datafile/tbs101.262.923139373' FORMAT '/tmp/tbs101.dbf_bk'; Starting conversion at target at 2016-09-21 14:51:16 using channel ORA_DISK_1 channel ORA_DISK_1: starting datafile conversion input file name=+DATA1/oralhrs/datafile/tbs101.262.923139373 converted datafile=/tmp/tbs101.dbf_bk channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:03 Finished conversion at target at 2016-09-21 14:51:19 ``` ### 7.5.3 将备份的文件拷贝到备库: ```bash [ZFLHRSDB1:oracle]:/tmp>scp /tmp/tbs101.dbf_bk oracle@192.68.155.16:/tmp/tbs101.dbf_bk The authenticity of host '192.68.155.16 (192.68.155.16)' can't be established. RSA key fingerprint is 7b:d6:ba:ca:b3:71:b5:0b:bf:14:f4:e4:18:5f:51:45. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '192.68.155.16' (RSA) to the list of known hosts. tbs101.dbf_bk 100% 100MB 50.0MB/s 00:02 ``` ### 7.5.4 在备库上转换文件为ASM格式: ```sql RMAN> CONVERT DATAFILE '/tmp/tbs101.dbf_bk' FORMAT '+DATA1'; Starting conversion at target at 2016-09-21 14:53:33 using target database control file instead of recovery catalog allocated channel: ORA_DISK_1 channel ORA_DISK_1: SID=1542 instance=oraLHRDG2 device type=DISK channel ORA_DISK_1: starting datafile conversion input file name=/tmp/tbs101.dbf_bk converted datafile=+DATA1/oralhrsg/datafile/tbs101.382.923151215 channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:01 Finished conversion at target at 2016-09-21 14:53:36 ``` #### 7.5.5 若备库文件不存在需要重建 > 备库上进行重命名操作,若是备库上64号文件被删除了,则需要先重建64号文件: ```sql SYS@oraLHRDG2> ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT='MANUAL' SID='*'; System altered. SYS@oraLHRDG2> ALTER DATABASE CREATE DATAFILE 64 AS '+DATA1'; Database altered. SYS@oraLHRDG2> SELECT A.FILE#,A.NAME,A.RECOVER,A.CHECKPOINT_CHANGE#,STATUS FROM V$DATAFILE_HEADER A WHERE A.FILE# IN (1,2,64); FILE# NAME REC CHECKPOINT_CHANGE# STATUS ---------- ------------------------------------------------ --- ------------------ ------- 1 +DATA1/oralhrsg/datafile/system.358.869055401 1.5761E+10 ONLINE 2 +DATA1/oralhrsg/datafile/sysaux.354.869047985 1.5761E+10 ONLINE 64 +DATA1/oralhrsg/datafile/tbs101.483.923151901 1.5761E+10 OFFLINE SYS@oraLHRDG2> ALTER DATABASE DATAFILE 64 ONLINE; ALTER DATABASE DATAFILE 64 ONLINE * ERROR at line 1: ORA-01113: file 64 needs media recovery ORA-01110: data file 64: '+DATA1/oralhrsg/datafile/tbs101.483.923151901' ``` ### 7.5.6 重命名备库文件 > 可以看到已经有64号文件了,下边进行重命名,修改为从主库拷贝过来的64号文件: ```sql SYS@oraLHRDG2> ALTER DATABASE RENAME FILE '+DATA1/oralhrsg/datafile/tbs101.483.923151901' TO '+DATA1/oralhrsg/datafile/tbs101.382.923151215'; ALTER DATABASE RENAME FILE '+DATA1/oralhrsg/datafile/tbs101.483.923151901' TO '+DATA1/oralhrsg/datafile/tbs101.382.923151215' * ERROR at line 1: ORA-01511: error in renaming log/data files ORA-01121: cannot rename database file 64 - file is in use or recovery ORA-01110: data file 64: '+DATA1/oralhrsg/datafile/tbs101.483.923151901' SYS@oraLHRDG2> ! oerr ora 01121 01121, 00000, "cannot rename database file %s - file is in use or recovery" // *Cause: Attempted to use ALTER DATABASE RENAME to rename a // datafile that is online in an open instance or is being recovered. // *Action: Close database in all instances and end all recovery sessions. ``` ### 7.5.7 关闭DG到MOUNT状态后再重命名 > 该错误提示文件在使用,不能被重命名. 由于该库是RAC库,需要先关闭DG,启动到MOUNT状态后再重命名: ```sql [ZFLHRSDB4:root]:/>srvctl stop db -d oralhrsg [ZFLHRSDB4:root]:/>srvctl start db -d oralhrsg -o mount ``` > 在数据库中重命名: ```sql SYS@oraLHRDG2> conn / as sysdba Connected. SYS@oraLHRDG2> ALTER DATABASE RENAME FILE '+DATA1/oralhrsg/datafile/tbs101.483.923151901' TO '+DATA1/oralhrsg/datafile/tbs101.382.923151215'; Database altered. SYS@oraLHRDG2> ALTER DATABASE DATAFILE 64 ONLINE; Database altered.<<<<<<<<<---------数据文件可以ONLINE了 SYS@oraLHRDG2> COL NAME FOR A50 SYS@oraLHRDG2> COL CHECKPOINT_CHANGE# FOR 9999999999999 SYS@oraLHRDG2> SELECT A.FILE#,A.NAME,A.RECOVER,A.CHECKPOINT_CHANGE#,STATUS FROM V$DATAFILE_HEADER A WHERE A.FILE# IN (1,2,64); FILE# NAME REC CHECKPOINT_CHANGE# STATUS ---------- -------------------------------------------------- --- ------------------ ------- 1 +DATA1/oralhrsg/datafile/system.358.869055401 15760776695 ONLINE 2 +DATA1/oralhrsg/datafile/sysaux.354.869047985 15760776695 ONLINE 64 +DATA1/oralhrsg/datafile/tbs101.382.923151215 15760492416 ONLINE SYS@oraLHRDG2> ALTER DATABASE OPEN READ ONLY; ALTER DATABASE OPEN READ ONLY * ERROR at line 1: ORA-10458: standby database requires recovery ORA-01194: file 64 needs more recovery to be consistent ORA-01110: data file 64: '+DATA1/oralhrsg/datafile/tbs101.382.923151215' <<<<<<<<<------------ 打开数据库依然报错,尝试手动恢复一下,看看需要哪些日志,因为64号文件已经是最新的了 SYS@oraLHRDG2> RECOVER DATABASE; ORA-00283: recovery session canceled due to errors ORA-01610: recovery using the BACKUP CONTROLFILE option must be done SYS@oraLHRDG2> RECOVER STANDBY DATABASE USING BACKUP CONTROLFILE; ORA-00279: change 15760492416 generated at 09/21/2016 11:38:54 needed for thread 1 ORA-00289: suggestion : /arch/1_12918_868895513.arc ORA-00280: change 15760492416 for thread 1 is in sequence #12918 Specify log: {<RET>=suggested | filename | AUTO | CANCEL} cancel ORA-01547: warning: RECOVER succeeded but OPEN RESETLOGS would get error below ORA-01194: file 64 needs more recovery to be consistent ORA-01110: data file 64: '+DATA1/oralhrsg/datafile/tbs101.382.923151215' ORA-01112: media recovery not started <<<<<<<<<------------ 缺少12918日志,很欣慰,因为12918已经是最新的日志了,这里解决起来就很简单了, --可以从主库拷贝12918日志到备库,但是这样太麻烦,可以开启备库的应用进程让其自动解决备库的GAP问题 SYS@oraLHRDG2> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION; Database altered. ``` > 此时查看告警日志,很欣慰看到了12918日志过来了: ```sql Wed Sep 21 15:24:33 2016 alter database recover managed standby database using current logfile disconnect from session Attempt to start background Managed Standby Recovery process (oraLHRDG2) Wed Sep 21 15:24:33 2016 MRP0 started with pid=44, OS id=12649040 MRP0: Background Managed Standby Recovery process started (oraLHRDG2) started logmerger process Wed Sep 21 15:24:39 2016 Managed Standby Recovery starting Real Time Apply Parallel Media Recovery started with 16 slaves Waiting for all non-current ORLs to be archived... All non-current ORLs have been archived. Wed Sep 21 15:24:40 2016 Media Recovery Log /arch/1_12918_868895513.arc Media Recovery Log /arch/2_12918_868895513.arc Completed: alter database recover managed standby database using current logfile disconnect from session Datafile 64 added to flashback set Media Recovery Log /arch/2_12919_868895513.arc Media Recovery Log /arch/1_12919_868895513.arc Media Recovery Log /arch/2_12920_868895513.arc Media Recovery Log /arch/1_12920_868895513.arc Media Recovery Log /arch/2_12921_868895513.arc Media Recovery Log /arch/1_12921_868895513.arc Media Recovery Waiting for thread 2 sequence 12922 (in transit) Recovery of Online Redo Log: Thread 2 Group 12 Seq 12922 Reading mem 0 Mem# 0: +DATA1/oralhrsg/onlinelog/group_12.353.869055809 Media Recovery Waiting for thread 1 sequence 12922 (in transit) Recovery of Online Redo Log: Thread 1 Group 8 Seq 12922 Reading mem 0 Mem# 0: +DATA1/oralhrsg/onlinelog/group_8.344.869055791 ``` ### 7.5.8 最后重启备库的2个节点: ```sql [ZFLHRSDB4:root]:/>srvctl stop db -d oralhrsg [ZFLHRSDB4:root]:/>srvctl start db -d oralhrsg [ZFLHRSDB4:root]:/>srvctl status db -d oralhrsg Instance oraLHRDG1 is running on node zflhrsdb3 Instance oraLHRDG2 is running on node zflhrsdb4 ``` ### 7.5.9 而数据库中64号文件已经正常了: ```sql SYS@oraLHRDG2> SELECT A.FILE#,A.NAME,A.RECOVER,A.CHECKPOINT_CHANGE#,STATUS FROM V$DATAFILE_HEADER A WHERE A.FILE# IN (1,2,64); FILE# NAME REC CHECKPOINT_CHANGE# STATUS ---------- -------------------------------------------------- --- ------------------ ------- 1 +DATA1/oralhrsg/datafile/system.358.869055401 15760815694 ONLINE 2 +DATA1/oralhrsg/datafile/sysaux.354.869047985 15760815694 ONLINE 64 +DATA1/oralhrsg/datafile/tbs101.382.923151215 15760815694 ONLINE SYS@oraLHRDG2> show parameter standby NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ standby_archive_dest string ?/dbs/arch standby_file_management string MANUAL SYS@oraLHRDG2> ALTER SYSTEM SET standby_file_management='AUTO' SID='*';====>>>>> 别忘记将该参数修改回来 System altered. ``` > 最后不要忘记将STANDBY_FILE_MANAGEMENT参数修改为AUTO. ## 7.6 备库数据文件移异常的物理DG之12c RMAN新特性通过网络远程恢复 ```sql --备库 alter system set standby_file_management='manual' sid='*'; --主库 create tablespace testdg datafile '/u01/app/oracle/oradata/orcl/testdg01.dbf'; --备库 alter database recover managed standby database using current logfile disconnect from session; col name for a100 set linesize 9999 pagesize 9999 col next_change# for 999999999999999 select thread#,name,sequence#,archived,applied,a.next_change# from v$archived_log a where a.sequence#>= (select max(b sequence#)-3 from v$archived_log b where b.thread#= a.thread# and b.resetlogs_change#=a.resetlogs_change# and b.resetlogs_change=(select d.resetlogs_change# from v$database d) and b.applied='yes' group by e.thread#) order by a.thread#,a.sequence#; tail-f/u07/app/oracle/diag/rdbms/1hr122dg/lhr122dg/trace/alert lhr122dg log --备库修复 ru{ set newname for database to '/u04/oradata/lhr122dg/lhr122dg/datafile/%f_%u'; restore datafile 5 from service primary_db; } alter database rename file '/u07/app/oracle/product/12.2.0/dbhome_1/dbs/unnamed00005' to '/u04/oradata/lhr122dg/lhr122dg/datafile/5_data_d-lhr122_ts-testdg_fno-5'; alter database recover managed standby database using current logfile disconnect from session; alter system set standby_file management='auto' sid='*'; ``` ## 7.7 主库NOLOGGING操作引起的备库ORA报错 > 众所周知,DG数据同步是基于日志流的,这也是为什么在配置DG阶段需要将主库设置为FORCE LOGGING的原因. 但是,这也会带来很多问题,例如,会导致DML类型的SQL执行效率变慢,尤其在大批量数据更新或导入的时候显得尤为明显. DBA在使用数据泵进行迁移时希望在最少停机时间内完成,这时候就可能会考虑到以最小日志导入的方式以加快导入速度,然后重新同步备库. > 在这些场景中,DBA可能会使用NOLOGGING操作去节省大量数据插入的时间,而这种操作所带来的问题就是,如果该库在有备库的情况下,因为主库的NOLOGGING插入操作不会生成Redo,所以不会在备库上传输和应用,这会导致备库的数据出现问题,报ORA-01578和ORA-26040的错误. ### 7.7.1 模拟环境 > 在一个具有主备关系的主库上将FORCE_LOGGING设置为NOLOGGING模式,然后创建一张表LHR.TESTDGNOLOG,设置为NOLOGGING模式: ```sql sql> alter database no force logging; sql> create table lhr.testdgnolog tablespace users pctfree 99 as select rownum n from xmltable('1 to 100'); sql> alter table lhr.testdgnolog nologging; ``` > 之后使用/* +append*/插入数据并提交: ```sql sql> insert /*+ append */ into lhr.testdgnolog select rownum n from xmltable('1 to 1000'); sql> commit; ``` > 这时候在备库对该表进行查询会看到如下报错信息: ```sql sql>select count(1) from lhr.testdgnolog; select count(1) from lhr.testdgnolog * ERROR at line 1: ORA-01578: ORACLE data block corrupted (file # 4, block # 819) ORA-01110: data file 4: '/data/data1/ORCL2/datafile/o1_mf_users_3ft1e9qb_.dbf' ORA-26040: Data block was loaded using the NOLOGGING option ``` > 对于这种情况,在Oracle的不同版本中有不同的处理办法. ### 7.7.2 Oracle 11g > 在Oracle 11g中,如果遇到这样的问题,可以通过将包含缺少数据的数据文件从主库复制到物理备库再重命名数据文件来解决问题. #### 7.7.2.1 查询主库 ```sql SQL> select name, unrecoverable_change# from v$datafile; NAME UNRECOVERABLE_CHANGE# -------------------------------------------- --------------------- +DATADG/orcl/datafile/system.270.972381717 0 +DATADG/orcl/datafile/sysaux.265.972381717 0 +DATADG/orcl/datafile/undotbs1.261.972381717 0 +DATADG/orcl/datafile/users.259.972381717 6252054 ``` #### 7.7.2.2 查询备库 ```sql sys@ORCLDG> select name, unrecoverable_change# from v$datafile; NAME UNRECOVERABLE_CHANGE# --------------------------------------------------------- --------------------- /data/data1/ORCLDG/datafile/o1_mf_system_3dt1e9op_.dbf 0 /data/data1/ORCLDG/datafile/o1_mf_sysaux_3ct1e9nb_.dbf 0 /data/data1/ORCLDG/datafile/o1_mf_undotbs1_3gt1e9qq_.dbf 0 /data/data1/ORCLDG/datafile/o1_mf_users_3ft1e9qb_.dbf 5383754 ``` #### 7.7.2.3 比较主备查询结果 > 在以上两个查询结果中,比较UNRECOVERABLE_CHANGE#列的值. 如果主库中UNRECOVERABLE_CHANGE#列的值大于备库中的同一列,那么需要将这些数据文件在备库恢复. > 将主库对应的数据文件拷贝至备库: ```sql SQL> alter tablespace users begin backup; SQL> exit ASMCMD>cp +DATADG/orcl/datafile/users.259.972381717 /tmp $ scp /tmp/users.259.972381717 10.10.10.123:/data/data1/ORCL2/datafile/ SQL> alter tablespace users end backup; ``` > 在备库上,将旧的数据文件RENAME至新的数据文件: ```sql SQL> STARTUP MOUNT FORCE SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL; SQL> ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=MANUAL; #在备库执行RENAME操作时,需要此参数为MANUAL SQL> ALTER DATABASE RENAME FILE '/data/data1/ORCLDG/datafile/o1_mf_users_3ft1e9qb_.dbf' TO '/data/data1/ORCLDG/datafile/users.259.972381717'; SQL> ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=AUTO; SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION; ``` > 之后就可以在备库查询到实例表LHR.TESTDGNOLOG: ```sql SQL> SELECT COUNT(1) FROM LHR.TESTDGNOLOG; COUNT(1) ---------- 1100 ``` ### 7.7.3 Oracle 12.1 > 对于这种情况,在Oracle 12.1版本中,RMAN提供了一种便捷的方式让DBA不再需要在主库上进行数据文件的备份传输而可以直接在备库使用restore database (or datafile ) from service进行恢复. > 当然,如果数据文件是正常的状态,RMAN可以根据它们的数据文件头进行跳跃恢复. 如果,由于NOLOGGING操作导致某些块被标记为损坏的,那么这部分数据文件就是需要恢复的. 在恢复命令中有FORCE选项. 因为有些时候数据文件是同步的,实时日志应用进程还是在运行的. 这个时候,为了恢复,需要停止应用. 一旦停止了应用,那么就不需要执行RESOTORE DATABASE FORCE操作,因为现在数据文件的状态是过旧的,就算不加FORCE选项RMAN也是不会跳过这些数据文件的. > 备库关掉实时日志应用,并重启至MOUNT状态: ```sql SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL; SQL> SHUTDOWN IMMEDIATE Database closed. Database dismounted. ORACLE instance shut down. SQL> STARTUP MOUNT ORACLE instance started ``` > 备库登陆RMAN,使用restore database (or datafile ) from service进行恢复: ```sql --这里的primary_db为备库至主库的TNS连接串的别名 RMAN> RESTORE DATABASE FROM SERVICE 'primary_db'; ``` > 当然要记得去起库并开启实时日志应用进程. 以上恢复过程也可以直接恢复相关数据文件即可: ```sql RMAN>RESTORE DATAFILE 7FROM SERVICE 'LHR122'; ``` ### 7.7.4 Oracle 12.2 > 在Oracle 12.2中,Oracle提供了一种更方便的方式去进行恢复主库会将未记录的块的列表发送至备库,并记录在备库控制文件中,DBA可以从备库的V$NONLOGGED_BLOCK这个视图查看到相关信息. 不需要发送主库的整个数据文件,而是在RMAN执行一个简单的命令来恢复它们: ```sql RECOVER DATABASE NONLOGGED BLOCK ``` > 首先,在备库停止实时日志应用: ```sql SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL; ``` > 备库登陆RMAN执行: ```sql RECOVER DATABASE NONLOGGED BLOCK ``` > 注意:执行此步骤前请确认主备库的LOG_ARCHIVE_CONFIG参数已经设置: ```sql RMAN> Recover Database Nonlogged Block; ``` > 恢复完成后,V$NONLOGGED_BLOCK视图中不再有数据. 最后别忘了开启实时日志应用进程. > 综上来看,在Oracle 12.2中这个特性在数据仓库等一些场景是可以尝试的. 以往DBA开启FORCE_LOGGING造成大量的Redo日志并且影响一部分DML语句的执行效率. 在Oracle 12.2中可以尝试使用NOLOGGING操作去节省大量数据插入的时间,然后在系统空闲时间进行备库恢复操作. 但是,这种操作也存在弊端,因为备库的可用性就大大降低了. # 八、Switch和Failover > 具体步骤参考部署文档. > 一个DG环境中只有两种角色:Primary和Standby. > 所谓角色转换就是让数据库在这两种角色中切换,切换也分两种:Switchover和Failover,关于角色切换需要注意以下几点: > > 1).Switchover是指主库转换成备库,然后将原备库转换成新主库;而Failover是指将备库转换成主库. > 2).使用场合不同 :Switchover用于有准备的、计划之中的切换,通常是系统升级、数据迁移等常态任务;Failover用于意料之外的突发情况,例如异常断电、自然灾难等等. > 3).数据丢失程度不同 :Switchover不会丢失数据,Failover通常意味着有部分数据丢失. > 4).善后处理的不同 :Switchover之后DG环境不会被破坏,仍然有Primary、Standby两种角色的系统存在,但是Failover之后,DG环境就会被破坏,一般情况下需要重建. 但是,若主库或备库开启了闪回功能,则都可以通过闪回数据库功能恢复DG环境. 例如,PROD1为主库,SBDB1为备库;若PROD1意外宕机,则SBDB1执行Failover操作变为主库;此时若想恢复DG环境,则有3种处理办法: > >> a)将PROD1利用闪回数据库功能闪回到SBDB1变为主库的SCN时间点,然后将PROD1转换为备库,最后利用switchover转换为最初的环境. 在这种情况下,PROD1需要开启闪回. >> b)将SBDB1利用闪回数据库功能闪回到SBDB1变为主库的SCN时间点,此时SBDB1仍然是主库的角色,然后将SBDB1转换为备库. 在这种情况下,SBDB1需要开启闪回,而且会丢失部分数据. >> c)利用RMAN重新搭建DG环境. >> > 下面给出角色切换过程中常用的一些SQL语句. ## 8.1 物理DG在Switchover主要SQL ```sql --在主库操作 alter database commit to switchover to physical standby with session shutdown; startup force mount; --在备库操作 select name, LOG_MODE, OPEN_MODE, database_role, SWITCHOVER_STATUS, db_unique_name, flashback_on from v$database; alter database commit to switchover to primary with session shutdown; alter database open; ``` ## 8.2 物理DG 在Failover主要SQL ```sql --在备库操作 alter database recover managed standby database finish force; alter database commit to switchover to primary with session shutdown; alter database open; ``` > 物理DG在执行Failover后,在原备库端查看V$DATABASE视图的STANDBY_BECAME_PRIMARY_SCN列,可以看到这个库成为primary的具体时间,如下所示: ```sql --新主库 SELECT STANDBY_BECAME_PRIMARY_SCN FROM V$DATABASE; --原主库或新主库 startup mount flashback database to scn 1326995; ``` > 在原主库或新主库执行闪回数据库后,切换主库为备库的SQL语句为: ```sql alter database convert to physical standby; startup force; alter database recover managed standby database using current logfile disconnect from session; ``` ## 8.3 逻辑DG在Switchover主要SQL ```sql select switchover_status,database_role,open_mode from gv$database; --在主库操作 alter database prepare to switchover to logical standby; select switchover_status from v$database;--PREPARING SWITCHOVER --在备库操作 alter database prepare to switchover to primary; select switchover_status from v$database;--PREPARING SWITCHOVER --在主库操作 --结果应该为:TO LOGICAL STANDBY,否则需要取消转换ALTER DATABASE PREPARE TO SWITCHOVER CANCEL; select switchover_status from v$database; --开始转换主库为逻辑备库 alter database commit to switchover to logical standby; --在备库操作 --状态应该为为TO PRIMARY,若不是该状态,则不能转换为主库,可能出现ORA-16109错误,那么就得回退刚刚的操作 select switchover_status from v$database; --开始转换逻辑备库为主库 alter database commit to switchover to primary; --新逻辑备库执行 --启动新逻辑standby的SQL应用 alter database start logical standby apply immediate; ``` ## 8.4 逻辑DG在Failover主要SQL ```sql --在备库操作 alter database activate logical standby database finish apply; ``` > 该语句主要是停止待转换的逻辑standby中RFS进程,并应用完当前所有已接收但并未应用的redo数据,然后停止SQL应用,将数据库转换成primary角色. 在切换完成后,原主备库关系遭到破坏,已经不能再使用简单的命令修复了. > 需要注意的是,要在primary和逻辑standby之间切换角色,一般是从操作primary开始. 如果primary或逻辑standby是RAC架构,那么只保留一个实例启动,其它实例全部shutdown,等角色转换操作完成之后再启动其它实例,角色转换的操作会自动传播到这些实例上,并不需要再对这些实例单独做处理. # 九、DG客户端特级配置 > 参考部署文档 > Data guard以最低成本实现最高的数据保护. 在硬件上没有特殊要求,普通PC机即可实现. 简单的来说,Data > Guard就是自动创建和维护生产数据库(或主数据库)的一个或多个事务致的副本(备用数据库)·如果主数据库不可用(因为故障维护或者灾难),那么可以激活个备用数据库并使之承担主数据库的角色. > 在配置完成DG后,若要实现主备的切换,需要在主备数据库上分别输入多个命令,切换步骤稍显麻烦. 所以,一般情况下,DBA会将整个切换过程编辑成脚本,以便自动运行,进行状态切换. 当然Oracle也提供了工具 > Data Guard Broker,仅在控制端输一个命令就能方便实现主备数据库间的切换. > 在Data Guard Broker的基础上,配置并启用Fast-start Failover,就能自动检测发现主机故障,实现主备切换,故障转移. ## 9.1 Data Guard Broker > Data Guard Broker是建立在DG基础上的一个对Data guard配置集中管理操作的一个平台,Data guard Broker的推出是为了简化DG复杂的管理过程,最大的作用就是集中化的统一管理. > Oracle data guard broker是个分布式管理框架,它不但自动化了DG配置的建、维护和监视,并对这些操作进行统一管理,可以通过 oracle企业管理器(它使用 Broker)或 Broker的专用命令行界面(DGMGRL)执行所有管埋操作,Data guard broker 11g还可以使用最高可用性或最佳性能模式将 Data guard配置为在数据库出现故障时自动切换. > 配置 Data Guard Broker使用到的客户端工具是DGMGRL,它是个命今行管理工具. > >> Ø 使用最高可用性或最佳性能模式针对配置启用自动数据库故障切换 >> Ø 启用可配置事件来触发对目标备用数据库的即时自动切换 >> Ø 改善了对重做传输选项的支持,使管理员可以为重做传输服务指定连接描述 >> Ø 消除在最高可用性和最佳性能保护模式间更换的数据库停机时间 >> Ø 支持使用rac]集群件和冷故障切换集群针对高可用性配置单一实例数据库 >> > 配置 Data Guard Broker主要有以下几个过程: > > 1).设置Primary和 standby启动时参数文件为spfi1e > 2).设置listener > 3).设置DG BROKER START为TRUE ## 9.2 Fast-Start Failover ### 9.2.1 介绍 > Fast-start Failover是建立在broker基础上的一个快速故障转移的机制,可以自动监测primary的故障,然后自动的Failover到预先指定的standby上,这样可以最大化减少故障时间,提高可用性. > Fast-Start Failover是在 broker的基础上再增加了一个单独的 observer,用来监控 primary和 standby数据库的状态,一旦 Primary不可用,observer就会自动的切换到指定的 standby上面. > FAST-START FAILOVER是oracle 10g的一项新功能. 这个功能可以实现当主库宕机时,预定的从库自动快速可靠地进行失败切换(FAILOVER),切换完成之后,原来的主库恢复正常之后,将会自动地配置为从库,大大减少了DBA的维护和管理工作. 尤其是减少了在出现突然问题时的心慌意乱和手忙脚乱,在整个过程中不需要人来干预,fast-start failover只能通过 dgmgrl与GC或EMCC来配置, ### 9.2.2 配置过程 #### 9.2.2.1 主备启用Flashback ```sql alter database recover managed standby database cancel; alter database flashback on; select flashback_on,force_logging from v$database; alter database recover managed standby database using current logfile disconnect; ``` #### 9.2.2.2 确保broker运行在最高可用或最高性能模式 ```sql select protection_mode from v$database; ``` #### 9.2.2.3 第三台机器安装DGMGRL > 用于启动observer,这里命令为observer server #### 9.2.2.4 配置observer > 配置observer的tns文件,保证observer正常连接到主备库 #### 9.2.2.5 配置Fast-start Failover > 在DGMGRL中完成. > 配置每个数据库Failover的目标. 这一步是决定当数据库出问题后会自动Failover目标 ```sql edit database'testa'set property 'FastStartFailoverTarget'='TESTB'; edit database'testb'set property 'FastStartFailoverTarget'='TESTA'; ``` #### 9.2.2.6 设定FastStartFailoverThreshold值 > 这个值决定了primary坏了多长时间后会自动执行Failover,此处设置的30s. ```sql edit configuration set property FastStartFailoverThreshold=30; ``` #### 9.2.2.7 启用Fast-Start Failover ```sql ENABLEND FAST_START FAILOVER; ``` #### 9.2.2.8 在observer启动observer ```sql start observer ``` > 注意启动observer后,DGMGRL就会阻塞在这个命令上. observer的操作信息以后会在这个窗口显示. > 后台运行observer: ```sql mkdir -p /u01/app/oracle/diag/dg/observer dgmgrl -logfile /u01/app/oracle/diag/dg/observer/observer.log sys/password@tns "start observer file='/u01/app/oracle/diag/dg/observer/fsfo.dat'" & --或者 nohup dgmgrl -silent sys/oracle@dg1 "start observer" & ``` #### 9.2.2.9 查看环境状态 > 可以开另一个DGMGRL ```sql show configuration verbose; show fast_start failover; show observer; ``` ### 9.2.3 Fast-start Failover工作过程及实例 #### 9.2.3.1 工作过程 > 在启用了fast-start failover和observer之后,broker会来监控primary和standby数据库的状态,一旦primary数据库出现故障,observer会根据一定的程序来执行自动的failover操作. > 1).当发生下列情形是observer会尝试启动failover操作 > Ø observer和primary数据库之间连接出现故障时 > Ø 当primary数据库故障或者是RAC环境中所有instance都故障时 > Ø 执行SHUTDOWN ABORT之后,特别注意正常的SHUTDOWN操作(NORMAL,IMMEDIATE,TRANSACTIONAL)不会引发 failover操作 > Ø 数据库文件OFFLINE > 除了最后一个数据库文件OFFLINE的情形,其他的情况下observer都会尝试在FastStartFailoverThreshold制定的时间之内重新连接数据库,如果还是无法连接之后才会执行自动failover操作. > 2).在FastStartFailoverThreshold指定的时间内重新连接数据库,在RAC环境中会尝试连接其他的instance. > 3).尝试时间结束后,observer将确定目标standby可用. 下面的这些情形会导致failover失败 > Ø fast-start failover没有启用 > Ø observer无法连接到standby数据库 > Ø standby与observer中记录的状态不一致 > Ø observer在primary fail的时候正好没有运行,再次启动之后只能找到一个standby > Ø 目标standby没有和primary完成同步 > Ø 目标standby是逻辑standby时,在V$DATABASE中显示LOADING DICTIONARY时 > Ø 目标standby还能和primary正常通讯时 > Ø 在V$DATABASE的列FS_FAILOVER_STATUS中显示了其他无法进行failover操作时 > Ø 有手工failover正在进行时 > 4).执行failover操作,使目标standby变成新的primary. > 5).reinstate之前失败的primary #### 9.2.3.2 FSFO实例 ```sql --查看当前状态 DGMGRL> show configuration --然后登录到主库上,执行一个SHUTDOWN ABORT命令 SQL> shutdown abort --然后在前面启动observer的会话里面我们可以看到自动failover信息了 DGMGRL> start observer --再看下状态,主库变成了htdb2,htdb1是禁用状态 DGMGRL> show configuration verbose --启动员主库htdb1到mount状态 SQL> startup mount --此时再观察前面htdb2启动observer的会话的信息 DGMGRL> start observer --再次启动htdb1到mount状态 SQL> startup mount --执行reinstate操作(在htdb2上) DGMGRL> reinstate database htdb1 --查看状态已经成功failover DGMGRL> show configuration verbose ``` > 要查看Fast-Start Failover更多的信息就要查看V$DATABASE视图中的相关的列了. ```sql FS_FAILOVER_STATUS --这个列显示了Fast-Start Failover的状态,通过查看这个列我们可以知道数据库时处于什么状态之中, --详细的状态信息在这里. FS_FAILOVER_CURRENT_TARGET --当前数据库的failover的目标数据库 FS_FAILOVER_THRESHOLD --执行自动failover的时间超时值 FS_FAILOVER_observer_PRESENT --是否启动了observer,通过查看这个列我们可以知道是否有observer在监控着这个数据库 FS_FAILOVER_observer_HOST --监控此数据库的observer所在的位置 ``` ### 9.2.4 禁用Fast-start Failover > 禁用Fast-StartFailover的命令为: ```sql DISABLEFAST_START FAILOVER [FORCE] ``` > 加上FORCE之后将会强行在执行DISABLE命令的数据库以及这个数据库可连通的其他数据库上面上禁用Fast-StartFailover,而其他无法连接上的数据库将保持原来的状态;不加FROCE时如果有那个数据库暂时无法连接的话那么DISABLE操作将会失败. 所以在当primary和standby数据库的网络连接良好的情况下要使用不带FORCE的命令. > 通常需要使用FORCE的情形 > Ø 当因为网络问题造成primary无法和observer及那些已完成同步的standby通讯时,primary将会停止工作,如果primary的恢复时间可期,且想要primary继续工作的话就需要使用FORCE选项暂时在primary上禁用fast-startfailover,不过之前一定要检查看数据库有没有自动failover. > Ø 当primary和standby没有完成同步的时候想要手工的执行failover的命令,在fast-startfailover启用的时候是无法执行的,这时候也需要使用FORCE选项强行禁用fast-startfailover. > Ø 在fast-startfailover失败之后还想将数据库failover到其他可用的standby上时也需要先使用FORCE强制禁用fast-startfailover然后在手工进行failover操作. > Ø 如果确定有问题的primary可以很快的恢复,此时不想让fast-startfailover自动failover,也可以使用FORCE选项强行禁用fast-startfailover. ### 9.2.5 Observer管理 > 启用observer的操作很简单,使用DGMGRL连接到数据库,然后执行STARTOBSERVER命令就行了. > 要启动observer的话必须使用SYS连接到DGMGRL,同一时间只能启动一个observer,如果尝试启动多个observer将会收到这样的消息 ```sql ORA-16647:could notstart more than one observer ``` > 从 oracle 12c开始,可以启动多个 observer. 在12c之前,observer只能启动一个,通过守护进程启动且必须要启动在备库上(如果启动在主库,出现主库网络不通或者其他原因,导致 fast failover功能不可用),12.2 fast failover高可用优化,且变成系统进程(不再通过&方式启动) > 要停止一个observer的话只需要用DGMGRL连接到数据库,然后执行STOPOBSERVER命令就行了. > 要确定一个数据库是否在observer的监视中必须要去查看V$DATABASE视图中的FS_FAILOVER_OBSERVER_PRESENT和FS_FAILOVER_OBSERVER_HOST. 只有当FS_FAILOVER_OBSERVER_PRESENT为YES的时候才说明这个数据库时处于observer的监控之中. > 同时数据库是否有observer监视这个信息我们也可以从DGMGRL中查看到 ```sql DGMGRL>show database orcl2 statusreport ``` > 在启动observer的时候,observer会自动的在当前目录中生成一个默认名字为fsfo.dat的二进制文件,这个文件里面保存了fast-startfailover的配置信息,同时也包含了到primary和standby的连接方式. 也可以在启动observer的时候使用FILE参数指定配置文件的位置,命令如下 > > ```sql > START OBSERVER [FILE=<observerconfigurationfile>]; > --内容如下 > [oracle@hotel01~]$ ls -l fsfo.dat > -rw-------1 oracle oinstall 322 09-30 15:07 fsfo.dat > [oracle@hotel01~]$ cat fsfo.dat > ``` ### 9.2.6 后台运行observer There are a few methods to achieve this: 1.start the dgmgrl process with nohup command, eg: ```sql nohup dgmgrl -logfile /tmp/dgmgrl.log <<eof connect sys/passwd@connect_string start observer EOF ``` 2.create a shell script and run the shell script at background: ```sql #!/bin/ksh ## Script to start observer via DGMGRL dgmgrl -echo -logfile /tmp/dgmgrl.log << EOF connect sys/passwd@connect_string start observer EOF chmod +x observer.sh ``` 3.From 11.2 onwards, one can use the following command to start observer: ```sql dgmgrl -logfile /tmp/observer.log sys/passwd@connect_string "start observer" & ``` ## 9.3 DG的TAF配置 ### 9.3.1 11g主备都是RAC(含ASM) ```sql srvctl add service -d testdgpri -s testdg_taf -r 'DGPRI1,DGPRI2' -p basic -e select -l primary -y automatic srvctl start service -d testdgpri -s testdg_taf srvctl add service -d testdgphy -s testdg_taf -r 'DGPRI1,DGPRI2' -p basic -e select -l primary -y automatic srvctl config service -d testdgphy -s testdg_taf mkdir -p /u01/app/oracle/diag/dg/observer/ dgmgrl -logfile /u01/app/oracle/diag/dg/observer/observer_pri.log sys/passwd@tns "start observer file='/u01/app/oracle/diag/dg/observer/fsfo.dat'" & ``` ### 9.3.2 11g主备都是单机(不含ASM) #### 9.3.2.1 在主库上配置TAF的service > 此服务在数据库出现故障时会发送通知给客户端,允许查询语句在故障转移发生后继续运行. ```sql SQL> begin DBMS_SERVICE.CREATE_SERVICE(service_name => 'dg_taf_lhr', network_name => 'dg_taf_lhr', aq_ha_notifications => TRUE, failover_method => 'BASIC', failover_type => 'SELECT', failover_retries => 30, failover_delay => 5); end; / col NAME format a10 col failover_method format all heading 'METHOD' col failover_type format a10 heading 'TYPE' col failover_retries format 9999999 heading 'RETRIES' col goal format a10 col clb_goal format a8 col AQ_HA_NOTOFICATIONS format a5 heading 'AQNOT' select name,failover_method,failover_type,failover_retries,goal, clb_goal,AQ_HA_NOTOFICATIONS from dba_services d where d.name='dg_taf'; ``` #### 9.3.2.2 主库建立调用service的存储过程 > 创建一个存储过程来实现此目的,如果当前数据库是主库它就启动此服务,如果是备库就停止. ```sql SQL> create or replace procedure dg_taf_proc_lhr is v_role VARCHAR(30); begin select DATABASE_ROLE into v_role from V$DATABASE; if v_role = 'PRIMARY' then DBMS_SERVICE.START_SERVICE('dg_taf_lhr'); else DBMS_SERVICE.STOP_SERVICE('dg_taf_lhr'); end if; end; / ``` #### 9.3.2.3 创建1个触发器来确保服务可以运行 > 创建两个触发器,让数据库在启动和角色转换时运行此存储过程. 用于当数据库open时,不需要重启数据库,如果是主库则执行存储过程. 当数据库切换后,如果是主库则执行存储过程. ```sql SQL> create or replace TRIGGER dg_taf_trg_startup_lhr after startup or db_role_change on database begin dg_taf_proc_lhr; end; / ``` #### 9.3.2.4 启动新创建的service > 在主库上执行该存储过程(或者重启数据库,在启动数据库时会触发执行dg_taf_proc的触发器),在主库做日志的切换,将变化应用到备库 ***主库执行:*** ```sql SQL> exec dg_taf_proc_lhr; alter system switch logfile; lsnrctl status ``` #### 9.3.2.5 在备库查询,确认触发器和存过已经应用到备库 ```sql select trigger_name, trigger_name from dba_triggers where trigger_name = 'DG_TAF_TRG_STARTUP_LHR'; select d.owner,d.OBJECT_NAME from dba_procedures d where d.OBJECT_NAME = 'DG_TAF_PROC_LHR'; ``` #### 9.3.2.6 客户端tnsnames 配置 #### 9.3.2.7 验证客户端的TAF > 先说说测试过程,首先我们在windows环境下添加tnsnames,然后cmd中连接到dg环境,执行一个长久的查询(select * from (select * from sys.dba_objects);),此时在dgmgrl中手动shutdown abort掉主库,那么连接的cmd中会停顿一会,等待fast-start failover切换完成后,则继续返回结果. > 主备切换不影响用户的select操作,但是如果是dml操作,则所有事务回滚: ```sql set line 9999 col name format a10 col FS_FAILOVER_OBSERVER_HOST format a20 col DB_UNIQUE_NAME format a15 SQL> select dbid,name, DB_UNIQUE_NAME,RESETLOGS_CHANGE#,current_scn,protection_mode,protection_level,database_role,force_logging,open_mode,switchover_status from v$database; SQL> SELECT d.DBID, d.DB_UNIQUE_NAME, d.FORCE_LOGGING, d.FLASHBACK_ON, DATAGUARD_BROKER, d.FS_FAILOVER_STATUS, d.FS_FAILOVER_CURRENT_TARGET, d.FS_FAILOVER_THRESHOLD, d.FS_FAILOVER_OBSERVER_PRESENT, d.FS_FAILOVER_OBSERVER_HOST FROM v$database d; ``` > 可以看到连接到的是主库. ```sql srvctl stop db -d orcl1 -o abort ``` > cmd卡住了,等待observer切换完成后cmd界面继续查询: > 切换后,在备库上存储过程启动了TAF的service ,客户端再连接时,自动连接到了当前的主库(原备库). ```sql select open_mode,database_role,db_unique_name from v$database; show parameter instance_number ``` ### 9.3.3 11g主备都是单机(含ASM) ```sql srvctl remove service -d orcl1 -s prod1_tag srvctl add service -d stby1 -s prod_taf -m basic -e select -l primary -y automatic srvctl add service -d prod1 -s prod_taf -m basic -e select -l primary -y automatic ``` ### 9.3.4 12c开始—主备都是单机(含ASM) ### 9.3.5 12c开始—主RAC备单机(含ASM) # 十、DG新特性 ## 10.1 通过网络远程恢复数据库(Restore/Recover From Service) > 在 Oracle 12c 中,可以在主数据库和备用数据库之间用一个服务名重新获得或恢复数据文件、控制文件、参数文件( SPFILE )、表空间或整个数据库. 这对于同步主数据库和备用数据库极为有用. > 当主数据库和备用数据库之间存在相当大的差异时,不再需要复杂的前滚流程来填补它们之间的差异. RMAN 能够通过网络执行备用恢复以进行增量备份,并且可以将它们应用到物理备用数据库. 可以用服务名直接将所需数据文件从备用点拷贝至主站,这是为了防止主数据库上数据文件、表空间的丢失,或是没有真正从备份集恢复数据文件. > 具体的几种用法: ```sql 数据库级别 : restore database from service < 服务别名 > 表空间 : restore tablespace from service < 服务别名 > 控制文件 : restore controlfile to ' 指定的位置 ' fromservice < 服务别名 > SPFILE : restore spfile from service < 服务别名 > ``` > 以下命令演示了如何用此新功能执行一个前滚来对备用数据库和主数据库进行同步. 在物理备用数据库上: ```sql rman target "username/password@standby_db_tnsas SYSBACKUP" RMAN> RECOVER DATABASE FROM SERVICE primary_db_tns USING COMPRESSED BACKUPSET; ``` > 以上案例使用备用数据库上定义的 primary_db_tns 连接字符串连接到主数据库,然后执行了一个增量备份,再将这些增量备份传输至备用目的地,接着将应用这些文件到备用数据库来进行同步. 然而,需要确保已经对 primary_db_tns 进行了配置,即在备份数据库端将其指向主数据库. > 在以下命令中,演示了通过从备用数据库获取数据文件来恢复主数据库上丢失的数据文件. > 在主数据库上: ```sql rman target "username/password@primary_db_tnsas SYSBACKUP" RMAN>RESTORE DATAFILE '+DG_DISKGROUP/DBANME/DATAFILE/filename'FROM SERVICE standby_db_tns; ``` > 使用from servce必要条件: > 1).两个数据库之间tns保持可连接 > 2).两个数据库密码文件必须一致 > 3).两个数据库的compatible参数必须为12.0 ## 10.2 DBCA创建物理备库 > 具体参考部署文档 > 之前通过Duplicate或RMAN备份还原的方法创建DG. > 到12cR2 (12.2.0.1)后,新增 DBCA 方式直接建立物理备库的方法. > 但是对版本和实例环境有一定限制条件: **12cR2中:** ```bash # 1、12cR2 主库必须是单机环境,非 RAC 数据库; # 若主库是 RAC 数据库,错误如下: [FATAL] [DBT-16056] Specified primary database is not a Single Instance (SI) database. CAUSE: Duplicate database operation is supported only for SI databases. # 2、12cR2 主库必须是非 CDB 环境; # 若主库是 CDB 环境,错误如下: [FATAL] [DBT-16057] Specified primary database is a container database (CDB). CAUSE: Duplicate database operation is supported only for non container databases. ``` **18c及以后:** > 18c(12.2.0.2)开始,这些限制条件已经取消,即主库是 CDB 或 RAC环境都可以通过 dbca 来创建物理备库 ## 10.3 DG中密码自动同步 > Oracle数据库软件是获得过最高级别的安全认证,完全超越其它所有数据库软件,并且在可维护性上基于大量的实践需要稳步前行,这里简单列举几个12c 关于password几个新特性. > Ø 新的password hash算法 > Ø 新的password verify function > Ø 密码文件可以存储到ASM > Ø 密码自动从primary同步到standby端在Dataguard环境中 > Ø 新的密码认证协议 > 以下将介绍其中几个内容: ### 10.3.1 密码文件可以存储到ASM > 在Oracle Database 12c之前,密码文件始终位于$ORACLE_HOME/dbs文件下,即使对于RAC实例和RAC ASM集群也是如此. 对于RAC而言,DBA必须设法保持这一点密码文件在每个节点上同步. 现在,在Oracle 12c中,可以将密码文件存储在ASM上. 这意味着一个共享密码文件Oracle RAC数据库为集群中的所有实例共享,与ASM spfile不同,ASM密码文件的访问只有在启动ASM ,并且在磁盘组mount后才可以访问. 用于创建密码文件的命令实用程序仍然是相同的:“orapwd” > asmcmd同样也可以创建密码文件 ### 10.3.2 密码自动从primary同步到standby > 12cR2中一个有用的增强功能是密码文件在Data Guard环境中自动同步,如果在primary database上更改了sys的密码,并且它自动也在standby database上进行了更改. 注意这里是密码同步不是密码文件同步,所以主备的密码文件还是需要手动创建的. 在主库更新密码文件,备库开启应用程序,密码会更新到备库. > Ø 11g中口令文件并不能实现存放于asm共享访问,修改sYs密码,需要再每个RAc节点手动实施同步,同样备库的口令文件也要手动进行更新覆盖 > Ø 12.1版本可以实现口令文件ASM共享存储,RAC中只需要一个节点执行alter user sys就可以实现主库所有节点同步,这点是11g中无法实现. 但是备库中口令文件依然需要手动同步主库的口令文件过来覆盖. > Ø 从12.2版本开始,如果主库是rac,那么 oracle在口令文件ASM共享存储的前提下,实现了口令文件自动同步主备听有节点 > 密码自动同步条件 > 1).备库开启应用进程 > 2).如果主库是rac,那么需要将主库密码文件存放在ASM共享中. 否则不能实现密码自动同步备库的功能. ## 10.4 18c DG新视图V$DATAGUARD_PROCESS > DATAGUARD_PROCESS用于查看DG的进程状态信息,取代了v$managed_standby视图. ```sql select name,type,role,action,group# from v$dataguard_process; ``` ## 10.5 19c ADG的自动DML重定向增强读写分离 > 就是在ADG环境下,可以连接到standby数据库执行都没了语句. > 原理是:通过将备库上的DML重定向到主库上执行,然后备库应用DML变化数据,至此完成备库DML操作. > 不支持XA事务中的DML操作. > 这个特性在18c是作为隐含参数_enable_proxy_adg_redirect调整的,但在19c中通过显示参数ADG_REDIRECT_DML参数调整. ```sql show parameter adg_redirect_dml; ``` > 模式是false > 自动重定向DML操作支持会话级别和系统级别,会话级别会覆盖系统级别配. > 在primary和 standby都打开 ```sql SQL>alter system set adg_redirect_dml=truescopeboth sid ='*'; ``` > 测试后发现是通过dblink的方式去 primay执行DML > 注意:不支持sys用户会话启用 > :OR-16397:statement redirection from Oracle Active Data Guard standby > 将偶然发送到ADG上的DML操作,自动转发到主库执行,然后通过主库日志传递到备库实时应用,在保证了ACID的前提下,增强了备库的实用性,被称为DML Redirection > 其实这个特性在18c中就已经提供,所以我们不必等到19c就能够体验到这个特性 > 在两个版本中,唯一的差别是 > 在18c中,这个特性是通过隐含参数 enable proxy adg redirect的调整来启用这个特性,这表示此特性是趋向内部的; > 在19c中,显式参数 ADG REDIRECT DML参数控制这个特性的开关,说明这个特性变成外部和成熟的; ## 10.6 级联DG(一主一备一级联) > DG一主-备一级联,意思是主库将日志传输给备库,然后备库再将日志传输给级联库,主库和级联库其实没有任何关系. > 另外,在11g中,关于数据同步问题,主库上的操作一般情况下是可以实时同步到备库的,但是级联库必须等备库归档时,才能同步,如果主库切换日志,那么这时级联库也能及时同步. > 12c的级联备库是支持实时应用的. > 在11.2.0.2及以上版本支持级联备库,就是第二备库从第一备库接受redo日志,而不是从主库接收,这样也会减小主库压力. 实际上和正常搭建DG没有什么区别,只是改下参数即可. > 最多支持30个级联备库,因为LOG_ARCHIVE_DEST_n只有31个. > 在用于级联的备库中的 LOG_ARCHIVE_DEST_n(1…10)指定 ASYNC,则是rea1-time.如果不指定,或者指定SYNC,则是non-real-time. 最后修改:2022 年 04 月 04 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 0 如果觉得我的文章对你有用,请随意赞赏