32、buffer_cache_2(redo log最佳实践、强加日志)
redo
1、redo的归档模式
2、redo对性能的影响
3、redo对数据库恢复的作用
redo的归档模式
[oracle@db11g ~]$ sqlplus / as sysdba
SQL*Plus: Release 11.2.0.4.0 Production on Sat Mar 25 16:18:06 2017
Copyright (c) 1982, 2013, Oracle. All rights reserved.
Connected to:Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> archive log list;
Database log mode Archive Mode -- 数据库的日志模式:归档模式
Automatic archival Enabled -- 自动归档模式:数据库启动归档模式之后,都是Enabled,也必须是Enabled
Archive destination /u01/app/oracle/product/11.2.0/db_1/dbs/arch
Oldest online log sequence 53 -- 最老的在线日志的序列号
Next log sequence to archive 55 -- 下一个归档的序列号
Current log sequence 55 -- 当前日志的序列号
查询redo log:
select * from v$log;
redo log一定要保证除了current日志,大部分(要保证60%以上的redo log是 YES 加 INACTIVE)的redo log已经归档了;
如果出现多个NO,说明归档慢;要调归档
如果出现多个ACTIVE,说明dbwr进程写的慢;要调dbwr进程
最好的情况是:除了current,其他的都保持是 YES 加 INACTIVE
再有就是调redo log的大小,大一点有足够的时间让上一个redo log由active变为inactive
还有redo log的切换时间间隔,控制在10~20分钟之间
查看数据库有多少个日志:
select * from v$logfile;
都是单成员的,这个不好,要使用redo log的复用方式,就是一组redo log里有多个成员
redo log的最佳实践
1、使用归档模式
2、复用归档路径,每个组两个成员,成员位于不同的存储
3、yes和inactive的数量
4、切换时间:10~20分钟,主要是日志文件的大小来控制的,同时配合参数的设置:alter system set archive_lag_target = 1800;
oracle有一个参数:archive_lag_target
SQL> show parameter lag
NAME TYPE VALUE
------------------------------------ -------------- -----------
archive_lag_target integer 0
client_result_cache_lag big integer 3000
plsql_ccflags string
设置archive_lag_target参数为20分钟之后,就算当前的redo log没有写满,它也会强行切换到下一个redo log
设置archive_lag_target参数:
SQL> alter system set archive_lag_target = 1800;
System altered.
SQL> show parameter lag
NAME TYPE VALUE
--------------------------- ----------- ----------
archive_lag_target integer 1800
client_result_cache_lag big integer 3000
plsql_ccflags string
启用和关闭归档模式:
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount
ORACLE instance started.
Total System Global Area 1603411968 bytes
Fixed Size 2253664 bytes
Variable Size 1442843808 bytes
Database Buffers 150994944 bytes
Redo Buffers 7319552 bytes
Database mounted.
SQL> alter database archivelog; -- 开启归档模式
Database altered.
SQL> alter database open;
Database altered.
SQL> alter database noarchivelog; -- 关闭归档模式
Database altered.
归档模式,设置归档相关的参数:
1、log_archive_start
2、log_archive_dest_n
3、log_archive_dest_1='location=+FRA mandatory'
4、log_archive_dest_2='location=/archive/ optional'
5、log_archive_min_succeed_dest -- 表示:两个路径,只要有一个路径的归档成功就行了,但是这样有可能造成归档连不起来,中间可能会有断档(比如:路径1成功了,路径2不成功;过了一段时间之后,路径1不成功,路径2成功了,这时候两个路径的归档都不完整)
6、log_archive_dest_state_n -- 假设,现在路径2坏了,就设置路径2为:defer,oracle就不往路径2里面归档了(临时性的措施)
7、alter system switch logfile;
8、archive log list
9、alter database archivelog;
设置归档相关参数:
1、设置自动归档:
SQL> show parameter log_archive_start
NAME TYPE VALUE
---------------------------- ----------- ------------
log_archive_start boolean FALSE
log_archive_start这个参数是TRUE的话,表示自动归档,但是在11g里面这个参数已经不用了,11g里面只要打开归档模式,它就是自动归档的
2、设置指定归档路径(建议:一般指定两个归档路径):
SQL> show parameter log_archive_dest_
NAME TYPE VALUE
----------------------------- ----------- ------------------------------
log_archive_dest_1 string
log_archive_dest_10 string
log_archive_dest_11 string
log_archive_dest_12 string
log_archive_dest_13 string
log_archive_dest_14 string
log_archive_dest_15 string
log_archive_dest_16 string
log_archive_dest_17 string
log_archive_dest_18 string
log_archive_dest_19 string
log_archive_dest_2 string
log_archive_dest_20 string
log_archive_dest_21 string
log_archive_dest_22 string
log_archive_dest_23 string
log_archive_dest_24 string
log_archive_dest_25 string
log_archive_dest_26 string
log_archive_dest_27 string
log_archive_dest_28 string
log_archive_dest_29 string
log_archive_dest_3 string
log_archive_dest_30 string
log_archive_dest_31 string
log_archive_dest_4 string
log_archive_dest_5 string
log_archive_dest_6 string
log_archive_dest_7 string
log_archive_dest_8 string
log_archive_dest_9 string
log_archive_dest_state_1 string enable
log_archive_dest_state_10 string enable
log_archive_dest_state_11 string enable
log_archive_dest_state_12 string enable
log_archive_dest_state_13 string enable
log_archive_dest_state_14 string enable
log_archive_dest_state_15 string enable
log_archive_dest_state_16 string enable
log_archive_dest_state_17 string enable
log_archive_dest_state_18 string enable
log_archive_dest_state_19 string enable
log_archive_dest_state_2 string enable
log_archive_dest_state_20 string enable
log_archive_dest_state_21 string enable
log_archive_dest_state_22 string enable
log_archive_dest_state_23 string enable
log_archive_dest_state_24 string enable
log_archive_dest_state_25 string enable
log_archive_dest_state_26 string enable
log_archive_dest_state_27 string enable
log_archive_dest_state_28 string enable
log_archive_dest_state_29 string enable
log_archive_dest_state_3 string enable
log_archive_dest_state_30 string enable
log_archive_dest_state_31 string enable
log_archive_dest_state_4 string enable
log_archive_dest_state_5 string enable
log_archive_dest_state_6 string enable
log_archive_dest_state_7 string enable
log_archive_dest_state_8 string enable
log_archive_dest_state_9 string enable
有好多的归档路径,建议:指定两个归档路径,归档到两个位置(本地存储一份,远端NAS服务器共享出来的NFS目录一份)
指定归档路径的时候,还可以加参数:
log_archive_dest_1='location=+FRA mandatory' -- mandatory:表示归档的时候,必须强制归档成功(本地归档)log_archive_dest_2='location=/archive/ optional' -- optional:表示归档成不成功都没关系(远端)
设置指定归档路径(指定的路径必须是有的):
SQL> alter system set log_archive_dest_1='location=+FRA mandatory';
System altered.
SQL> alter system set log_archive_dest_2='location=/archive/ optional';
System altered.
查询归档日志:
select * from v$archived_log;
Force logging(强加日志:也就是强迫oracle记录所有的日志):
有很多时候,我们挖日志的时候,有些事务做了,但是日志挖不到,因为有些日志oracle它不记录,我们希望oracle把所有的操作(所有的事务、DDL、DML)都记录相关的日志,这时候我们就可以把Force logging这个参数启用一下
启用Force logging:
SQL> ALTER DATABASE FORCE LOGGING; -- 启用FORCE LOGGING
Database altered.
SQL> SELECT FORCE_LOGGING FROM V$DATABASE; -- 查询FORCE LOGGING的状态
FOR
---
YES
注意:在繁忙的生产期间,不要启用Force logging,不然会导致oracle hang住
关闭Force logging:
SQL> ALTER DATABASE NO FORCE LOGGING;
Database altered.
查询oracle的一个隐含参数:_disable_logging
select a.ksppinm name, b.ksppstvl value, a.ksppdesc description
from x$ksppi a, x$ksppcv b
where a.indx = b.indx and a.ksppinm like '_disable_logging';
FALSE:表示不禁用日志;在生产里面,这个参数我们一般不去做
以下几种情况,可以将_disable_logging参数设置为:TRUE
1、测试系统、不正规的系统,不怕数据丢失的系统
2、数据库处于非归档模式
3、日志成为数据库的性能瓶颈:
有大量的加载
有大量的批处理
有大量的卸载数据
4、将整个数据库的日志功能关闭
还有些情况是:某些表,某些操作希望关闭日志功能
比如:
1、启用表的nologging模式
2、然后加上append
这时候就不会产生redo log日志
设置表为NOLOGGING模式:
SQL> alter table t1 nologging;
Table altered.
查询表的LOGGING模式:
select * from dba_tables d where d.table_name='T1';
查询当前会话的sid:
SQL> select sid from v$mystat where rownum = 1;
SID
----------
20
1、查询当前会话的统计信息(redo的信息):
select * from v$sesstat b,v$statname c where b.STATISTIC# = c.STATISTIC# and b.SID=20 and c.NAME like '%redo%';
2、向t1表中插入数据:
SQL> insert into t1 select * from dba_objects;
86260 rows created.
3、再次查询会话的redo信息:
select * from v$sesstat b,v$statname c where b.STATISTIC# = c.STATISTIC# and b.SID=20 and c.NAME like '%redo%';
redo的大小增加了
4、再次插入数据(加上append):
SQL> insert /*+append */ into t1 select * from dba_objects;
86260 rows created.
5、查询会话的redo信息:
select * from v$sesstat b,v$statname c where b.STATISTIC# = c.STATISTIC# and b.SID=20 and c.NAME like '%redo%';
append的作用:
1、加append的时候:
用户连接上数据库,插入数据的时候,数据直接写入到磁盘上,但是也产生redo日志,不经过buffer cache
2、不加append的时候(走buffer cache):
用户连接上数据库,插入数据的时候,先将数据读到buffer cache里,产生的redo写到log buffer里去,然后再写到redo log里面去,然后再把buffer cache里面的数据写到磁盘上
这里设置表为nologging了,插入数据的时候也加了append,应该是不产生redo的,但是因为之间我们开启了Force logging,它就产生了redo日志(这里产生的redo日志跟不加append产生的日志是不一样的)
6、禁用Force logging:
SQL> alter database no force logging;
Database altered.
7、再次插入数据(加上append):
SQL> insert /*+append */ into t1 select * from dba_objects;
insert /*+append */ into t1 select * from dba_objects
*
ERROR at line 1:
ORA-12838: cannot read/modify an object after modifying it in parallel -- 报错
报错:因为之前append过一次,append之后,必须commit提交之后,才能做下一次的append
SQL> commit;
Commit complete.
SQL> insert /*+append */ into t1 select * from dba_objects;
86260 rows created.
8、再次查询会话的redo信息:
select * from v$sesstat b,v$statname c where b.STATISTIC# = c.STATISTIC# and b.SID=20 and c.NAME like '%redo%';
redo日志的大小基本没变(没有产生redo日志,或者产生的比较少,基本可以忽略不计)
9、查询会话的锁:
select * from v$lock where type = 'TM';
TM:表示表锁(LMODE:6(这是一个排它锁))
也就是:insert的时候,在t1表上加了一个排它锁
select * from dba_objects where object_id = '87367';
10、在t1表上做update操作:
SQL> select * from t1 for update;
这时候,被挂住了
select * from v$lock where type = 'TM';
SQL> commit;
Commit complete.
commit提交之后,锁才会被释放,锁被释放之后,update操作就可以执行了
select * from v$lock where type = 'TM';
update的时候,在t1表上又加上了另外一个锁
可以使用nologging子句的情况:
1、创建索引或重建索引时
2、insert into的时候,通过/*+append /提示(上面已经演示),使用直接路径批量INSERT操作或SQLLoader直接路径加载数据
3、CTAS方式(create table as)创建数据表时
1、建一个索引(加上nologging):
SQL> create index i_t1 on t1(object_id) nologging;
Index created.
2、查询redo信息:
select * from v$sesstat b,v$statname c where b.STATISTIC# = c.STATISTIC# and b.SID=20 and c.NAME like '%redo%';
redo的大小,基本没变