逻辑备库的定制
在逻辑备库上使用实时应用
默认大的dg等待全部的归档日志到达备库上,才开始应用到备库上,然而,如果你在逻辑备库上配置了standb redo日志,那么你可以启用实时应用,开启了实时应用,在日志填写到standby redo日志的时候,sql apply就开始应用redo数据,这个功能使备库与主库保持同步,可以快速的转换及故障转移,下面的命令是启用实时应用的。
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;
使用dbms_logstdby.skip来阻止对特定对象的改变
例如为了阻止hr.employees表的改变,你可以指定下面的规则来阻止dml和ddl对特定表的改变
1.Stop SQL Apply:
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;
2.Register the SKIP rules:
SQL> EXECUTE DBMS_LOGSTDBY.SKIP (stmt => 'DML', schema_name => 'HR', -
object_name => 'EMPLOYEES', proc_name => null);
SQL> EXECUTE DBMS_LOGSTDBY.SKIP (stmt => 'SCHEMA_DDL', schema_name => 'HR', -
object_name => 'EMPLOYEES', proc_name => null);
3.Start SQL Apply:
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;
修改逻辑备库
默认的,逻辑备库被设置成最受限制,不允许对数据库做任何用户的改变,可以通过执行alter session disable guard语句来改变设置。
在逻辑备库上执行ddl语句
下面描述怎么通过sql apply在维护的表上添加约束
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;
Database altered.
SQL> ALTER SESSION DISABLE GUARD;
PL/SQL procedure successfully completed.
SQL> ALTER TABLE SCOTT.EMP ADD CONSTRAINT EMPID UNIQUE (EMPNO);
Table altered.
SQL> ALTER SESSION ENABLE GUARD;
PL/SQL procedure successfully completed.
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY;
Database altered.
在主库上导入可传输的表空间
1.Disable the guard setting so that you can modify the logical standby database:
SQL> ALTER SESSION DISABLE GUARD;
2.Import the tablespace at the logical standby database.
3.Enable the database guard setting (or disconnect from the session):
SQL> ALTER SESSION ENABLE GUARD;
4.Import the tablespace at the primary database.
使用物化视图
sql apply不支持包含下面语句的物化视图
CREATE
, ALTER
, or DROP
MATERIALIZED VIEW
CREATE
, ALTER
, or DROP
MATERIALIZED VIEW LOG
因此在主库上的新建的,修改的,删除的物化视图不会反应到之前创建的逻辑备库上,然而,在逻辑备库创建之前的主库上的武汉视图在备库上也是存在的。
对存在主库和备库上的物化视图,on-commit事务视图在逻辑库上当事务提交的时候被刷新。on-demand物化视图不被sql apply自动刷新,必须执行dbms_mview.refresh来刷新他,在逻辑备库上刷新视图的例子:
SQL> EXECUTE DBMS_MVIEW.REFRESH ( LIST => 'HR.DEPARTMENTS_MV', METHOD => 'F');
在逻辑备库上创建的on-commit物化视图被自动维护,额外创建的on-demand物化视图不会被sql apply维护,必须使用dbms_mview.refresh.
逻辑备库上的触发器和约束怎么被处理
默认的触发器和约束在逻辑备库上自动被启用和处理
在逻辑备库上添加或重新创建表
下面的例子是重建一个叫hr.employees的表,假设已经存在了一个dblink叫boston来访问主库
The following list shows how to re-create a table and restart SQL Apply on that table:
Stop SQL Apply:
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;
Ensure no operations are being skipped for the table in question by querying the DBA_LOGSTDBY_SKIP
view:
SQL> SELECT * FROM DBA_LOGSTDBY_SKIP; ERROR STATEMENT_OPT OWNER NAME PROC ----- ------------------- ------------- ---------------- ----- N SCHEMA_DDL HR EMPLOYEES N DML HR EMPLOYEES N SCHEMA_DDL OE TEST_ORDER N DML OE TEST_ORDER
Because you already have skip rules associated with the table that you want to re-create on the logical standby database, you must first delete those rules. You can accomplish that by calling the DBMS_LOGSTDBY.UNSKIP
procedure. For example:
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');
Re-create the table HR.EMPLOYEES
with all its data in the logical standby database by using the DBMS_LOGSTDBY.INSTANTIATE_TABLE
procedure. For example:
SQL> EXECUTE DBMS_LOGSTDBY.INSTANTIATE_TABLE(shema_name => 'HR', - object-+_name => 'EMPLOYEES', - dblink => 'BOSTON');
Start SQL Apply:
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;
为了确保这个新表和别的库保持一致,等待sql apply赶上主库,你可以做下面的操作
V$DATABASE
view:SQL> SELECT CURRENT_SCN FROM V$DATABASE@BOSTON; CURRENT_SCN --------------------- 345162788
Make sure SQL Apply has applied all transactions committed before the CURRENT_SCN
returned in the previous query:
SQL> SELECT APPLIED_SCN FROM V$LOGSTDBY_PROGRESS; APPLIED_SCN -------------------------- 345161345
When the APPLIED_SCN
returned in this query is greater than the CURRENT_SCN
returned in the first query, it is safe to query the newly re-created table.
调优逻辑备库
创建一个主键rely约束
在主库上,如果一个表没有主键或是唯一索引,同时你确定行是唯一的,那么创建一个主键rely约束,在逻辑备库上,在主键列上创建一个索引。下面的查询时查询表上没有索引的表,这些表可以被逻辑备库用来应用唯一标记行。
SQL> SELECT OWNER, TABLE_NAME FROM DBA_TABLES 2> WHERE OWNER NOT IN('SYS','SYSTEM','OUTLN','DBSNMP') 3> MINUS 3> SELECT DISTINCT TABLE_OWNER, TABLE_NAME FROM DBA_INDEXES 4> WHERE INDEX_TYPE NOT LIKE ('FUNCTION-BASED%') 5> MINUS 6> SELECT OWNER, TABLE_NAME FROM DBA_LOGSTDBY_UNSUPPORTED;
You can add a rely primary key constraint to a table on the primary database, as follows:
Add the primary key rely constraint at the primary database
SQL> ALTER TABLE HR.TEST_EMPLOYEES ADD PRIMARY KEY (EMPNO) RELY DISABLE; SQL> ALTER SESSION DISABLE GUARD;
This will ensure that the EMPNO
column, which can be used to uniquely identify the rows in HR.TEST_EMPLOYEES
table, will be supplementally logged as part of any updates done on that table.
Note that the HR.TEST_EMPLOYEES
table still does not have any unique index specified on the logical standby database. This may cause UPDATE
statements to do full table scans on the logical standby database. You can remedy that by adding a unique index on the EMPNO
column on the logical standby database.See Section 4.1.2, "Ensure Table Rows in the Primary Database Can Be Uniquely Identified" and Oracle Database SQL Reference for more information about RELY
constraints.
Stop SQL Apply:
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;
Disable the guard so that you can modify a maintained table on the logical standby database:
SQL> ALTER SESSION DISABLE GUARD;
Add a unique index on EMPNO
column:
SQL> CREATE UNIQUE INDEX UI_TEST_EMP ON HR.TEST_EMPLOYEES (EMPNO);
Enable the guard:
SQL> ALTER SESSION ENABLE GUARD;
Start SQL Apply:
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;
调整applier进程数量
下面的步骤来找到是否要调整applier进程的数量来帮助你获得更大的吞吐
1来看applier是否很忙
SQL> SELECT COUNT(*) AS IDLE_APPLIER FROM V$LOGSTDBY_PROCESS WHERE TYPE = 'APPLIER' and status_code = 16166;
IDLE_APPLIER
-------------------------
0
2一旦确认了没有空闲的applier进程,执行下面的查询来确认对新增的applier进程有足够的工作
SQL> SELECT NAME, VALUE FROM V$LOGSTDBY_STATS
WHERE NAME LIKE 'TRANSACTIONS%';
NAME VALUE
--------------------- -------
transactions ready 27896
transactions applied 25671
如果transactions read-transactions applied比applier进程的2倍还要多,那么就可以增加applier进程的数量来获得高的吞吐量。
为了调整applier进程数量,执行下面的步骤
Stop SQL Apply:
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY; Database altered
Set the number of APPLY_SERVERS
to 20:
SQL> EXECUTE DBMS_LOGSTDBY.APPLY_SET('APPLY_SERVERS', 20); PL/SQL procedure successfully completed
Start SQL Apply:
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE; Database altered
调整preparer进程数量
你要调整prepare进程数量的情况很少,在你要增加prepare进程数量的时候,确保下面的条件成立:
1所有的prepare都很忙
2要被应用的事务的数量少于applier的数量
3有applier空闲进程
Ensure all PREPARER
processes are busy:
SQL> SELECT COUNT(*) AS IDLE_PREPARER FROM V$LOGSTDBY_PROCESS WHERE TYPE = 'PREPARER' and status_code = 16166; IDLE_PREPARER ------------- 0
Ensure the number of transactions ready to be applied is less than the number of APPLIER
processes:
SQL> SELECT NAME, VALUE FROM V$LOGSTDBY_STATS WHERE NAME LIKE 'transactions%'; NAME VALUE --------------------- -------transactions ready 27896 transactions applied 27892 SQL> SELECT COUNT(*) AS APPLIER_COUNT FROM V$LOGSTDBY_PROCESS WHERE TYPE = 'APPLIER'; APPLIER_COUNT ------------- 20
Note: Issue this query several times to ensure this is not a transient event.
Ensure there are idle APPLIER
processes:
SQL> SELECT COUNT(*) AS IDLE_APPLIER FROM V$LOGSTDBY_PROCESS WHERE TYPE = 'APPLIER' and status_code = 16166; IDLE_APPLIER ------------------------- 19
In the example, all conditions have been satisfied. Therefore, you can now increase the number of PREPARER
processes to 4 (from the default value of 1), by performing the following steps:
Stop SQL Apply:
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY; Database altered
Set the number of PREPARE_SERVERS
to 4:
SQL> EXECUTE DBMS_LOGSTDBY.APPLY_SET('PREPARE_SERVERS', 4); PL/SQL procedure successfully completed
Start SQL Apply:
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE; Database altered
调整lcr cache的内存
在一定负载下,sql apply也许会有大量的pageout操作,为了确定增加lcr cache是否有利,执行下面的步骤:
Issue the following query to obtain a snapshot of pageout activity:
SQL> SELECT NAME, VALUE FROM V$LOGSTDBY_STATS WHERE NAME LIKE '%PAGE%' OR NAME LIKE '%UPTIME%' OR NAME LIKE '%idle%'; NAME VALUE -------------------------- --------------- coordinator uptime in secs 894856 bytes paged out 20000 seconds spent in pageout 2 system idle time in secs 1000
Issue the query again in 5 minutes:
SQL> SELECT NAME, VALUE FROM V$LOGSTDBY_STATS WHERE NAME LIKE '%PAGE%' OR NAME LIKE '%UPTIME%' OR NAME LIKE '%idle%'; NAME VALUE -------------------------- --------------- coordinator uptime in secs 895156 bytes paged out 1020000 seconds spent in pageout 100 system idle time in secs 1000
Compute the normalized pageout activity. For example:
Change in coordinator uptime (C)= (895156 – 894856) = 300 secs Amount of additional idle time (I)= (1000 – 1000) = 0 Change in time spent in pageout (P) = (100 – 2) = 98 secs Pageout time in comparison to uptime = P/(C-I) = 98/300 ~ 32.67%
Ideally, the pageout activity should not consume more than 5 percent of the total uptime. If you continue to take snapshots over an extended interval and you find the pageout activities continue to consume a significant portion of the apply time, increasing the memory size may provide some benefits. You can increase the memory allocated to SQL Apply by performing the following steps:
Stop SQL Apply:
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY; Database altered
Set the memory allocated to LCR cache (for this example, the SGA is set to 1 GB):
SQL> EXECUTE DBMS_LOGSTDBY.APPLY_SET('MAX_SGA', 1024); PL/SQL procedure successfully completed
Because the MAX_SGA
is specified in megabytes (MB), increasing the memory to 1 GB is specified as 1024 (MB) in the example.
Start SQL Apply:
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE; Database altered
调整逻辑备库上事务的应用方式
默认的,在备库上的事务应用是以他们在主库上的提交顺序的。这种默认的提交事务顺序可以让报表应用透明的转向逻辑备库。然而,一些时候,你想让逻辑备库赶上主库,能忍受不运行报表程序,这种情况下,你可以改变应用的方式:
Stop SQL Apply:
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY; Database altered
Issue the following to allow transactions to be applied out of order from how they were committed on the primary databases:
SQL> EXECUTE DBMS_LOGSTDBY.APPLY_SET('PRESERVE_COMMIT_ORDER', 'FALSE'); PL/SQL procedure successfully completed
Start SQL Apply:
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE; Database altered
Once you have caught up with the primary database (verify this by querying the V$LOGSTDBY_STATS
view), and you are ready to open the logical standby database for reporting applications, you can change the apply mode as follows:
Stop SQL Apply:
SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY; Database altered
Restore the default value for the PRESERVE_COMMIT_ORDER
parameter:
SQL> EXECUTE DBMS_LOGSTDBY.APPLY_UNSET('PRESERVE_COMMIT_ORDER'); PL/SQL procedure successfully completed
Start SQL Apply:
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE; Database altered
For a typical online transaction processing (OLTP) workload, the nondefault mode can provide a 50 percent or better throughput improvement over the default apply mode.