<< 返回文章列表

Oracle数据恢复:深入剖析dump block对数据库的影响

2017年12月25日
张乐奕
1648

【云和恩墨,提供7*24最专业的数据恢复(Oracle,MySQL,SQL server)服务,致力于为您的数据库系统做最后一道安全防护!服务热线:010-59007017-7030】数据恢复|数据库运维|性能优化|安全保障|Oracle培训|MySQL培训


中国有一句古话说“熟视无睹,常见不疑”,指的是我们可能忽视那些随时可见的事物,并且对常见之处深信不疑,这期间可能存在巨大的误区。能够基于常见问题提出辨析和思考,并通过实践验证,是最为考验一个人知识体系的。


接下来我们分析两个常见的案例


一、当我们使用Dump Block方式进行数据块转储时,是否需要将数据读入内存呢?

这是个常用的操作,可是很少有人思考过这个问题,有了思考还要有方法去验证,这整个过程代表着一个工程师在技术上的成熟。


我们立即动手,通过实例来求解一下这个问题的答案。

1、重启一下数据库,这样buffer cache中几乎就没什么用户数据了,方便测试。


2、找一张表看看是在哪个file哪个block里面(测试表,一行数据)。

SQL> select dbms_rowid.rowid_relative_fno(rowid)fno,dbms_rowid.rowid_block_number (rowid) block# from t1;

FNO  BLOCK#

---- --------

1      103001


3、T1表在数据文件1中,第一个block是103001,检查v$bh,看看这个block有没有在buffer cache中。

SQL> select count(*)

  2  from v$bh

  3  where file# = 1 and block# = 103001;

  COUNT(*)

----------

         0


v$bh视图保存着buffer cache中每一个block的信息,是一个重要视图。


4、目前buffer cache中没有这个block,做一次Dump再看看有没有。

SQL> alter system Dump datafile 1 block 103001;

System altered

SQL> select count(*)

  2  from v$bh where file# = 1 and block# = 103001;

COUNT(*)

----------

         0


5、这就验证了做block Dump不会把数据块先读入buffer cache。


6、继续做一次select看看,这次一定是读进buffer cache了。

SQL> select * from ops$kamus.t1;

SQL> select count(*)

  2  from v$bh

  3  where file# =1 and block# =103001;

  COUNT(*)

----------

         1


这就证明了我们的结论:DumpBlock操作不会引发Block读入Buffer Cache。


二、 Dump Block是否会引起脏数据写入磁盘

伴随着上一个问题,随之而来的问题是:Dump Block会否触发脏数据写入磁盘?


这一次我们尝试一个不同的工具BBED。BBED(OracleBlock Browser and Editor)工具是Oracle内部提供的数据块级别查看和修改工具。借助这个工具,我们可以方便的查看Oracle块block级别的存储细节信息,更好地了解Oracle Internal结构的技术细节,DBA们应当了解这个工具的简单使用方法。

掌握尽量多的工具,会让我们具备选择的基础,这也是DBA的基本技能要求。


首先亮出结论:Dump Block不会引起Buffer cache中的脏数据回写入磁盘。

然后我们使用bbed工具来验证一下。


1、创建一个测试表。


SQL> CREATE TABLE t (n NUMBER);

TABLE created


2、插入一条数据,提交,然后强制checkpoint。


SQL> INSERT INTO t VALUES(1);

1 ROW inserted

SQL> commit;

Commit complete

SQL> ALTER system checkpoint;

System altered


3、此时这条数据一定已经写回磁盘,这个无需验证,继续插入另外一条数据,提交,但是不checkpoint。

SQL> INSERT INTO t VALUES(2);

1 ROW inserted 

SQL> commit;

Commit complete


4、此时这条脏数据在buffer cache中,我们可以通过Dump block来验证。

block_row_Dump:

tab 0, row 0, @0x1f9a

tl: 6 fb: --H-FL-- lb: 0x1  cc: 1

col  0: [ 2]  c1 02

tab 0, row 1, @0x1f94

tl: 6 fb: --H-FL-- lb: 0x2  cc: 1

col  0: [ 2]  c1 03

end_of_block_Dump


5、通过dbms_rowid包取得T表中记录的文件号和block号,本例中取得是file#=58, block#=570。


6、关键步骤到了,现在我们要用bbed来获取磁盘上的数据块内容,然后跟Dump block的结果比较一下。


创建一个filelist文件,命名为files.lst。

$ cat files.lst

58 /fin/u06/cnctest2data/system12.dbf 1048576000


创建一个参数文件par.bbd,用以被bbed调用。

$ cat par.bbd

blocksize=8192

listfile=/home/oraaux/files.lst

mode=browse


执行bbed。

image.png

到目前为止我们已经验证了Dump block并不会把脏数据写回磁盘,为了看一下checkpoint的效果,我们继续往下。


7、做checkpoint

SQL> ALTER system checkpoint;

System altered


8、再次运行bbed。

image.png

checkpoint将buffer cache中的脏数据写回数据文件了。