Oracle之redo分析
作为一名开发人员,应该能够测量你的操作生成了多少redo,这往往很重要。生成的redo越多,你的操作花费的时间就越长,整个系统也会越慢。你不光在影响你自己的会话,还会影响每一个会话。redo管理是数据库中的一个串行点。任何Oracle实例都只有一个LGWR,最终所有事务都会归于LGWR,要求这个进程管理它们的redo,并BOMMIT其事务,LGWR要做的越多,系统就会越慢。通过查看一个操作会生成多少redo,并对一个问题的多种解决方法进行测试,可以从中找出最佳的方法。
1. 测量redo
以下示例只是测试简单的sql语句。
a. 建立两个脚本mystat.sql与mystat2.sql
Mystat.sql内容如下:
set verify off
column value new_val V
define S="&1"
set autotrace off
select a.name, b.value
from v$statname a, v$mystat b
where a.statistic# = b.statistic#
and lower(a.name) like '%' || lower('&S')||'%'
/
Mystat2.sql内容如下:
set verify off
select a.name, b.value V, to_char(b.value-&V,'999,999,999,999') diff
from v$statname a, v$mystat b
where a.statistic# = b.statistic#
and lower(a.name) like '%' || lower('&S')||'%'
/
<!--EndFragment-->
<!--EndFragment--><!--EndFragment--> <!--EndFragment-->
b. 以dba身份登录数据库,比如:ob37/ob37 as sysdba
c. 创建一个测试表T:
create table t
as
select a.*
from all_objects a
where a.data_object_id=258 (258能够唯一区分出a表里面的一条记录,这里只是为了创建一个和a表字段完全一样的表,先插入一条记录。)
d. 运行如下命令:@mystat “redo size”(注意在用命令sqlplus登录数据库的时候,cmd的路径需要切换到mystat.sql与mystat2.sql的目录下面)
e. 运行如下命令:insert into t select * from all_objects
f. 运行如下命令:@mystat2 ,总体运行结果如下:
2. 我能关掉重做日志文件吗
这个问题经常被问到。答案很简单:不能。因为重做日志对于数据库至关重要;它不是开销,不是浪费。不论你是否相信,重做日志对你来说确确实实必不可少。这是无法改变的事实,也是数据库采用的工作方式。如果你真的“关闭了redo”,那么磁盘驱动器的任何暂时失败、掉电或每个软件崩溃都会导致整个数据库不可用,而且不可恢复。不过需要指出,有些情况下执行某些操作时确实可以不生成重做日志。
a. 在SQL语句中设置NOLOGGING
有些SQL语句和操作支持使用NOLOGGING子句。这并不是说:这个对象的所有操作在执行时都不生成重做日志,而是说有些特定操作生成的redo会比平常(即不使用NOLOGGING子句时)少得多。
比如这两条创建表SQL语句:
create table t as select * from all_objects;
create table t nologging as select * from all_objects;
第一条语句会生成5.5M左右的redo信息,而第二条语句只会生成80KB左右(在我的电脑上测试的结果)
看起来redo信息少多了,但是必须非常谨慎使用这种模式。因为你一旦以这种模式创建了一个表,那么对这个表的修改,删除,更新操作虽然会计入重做日志文件,但是初始数据没有记录在里面。一旦数据发生崩溃,无法从归档的重做日志文件恢复这个表的所有数据。
b. 在索引上设置NOLOGGING
可以把一个索引或表修改为默认采用NOLOGGING模式。这说明,以后重建这个索引不会生成日志。
比如:
create index t_idx on t(object_name);
alter index t_idx rebuild; //这条语句生成了2.2Mredo
alter index t_idx nologging;
alter index t_idx rebuild; //这条语句生成61KBredo
但是,现在这个索引没有得到保护(unprotected),如果它所在的数据文件失败而必须从一个备份恢复,我们就会丢失这个索引数据。
c. NOLOGGING总结
可以采用NOLOGGING模式执行以下操作:
1. 索引的创建和ALTER(重建)。
2. LOB操作(对大对象的更新不必生成日志)。
3. 通过CREATE TABLE AS SELECT创建表。
4. 各种ALTER TABLE操作,如MOVE和SPLIT。
在一个ARCHIVELOG模式的数据库上,如果NOLOGGING使用得当,可以加快许多操作的速度,因为它能显著减少生成的重做日志量。假设你有一个表,需要从一个表空间移到另一个表空间。可以适当地调度这个操作,让它在备份之后紧接着发生,这样就能把表ALTER为NOLOGGING模式,移到表,创建索引(也不生成日志),然后再把表ALTER回LOGGING模式。当然,要想适当地使用这个特性,需要DBA的参与,或者必须与负责数据库备份和恢复(或任何备用数据库)的人沟通。