防止客户端连接到错误的数据库
使用数据库服务来防止客户端连接到 Data Guard 配置中的错误数据库。
数据库服务充当客户端和数据库实例之间的抽象层。
- 数据库服务向侦听器注册,客户端连接到数据库服务而不是数据库实例。
侦听器使用注册详细信息来确定哪些实例在特定时间支持特定服务。然后侦听器将连接请求定向到正确的实例;否则,返回适当的错误。
将连接请求发送到错误主机的客户端可能连接到错误的数据库实例,或者他们可能会收到如下错误消息:
ORA-01033: ORACLE initialization or shutdown in progress
管理服务
数据库服务是通过 DBMS_SERVICE 包实现的。该包为单个数据库实例提供服务的创建、删除、启动和停止。数据库服务属性:
- 服务名称:管理服务的名称服务名称:管理服务的名称
- 网络名称:用于客户端连接的 SQLNet 连接描述符中的服务网络名称
- 参数数组:具有用于定义的名称-值对的关联数组:
- 透明应用程序故障转移 (TAF) 属性
- 服务的工作负载管理目标指令
- 快速申请通知 (FAN)
- 分布式事务处理(DTP 或者 XA)
注意:如果通过为独立服务器安装 Grid Infrastructure 来安装和配置 Oracle Restart,则应使用 SRVCTL 实用程序来管理基于角色的服务,而不是 DBMS_SERVICE。
应始终使用 Oracle Real Application Clusters 的 SRVCTL 实用程序来管理集群环境的基于角色的服务。
OLE DB 客户端的自动故障转移
要自动为 OLE DB 客户端进行故障转移,请执行以下步骤来配置数据库:
- 确保配置由 Data Guard 代理管理。
- 执行 DBMS_SERVICE.CREATE_SERVICE 过程或者 SRVCTL 以创建数据库服务、启用高可用性通知并配置服务器端 TAF 设置。
- 如果需要,创建一个触发系统启动事件的触发器。此触发器在角色转换到在步骤 2 中创建的服务后重新定位数据库。
为 Data Guard 配置数据库创建服务
通过使用 DBMS_SERVICE.CREATE_SERVICE 过程,我们可以定义一个服务来表示 Data Guard 配置中的数据库可以运行的每个角色或者状态。
使用 DBMS_SERVICE.CREATE_SERVICE 创建的服务不知道实际的数据库角色。
此功能仅适用于 Real Application Clusters 和 Oracle Restart 的 SRVCTL 接口。
在下面显示的示例中,服务名称用于提示数据库角色,这在角色转换后可能不准确。
CREATE_SERVICE 过程在数据字典中创建一个服务名称。
DBMS_SERVICE.CREATE_SERVICE( SERVICE_NAME => 'DG_PROD', NETWORK_NAME => 'DG_PROD', FAILOVER_METHOD => 'BASIC', FAILOVER_TYPE => 'SELECT', FAILOVER_RETRIES => 180, FAILOVER_DELAY => 1);
DBMS_SERVICE.CREATE_SERVICE( SERVICE_NAME => 'DG_RTQ', NETWORK_NAME => 'DG_RTQ');
DBMS_SERVICE.CREATE_SERVICE('DG_LSBY','DG_LSBY');
DBMS_SERVICE.CREATE_SERVICE('DG_SNAP','DG_SNAP');
当物理备库以只读方式打开时(使用实时查询),并且当它转换为快照备库时,我们应该为物理备库创建服务。
DBMS SERVICE CREATE SERVICE DBMS_SERVICE.CREATE_SERVICE 将无法在物理备用数据库上执行,甚至无法在物理备用数据库上执行,即使它以只读方式打开。
该服务必须在主服务器上创建并允许传播到物理备用服务器。
此外,在配置中为逻辑备用数据库创建一个服务。
注意:上面显示的数据库服务名称是示例。
为故障转移配置 JDBC 客户端
为故障转移配置 JDBC 客户端:
- 将 FastConnectionFailoverEnabled DataSource 属性设置为 True,以便客户端应用程序在其数据源上使用隐式 JDBC 连接缓存。
- 在数据源上将 oracle.net.ns.SQLnetDef.TCP_CONNTIMEOUT_STR 属性设置为 3 秒的值。此属性使 JDBC 客户端能够在发生故障时快速遍历地址列表。如果客户端尝试连接到不可用的主机,则连接尝试被限制为 SQLnetDef.TCP_CONNTIMEOUT_STR 属性指定的时间,在此之后客户端尝试连接到地址列表中的下一个主机。地址列表中的每台主机的行为都会继续,直到成功连接。 地址列表中的每个主机的行为都会继续,直到建立成功的连接。
- 创建一个 Oracle Net 服务名称,其中包含主数据库主机和所有备用数据库主机的 ADDRESS 条目。
- 在 JDBC 客户端上配置远程 ONS 订阅,以便客户端上不需要 ONS 守护程序。远程 ONS 订阅应包含所有可能成为主数据库的主机。
- 为通信启用 SSL。SSL 应用于所有 ONS 通信。
连接到合适的环境
不使用 Active Data Guard 的物理备用数据库以挂载模式维护数据库,并且通常不允许普通用户连接侦听器。
但是,使用 Active Data Guard,数据库以只读方式打开,以允许针对物理备用数据库进行报告。
此外,添加开放读写的逻辑备用数据库将允许客户端使用标准数据库身份验证方案(例如用户名和密码)成功连接。
客户端连接到适当的环境很重要。
JDBC 客户端的自动故障转移
要为 JDBC 客户端自动进行故障转移,请执行以下步骤来配置数据库:
- 执行 DBMS_SERVICE.CREATE_SERVICE 过程或者 SRVCTL 为 JDBC 客户端创建数据库服务。因为 JDBC 客户端使用 FCF 而不是 TAF,所以没有为 AQ HA 事件配置 JDBC 客户端的数据库服务。相反,当发生 Data Guard 故障转移时,需要触发器来通知 JDBC 客户端。
- 在可能包含主数据库的所有主机上配置并启动 ONS 守护进程。在 $ORACLE_HOME/opmn/conf 目录中配置 ONS(类似于幻灯片中的示例)。有关详细信息,请参阅 Oracle 数据库 JDBC 开发人员教程和参考。
- 启动 ONS 守护程序 启动 ONS 守护程序。
- 如果需要,在系统启动事件上创建触发器以在角色转换后重新定位数据库服务。使用 Oracle Restart 时不需要触发器。
- 创建为 DB_ROLE_CHANGE 系统事件启用的触发器,该事件调用名为 FAN ONS Publisher 的 C 程序。此触发器是必需的,因为 ONS 守护程序所在的主要主机不再可用。通过基于在 DB_ROLE_CHANGE 系统事件上启用的触发器调用 FAN ONS Publisher 程序,JDBC 客户端会收到主站点故障的通知,并指示重新连接到新的主数据库。
示例:配置基于角色的服务
$ srvctl add service -d boston -s payroll -l PRIMARY –m BASIC –e SELECT –w 1 –z 180 $ srvctl add service –d dallas –s payroll –l PRIMARY –m BASIC –e SELECT –w 1 –z 180 $ srvctl add service -d dallas -s orderstatus -l PHYSICAL_STANDBY
上面的示例显示了两个特定于角色的服务的配置:
- PAYROLL 是一种读写服务,它始终以主要角色在数据库上运行。
- ORDERSTATUS 是一个只读服务,它始终在 Active Data Guard 备用数据库上运行,该数据库当前定义为 Dallas 数据库,同时它处于 PHYSICAL_STANDBY 角色。角色转换可以停止此服务。
注意:数据库服务链接到 Oracle Restart Configuration 中的特定 DB_UNIQUE_NAME。
为了将 PAYROLL 服务与主数据库和备用数据库相关联,它必须单独注册到每个数据库。
角色设置为 PRIMARY,因此它只会在两个数据库之一上启动
将备用数据库添加到 Oracle 重启配置
当 Enterprise Manager Cloud Control 用于通过向导驱动的方法创建备用数据库时,新创建的备用数据库不会自动注册到 Oracle Restart 配置。
在数据库服务与备库关联之前,使用SRVCTL在Oracle Restart Configuration中创建数据库对象。
下面显示了用于创建新数据库对象的 SRVCTL 语法。
$ srvctl add database -d [db_unique_name] -o [oracle_home] [-m [domain_name]] [-p [spfile]] [-r [PRIMARY | PHYSICAL_STANDBY | LOGICAL_STANDBY | SNAPSHOT_STANDBY ]] [-s [start_options]] [-t [stop_options]] [-n [db_name]] [-y [AUTOMATIC | bananaAL]] [-a "[diskgroup_list]"]
start_options 的值包括 open 、 mount 或者 nomount 。
stop_options 的值包括 normal 、 transactional 、immediate 或者 abort 。
例子:
$ srvctl add database -d london –o /u01/app/oracle/product/11.2.0/dbhome_1 –m example.com –p /u01/app/oracle/product/11.2.0/dbhome_1/dbs/spfilelondon.ora -r PHYSICAL_STANDBY –n boston –a "SBDAT,SBFRA"
注意:从 Oracle Database 12c Release 1(12.1) 开始,Oracle Restart 已被弃用。
它目前仍然可以使用,但可能会在未来的版本中被删除。
上面显示的示例使用了对 Oracle Database 11 2 的引用,其中 Oracle Restart 是建议的最佳实践。
客户端故障转移:组件
以下功能用于实施客户端故障转移并最大限度地减少计划内和计划外中断的影响:
- 连接时间故障转移:将失败的连接请求重定向到辅助侦听器。
- 透明应用程序故障转移 (TAF):使 Oracle 调用接口 (OCI) 客户端应用程序能够在原始连接失败时自动重新连接到数据库。 TAF 仅故障转移会话和 SELECT 语句。当为 SELECT 故障转移配置 TAF 时,SELECT 语句会在新会话中自动重新启动。 INSERT、UPDATE 和 DELETE 语句必须由应用程序回滚。此外,任何会话自定义(例如,ALTER SESSION 语句)都必须由应用程序重新执行。进程状态变量(例如 PL/SQL 会话级变量)不会重新建立,但可以使用 TAF 回调重新建立。
- 快速应用程序通知 (FAN):在资源(例如实例、服务、节点或者数据库)出现故障时提供快速通知。通过使用 FAN 集成的 Oracle 客户端(使用 JDBC、OCI 或者 OLE DB 的客户端)的快速连接故障转移或者使用 FAN API 直接读取 FAN 事件,所有应用程序都可以使用 FAN
- 快速连接故障转移:通过使我们能够配置集成 FAN 的 JDBC 客户端来自动订阅 FAN 高可用性事件并对服务、实例和数据库 UP 和 DOWN 事件做出反应,从而提供数据库连接的快速故障转移。
- DB_ROLE_CHANGE 系统事件:在发生 Data Guard 角色转换后首次打开任何数据库时触发。使用此系统事件,我们可以编写触发器来执行角色更改后的操作。
OCI 客户端的自动故障转移
要为 OCI 客户端自动进行故障转移,请执行以下步骤来配置数据库:
- 确保配置由 Data Guard 代理管理。
- 执行 DBMS SERVICE CREATE SERVICE 过程以创建数据库服务、启用高可用性通知并配置服务器端 TAF 设置。
- 创建一个触发系统启动事件的触发器。在角色转换后,此触发器将数据库(在步骤 2 中创建)重新定位到 Data Guard 备用数据库。
要为 OCI 客户端自动进行故障转移,请执行以下步骤来配置 OCI 客户端以接收 FAN 高可用性 g 事件的通知并避免重新连接到失败的实例:
- 创建一个 Oracle Net 服务名称,其中包含主数据库主机和所有备用数据库主机的 ADDRESS 条目。
- 使用 OCI_EVENTS 参数初始化环境,以便 OCI 客户端接收 FAN 通知: OCIEnvCreate(...OCI_EVENTS...)
- 将 OCI 客户端应用程序链接到 libthread 或者 libpthread 线程库
- 将 sqlnet.ora 文件中的 SQLNET.OUTBOUND_CONNECT_TIMEOUT 参数设置为 3 秒的值。此参数使客户端能够在发生故障时快速遍历地址列表。如果客户端尝试连接到不可用的主机,则连接尝试被限制为 SQLNET.OUTBOUND_CONNECT_TIMEOUT 参数指定的时间,在此之后客户端尝试连接到地址列表中的下一个主机。对于地址列表中的每个主机,此行为将继续,直到建立成功连接。
- 注册一个在高可用性事件发生时调用的回调。
在 Data Guard 配置中自动化客户端故障转移
在 Data Guard 配置中自动化客户端故障转移包括:
- 作为 Data Guard 故障转移的一部分,将数据库服务重定位到新的主数据库
- 通知客户端发生了故障,以使它们摆脱 TCP 超时
- 将客户端重定向到故障转移操作期间建立的主数据库
在 tnsnames ora 文件中配置服务名称
要确保客户端以正确的状态和角色连接到特定服务的数据库,请在 tnsnames.ora 文件中为每个服务配置网络服务名称。
对于每个条目,都会列出主数据库上的侦听端点和备用数据库上的侦听端点。
如果发生故障转移和切换等角色反转事件,则需要这样做。
请记住,即使未指定,ADDRESS_LIST 语法也会导致启用 FAILOVER=on 模式。
PROD = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS=(PROTOCOL = TCP)(HOST = host01)(PORT = 1521)) (ADDRESS=(PROTOCOL = TCP)(HOST = host03)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = DG_PROD))) RTQ (DESCRIPTION (ADDRESS LIST RTQ = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS=(PROTOCOL = TCP)(HOST = host01)(PORT = 1521)) (ADDRESS=(PROTOCOL = TCP)(HOST = host03)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = DG_RTQ))) SNAP = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS=(PROTOCOL = TCP)(HOST = host01)(PORT = 1521)) (ADDRESS=(PROTOCOL = TCP)(HOST = host03)(PORT = 1521))) (ADDRESS=(PROTOCOL = TCP)(HOST = host03)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = DG_SNAP))) LSBY = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS=(PROTOCOL = TCP)(HOST = host01)(PORT = 1521)) (ADDRESS=(PROTOCOL = TCP)(HOST = host03)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = DG_LSBY)))
Data Guard Broker 和快速应用程序通知 (FAN)
当故障转移操作完成时,Data Guard 代理发布快速应用程序通知 (FAN) 事件以通知应用程序旧主数据库已关闭,并且旧主数据库上的服务已关闭。
这使应用程序能够透明地故障转移到新的主数据库。
FAN 通知在故障转移后为配置了集群就绪服务 (CRS) 的数据库和使用 Oracle Restart 注册的单实例数据库发送。
使用以下 Oracle 集成数据库客户端的应用程序可以配置为快速连接故障转移 (FCF),以便在故障转移后自动连接到新的主数据库:
- Oracle 数据库 JDBC
- Oracle 数据库 Oracle 调用接口 (OCI)
- Oracle 数据库 ODP.NET
这些客户端无需编程更改即可使用 FAN。
应用程序可以通过使用 Oracle 通知服务 (ONS) 应用程序编程接口以编程方式使用 FAN 来订阅 FAN 事件并在接收到事件时执行事件处理操作。
了解 Data Guard 配置中的客户端连接
在 Data Guard 配置中管理客户端连接时,请注意以下问题:
- 数据库驻留在 Data Guard 配置中的不同主机上。
- 客户端必须连接到提供特定业务角色的正确数据库,例如主数据库、逻辑备用数据库、快照备用数据库或者物理备用数据库。
- 主数据库和备用数据库可以通过切换和故障转移操作来替代主机。
- 如果客户端向错误的主机发送连接请求,它们可能连接到错误的数据库或者收到错误。
- 发生故障转移时,客户端必须自动重新连接到正确的数据库。
将客户端连接到正确的数据库
通过使用数据库事件触发器,确保客户端连接到在 Data Guard 配置中处于正确状态和角色的数据库实例。
AFTER STARTUP 触发器在数据库上启动相应的服务。
如果没有处于正确状态和角色的数据库,gg 触发器可确保客户端不会连接到数据库。
注意:下面显示的数据库服务名称仅作为示例显示。
如果服务由 Oracle Clusterware 管理,则没有必要使用 AFTER STARTUP 触发器。
为基于角色的服务创建 AFTER STARTUP 触发器
CREATE TRIGGER MANAGE_SERVICES AFTER STARTUP ON DATABASE DECLARE ROLE VARCHAR2(30); OMODE VARCHAR2(30); BEGIN SELECT DATABASE_ROLE INTO ROLE FROM V$DATABASE; SELECT OPEN_MODE INTO OMODE FROM V$DATABASE; IF ROLE = 'PRIMARY' THEN DBMS_SERVICE.START_SERVICE ('DG_PROD'); ELSIF ROLE = 'PHYSICAL STANDBY' THEN IF OMODE LIKE 'READ ONLY%' THEN DBMS_SERVICE.START_SERVICE ('DG_RTQ'); END IF; ELSIF ROLE 'LOGICAL STANDBY' THEN ELSIF ROLE = 'LOGICAL STANDBY' THEN DBMS_SERVICE.START_SERVICE ('DG_LSBY'); ELSIF ROLE = 'SNAPSHOT STANDBY' THEN DBMS_SERVICE.START_SERVICE ('DG_SNAP'); END IF; END; /
使用触发器启动已经创建的数据库服务。
- DG_PROD:主数据库
- DG RTQ _ : 物理备库打开于 : 物理备库以 READ ONLY 模式打开(实时查询)
- DG_SNAP:物理备库转换为快照备库
- DG_LSBY:逻辑备用数据库
AFTER STARTUP 触发器在数据库打开时被调用。
触发器检查数据库角色和数据库的打开模式,并根据这些值调用 DBMS_SERVICE.START_SERVICE 过程来启动适当的服务。
CREATE TRIGGER SQL 命令只需要在主数据库中运行。
它将被复制到所有备用数据库。
从 Oracle Database 12c 第 1 版 (12.1) 开始,V$DATABASE 视图的 DATABASE_ROLE 列有一个新的角色值。
已添加值 FAR SYNC。
不应为此角色类型启动其他服务。
注意:根据情况,可能需要另外的触发功能。
如果服务由 Oracle Clusterware 管理,则没有必要使用 AFTER STARTUP 触发器。
上面列出的触发器没有考虑可插拔数据库的影响。
在本类的练习类中,我们将编写一个能够识别可插入数据库的启动触发器。
应用程序自动故障转移到新的主数据库
在不使用 Oracle Data Guard 代理的情况下,需要用户编写的数据库触发器来实现自动故障转移,如下所示:
- 启动触发器用于在新的主数据库上启动数据库服务。
- 角色更改触发器用于发布 FAN ONS 事件,以在 TCP 超时后中断仍连接到原始主数据库的 JDBC 客户端。
我们可以自动将应用程序快速故障转移到新的主数据库,而无需用户编写的触发器。
我们必须使用 Data Guard 代理才能使用此功能。
故障转移后应用程序客户端自动快速故障转移到新的主数据库需要:
- 快速数据库故障转移
- 在新的主数据库上重启数据库服务
- 通知客户端发生了故障,以使它们摆脱 TCP 超时并将它们重定向到新的主数据库
使用 Oracle Clusterware 配置基于角色的服务
我们可以在 Oracle RAC 数据库或者使用 Oracle Restart 注册的单实例数据库上使用数据库角色配置数据库服务。
Data Guard 代理与 Oracle Clusterware 或者 Oracle Restart 交互以确保在角色更改后正确的数据库服务处于活动状态。
此功能仅在 Data Guard 配置由代理管理时可用。
$ srvctl add service -db [db_unique_name] -service [service_name] -role "[PRIMARY] [,PHYSICAL_STANDBY] [,LOGICAL_STANDBY][,SNAPSHOT_STANDBY]" [-policy [AUTOMATIC | bananaAL]]
SRVCTL ADD SERVICE 和 MODIFY SERVICE 命令支持以下属性:
- -role :具有 PRIMARY、PHYSICAL_STANDBY、LOGICAL_STANDBY 和 SNAPSHOT_STANDBY 值的 ROLE 属性。默认值为 PRIMARY。此属性用于指定给定数据库服务应为其激活的数据库角色,用于指定给定数据库服务应为其激活的数据库角色。
- -policy : MANAGEMENT POLICY 属性,值为 AUTOMATIC 和 bananaAL。默认为自动。
当数据库实例启动时,如果 MANAGEMENT POLICY 属性设置为 AUTOMATIC 并且 ROLE 属性的值与数据库角色匹配,则服务会自动启动。
如果数据库实例已启动,用户也可以手动启动服务。
注意:如果服务是在已经启动的数据库实例上创建的,那么第一次需要手动启动服务。
以下语法说明了使用 SRVTL 手动启动服务:
$ srvctl start service –db DG_PRMY –service DG_PRMY
对于不使用 Real Application Clusters (RAC) 的独立服务器,SRVCTL ADD SERVICE 命令的以下选项仅适用于 Oracle Data Guard 环境:
- 具有值 { NONE | 的故障转移类型 ( -failovertype )会议 |选择 |交易 }
- 具有值 { NONE | 的故障转移方法 ( -failovermethod )基本的 }
- 故障转移延迟 (-failoverdelay) 以秒为单位的整数值
- 故障转移重试 ( -failoverretry ) 指示计数的整数值
注意:从 Oracle Database 12c Release 1(12.1) 开始,Oracle Restart 已被弃用。
它目前仍然可以使用,但可能会在未来的版本中被删除。
为故障转移配置 OLE DB 客户端
配置 OLE DB 客户端以接收 FAN 高可用性事件的通知:
- 设置以下 OraOLEDB 连接字符串属性:
- DBNotifications = 真
- DBNotificationPort = [无符号整数]
- 设置 DBNotificationPort 属性允许指定端口。如果未设置此属性,则随机选择端口。
- 将 sqlnet.ora 文件中的 SQLNET.OUTBOUND_CONNECT_TIMEOUT 参数设置为 3 秒的值。此参数使客户端能够在发生故障时快速遍历地址列表。如果客户端尝试连接到不可用的主机,则连接尝试被限制为 SQLNET.OUTBOUND_CONNECT_TIMEOUT 参数指定的时间,在此之后客户端尝试连接到地址列表中的下一个主机。对于地址列表中的每个主机,此行为将继续,直到建立成功连接。