管理逻辑备数据库(Logical Standby Database)

news2024/10/2 3:20:52

1. SQL Apply架构概述

SQL Apply使用一组后台进程来应用来自主数据库的更改到逻辑备数据库。

在这里插入图片描述

在日志挖掘和应用处理中涉及到的不同的进程和它们的功能如下:

在日志挖掘过程中:
1)READER进程从归档redo日志文件或备redo日志文件中读取redo记录
2)PREPARER进程转换redo记录中包含的数据块更改到逻辑更改记录(LCRs,Logical Change Records)。可以为一个指定的redo日志文件激活多个PREPARER进程。LCRs存放在SGA(system global area)中,称为LCR缓存。
3)BUILDER进程将LCRs组合成事务和执行其他任务,比如在LCR缓存中进行内存管理,重启与SQL Apply相关的检查点和滤除无用的更改。

在应用过程中:
1)ANALYZER进程确认不同事务之间的依赖关系。
2)COORDINATOR进程(LSP)分配事务给不同的应用器,然后在事务间进行协调来确保遵循事务之间的依赖关系。
3)APPLIER进程在协调进程的监督下应用事务到逻辑备数据库。


1.1. SQL Apply考虑的各种因素

1.1.1. 事务大小考虑

SQL Apply将事务分成两类:小事务和大事务。

每种类别的定义如下:
1)小事务—SQL Apply一旦遇到redo日志文件中的事务提交记录,就会启动应用属于小事务的LCRs。
2)大事务—SQL Apply将大事务分割成更小的事务块(transcation chunks),然后在看到redo日志文件中的大事务提交记录之前启动应用事务块。这样可以减轻LCR缓存的内存压力和减少整体故障切换的时间。
例如,如果不将大事务分割成小块事务,SQL*Loader导入1千万行,每行100 bytes,那么LCR缓存将会使用1G的内存。如果分配给LCR缓存的内存小于1G,就会导致从LCR缓存中移出页面(pageout)。
降了内存方面的考虑,如果SQL Apply直到遇到事务的COMMIT记录才开始应用SQL*Loader导入1千万行的相关的更改,它会阻滞角色的转换。在事务提交后发起的正常切换或故障切换不能完成,直到SQL Apply已经应用事务到逻辑备数据库为止。
虽然使用了事务块,当处理修改多于8百万行的事务时,SQL Apply的性能可能会降低。对于多于8百万行的事务,SQL Apply使用临时段来存放处理事务的部分内部元数据。确保在临时段中分配更多的空间让SQL Apply能成功地处理多于8百万行的事务。

所有事务开始时会分类成小事务。取决于LCR缓存的可用内存容量和属于事务的LCR消耗的内存容量,SQL Apply决定什么时候重新将事务分类为大事务。


1.1.2. 页出(pageout)考虑

当LCR缓存的内存耗尽时,需要释放空间来让SQL Apply来继续进行,就会发生页出(pageout)。

例如,假设分配给LCR缓存的内存是100MB,SQL Apply遇到一条INSERT到表的一个LONG列的大小为300MB的事务。在这种情况下,日志挖掘组件页出第一部分LONG数据来读取后面部分的列更改。在一个调优好的逻辑备数据库中,页出活动偶尔会发生,不会影响系统 的整体吞吐量。

参考“自定义逻辑备数据库”章节关于如何识别有问题的页出和执行纠正操作。


1.1.3. 重启考虑

对逻辑备数据库的更改不会成为持久的,直到从redo日志文件中挖掘到事务的提交记录和应用到逻辑备数据库为止。

因此,每次SQL Apply停止时,不管是因为用户的指令还是系统故障的结果,SQL Apply必须进行回溯,重新挖掘最早的没有提交的事务。

在事务只做了少量的工作但打开了很长一段时间的情况下,从一开始重启SQL Apply可能会付出过高的代价,因为SQL Apply必须重新挖掘大量的归档redo日志文件,只为了读取一部分没有提交的数据的redo数据。为了减轻这种情况,SQL Apply定期地对旧的未提交的数据执行检查点操作。检查点进行时的SCN反映在视图V$LOGSTDBY_PROGRESS的列RESTART_SCN中。在进行重启时,SQL Apply从大于列RESETART_SCN的值的SCN时产生的redo记录开始挖掘。重启时不需要的归档redo日志文件会自动被SQL Apply删除。

某些负载,例如大的DDL事务,并行的DML语句(PDML),和直接路径导入,阻止RESTART_SCN在负载的持续时间里向前推进。


1.1.4. DML Apply考虑

SQL Apply在应用影响逻辑备数据库的吞吐量和延迟的DML事务时有以下特性:
1)在主数据库上做批量更新或删除时,一条语句会导致多行被修改,这时在逻辑备数据库上则作为单独的行修改来应用。因为,对于每个维护的表,必须有唯一的索引或主键。
2)在主数据库上执行的直接路径插入,在逻辑备数据库上使用传统的INSERT语句来应用。
3)并行的DML(PDML)事务在逻辑备数据库上不是并行地执行。


1.1.5. DDL Apply考虑

SQL Apply在应用影响逻辑备数据库的吞吐量和延迟的DDL事务时有以下特性:
1)DDL事务在逻辑备数据库上是串行地应用。因此,在主数据库上并行应用的DDL事务是一次一个地在逻辑备数据库上应用。
2)CREATE TABLE AS SELECT(CTAS)语句如此执行以致DML操作(CATS语句的一部分)在逻辑备数据库上受到抑制。作为CTAS语句的一部分插入到新创建的表的行从redo日志文件中挖掘出来和使用INSERT语句应用到逻辑备数据库。
3)SQL Appy重新发出在主数据库上执行的DDL,确保作为DDL操作目标的相同对象上的相同的事务中发生的DML不会在逻辑备数据库上复制(SQL Apply reissues the DDL that was performed at the primary database, and ensures that DMLs that occur within the same transaction on the same object that is the target of the DDL operation are not replicated at the logical standby database)。因此,以下两个情况会导致主备数据库相互偏离:
a. DDL包含从主数据库的状态获取的非文字的值。这样的DDL的一个例子是:
ALTER TABLE hr.employees ADD (start_date date default sysdate);
由于SQL Apply在逻辑备数据库重新发出相同的DDL,函数sysdate() 在逻辑备数据库重新取值。因此,列start_date使用与主数据库不同的缺省值来创建。
b. DDL激发在目标表上定义的DML触发器。由于触发的DMLs发生在与DDL相同的事务上,操作的表也是DDL的目标,这些触发的DML不会在逻辑备数据库上复制。
例如,假设创建一个如下的表:
create table HR.TEMP_EMPLOYEES (
emp_id number primary key,
first_name varchar2(64),
last_name varchar2(64),
modify_date timestamp);

假设在表上创建一个触发器使得任何时候表进行更新时列modify_date也更新来反映更改的时间:
CREATE OR REPLACE TRIGGER TRG_TEST_MOD_DT BEFORE UPDATE ON HR.TEST_EMPLOYEES
REFERENCING
NEW AS NEW_ROW FOR EACH ROW
BEGIN
:NEW_ROW.MODIFY_DATE:= SYSTIMESTAMP;
END;
/

表在一般的DML/DDL负载下可以正确地维护。但如果使用缺省值往表里增加一列,ADD COLUMN DDL操作会激发更新触发器,更改表中所有行的MODIFY_DATE列为新的时间戳。这些对MODIFY_DATE列的更改不会复制到逻辑备数据库上。接下来对表的DML操作会停止SQL Apply,因为记录在redo流中的MODIFY_DATE列数据与存在于逻辑备数据库上的数据不匹配。


1.1.6. 密码验证函数

检查密码复杂度的密码验证函数必须在SYS模式中创建。

因为SQL Apply不会复制SYS模式中创建的对象,这些密码验证函数不会复制到逻辑备数据库。必须在逻辑备数据库上手动创建密码验证函数,然后与合适的profile关联。


2.控制用户对表的访问

SQL语句ALTER DATABASE GUARD在逻辑备数据库上控制用户对表的访问。

缺省情况下,在逻辑备数据库上database guard设置为ALL。

ALTER DATABASE GUARD语句允许以下关键字:
1)ALL
指定ALL来阻止除SYS外的所有用户对逻辑备数据库的任何数据进行更改。
2)STANDBY
指定STANDBY来阻止除SYS之外的所有用户对通过SQL Apply维护的任何表或序列进行DML和DDL更改。
3)NONE
指定NONE来对数据库的所有数据使用典型的保护措施。

例如,使用以下语句来启用用户更改不是SQL Apply维护的表。
SQL> ALTER DATABASE GUARD STANDBY;

特权用户可以分别使用ALTER SESSION DISABLE GUARD和ALTER SESSION ENABLE GUARD语句为当前会话临时关闭和打开database guard。这个语句替代了DBMS_LOGSTDBY.GUARD_BYPASS PL/SQL存储过程在Oracle 9i中执行相同的功能。当你想临时禁用database guard来对数据库进行更改时,语句ALTER SESSION [ENABLE|DISABLE] GUARD很有用。

注:在database guard禁用时,不要让主数据库和逻辑备数据库偏离。


3.监控逻辑备数据库

3.1. 监控SQL Apply的进度

SQL Apply可以在六个进度状态中的任何一个:初始化SQL Apply,等待字典日志,导入LogMiner字典,应用redo数据,等待归档缺口(gap)得到解决,和空闲。

下图显示了这些状态的流动:
在这里插入图片描述

3.1.1.初始化状态

当使用ALTER DATABASE START LOGICAL STANDBY APPLY语句启动SQL APPLY时,它会进入到initializing状态。

查询V$LOGSTDBY_STATE视图来确认SQL Apply的当前状态。
SQL> SELECT SESSION_ID, STATE FROM V$LOGSTDBY_STATE;

SESSION_ID 	STATE
---------- -------------
1 			INITIALIZING

列SESSION_ID显示SQL Apply创建的持久的LogMiner会话,用来挖掘主数据库产生的归档redo日志文件。


3.1.2.等待字典日志

SQL Apply第一次启动时,它需要导入redo日志文件中记录的LogMiner字典。SQL Apply停留在WAITING FOR DICTIONARY LOGS状态直到它已经接收到导入LogMiner字典所要求的所有的redo数据。


3.1.3.导入字典状态

Loading dictionary的状态会持续一会。导入一个大数据库的LogMiner字典会花很长的时间。当导入字典时,查询视图V$LOGSTDBY_STATE会返回以下输出:
SQL> SELECT SESSION_ID, STATE FROM V$LOGSTDBY_STATE;

SESSION_ID STATE
---------- ------------------
1 			LOADING DICTIONARY

只有COORDINATOR进程和挖掘进程启动直到LogMiner字典完全导入为止。因此,此时如果查询视图V$LOGSSTDBY_PROCESS,将会看不到任何APPLIER进程。
SQL> SELECT SID, SERIAL#, SPID, TYPE FROM V$LOGSTDBY_PROCESS;

SID 	  SERIAL#    SPID     TYPE
------ --------- --------- ---------------------
47        3 		11438 	COORDINATOR
50        7 		11334 	READER
45        1 		11336 	BUILDER
44        2 		11338 	PREPARER
43        2 		11340 	PREPARER

可以通过查询视图V$LOGMNR_DICTIONARY_LOAD来获取关于导入字典进度更详细的信息。导入字典分3个阶段进行:
1)挖掘相关的归档redo日志文件或备redo日志文件来收集与导入LogMiner字典相关的redo更改;
2)这些更改被处理和导入到数据库中的阶段表;
3)发出一序列的DDL语句导入LogMiner字典表。
SQL> SELECT PERCENT_DONE, COMMAND FROM V$LOGMNR_DICTIONARY_LOAD WHERE SESSION_ID = (SELECT SESSION_ID FROM V$LOGSTDBY_STATE);

PERCENT_DONE COMMAND
------------- -------------------------------
40           alter table SYSTEM.LOGMNR_CCOL$ exchange partition P101 with table SYS.LOGMNRLT_101_CCOL$ excluding indexes without validation

如果PERCENT_DONE或COMMAND列很长一段时间没有变化,查询视图V$SESSION_LONGOPS来监控有问题的DDL事务的进度。


3.1.4.应用状态

在这个状态中,SQL Apply已经成功导入LogMiner字典的初始快照和正在应用redo数据到逻辑备数据库。

查询视图V$LOGSTDBY_PROGRESS,取得关于SQL Apply进度的详细信息:
SQL> ALTER SESSION SET NLS_DATE_FORMAT = ‘DD-MON-YYYY HH24:MI:SS’;
SQL> SELECT APPLIED_TIME, APPLIED_SCN, MINING_TIME, MINING_SCN FROM V$LOGSTDBY_PROGRESS;

APPLIED_TIME 		 APPLIED_SCN 	MINING_TIME 			MINING_SCN
-------------------- -----------   -------------------- 	-----------
10-JAN-2005 12:00:05 346791023 		10-JAN-2005 12:10:05 	3468810134

主数据库的所有在APPLIED_SCN(或APPLIED_TIME)之前的提交的事务都已经应用到逻辑备数据库。挖掘引擎已经处理了所有在MINING_SCN(和MINING_TIME)之前产生的redo记录。在稳定的状态下,MINING_SCN(和MINING_TIME)总是在APPLIED_SCN(和APPLIED_TIME)的前面。


3.1.5.等待gap状态

这个状态发生在当SQL Apply已经挖掘和应用所有可用的redo记录,在等待新的日志文件(或缺失的日志文件)来通过RFS进程归档的时候。
SQL> SELECT STATUS FROM V$LOGSTDBY_PROCESS WHERE TYPE = ‘READER’;

STATUS
------------------------------------------------------------------------
ORA-16240: waiting for log file (thread# 1, sequence# 99)

3.1.6.空闲状态

一旦SQL Apply已经应用完主数据库产生的所有redo,它就进入到这个状态。
SQL> SELECT SESSION_ID, STATE FROM V$LOGSTDBY_STATE;

SESSION_ID  STATE
---------- -----------------
1           IDLE

3.2. 自动删除日志文件

外来的归档日志包含从主数据库传输来的redo。

有两种方式来存储外来的归档日志:
1)快速恢复区域
2)在快速恢复区域以外的目录

存储在快速恢复区域的外来归档日志由SQL Apply管理。包含在日志中的所有redo记录已经应用到逻辑备数据库后,它们会保留一段由参数DB_FLASHBACK_RETENTION_TARGET指定的时间(或如果参数DB_FLASHBACK_RETENTION_TARGET没有指定,则保留1440分钟)。不可以撤销自动管理存放在快速恢复区域中的外来归档日志。

不是存储在快速恢复区域的外来归档日志缺省由SQL Apply管理。在自动管理下,在日志包含的所有redo记录已经应用到逻辑备数据库后,不是存储在快速恢复区域的外来归档日志,保留一段由参数LOG_AUTO_DEL_RETENTION_TARGET指定的时间。可以执行以下PL/SQL存储过程取消自动管理不是存储在快速恢复区域中的外来归档日志。
SQL> EXECUTE DBMS_LOGSTDBY.APPLY_SET(‘LOG_AUTO_DELETE’, ‘FALSE’);

注:使用DBMS_LOGSTDBY.APPLY_SET存储过程来设置这个参数,如果不明确指定参数LOG_AUTO_DEL_RETENTION_TARGET,它缺省为逻辑备数据库设置的参数DB_FLASHBACK_RETENTION_TARGET的值,或者在DB_FLASHBACK_RETENTION_TARGET参数没有设置时为1440分钟。

如果撤消缺省的自动日志删除功能,定期执行以下步骤来发现和删除SQL Apply不再需要的归档redo日志文件:
1)执行以下PL/SQL语句来清除不需要的元数据的逻辑备会话:
SQL> EXECUTE DBMS_LOGSTDBY.PURGE_SESSION;
这条语句也更新视图DBA_LOGMNR_PURGED_LOG。

2)查询视图DBA_LOGMNR_PURGED_LOG来列出可以删除的归档redo日志文件:
SQL> SELECT * FROM DBA_LOGMNR_PURGED_LOG;

FILE_NAME
------------------------------------
/boston/arc_dest/arc_1_40_509538672.log
/boston/arc_dest/arc_1_41_509538672.log
/boston/arc_dest/arc_1_42_509538672.log
/boston/arc_dest/arc_1_43_509538672.log
/boston/arc_dest/arc_1_44_509538672.log
/boston/arc_dest/arc_1_45_509538672.log
/boston/arc_dest/arc_1_46_509538672.log
/boston/arc_dest/arc_1_47_509538672.log

3)使用操作系统的命令来删除查询列出的归档redo日志文件。


4.自定义逻辑备数据库

4.1.在视图DBA_LOGSTDBY_EVENTS中自定义事件记录

视图DBA_LOGSTDBY_EVENTS可以视为一个循环的日志,日志包含最近的发生在SQL Apply环境中有用的事件。
缺省情况下,最后的10,000个事件会记录在事件视图中。可以调用存储过程DBMS_LOGSTDBY.APPLY_SET更改记录的事件数量。例如,可以执行以下语句来确保最后的100,000事件会被记录。
SQL> EXECUTE DBMS_LOGSTDBY.APPLY_SET (‘MAX_EVENTS_RECORDED’, ‘100000’);

引起SQL Apply停止的错误会一直记录在DBA_LOGSTDBY_EVENTS视图中(除非SYSTEM表空间没有足够的空间)。这些事件也会存放到alert告警文件中,文本包含关键字LOGSTDBY。当查询视图时,通过EVENT_TIME,COMMIT_SCN和CURRENT_SCN排序来选择这些列。这样排序确保关闭故障显示在视图的最后。

下面的示例显示DBMS_LOGSTDBY子程序指定记录到视图中的事件。

示例1:确认DDL语句是否已经应用
例如,执行以下语句来记录应用DDL事务到DBA_LOGSTDBY_EVENTS视图中。
SQL> EXECUTE DBMS_LOGSTDBY.APPLY_SET (‘RECORD_APPLIED_DDL’, ‘TRUE’);

示例2:检查视图DBA_LOGSTDBY_EVENTS来确认逻辑备数据库不支持的操作
执行以下语句来捕获运行在主数据库上的逻辑备数据库不支持的事务信息
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;
SQL> EXEC DBMS_LOGSTDBY.APPLY_SET(‘RECORD_UNSUPPORTED_OPERATIONS’, ‘TRUE’);
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;

然后,检查DBA_LOGSTDBY_EVENTS视图来查看不支持的操作。一般情况下,在不支持的表上的操作会被SQL Apply安静地忽略。然而,在滚动升级过程(当备数据库在更高的版本,挖掘更低版本的主数据库产生的redo时),如果在主数据库执行不支持的操作,逻辑备数据库可能不是你想执行正常切换的数据库。Oracle Data Guard在视图DBA_LOGSTDBY_EVENTS中为每个表记录至少一条不支持的操作。


4.2. 使用DBMS_LOGSTDBY.SKIP来阻止更改特定的模式对象

缺省情况下,主数据库上所有支持的表都会复制到逻辑备数据库。

可以通过指定规则来略过应用特定的表的修改,从而更改缺省的行为。例如,为了忽略表HR.EMPLOYEES的更改,可以指定规则来阻止应用DML和DDL更改到特定的表。例如:
1)停止SQL Apply:
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;

2)注册SKIP规则:
SQL> EXECUTE DBMS_LOGSTDBY.SKIP (stmt => ‘DML’, schema_name => ‘HR’, object_name => ‘EMPLOYEES’);
SQL> EXECUTE DBMS_LOGSTDBY.SKIP (stmt => ‘SCHEMA_DDL’, schema_name => ‘HR’, object_name => ‘EMPLOYEES’);

3)启动SQL Apply:
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;


4.3. 为DDL语句设置Skip Handler

可以创建一个存储过程来拦截某些DDL语句和使用不同的语句替换原始的DDL语句。

例如,如果逻辑备数据库的文件系统结构与主数据库的不同,可以写一个DBMS_LOGSTDBY.SKIP存储过程来使用文件规范透明地处理DDL事务。

下面的步骤可以处理主备数据库之间不同的文件系统结构,只要为文件参数字符串使用特定的命名惯例。
1)创建SKIP存储过程来处理表空间DDL事务:

CREATE OR REPLACE PROCEDURE SYS.HANDLE_TBS_DDL (
  OLD_STMT IN VARCHAR2,
  STMT_TYP IN VARCHAR2,
  SCHEMA IN VARCHAR2,
  NAME IN VARCHAR2,
  XIDUSN IN NUMBER,
  XIDSLT IN NUMBER,
  XIDSQN IN NUMBER,
  ACTION OUT NUMBER,
  NEW_STMT OUT VARCHAR2
) AS
BEGIN
  -- All primary file specification that contains a directory
  -- /usr/orcl/primary/dbs
  -- should go to /usr/orcl/stdby directory specification
  NEW_STMT := REPLACE(OLD_STMT,'/usr/orcl/primary/dbs','/usr/orcl/stdby');
  ACTION := DBMS_LOGSTDBY.SKIP_ACTION_REPLACE;
EXCEPTION
  WHEN OTHERS THEN
    ACTION := DBMS_LOGSTDBY.SKIP_ACTION_ERROR;
    NEW_STMT := NULL;
END HANDLE_TBS_DDL;

c. 停止SQL Apply:
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;

d. 注册SKIP存储过程:
SQL> EXECUTE DBMS_LOGSTDBY.SKIP (stmt => ‘TABLESPACE’, proc_name => ‘sys.handle_tbs_ddl’);

e. 停止SQL Apply:
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;


4.4. 修改逻辑备数据库

逻辑备数据库可以用来做报告活动,即使在SQL语句正在应用的时候。

在逻辑备数据库中,Database guard控制用户对表的访问,语句ALTER SESSION DISABLE GUARD用来绕过database guard,允许在逻辑备数据库中修改表。

注:为了使用逻辑备数据库来存放其他应用程序,处理从主数据库复制过来的数据,同时创建属于它们自己的其他表,database guard必须设置为STANDBY。为了这些应用程序无缝地工作,确保PRESERVE_COMMIT_ORDER参数设置为TRUE(SQL Apply的缺省设置)。(参考Oracle Database PL/SQL Packages and Types Reference关于在DBMS_LOGSTDBY PL/SQL包的参数PRESERVE_COMMIT_ORDER的信息)
执行以下SQL语句来设置database guard为STANDBY:
SQL> ALTER DATABASE GUARD STANDBY;
在这个设置中,从主数据库复制的表被保护不允许用户更改,但在备数据库上创建的表可以被运行在逻辑备数据库的应用程序更改。

缺省时,逻辑备数据库以database guard设置为ALL来运行,这是最有限制性的设置,不允许任何用户对数据库执行更改。可以执行ALTER SESSION DISABLE GUARD撤销database guard,允许对逻辑备数据库更改。特权用户可以执行这个语句来为当前会话关闭database guard。

以下部分提供了一些示例。这些部分中的讨论假设database guard设置为ALL或STANDBY。


4.4.1. 在逻辑备数据库上执行DDL

可以增加约束到SQL Apply维护的表。

缺省时,当database guard设置为ALL或STANDBY时,只有具有SYS特权的账户可以修改数据库。如果以SYSDG,,SYSTEM,或其他特权账户登录,不可以在逻辑备数据库上执行DDL语句,除非先在会话中绕过database guard。

下面的示例显示如何停止SQL Apply,绕过database guard,在逻辑备数据库上执行SQL语句,然后重新启用guard。在这个示例中,探测索引(soundex index)被增加到姓氏列SCOTT.EMP来加速部分匹配查询。探测索引在主数据库上可能被禁止维护。

SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;
Database altered.

SQL> ALTER SESSION DISABLE GUARD;
PL/SQL procedure successfully completed.

SQL> CREATE INDEX EMP_SOUNDEX ON SCOTT.EMP(SOUNDEX(ENAME));
Table altered.

SQL> ALTER SESSION ENABLE GUARD;
PL/SQL procedure successfully completed.

SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;
Database altered.

SQL> SELECT ENAME,MGR FROM SCOTT.EMP WHERE SOUNDEX(ENAME) = SOUNDEX(‘CLARKE’);

ENAME 			MGR
---------- ----------
CLARK 			7839

Oracle建议当绕过database guard启用时,不要在SQL Apply维护的表上执行DML操作。这样做会影响主备数据库的偏离,让逻辑备数据库不可能被维护。


4.4.2. 修改不是SQL Apply维护的表

有时,报告应用程序必须收集统计结果和临时存储它们或跟踪报告运行的次数。虽然应用程序的主要目的是执行报告活动,应用程序也许需要在逻辑备数据库上执行DML(插入,更新和删除)操作。它可能需要创建或删除表。可以设置database guard来允许报告操作更改数据,只要数据不是由SQL Apply正在维护。

分两个步骤来实现对不是SQL Apply维护的表进行更改:
1)在逻辑备数据库上执行存储过程DBMS_LOGSTDBY.SKIP指定一组应用程序可以写数据的表。忽略的表不会被SQL Apply维护。
2)设置database guard只保护备表。

在下面的示例中,假设报告写的表也在主数据库上。

示例停止SQL Apply,忽略需要修改的表,重新启动SQL Apply。报告应用程序写到模式HR的对象TESTEMP%。这些表不再由SQL Apply维护。

SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;
Database altered.

SQL> EXECUTE DBMS_LOGSTDBY.SKIP(stmt => ‘SCHEMA_DDL’,schema_name => ‘HR’, object_name => ‘TESTEMP%’);
PL/SQL procedure successfully completed.

SQL> EXECUTE DBMS_LOGSTDBY.SKIP(‘DML’,‘HR’,‘TESTEMP%’);
PL/SQL procedure successfully completed.

SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;
Database altered.

一旦SQL Apply启动,它需要为增加到skip规则的新指定的表更新备数据库上的元数据。

在SQL Apply有机会更新元数据之前,尝试更改新忽略的表会失败。执行以下查询,可以确认SQL Apply是否已经成功将刚增加的SKIP规则考虑在内:
SQL> SELECT VALUE FROM SYSTEM.LOGSTDBY$PARAMETERS WHERE NAME = ‘GUARD_STANDBY’;

VALUE
---------------
Ready

当VALUE值显示为Ready时,SQL Apply已经成功为略过的表更新所有相关的元数据,可以安全地修改表。


4.5. 在逻辑备数据库上增加或重建表

一般情况下,使用DBMS_LOGSTDBY.INSTANTIATE_TABLE存储过程在无法恢复的操作后重建表。

也可以使用这个存储过程来为之前跳过的表启用SQL Apply。

在创建表前,必须满足“确保主数据库的表行可以被唯一区别”章节描述的要求。然后,可以使用以下步骤来重建表HR.EMPLOYEES和恢复SQL Apply。指令假设已经存在一个定义来访问主数据库的链接BOSTON。

1)停止SQL Apply:
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;

2)查询视图DBA_LOGSTDBY_SKIP,确保有问题的表没有操作正在被忽略:
SQL> SELECT * FROM DBA_LOGSTDBY_SKIP;

ERROR STATEMENT_OPT OWNER   NAME 
----- ------------ ----- -----------
N     SCHEMA_DDL     HR  EMPLOYEES
N     DML            HR  EMPLOYEES
N     SCHEMA_DDL     OE TEST_ORDER
N     DML            OE TEST_ORDER

因为在逻辑备数据库上已经有SKIP规则与想重建的表相关联,必须首先删除这些规则。可以调用DBMS_LOGSTDBY.UNSKIP存储过程来完成。例如:
SQL> EXECUTE DBMS_LOGSTDBY.UNSKIP(stmt => ‘DML’, schema_name => ‘HR’, object_name => ‘EMPLOYEES’);
SQL> EXECUTE DBMS_LOGSTDBY.UNSKIP(stmt => ‘SCHEMA_DDL’, schema_name => ‘HR’, object_name => ‘EMPLOYEES’);

3) 在逻辑备数据库使用它所有的数据来重建表HR.EMPLOYEES。例如:
SQL> EXECUTE DBMS_LOGSTDBY.INSTANTIATE_TABLE(schema_name => ‘HR’, table_name => ‘EMPLOYEES’, dblink => ‘BOSTON’);

4)启动SQL Apply:
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;

为了确保新实例化的表和数据库的其余数据有一个一致性的视图,在查询表之前等待SQL Apply追上主数据库。可以执行以下步骤来确认:
1)在主数据库上,确认当前的SCN:
SQL> SELECT CURRENT_SCN FROM V$DATABASE@BOSTON;

CURRENT_SCN
---------------------
345162788

2)确保SQL Apply已经应用所有在CURRENT_SCN之前提交的事务:
SQL> SELECT APPLIED_SCN FROM V$LOGSTDBY_PROGRESS;

APPLIED_SCN
--------------------------
345161345

当查询返回的APPLIED_SCN大于前面查询中返回的CURRENT_SCN时,可以安全地查询新重建的表。


5.管理逻辑备数据库环境下特定的负载

5.1. 导入可传输的表空间到主数据库

可传输的表空间可以导入到主数据库。

执行以下步骤:
1)禁用database guard设置从而可以修改逻辑备数据库:
SQL> ALTER DATABASE GUARD STANDBY;

2)在逻辑备数据库导入表空间。

3)启用database guard设置:
SQL> ALTER DATABASE GUARD ALL;

4)在主数据库导入表空间。


5.2. 使用物化视图

逻辑备数据库自动跳过与物化视图有关的DDL语句。

例如,逻辑备数据库跳过下面的语句:
1)CREATE,ALTER,或DROP MATERIALIZED VIEW
2)CREATE,ALTER,或DROP MATERIALIZED VIEW LOG

在逻辑备数据库已经创建之后在主数据库上创建,修改,或删除的新的物化视图不会在逻辑备数据库上创建。然而,在逻辑备数据库创建之前在主数据库上创建的物化视图存在于逻辑备数据库上。

逻辑备数据库支持本地创建和维护新的物化视图,除了其他种类的辅助数据结构之外。例如,OLTP系统为了更新性能会频繁地使用高度标准化(normalized)的表,但这些会导致复杂决策支持查询的响应时间缓慢。为了在逻辑备数据库上有更高效的查询支持,非标准化(denormalize)复制的数据的物化视图可以被创建,如下(在执行以下语句前以SYS用户连接):
SQL> ALTER SESSION DISABLE GUARD;

SQL> CREATE MATERIALIZED VIEW LOG ON SCOTT.EMP WITH ROWID (EMPNO, ENAME, MGR, DEPTNO) INCLUDING NEW VALUES;

SQL> CREATE MATERIALIZED VIEW LOG ON SCOTT.DEPT WITH ROWID (DEPTNO, DNAME) INCLUDING NEW VALUES;

SQL> CREATE MATERIALIZED VIEW SCOTT.MANAGED_BY REFRESH ON DEMAND ENABLE QUERY REWRITE AS SELECT E.ENAME, M.ENAME AS MANAGER FROM SCOTT.EMP E, SCOTT.EMP M WHERE E.MGR=M.EMPNO;

SQL> CREATE MATERIALIZED VIEW SCOTT.IN_DEPT REFRESH FAST ON COMMIT ENABLE QUERY REWRITE AS SELECT E.ROWID AS ERID, D.ROWID AS DRID, E.ENAME, D.DNAME FROM SCOTT.EMP E, SCOTT.DEPT D WHERE E.DEPTNO=D.DEPTNO;

在逻辑备数据库上:
1)ON-COMMIT物化视图会在事务提交发生时在逻辑备数据库上自动刷新。
2)ON-DEMAND物化视图不会自动刷新:必须执行DBMS_MVIEW.REFRESH存储过程来刷新。

例如,执行以下命令来刷新在前面示例中创建的ON-DEMAND物化视图:
SQL> ALTER SESSION DISABLE GUARD;
SQL> EXECUTE DBMS_MVIEW.REFRESH (LIST => ‘SCOTT.MANAGED_BY’, METHOD => ‘C’);

如果DBMS_SCHEDULER工作被使用来定期刷新ON-DEMAND物化视图,database guard必须设置为STANDBY。(不可能在PL/SQL块中使用ALTER SESSION DISABLE GUARD语句和让它生效。)


5.3. 在逻辑备数据库上的触发器和约束如何处理

缺省情况下,触发器和约束会在逻辑备数据库上自动启用和处理。

对于由SQL Apply维护的表的触发器和约束:
1)约束—–检查约束会在主数据库上估值,不需要在逻辑备数据库上重新估值
2)触发器—在主数据库上执行触发器的效果会记录和应用到备数据库上。

对于不是SQL Apply维护的表的触发器和约束:
1)约束会估值
2)触发器会触发


5.4. 使用触发器来复制不支持的表

在表上创建的DML触发器的参数DBMS_DDL.SET_TRIGGER_FIRING_PROPERTY fire_once缺省时设置为TRUE。

触发器只有在表被用户进程修改时才触发。在SQL Apply进程中,它们会自动被禁用,因此SQL Apply进程修改表时不会触发。作为SQL Apply进程更改维护的表的结果,存在两种方法来触发触发器:
1)设置触发器的参数fire_once为FALSE,允许它在用户进程或SQL Apply进程的环境中触发
2)设置apply_server_onl参数为TRUE,导致触发器只有在SQL Apply进程的环境中触发,在用户进程的环境中不触发。

fire_onceapply_server_only描述
TRUEFLASE这是DML触发器缺省的属性设置。触发器只有在用户进程修改基础表时触发。
FALSEFALSE触发器在用户进程和SQL Apply进程修改基础表的环境中触发。可以使用DBMS_LOGSTDBY.IS_APPLY_SERVER函数区分这两种环境。
TRUE/FALSETRUE触发器只有在SQL Apply进程修改基础表时触发。触发器在用户进程修改基础表时不触发。因此属性apply_server_only覆写触发器的参数fire_once。

由于简单对象类型列而不支持的表,可以通过创建在SQL Apply环境中触发的触发器来复制(设置触发器的参数fire_once为FALSE或设置触发器的apply_server_only参数为TRUE)。可以在主数据库上使用普通的DML触发器来flatten对象类型到可以支持的表。在逻辑备数据库上SQL Apply环境中触发的触发器重组对象类型,以事务的方式更新不支持的表。

下面的示例显示具有简单对象类型的表如何使用触发器来复制。示例显示如何处理插入;相同的规则可以应用到更新和删除。嵌套表和VARRAY也可以使用这种技术和标准化嵌套数据的循环的额外步骤来复制。

-- simple object type
create or replace type Person as object
(
  FirstName varchar2(50),
  LastName varchar2(50),
  BirthDate Date
)

-- unsupported object table
create table employees
(
  IdNumber varchar2(10) ,
  Department varchar2(50),
  Info Person
)

-- supported table populated via trigger
create table employees_transfer
(
  t_IdNumber varchar2(10),
  t_Department varchar2(50),
  t_FirstName varchar2(50),
  t_LastName varchar2(50),
  t_BirthDate Date
)

--
-- create this trigger to flatten object table on the primary
-- this trigger will not fire on the standby
--
create or replace trigger flatten_employees
  after insert on employees for each row
declare
begin
  insert into employees_transfer
    (t_IdNumber, t_Department, t_FirstName, t_LastName, t_BirthDate)
  values
(:new.IdNumber, :new.Department, :new.Info.FirstName,:new.Info.LastName, :new.Info.BirthDate);
end


--
-- Option#1 (Better Option: Create a trigger and
-- set its apply-server-only property to TRUE)
-- create this trigger at the logical standby database
-- to populate object table on the standby
-- this trigger only fires when apply replicates rows
-- to the standby
--
create or replace trigger reconstruct_employees_aso
  after insert on employees_transfer for each row
begin
  insert into employees (IdNumber, Department, Info)
  values (:new.t_IdNumber, :new.t_Department,
  Person(:new.t_FirstName, :new.t_LastName, :new.t_BirthDate));
end
-- set this trigger to fire from the apply server
execute dbms_ddl.set_trigger_firing_property(trig_owner => 'scott', trig_name => 'reconstruct_employees_aso', property => dbms_ddl.apply_server_only, setting => TRUE);


--
-- Option#2 (Create a trigger and set
-- its fire-once property to FALSE)
-- create this trigger at the logical standby database
-- to populate object table on the standby
-- this trigger will fire when apply replicates rows to -- the standby, but we will need to make sure we are
-- are executing inside a SQL Apply process by invoking
-- dbms_logstdby.is_apply_server function
--
create or replace trigger reconstruct_employees_nfo
  after insert on employees_transfer for each row
begin
  if dbms_logstdby.is_apply_server() then
    insert into employees (IdNumber, Department, Info)
    values (:new.t_IdNumber, :new.t_Department,
              Person(:new.t_FirstName, :new.t_LastName, :new.t_BirthDate));
   end if;
end
-- set this trigger to fire from the apply server
execute dbms_ddl.set_trigger_firing_property(trig_owner => 'scott', trig_name => 'reconstruct_employees_nfo', property => dbms_ddl.fire_once, setting => FALSE);

5.5.在主数据库执行时间点恢复

当逻辑备数据库收到新的redo数据分支时,SQL Apply自动处理新分支的redo数据。

对于逻辑备数据库,如果备数据库没有应用超过新resetlogs SCN的redo数据(超过redo数据新分支的起点),不需要进行人工干预。

下表描述了如何让备数据库与主数据库分支同步。

如果备数据库…那么…执行这些步骤…
没有应用超过新resetlogs SCN(超过redo数据新分支起点)的redo数据SQL Apply自动处理新分支的redo数据不需要人工干预。SQL Apply使用新分支的redo数据自动同步备数据库。
已经应用超过新resetlogs SCN(超过redo数据新分支起点)的redo数据和闪回数据库已经在备数据库上启用备数据库恢复到redo数据新分支的未来1.闪回逻辑备数据库到特定的时间点。
2.重启SQL Apply来继续应用redo数据到新的resetlogs分支。
已经应用超过新resetlogs SCN(超过redo数据新分支起点)的redo数据和闪回数据库没有在备数据库上启用主数据库与备数据库在指定的主数据库分支上偏离重建逻辑备数据库
缺失从之前分支的redo数据末尾开始的归档redo日志文件SQL Apply不能继续直到找回缺失的日志文件找到和注册来自之前分支的缺失的归档redo日志文件

5.6. 在逻辑备数据库上运行Oracle流捕获进程

可以在逻辑备数据库上运行Oracle流捕获进程(Oracle Streams capture process)来捕获存在于逻辑备数据库上的任何表的更改(不管它是一个本地表还是正在从主数据库复制的一个被维护的表)。

当捕获到被维护的表的更改时,跟运行在主数据库上的Oracle流捕获进程相比,存在额外的延迟。额外的延迟是由于在逻辑备数据库时,Oracle流捕获进程必须等待更改从主数据库传输到逻辑备数据库和被SQL Apply应用。在大部分情况下,如果运行实时应用,不会超过几秒钟。

Oracle流捕获进程与创建它的数据库关联;与数据库的角色无关。例如,假设有一个主数据库名为Boston和一个逻辑备数据库名为London。不可以在角色转换时,从一个数据库移动Oracle流捕获进程到其他数据库。例如,如果在逻辑备数据库London上创建Oracle流捕获进程,那么它一直在London上,即使London作为角色转换操作的结果(例如swichover或failover)成为主数据库。为了让Oracle流捕获进程在角色转换后继续工作,必须写一个角色转换触发器,比如以下:

create or replace trigger streams_aq_job_role_change1
after DB_ROLE_CHANGE on database
declare
cursor capture_aq_jobs is
  select job_name, database_role
  from dba_scheduler_job_roles
  where job_name like 'AQ_JOB%';
u capture_aq_jobs%ROWTYPE;
my_db_role varchar2(16);

begin
  if (dbms_logstdby.db_is_logstdby() = 1) then my_db_role := 'LOGICAL STANDBY';
  else my_db_role := 'PRIMARY';
  end if;

open capture_aq_jobs;
loop
  fetch capture_aq_jobs into u;
  exit when capture_aq_jobs%NOTFOUND;

  if (u.database_role != my_db_role) then
    dbms_scheduler.set_attribute(u.job_name,'database_role', my_db_role);
  end if;
end loop;
close capture_aq_jobs;

exception
  when others then
  begin
    raise;
  end;
end;

6.调优逻辑备数据库

6.1. 创建主键依赖约束

在主数据库上,如果一个表不存在主键或唯一索引和你确定行是唯一的,那么可以创建一个主键RELY约束。

在逻辑备数据库上,在组成主键的列上创建索引。下面的查询产生一系列表,这些表没有索引信息可以被逻辑备数据库使用来唯一识别行。通过在下面的表上创建索引,性能可以显著地改善。

SQL> SELECT OWNER, TABLE_NAME FROM DBA_TABLES WHERE OWNER NOT IN (SELECT OWNER FROM DBA_LOGSTDBY_SKIP WHERE STATEMENT_OPT = ‘INTERNAL SCHEMA’) MINUS SELECT DISTINCT TABLE_OWNER, TABLE_NAME FROM DBA_INDEXES WHERE INDEX_TYPE NOT LIKE (‘FUNCTION-BASED%’) MINUS SELECT OWNER, TABLE_NAME FROM DBA_LOGSTDBY_UNSUPPORTED;

可以在主数据库上增加一个主键依赖约束到表,如下所示:
1)在主数据库增加主键依赖约束:
SQL> ALTER TABLE HR.TEST_EMPLOYEES ADD PRIMARY KEY (EMPNO) RELY DISABLE;

这确保列EMPNO用来唯一识别表HR.TEST_EMPLOYEES的行,作为表上所做的任何更新的一部分,补充地记录下来。

注意表HR.TEST_EMPLYEES在逻辑备数据库上依旧没有指定唯一索引。这可能会导致UPDATE语句在逻辑备数据库上去做全表扫描。可以在逻辑备数据库上通过增加唯一索引来补救。
参考章节“确保主数据库的表行可以被唯一区别”关于RELY约束的描述。

2)停止SQL Apply:
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;

3)禁用guard,从而可以修改逻辑备数据库上的被维护表:
SQL> ALTER SESSION DISABLE GUARD;

4)在列EMPNO上增加唯一索引:
SQL> CREATE UNIQUE INDEX UI_TEST_EMP ON HR.TEST_EMPLOYEES (EMPNO);

5)启用guard:
SQL> ALTER SESSION ENABLE GUARD;

6)启用SQL Apply:
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;


6.2. 在逻辑备数据库上收集数据

在逻辑备数据库上使用STATS 包和视图 V$SYSSTAT 确认哪些表消耗大部分资源和表扫描。


6.3. 调整进程的数量

有3个参数可以被修改来控制分配给SQL Apply的进程数量:MAX_SERVERS,APPLY_SERVERS,和PREPARE_SERVERS。

下面的关系必须总是适用的:
1)APPLY_SERVERS + REPARE_SERVERS = MAX_SERVERS -3

因为SQL Apply总是分别为READER,BUILDER,和ANALYZER角色分配一个进程。

2)缺省时,MAX_SERVERS设置为9,PREPARE_SERVERS设置为1,和APPLY_SERVERS设置为5。

3)Oracle建议通过DBMS_LOGSTDBY.APPLY_SET存储过程只更改MAX_SERVERS参数,允许SQL Apply在PREPARE和APPLY进程之间合理地分配服务器进程。

4)SQL Apply使用进程分配算法来为分配给SQL Apply的每20个服务器进程(由MAX_SERVERS指定)分配1个PREPARE_SERVER进程和限制PREPARE_SERVERS的数量为5。因此,如果设置MAX_SERVERS为1和20之间的任意值,SQL Apply分配1个服务器进程来担任PREPARER,在满足前面描述的关系后,分配剩余的进程为APPLIERS。相似地,如果设置MAX_SERVERS的值在21和24之间,SQL Apply分配2个服务器进程来担任PREPARERS,在满足前面描述的关系后,分配剩余的进程为APPLIERS。只要前面描述的关系满足时,可以通过直接设置APPLY_SERVERS和PREPARE_SERVERS来覆盖内部的进程分配算法。


6.3.1.调整APPLIER进程的数量

在调整APPLIER进程的数量之前,应该确认这样做是否会帮助获得更高的吞吐量。

为了确认这个,执行以下步骤:
1)执行以下查询检查APPLIER进程是否繁忙:
SQL> SELECT COUNT(*) AS IDLE_APPLIER FROM V$LOGSTDBY_PROCESS WHERE TYPE = ‘APPLIER’ and status_code = 16116;

IDLE_APPLIER
-------------------------
0

一旦确认不存在空闲的APPLIER进程,执行以下查询来确保如果选择调整APPLIERS进程的数量,存在足够的可用工作来使用额外的APPLIER进程。
SQL> SELECT NAME, VALUE FROM V$LOGSTDBY_STATS WHERE NAME = ‘txns applied’ OR NAME
= ‘distinct txns in queue’;

这两个统计数字存放准备被APPLIER进程应用的累积的事务总数和和已经被应用的事务数量。
如果数字(distinct txns in queue – txns applied)高于2倍的可用APPLIER进程数量,增加APPLIER进程的数量可能会带来吞吐量的提升。

假设想调整APPLIER进程的数量从缺省的5到20,同时保持PREPARER进程的数量为1。由于需要满足以下等式:
APPLY_SERVERS + REPARE_SERVERS = MAX_SERVERS -3
必须首先设置MAX_SERVERS为24。一旦完成后,就可以设置APPLY_SERVERS的数量为20,如下所示:
SQL> EXECUTE DBMS_LOGSTDBY.APPLY_SET(‘MAX_SERVERS’, 24);
SQL> EXECUTE DBMS_LOGSTDBY.APPLY_SET(‘APPLY_SERVERS’, 20);


6.3.2.调整PREPARER进程的数量

需要调整PREPARER进程的数量是比较少见的。在增加它们的数量前,必须确保某些条件为真,如下所示:
1)所有PREPARER进程很繁忙;
2)准备应用的事务数量比可用的APPLIER进程少;
3)存在空闲的APPLIER进程。

下面的步骤显示如何确认这些条件为真:
1)确认所有REPARER进程繁忙:
SQL> SELECT COUNT(*) AS IDLE_PREPARER FROM V$LOGSTDBY_PROCESS WHERE TYPE = ‘PREPARER’ and status_code = 16116;

IDLE_PREPARER
-------------
0

2)确认准备应用的事务数量比可用的APPLIER进程少;
SQL> SELECT NAME, VALUE FROM V$LOGSTDBY_STATS WHERE NAME = ‘txns applied’ OR NAME = ‘distinct txns in queue’;

NAME                    VALUE
--------------------- -------
txns applied           27892
distinct txns in queue 12896

SQL> SELECT COUNT(*) AS APPLIER_COUNT FROM V$LOGSTDBY_PROCESS WHERE TYPE = ‘APPLIER’;

APPLIER_COUNT
-------------
20

注:执行查询几次来确保这不是瞬时的事件。

3)确保存在空闲的APPLIER进程:
SQL> SELECT COUNT(*) AS IDLE_APPLIER FROM V$LOGSTDBY_PROCESS WHERE TYPE = ‘APPLIER’ and status_code = 16116;

IDLE_APPLIER
-------------------------
19

在这个例子中,为增加PREPARER进程数量的所有3个必要条件都满足。假设想保持APPLIER进程的数量为20,和增加PREPARER进程的数量从缺省的1到3。由于需要满足以下等式:
APPLY_SERVERS + REPARE_SERVERS = MAX_SERVERS -3
必须首先增加MAX_SERVERS从24到26来容纳增加的PREPARER进程。然后就可以增加PREPARER进程的数量,如下所示:
SQL> EXECUTE DBMS_LOGSTDBY.APPLY_SET(‘MAX_SERVERS’, 26);
SQL> EXECUTE DBMS_LOGSTDBY.APPLY_SET(‘PREPARE_SERVERS’, 3);


6.4.调整LCR(logical change records)缓存使用的内存

对于某些负载,SQL Apply可能会使用大量的页出操作,因此,减少系统总体的吞吐量。增加分配给LCR缓存的内存可能会有所帮助。

执行以下步骤,确认增加分配给LCR缓存的内存是否是有益的:
1)执行以下查询来获取页出活动的快照:
SQL> SELECT NAME, VALUE FROM V$LOGSTDBY_STATS WHERE NAME LIKE ‘%page%’ OR NAME LIKE ‘%uptime%’ OR NAME LIKE ‘%idle%’;

NAME 							VALUE
---------------------------- --------------
coordinator uptime (seconds) 	894856
bytes paged out 				20000
pageout time (seconds) 			2
system idle time (seconds) 		1000

2)5分钟后再次执行查询:
SQL> SELECT NAME, VALUE FROM V$LOGSTDBY_STATS WHERE NAME LIKE ‘%page%’ OR NAME LIKE ‘%uptime%’ OR NAME LIKE ‘%idle%’;

NAME 							VALUE
---------------------------- --------------
coordinator uptime (seconds) 	895156
bytes paged out 				1020000
pageout time (seconds) 			100
system idle time (seconds) 		1000

3)计算标准化的页出活动。例如:
Change in coordinator uptime ©= (895156 – 894856) = 300 secs
Amount of additional idle time (I)= (1000 – 1000) = 0
Change in time spent in pageout § = (100 – 2) = 98 secs
Pageout time in comparison to uptime = P/(C-I) = 98/300 ~ 32.67%

理想情况下,页出活动应该不要消耗多于5%的总运行时间。如果继续在持续的间隔里拍快照,发现页出活动继续消耗相当部分的应用时间,增加内存大小可能会提供某些好处。可以通过设置分配给LCR缓存的内存来增加分配给SQL Apply的内存(这个示例中,SGA设置为1GB):
SQL> EXECUTE DBMS_LOGSTDBY.APPLY_SET(‘MAX_SGA’, 1024);
PL/SQL procedure successfully completed


6.5. 调整事务如何在逻辑备数据库上应用

缺省时,事务在逻辑备数据库上按照在主数据库上提交的精确的顺序被应用。

这种严格的提交事务的缺省顺序允许任何应用程序在逻辑备数据库上透明地运行。

然而,许多应用程序在所有事务当中不需要如此严格的排序。这些应用程序不需要包含不重叠的行集的事务按照与主数据库上相同的提交顺序提交。这种较不严格的排序通常会在逻辑备数据库上带来更高的应用速度。执行以下步骤可以更改提交事务的缺省顺序:
1)停止SQL Apply:
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;

2)执行以下命令允许事务不按照在主数据库上提交的顺序应用:
SQL> EXECUTE DBMS_LOGSTDBY.APPLY_SET(‘PRESERVE_COMMIT_ORDER’, ‘FALSE’);

3)启动SQL Apply:
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;

使用以下步骤更改回应用模式:
1)停止SQL Apply:
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;

2)恢复参数PRESERVE_COMMIT_ORDER的缺省值:
SQL> EXECUTE DBMS_LOGSTDBY.APPLY_UNSET(‘PRESERVE_COMMIT_ORDER’);

3)启动SQL Apply:
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;

对于典型的在线事务处理(OLTP)负载,不是缺省的模式对比缺省的模式可以提供50%或更高的吞吐量提升。


7.逻辑备数据库环境下的备份和恢复

可以使用传统的可用方法来备份逻辑备数据库,然后通过还原数据库备份和与备份结合在归档日志上执行介质恢复来恢复数据库。

下面的项目在逻辑备数据库的环境下是相关的。

创建和使用本地RMAN恢复目录时的考虑
如果计划创建RMAN恢复目录或执行任何修改恢复目录的RMAN活动,必须在逻辑备数据库上设置GUARD为STANDBY。
如果本地恢复目录只保留在逻辑备数据库的控制文件中,可以让GUARD设置为ALL。

控制文件备份的考虑
Oracle建议在实例化逻辑备数据数据库后立即备份控制文件。

时间点恢复考虑
当SQL Apply在时间点恢复后第一次启动时,必须可以在本地系统上找到要求的归档日志或从主数据库上获取。使用V$LOGSTDBY_PROCESS视图来确认主数据库上是否有任何需要还原的归档日志。

表空间时间点恢复考虑
如果在逻辑备数据库上执行表空间的时间点恢复,必须确保满足以下条件中的一个:
1)表空间不包含由SQL Apply进程正在维护的表或分区
2)如果表空间包含由SQL Apply进程正在维护的表或分区,那么使用DBMS_LOGSTDBY.INSTANTIATE_TABLE存储过程在逻辑备数据库上重新实例化所有包含在恢复表空间的维护的表,或使用DBMS_LOGSTDBY.SKIP存储过程注册所有包含在恢复表空间的表,在逻辑备数据库上从维护表列表中跳过这些表。


8.主数据库执行Open Resetlogs语句后闪回数据库

如果在Oracle Data Guard环境的主数据库发生一个错误,备数据库正在使用实时应用,那么相同的错误也会应用到备数据库。如果闪回数据库已启用,可以复原主数据库和备数据库到错误之前的状态。

为了这些做,在主数据库上执行FLASHBACK DATABASE和OPEN RESETLOGS语句,然后在重启Apply Service之前,在备数据库上执行相应的FLASHBACK STANDBY DATABASE语句。如果闪回数据库没有启用,那么在主数据库上执行时间点恢复之后,需要重建备数据库。

8.1. 闪回逻辑备数据库到指定时间点

这些步骤描述如何闪回主数据库和使用OPEN RESETLOGS语句打开它后避免重建逻辑备数据库。

注:如果SQL Apply检测到主数据库resetlogs操作的发生,如果可能这么做而不需要闪回逻辑备数据库,它会自动挖掘正确的redo分支。否则,SQL Apply会停止和报错“ORA-1346: LogMiner processed redo beyond specified reset log scn”。在这个部分中,假设SQL Apply已经停止和有这个报错。

1)在主数据库上,使用以下查询来获取主数据库在RESETLOGS操作发生前2个SCN的SCN值:
SQL> SELECT TO_CHAR(RESETLOGS_CHANGE# - 2) AS FLASHBACK_SCN FROM V$DATABASE;

2)在逻辑备数据库上,确认闪回操作的目标SCN。
SQL> SELECT DBMS_LOGSTDBY.MAP_PRIMARY_SCN (PRIMARY_SCN => FLASHBACK_SCN) AS TARGET_SCN FROM DUAL;

3)执行下面的SQL语句来闪回逻辑备数据库到指定的SCN,然后使用RESETLOGS选项打开逻辑备数据库:
SQL> SHUTDOWN;
SQL> STARTUP MOUNT EXCLUSIVE;
SQL> FLASHBACK DATABASE TO SCN <TARGET_SCN>;
SQL> ALTER DATABASE OPEN RESETLOGS;

4) 在SQL启动之前确认来自主数据库新分支的日志文件已经注册。

在主数据库执行以下查询:
SQL> SELECT resetlogs_id FROM V$DATABASE_INCARNATION WHERE status = ‘CURRENT’;

在备数据库上执行以下查询:
SQL> SELECT * FROM DBA_LOGSTDBY_LOG WHERE resetlogs_id = resetlogs_id_at_primary;

如果返回一行或多行,它确认存在注册的来自主数据库新分支的日志文件。

1) 启动SQL Apply:
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;


9. 主数据库指定NOLOGGING子语句以后恢复

有些SQL语句允许指定NOLOGGING子语句,因此操作就不会记录在在线redo日志文件中。

实际上,redo记录仍然会写到在线redo日志文件,但没有数据与记录关联。这将导致备站点上的日志应用程序或数据访问错误,可能需要手动恢复来重新开始applying日志文件。

9.1. 在逻辑备数据库上的恢复步骤

在逻辑备数据库上,当SQL Apply遇到在表上执行NOLOGGING子语句的操作的redo记录时,它会停止和报以下错误:
ORA-16211 unsupported record found in the archived redo log

为了在指定的NOLOGGING子语句之后进行恢复,按照章节“在逻辑备数据库上增加或重建表”所描述的方法,重建来自主数据库的一个或多个表。

注:一般情况下,使用NOLOGGING子语句是不建议的。因此,如果你提前知道使用NOLOGGING子语句的操作会在主数据库的某些表上执行,那么你可能想阻止应用与这些表相关的SQL语句到逻辑备数据库。可以通过使用DBMS_LOGSTDBY.SKIP存储过程来实现。




来源:《Oracle Data Guard Concepts and Administration, 19c》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/380444.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Apache Airflow Provider Sqoop 模块远程代码执行漏洞

漏洞描述 Apache Airflow 是一个以编程方式管理 workflow 的平台&#xff0c;Sqoop 模块用于在 Hadoop 和结构化数据存储&#xff08;例如关系数据库&#xff09;之间高效传输大量数据。 apache-airflow-providers-apache-sqoop 3.1.1 之前版本中&#xff0c;由于 SqoopHook …

【ONE·C || 自定义类型:结构体、段位、枚举、联合】

总言 C语言&#xff1a;自定义类型介绍。 文章目录总言1、结构体1.1、结构体声明1.1.1、基本声明方式1.1.2、特殊的声明&#xff1a;不完全声明1.2、结构体自引用1.2.1、结构体自引用说明1.2.2、typdef对结构体重命名1.3、结构体变量的定义和初始化1.4、结构体变量大小计算&…

VMware虚拟机安装Ubuntu(超详细图文教程)

VMware虚拟机安装Ubuntu&#xff08;超详细图文教程&#xff09; 1、Ubuntu下载 Ubuntu下载地址&#xff1a;点这里 注&#xff1a;但官网下载比较慢 也可关注公众号Time木回复&#xff1a; ubuntu22 获取 2、打开VMware VMware安装过程&#xff1a;待更新 2.1 创建新的虚…

5个面向开发人员的顶级报表工具

报表工具对有处理大量数据需求的公司至关重要。实际上&#xff0c;报表可以帮助公司实时访问公司资源&#xff0c;同时能够以可读和调整的格式分析和显示数据。本文为大家推荐五种成熟且强大的报表工具&#xff0c;重点介绍它们的功能和优势。 Stimulsoft Stimulsoft主要用于…

【安装教程】SSH远程连接工具-FinalShell的安装

&#x1f449;&#x1f449;&#x1f449;&#x1f449;&#x1f449;&#x1f449; 【目录在右侧哦~】省时间可以直接跳转到【安装步骤】 &#x1f449;&#x1f449;&#x1f449;&#x1f449;&#x1f449;&#x1f449;&#x1f449;一、软件介绍&#xff08;点我查看该软…

【python学习笔记】:环境搭建

Python 环境搭建 本章学习如何在本地搭建Python开发环境。 Python可应用于多平台包括 Linux 和 Mac OS X。 你可以通过终端窗口输入 "python" 命令来查看本地是否已经安装Python以及Python的安装版本。 Unix (Solaris, Linux, FreeBSD, AIX, HP/UX, SunOS, IRIX,…

「TCG 规范解读」PC 平台相关规范(3)

可信计算组织&#xff08;Ttrusted Computing Group,TCG&#xff09;是一个非盈利的工业标准组织&#xff0c;它的宗旨是加强在相异计算机平台上的计算环境的安全性。TCG于2003年春成立&#xff0c;并采纳了由可信计算平台联盟&#xff08;the Trusted Computing Platform Alli…

消息队列原理与实战-学习笔记

消息队列&#xff1a;保存消息的一个容器&#xff0c;本质是个队列&#xff0c;但是需要支持高吞吐、高并发、高可用。 1 前世今生 1.1 业界消息队列对比 Kafka:分布式的、分区的、多副本的日志提交服务&#xff0c;在高吞吐场景下发挥较为出色RocketMQ:低延迟、强一致、高性…

概率论与数理统计期末小题狂练 11-12两套,12-13-1

11-12第一学期A1 略。2 X服从正态分布N&#xff08;0&#xff0c;1&#xff09;&#xff0c;X^2服从卡方分布。又考查了卡方分布均值和方差公式。一开始如果对本题无从下手&#xff0c;大概是没看出来是什么分布。3 第二小空本身也可以作为一个结论。4 考查切比雪夫不等式&…

王道操作系统课代表 - 考研计算机 第三章 内存管理 究极精华总结笔记

本篇博客是考研期间学习王道课程 传送门 的笔记&#xff0c;以及一整年里对 操作系统 知识点的理解的总结。希望对新一届的计算机考研人提供帮助&#xff01;&#xff01;&#xff01; 关于对 “内存管理” 章节知识点总结的十分全面&#xff0c;涵括了《操作系统》课程里的全部…

装修的正确顺序是什么?

装修的正确顺序可以概括为以下几个步骤&#xff1a;1.设计阶段&#xff1a;根据你的需求和预算&#xff0c;设计师会提供多个方案供你选择&#xff0c;确定最终的设计方案。2.拆除阶段&#xff1a;清除室内所有旧的装修材料&#xff0c;包括地板、瓷砖、灯具、门窗等&#xff0…

Windows Server 2016搭建文件服务器

1&#xff1a;进入系统在服务器管理器仪表盘中添加角色和功能。 2&#xff1a;下一步。 3&#xff1a;继续下一步。 4&#xff1a;下一步。 5&#xff1a;勾选Web服务器(IIS) 6&#xff1a;添加功能。 7&#xff1a;下一步。 8&#xff1a;下一步。 9&#xff1a;下一步。 10&a…

视觉SLAM十四讲 ch3 (三维空间刚体运动)笔记

本讲目标 ●理解三维空间的刚体运动描述方式:旋转矩阵、变换矩阵、四元数和欧拉角。 ●学握Eigen库的矩阵、几何模块使用方法。 旋转矩阵、变换矩阵 向量外积 向量外积&#xff08;又称叉积或向量积&#xff09;是一种重要的向量运算&#xff0c;它表示两个向量所形成的平行…

2023你还不会稳定性测试?这篇文章彻底讲透了

稳定性对产品的重要性不言而喻。 而作为质量保障&#xff0c;在稳定性测试方面的探索也在不断演化。记得两年前我们做稳定性测试还是基于恒定的压力&#xff0c;7*24小时长时间运行&#xff0c;关注的指标无非是吞吐量TPS的抖动、响应时间的变化趋势&#xff0c;以及各种资源是…

浅浅谈一谈B树和B+树

目录: &#x1f680;1.B树 &#x1f680;2.B树 索引背后的数据结构是啥呢,是B树,是为了数据库索引设计的,我们可以先了解B树,再说B树 1.什么是B树 B树也叫B-树,这里的-不读减,是一个符号 我们已经学过了二叉搜素树,B树其实就是N叉搜素树,二叉搜索树只能在每一个结点放一个…

HCIP-5OSPF基本原理及基本配置学习笔记

1、OSPF基本原理 开放式最短路径优先OSPF&#xff08;Open Shortest Path First&#xff09;协议是IETF定义的一种基于链路状态的内部网关路由协议。 RIP是一种基于距离矢量算法的路由协议&#xff0c;存在着收敛慢、易产生路由环路、可扩展性差等问题&#xff0c;目前已逐渐被…

C++---最长上升子序列模型---合唱队形(每日一道算法2023.3.1)

注意事项&#xff1a; 本题为"线性dp—最长上升子序列的长度" 和 “最长上升子序列模型—怪盗基德的滑翔翼” 和 “最长上升子序列模型—登山” 的扩展题&#xff0c;所以dp思路这里就不再赘述。 题目&#xff1a; N位同学站成一排&#xff0c;音乐老师要请其中的 (…

【C++】构造函数(初始化列表)、explicit、 Static成员、友元、内部类、匿名对象

构造函数&#xff08;初始化列表&#xff09;前提构造函数体赋值初始化列表explicit关键字static成员概念特性&#xff08;重要&#xff09;有元友元函数友元类内部类匿名对象构造函数&#xff08;初始化列表&#xff09; 前提 前面 六个默认成员对象中我们已经学过什么是构造…

1.4 黑群晖安装:SataPortMap和DiskIdxMap两种获取方式

tinycore及安装工具下载&#xff1a;工具&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1CMLl6waOuW-Ys2gKZx7Jgg?pwdchct提取码&#xff1a;chcttinycore&#xff1a;链接&#xff1a;https://pan.baidu.com/s/19lchzLj-WDXPQu2cEcskBg?pwddcw2 提取码&#xff1a;d…

【博学谷学习记录】超强总结,用心分享丨人工智能 深度学习 神经网络基础知识点总结

目录神经网络激活函数引入激活函数原因&#xff1a;sigmoid激活函数tanh 激活函数ReLU 激活函数&#xff08;最常用&#xff09;SoftMax如何选择反向传播参数初始化方法优化方法正则化批量归一层网络模型调优的思路神经网络 简单的神经网络包括三层&#xff1a;输入层&#xf…