Chinaunix首页 | 论坛 | 博客
  • 博客访问: 437216
  • 博文数量: 55
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1584
  • 用 户 组: 普通用户
  • 注册时间: 2013-05-04 15:15
个人简介

热衷技术,热爱交流

文章分类

全部博文(55)

文章存档

2014年(7)

2013年(48)

分类: Oracle

2013-05-13 00:59:03

数据库打开前检验过程包含下面两个步骤:

1.比较数据文件头中的cnt与控制文件记录的cnt,如果一致进行下一步比较。如果不一致,那么数据文件有可能是备份的,控制文件也可能是备份的,这种情况就需要手动进行恢复,或者重建控制文件。
2.比较数据文件头中的scn与控制文件中记录的结束scn。数据库正常关闭情况下,执行完常规检查点后,控制文件中记录的数据文件的结束scn和检查点scn应该相等。异常关闭时候,由于没有执行完全检查点,控制文件中记录的数据文件的stop scn是全f,这样就需要恢复。

恢复起点是控制文件中记录的low cache rba,终点至少应该是控制文件中记录的 on disk scn(终点究竟在哪里需要进一步研究

一、异常关闭数据库后的前滚恢复(cache recovery)

oracle[~]$sqlplus / as sysdba
SYS AS SYSDBA >Shutdown abort;
SYS AS SYSDBA >Start mount;
转储控制文件:
alter session set events 'immediate trace name controlf level 8'
数据库检查点:
***************************************************************************
DATABASE ENTRY
***************************************************************************
 Database checkpoint: Thread=1 scn: 0x0000.004eb574                         
 Controlfile Checkpointed at scn:  0x0000.004eb576 05/11/2013 22:57:20                                 
 thread:0 rba:(0x0.0.0) 

检查点rba记录,脏块记录:
***************************************************************************                            
CHECKPOINT PROGRESS RECORDS                                                                            
***************************************************************************                       
THREAD #1 - status:0x2 flags:0x0 dirty:66                                                              
low cache rba:(0x8b.19515.0) on disk rba:(0x8b.195f3.0)                                                
on disk scn: 0x0000.004eb5f9 05/11/2013 22:58:12                                                       
resetlogs scn: 0x0000.003cef48 04/26/2013 21:26:02                                                     
heartbeat: 815191527 mount id: 771559300 

重做日志检查点记录:
***************************************************************************                            
REDO THREAD RECORDS
***************************************************************************            
opened at 05/11/2013 22:21:32 by instance hx                                                          
Checkpointed at scn:  0x0000.004eb574 05/11/2013 22:57:13                                              
 thread:1 rba:(0x8b.194ba.10)                                                                          
 enabled  threads:  01000000 00000000 00000000 00000000 00000000 00000000  
 
数据文件检查点记录:
***************************************************************************                            
DATA FILE RECORDS                                                                                      
***************************************************************************              
Checkpoint cnt:1036 scn: 0x0000.004eb574 05/11/2013 22:57:13                                          
Stop scn: 0xffff.ffffffff 05/11/2013 22:17:37                                                         
Creation Checkpointed at scn:  0x0000.00000009 02/06/2013 17:15:16  
****************************************************************************

SYS AS SYSDBA >alter database open;
oracle[~]$cat /u01/diag/rdbms/hx/hx/trace/alert_hx.log 
Sat May 11 23:35:18 2013
1. smon进程开始crash recovery工作
Beginning crash recovery of 1 threads
2. 提示,事务回滚采用并行方式,开启两个进程进行(事务回滚并不是非要数据库打开后才能进行。)
parallel recovery started with 2 processes(并行恢复)
3. smon进程用控制文件的low cache rba定位到重做日志文件,开始扫描(应用的日志终点不一定是到on disk rba,扫描时候貌似和on disk rba没有关系。)
Started redo scan
Completed redo scan
 read 111 KB redo, 66 data blocks need recovery
4. 扫描完成后,开始应用重做日志(这里可以确定终点了,实际就是 ON DISK RBA。什么情况下重做日志应用终点大于 on disk rba呢?难道和事务回滚相关?问题先留着。)
Started redo application at
 Thread 1: logseq 139, block 103701 (正好是控制文件中的:low cache rba 19515)
Recovery of Online Redo Log: Thread 1 Group 1 Seq 139 Reading mem 0
  Mem# 0: /u01/oradata2/hx/redo01.log
5. 完成重做日志的应用
Completed redo application of 0.09MB
Completed crash recovery at
 Thread 1: logseq 139, block 103923(正好是控制文件中的:on disk rba(195f3)), scn 5178393
 data blocks read, 66 data blocks written, 111 redo k-bytes read
6.打开数据库,切换到新的重做日志文件(为什么要切换到新的重做日志呢?接着之前的重做日志文件不行么?)
Sat May 11 23:35:22 2013
Thread 1 advanced to log sequence 140 (thread open)
Thread 1 opened at log sequence 140
  Current log# 2 seq# 140 mem# 0: /u01/oradata2/hx/redo02.log
Successful open of redo thread 1

MTTR advisory is disabled because FAST_START_MTTR_TARGET is not set
Sat May 11 23:35:23 2013

二、异常关闭数据库的事务回滚(transaction recovery)


执行shutdown immediate操作,oracle会关闭一切客户端连接,立即停止所有的事务,对于没有提交或者提交失败的事务,oracle使用undo进行事务回滚,从而保证数据库的一致性。事务回滚也会产生重做日志,回滚完成后再进行常规检查点。对于异常关闭数据库的情况,完成cache recovery后,由于数据文件中包含了提交和未提交的事务修改的数据(如果没提交就标记为uncommited),所以需要进行事务回滚(transaction recovery)。回滚实质就是利用撤销表空间的内容修改buffer cache。需要注意的是:在大事务的情况下如果data buffer cache中块已经被写入磁盘(没有commit),或者该事务更改的块超过data buffer cache总大小的 10%,则不再对这些块标志该事务为已经提交,这会影响到我们下次读该块(biti_rainy的描述)。未提交的数据其他用户无法访问?所以写大数据量时候,尽量要执行提交?
实验:简单理解事务回滚过程
1. 提交所有事务:
SYS AS SYSDBA >commit
2. 检查是否还有未提交事务
SYS AS SYSDBA >SELECT XID AS "txn id", XIDUSN AS "undo seg", XIDSLOT AS 
  2  "slot",  
  3   XIDSQN AS "seq", STATUS AS "txn status" 
  4   FROM V$TRANSACTION;  
no rows selected

3. 开启一个会话,插入数据:
begin
for i in 0 .. 1000
loop
insert into huangxing.test select * from dba_objects;
    end loop;
end;
4. 异常关闭数据库:
SYS AS SYSDBA >shutdown abort; 

5. 启动数据库,观察回滚执行:
SYS AS SYSDBA >shutdown start; 
select usn,seq,state,UNDOBLOCKSDONE,UNDOBLOCKSTOTAL from  v$fast_start_transactions; -----并行事务回滚执行情况
       USN|       SEQ|STATE           |UNDOBLOCKSDONE|UNDOBLOCKSTOTAL
----------|----------|----------------|--------------|---------------
         3|      1621|RECOVERED       |           241|            241

select name,value from v$sysstat where name in (user commits,transaction);--事务回退率
NAME                                                            |     VALUE
----------------------------------------------------------------|----------
user commits                                                    |         5


select count(*) from x$bh where state = 3; --从回滚段取回before image 再rollback而重构生成的block,
  COUNT(*)
----------
        43

问题:什么需要回滚呢?
大概可以这么理解:未提交的数据,其他会话是不能查看的。如果不进行回滚,这些数据是没法访问的(uncommitted),既然没法访问,那就是垃圾数据,最好回滚,腾出空间,让用户能访问。重做日志文件中的内容也可能是未提交的((lgwr写出不一定非要commit)。未提交的数据在进入buffer cache以后首先会被标记为uncommited,写入数据文件后(不是检查点引起写出的),由于仍是未提交数据,就需要进行回滚。

oracle8i以后 fast-start fault recovery 中的fast-start on-demand和fast-start parallel rollback特性对事务回滚进行了优化:
fast-start on-demand:
即按需回滚,数据库打开时,是后台回滚的,如果用户访问这些正在回滚的记录的脏块,那么就优先回滚,回滚后用户才可以继续访问这些数据库,前面已经有所提及。
 SYS AS SYSDBA >show parameter fast;
 NAME                                |TYPE       |VALUE
------------------------------------|-----------|------------------------------
fast_start_io_target                |integer    |0
fast_start_mttr_target              |integer    |0
fast_start_parallel_rollback        |string     |LOW
SYS AS SYSDBA >show parameter cpu_count;
NAME                                |TYPE       |VALUE
------------------------------------|-----------|------------------------------
cpu_count                           |integer    |2

从上面来看,有两个cpu,fast_start_parallel_rollback设置成low,表示并行进程2,那么同时就可以使用4个进程进行事务回滚。但是,对于回滚量很大的环境,并行回滚效果并不是那么好的。一般来说,oracle事务回滚优先采用并行方式,如果并行方式失败,将采用单进程方式回滚。这个过程将会比较缓慢,所以,在提交大数据量事务时候,尤其需要注意。

实验分析新特性
1. 首先插入大量数据数据:
for i in 0 .. 100
loop
insert into huangxing.test select * from dba_objects;
    end loop;
end;
2. 插入中途直接kill dbwr进程
3. SYS AS SYSDBA >startup;

4. 启动数据库,查看回滚过程日志(日志记录的并没有前滚恢复那么丰富
回滚日志如下;
SMON: enabling cache recovery                                                                          
Sun May 12 11:48:29 2013                                                                               
Incremental checkpoint up to RBA [0x95.3.0], current log tail at RBA [0x95.17.0]                       
[2579] Successfully onlined Undo Tablespace 2.                                                         
Undo initialization finished serial:0 start:2445474 end:2446884 diff:1410 (14 seconds)                 
Verifying file header compatibility for 11g tablespace encryption..                                    
Verifying 11g file header compatibility for tablespace encryption completed                            
SMON: enabling tx recovery                                                                             
Database Characterset is ZHS16GBK                                                                      
No Resource Manager plan active                                                                        
Sun May 12 11:48:40 2013                                                                               
replication_dependency_tracking turned off (no async multimaster replication found)                    
Sun May 12 11:48:52 2013                                                                               
Starting background process QMNC                                                                       
Sun May 12 11:48:52 2013                                                                               
QMNC started with pid=25, OS id=2592                                                                   
Completed: alter database open                                                                         
Sun May 12 11:49:13 2013                                                                               
SMON: Parallel transaction recovery tried   
5. 查看回滚进程
SYS AS SYSDBA >select sid,program,event from v$session where program like '%P00%';  ----开启四个后台进程,进行并行回滚(后面的event是动态变化的)
       SID|PROGRAM                                         |EVENT
----------|------------------------------------------------|--------------------------------------------------
        10|oracle@huangxing (P001)                         |db file sequential read
        11|oracle@huangxing (P003)                         |db file sequential read
       136|oracle@huangxing (P000)                         |db file sequential read
       137|oracle@huangxing (P002)                         |db file sequential read
  
6. 查看剩余需要回滚的总量:10608640bytes,即10m.
SYS AS SYSDBA >select usn,rssize,writes,xacts,hwmsize,status from v$rollstat where xacts > 0;  ---回滚结束后视图内容消失
       USN|    RSSIZE|    WRITES|     XACTS|   HWMSIZE|STATUS      
----------|----------|----------|----------|----------|-------
         7|  10608640|       464|         1|  10608640|ONLINE 
7. 查看工作完成情况:
SYS AS SYSDBA >select usn,seq,state,UNDOBLOCKSDONE,UNDOBLOCKSTOTAL from  v$fast_start_transactions;
       USN|       SEQ|STATE           |UNDOBLOCKSDONE|UNDOBLOCKSTOTAL
----------|----------|----------------|--------------|---------------
         3|      1603|RECOVERED       |           514|            514
结果显示已经完成了514个undo块(UNDOBLOCKSDONE),总共需要回滚514个块(UNDOBLOCKSTOTAL),cpu时间消耗44s,平均每秒回滚11个undo块。
如果并行进程恢复失败,将会切换为单进程进行恢复,通过下面视图就可以查看单进程恢复进度:
SYS AS SYSDBA >select * from v$fast_start_servers;
注意:在回滚过程中,如果异常关闭数据库,那么回滚事务将会变成死事务(v$transactions中没有记录),这个时候,就需要通过其他内部表来查看了
SYS AS SYSDBA >select distinct(ktuxecfl),count(*) from x$ktuxe group by ktuxecfl; 
KTUXECFL                |  COUNT(*)
------------------------|----------
DEAD                    |         1
NONE                    |       437   
最后:

concepts中下面这段话值得回味:
When a transaction is committed, log writer (LGWR) writes both the 
remaining redo entries in memory and the transaction SCN to the online 
redo log. However, the database writer (DBWn) process writes modified 
data blocks to the data files whenever it is most efficient. For this reason, 
uncommitted changes may temporarily exist in the data files while 
committed changes do not yet exist in the data files.(是不是可以理解成,数据文件中记录的已提交的内容必须拥有重做日志?
阅读(3240) | 评论(1) | 转发(2) |
给主人留下些什么吧!~~

bobobht2013-05-13 20:00:11

威武霸气  我敢乱说~~~