转自:http://www.ningoo.net/html/2008/oracle10gr2_logical_standby_managing_and_tuning.html
对于逻辑备库来说,日常管理主要需要关注SQL Apply。切换是很少发生的动作,而logminer的速度相对于sql apply来说是很快的,恢复的进度主要还是取决于SQL Apply的进度。
一、SQL Apply进程
SQL Apply实际上是一组后台并行进程,包括reader,preparer,builder,analyzer,coordinator,applier 六种不同作用的进程:
- reader:读取redo记录传递给preparer进程
- preparer: 根据redo记录和数据字典信息生成LCR
- builder: 将同一个事务的LCR打包。对于大事务(eager transaction),可能被打成多个事务包(transaction chunk),那么可能有些包里是不包含commit的,每一个事务包都可能交给不同的applier进程。
- analyzer:分析事务包之间的依赖关系
- coordinator:将分析好的事务包交给applier进程
- applier:将事务包应用,如果事务包依赖其他事务包,则需要等待相应的事务包完成。事务能否commit,可能还需要根据不同的情况从coordinator获得相应的信息。
其中,reader,builder,analyzer和coordinator只能有一个进程,而preparer和applier则可以根据需要开启多个并行进程,但是系统中所有的并行进程不能超过初始化参数parallel_max_servers的限制:
alter database stop logical standby apply; execute dbms_logstdby.apply_set('PREPARE_SERVERS', 2); execute dbms_logstdby.apply_set('APPLY_SERVERS', 8); alter database start logical standby apply;
一般来说,一个preparer进程可以满足20个applier进程的需要。applier的个数,需要根据系统的情况来看,如果所有的applier进程都比较忙碌,可能要考虑增加。简单的可以通过transactions ready和transactions applied两个状态统计来判断,如果两者差值很大,applier进程数可能太少。
SQL> select name,value from v$logstdby_stats where name like 'transactions%'; NAME VALUE ------------------------------ ------------- transactions ready 154100 transactions applied 154058
系统中当前已有的preparer和applier进程也可以通过v$logstdby_stats来查询:
SQL> select name,value from v$logstdby_stats where name like 'number%'; NAME VALUE ------------------------------ -------------- number of preparers 2 number of appliers 8
各个SQL Apply进程的状态可以通过v$logstdby_process视图获得:
SQL> select sid,type,status from v$logstdby_process; SID TYPE STATUS ----- ------------ -------------------------------------------------------------------------------- 1080 COORDINATOR ORA-16116: no work available 1085 READER ORA-16127: stalled waiting for additional transactions to be applied 1023 BUILDER ORA-16127: stalled waiting for additional transactions to be applied 1025 PREPARER ORA-16127: stalled waiting for additional transactions to be applied 1083 PREPARER ORA-16127: stalled waiting for additional transactions to be applied 1084 ANALYZER ORA-16120: dependencies being computed for transaction at SCN 0x0582.1294c01c 1073 APPLIER ORA-16124: transaction 57 17 2322872 is waiting on another transaction 1049 APPLIER ORA-16124: transaction 44 7 4445763 is waiting on another transaction 1059 APPLIER ORA-16124: transaction 59 5 2277932 is waiting on another transaction 1092 APPLIER ORA-16124: transaction 13 8 12274153 is waiting on another transaction 1036 APPLIER ORA-16124: transaction 2 18 24555358 is waiting on another transaction 1051 APPLIER ORA-16124: transaction 45 0 4338376 is waiting on another transaction 1064 APPLIER ORA-16124: transaction 56 11 2362783 is waiting on another transaction 1071 APPLIER ORA-16113: applying change to table or sequence "NINGOO"."TEST"
从这里可以看到,由于存在一个大事务,大部分applier进程都在等待1071事务的完成,这样应用日志的效率就非常低下。从实际情况来看,大事务对于逻辑备库的影响是非常大的,主库一条语句更新1000行,到逻辑备库就需要解析出1000条语句逐条执行,如果这个表没有主键,那么这些语句甚至需要走全表扫描,那代价就更高了,你会发现一个事务,也许一个小时都未必能应用完成。要在产品环境中使用逻辑备库,一定要想办法打散大事务。
逻辑备库上当前执行的事务可以从v$transaction中获得,然后通过关联v$session和v$sqlarea可以获得事务的SQL语句,进来获得执行计划。
二、LCR Cache
逻辑备库需要将redo记录解析成LCR,会在shared pool里分配一部分空间来作为LCR Cache,如果cache太小,就会像OS的虚拟内存管理一样,需要做page out,这会严重影响应用日志的性能。曾经碰到过这么一个案例,由于存在一个比较大的事务,跨越了5个logfile,逻辑备库重启后,需要从最早一个没有commit的事务开始重新读取解析和应用日志,因为LCR Cache太小,重新分析这5个logfile的时候产生了大量的page out,即使只需要应用这一个事务,每解析一个日志都花了将近半个小时。后来将LCR Cache增加,一个日志只花了一分钟不到。
默认情况下,LCR Cache为Shared pool的四分之一,最少不少于30M,否则SQL Apply不能启动。如果机器的内存足够,建议将LCR Cache尽量设大一点,当然,同时share pool也要足够大。如果机器内存有限,那可以考虑将buffer cache减少一点来给LCR Cache腾出空间。
下面的语句将LCR cache设置为1000M:
alter database stop logical standby apply; EXECUTE DBMS_LOGSTDBY.APPLY_SET('MAX_SGA', 1000); alter database start logical standby apply;
可以根据系统中page out的情况来调整LCR Cache的大小:
SQL> select name,value from v$logstdby_stats where name like '%page%'; NAME VALUE ------------------------------ -------------- bytes paged out 0 seconds spent in pageout 0
如果LCR Cache设置太大也是浪费,下面的SQL可以查询其使用率:
select name,(least(max_sga,bytes)/max_sga) * 100 pct_utilization from ( select * from v$sgastat where name = 'Logminer LCR c' ), (select value*(1024*1024) max_sga from dba_logstdby_parameters where name = 'MAX_SGA' ); NAME PCT_UTILIZATION ------------------------------ --------------- Logminer LCR c 100
三、忽略不需要应用日志的对象
逻辑备库一般是用来做报表,或者做读写分离来分担主库的读压力。对于很多系统,实际上不需要将主库上所有对象的变更都应用到逻辑备库上。比如OLTP上可能有些表是定期从数据仓库里回流过来的,这些表在数据仓库中都已经存在,没有必要到逻辑备库上查询。而且这些回流的表一般都是通过批量的方式拉过来的,都是大事务,对于逻辑备库的性能有很大的影响,那么能在逻辑备库上忽略掉是最好的了。注意参数需要大写。
alter database stop logical standby apply; --忽略某个表上的DML execute dbms_logstdby.skip (stmt => 'DML', schema_name => 'HR', object_name => 'EMPLOYEES', proc_name => null); --忽略某个表上的DDL execute dbms_logstdby.skip (stmt => 'SCHEMA_DDL', schema_name => 'HR', object_name => 'EMPLOYEES', proc_name => null); --忽略某个Schema的DML execute dbms_logstdby.skip (stmt => 'DML', schema_name => 'NINGOO', object_name => '%', proc_name => null); --忽略某个Schema的DDL execute dbms_logstdby.skip (stmt => 'SCHEMA_DDL', schema_name => 'NINGOO', object_name => '%', proc_name => null); alter database start logical standby apply;
四、事务一致性
逻辑备库在恢复的过程中,可以设置不同的事务一致性级别,一共有三种(9i):
- Full:这是默认的级别,事务应用的顺序和主库完全一致
- Read Only:这个级别的性能要比full好一些,并且对于select等到的数据还是一致的。但是事务在应用过程中可能和主库中commit的顺序是不一致的。
- NONE:完全不管主库的事务顺序,这个级别性能最好,但是可能读取到不一致的数据。
alter database stop logical standby apply; exec dbms_logstdby.apply_set('TRANSACTION_CONSISTENCY','READ_ONLY'); alter database start logical standby apply;
Oracle10gR2已经不建议使用TRANSACTION_CONSISTENCY,而是使用另外一个替代参数PRESERVE_COMMIT_ORDER,设置为TRUE相当于TRANSACTION_CONSISTENCY=FULL,而设置设置为FALSE相当于TRANSACTION_CONSISTENCY=NONE,而READ_ONLY模式在10g实际上已经被取消了(Metalink:387450.1)。据文档说PRESERVE_COMMIT_ORDER=FALSE可以提升应用日志50%的性能,但不保证此时读取的数据是一致的。
五、自动删除已经应用过的日志
默认情况下,SQL Apply会在日志应用完成,并且日志涉及到的事务都已经全部commit的情况下,自动删除日志。因为逻辑备库一方面需要接收主库传过来的日志,一方面自己也会产生日志,不及时删除,可能很快归档空间就要爆掉了。
这个行为也可以通过修改apply的参数来改变:
alter database stop logical standby apply; execute dbms_logstdby.apply_set('LOG_AUTO_DELETE', FALSE); alter database start logical standby apply;
六、更改logminer的默认表空间
逻辑备库使用logminer技术来获取logfile中的redo记录,logminer需要保存很多的元数据,在10gR2中,logminer默认使用sysaux表空间。一般的系统中,sysaux都不会给太大,可能很快就被logminer撑爆了,可以考虑修改logminer的默认表空间:
exec DBMS_LOGMNR_D.set_tablespace('TBS_NINGOO_DAT');
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/110321/viewspace-611001/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/110321/viewspace-611001/