重庆思庄Oracle、Redhat认证学习论坛

标题: UNIX使用DD备份和恢复裸设备 [打印本页]

作者: 郑全    时间: 2013-4-16 15:39
标题: UNIX使用DD备份和恢复裸设备

UNIX使用DD备份和恢复裸设备

dd工具使用

dd重要参数

参数

含义

if

输入设备或者文件

of

输出设备或文件

bs

dd缓冲区。设定dd时一次io拷贝多少数据,它与输入文件和输出文件的block size都没有直接联系。

一般来说,bs越大,拷贝速度越快

skip

设定dd时从输入文件中跳过多少个dd缓冲区开始拷贝数据。一般在裸设备有offset时使用

seek

设定dd时从输出文件中跳过多少个dd缓冲区开始写入数据。一般在裸设备有offset时使用

count

设置ddio数量。如果省略了count,表示完全拷贝输入文件到输出文件上

dd参数适用范围

备份源

备份目的地

适用参数

裸设备

裸设备

if of bs skip seek count

裸设备

文件系统

if of bs skip count

文件系统

裸设备

if of bs seek

文件系统

文件系统

if of bs

dd拷贝oracle数据文件需要考虑的因素

因素

含义

block size

dd一次iobuffer大小

offset

只适用于裸设备,有些操作系统在裸设备上保留一定的空间给内部使用,拷贝时要跳过这部分内容

block 0

每一个oracle数据文件的头都包含一个与数据文件所在表空间的blocksize的相等的block

这个block是不计算入oracle数据文件的bytes的,但在操作系统中,它是会占用空间的。

如何用dd测试磁盘速度?

首先要了解两个特殊的设备:

/dev/null:回收站、无底洞

/dev/zero:产生字符

? 测试磁盘写能力

time dd if=/dev/zero of=/test.dbf bs=8k count=300000

因为/dev//zero是一个伪设备,它只产生空字符流,对它不会产生IO,所以,IO都会集中在of文件中,of文件只用于写,所以这个命令相当于测试磁盘的写能力。

? 测试磁盘读能力

time dd if=/dev/sdb1 of=/dev/null bs=8k

因为/dev/sdb1是一个物理分区,对它的读取会产生IO/dev/null是伪设备,相当于黑洞,of到该设备不会产生IO,所以,这个命令的IO只发生在/dev/sdb1上,也相当于测试磁盘的读能力。

? 测试同时读写能力

time dd if=/dev/sdb1 of=/test1.dbf bs=8k

这个命令下,一个是物理分区,一个是实际的文件,对它们的读写都会产生IO(对/dev/sdb1是读,对/test1.dbf是写),假设他们都在一个磁盘中,这个命令就相当于测试磁盘的同时读写能力。

是否需要skip数据文件的block 0

不需要。

因为block 0位于offset之后,而block 0是所有数据文件都需要的,无论它是基于裸备还是文件系统,且block0的大小只与oracleblock size有关,所以,把block 0dd出来是必要的,不需要skip数据文件的block 0

是否所有系统都有offset

不是。aixTurbo unix要注意offset,其他的一般没有。

如何计算数据文件的占用的实际空间大小?

实际的数据文件大小是在dba_data_files中的bytes + 1* blocksize

如:

SQL> select file_name,bytes from dba_data_files;

FILE_NAME BYTES BLOCKSIZE

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

/opt/oracle/oradata/test1/system01.dbf 360710144 8192

在操作系统查看文件大小:

[root@suk1 soft]# ls -l system01.dbf

-rw-r--r-- 1 oracle oinstall 360718336 Nov 15 11:53 system01.dbf

360718336 = 360710144 + 8192 (8192是数据文件所在表空间的blocksize)

一个裸设备的数据文件最多可以是多大?

这个和具体的操作系统和数据文件所在表空间的blocksize有关。

假设裸设备的大小是r,操作系统裸设备的offsetf,数据文件所在表空间的blocksizeb,则数据文件的最大大小为:

d=r – f – b*1 (1block 0)

如裸设备大小为1008koffset0,表空间的blocksize4k,则在此裸设备的数据文件的最大大小为:

d=1008-0-1*4=1004(k)

在裸设备之间拷贝数据文件

本例测试在裸设备之间拷贝oracle数据文件的步骤,并考虑两个问题:

1) 假设旧设备比新设备小,把大的裸设备数据文件拷贝到小的裸设备是否可行?

2) 旧裸设备比新裸设备小,是否可以拷贝数据文件到新裸设备上?

测试步骤:

#创建逻辑卷

[root@suk1 ~]# lvcreate -L 10m -n lv10_old vgdata

Logical volume "lv10_old" created

[root@suk1 ~]# lvcreate -L 20m -n lv20_new vgdata

Logical volume "lv20_new" created

[root@suk1 ~]# lvcreate -L 40m -n lv40_old vgdata

Logical volume "lv40_old" created

[root@suk1 ~]# lvcreate -L 30m -n lv30_new vgdata

Logical volume "lv30_new" created

#绑定裸设备

[root@suk1 ~]# raw /dev/raw/raw100 /dev/vgdata/lv10_old

/dev/raw/raw100: bound to major 253, minor 2

[root@suk1 ~]# raw /dev/raw/raw200 /dev/vgdata/lv20_new

/dev/raw/raw200: bound to major 253, minor 3

[root@suk1 ~]# raw /dev/raw/raw400 /dev/vgdata/lv40_old

/dev/raw/raw400: bound to major 253, minor 4

[root@suk1 ~]# raw /dev/raw/raw300 /dev/vgdata/lv30_new

/dev/raw/raw300: bound to major 253, minor 5

#基于裸设备创建表空间

SQL> create tablespace mytest datafile '/dev/raw/raw100' size 9m,'/dev/raw/raw400' size 20m;

Tablespace created.

#从小裸设备到大裸设备

[root@suk1 ~]# dd if='/dev/raw/raw100' of='/dev/raw/raw200'

20480+0 records in

20480+0 records out

#从大裸设备到小裸设备,但数据文件比小裸设备小

[root@suk1 ~]# dd if='/dev/raw/raw400' of='/dev/raw/raw300' bs=1024k count=25

25+0 records in

25+0 records out

注意:这里bs*count要大于原裸设备上的数据文件尺寸

SQL> startup mount

ORACLE instance started.

Total System Global Area 167772160 bytes

Fixed Size 1260696 bytes

Variable Size 138412904 bytes

Database Buffers 25165824 bytes

Redo Buffers 2932736 bytes

Database mounted.

#重命名数据文件

SQL> alter database rename file '/dev/raw/raw100' to '/dev/raw/raw200';

Database altered.

SQL> alter database rename file '/dev/raw/raw400' to '/dev/raw/raw300';

Database altered.

SQL> alter database open;

Database altered.

 


作者: 郑全    时间: 2013-4-16 15:40

从这个测试可以看出:

1) 从小裸设备到大裸设备,只需把小裸设备的所有数据块dd到大裸设备即可

2) 是否可以把大裸设备上的数据文件dd到小裸设备,取决于位于大裸设备上的数据文件尺寸(+block 0)是否比小裸设备小。如果数据文件小于小裸设备,则可以把数据文件从大裸设备dd到小裸设备上,在dd过程中不需要太准确计算原来数据文件的大小,只要保证dd的总量大于数据文件并小于小裸设备的尺寸即可。

3) 如果数据文件大于小裸设备的尺寸,则肯定不能把它从大裸设备拷贝到小裸设备上

4) 裸设备之间拷贝数据文件比裸设备到文件系统之间拷贝的有点在于:不需要精确计算要拷贝多少数据,只需要保证覆盖了数据文件+block 0即可;而从裸设备到文件系统拷贝数据文件时,必须准确计算出要拷贝的数据量(数据文件+block 0),dd多一点或者少一点都会报错。

5) 如果有offset的话,在裸设备之间拷贝数据文件的时候都要考虑(skipseek

从文件系统到裸设备拷贝ORACLE数据文件

这个比较简单,首先要保证裸设备的大小要大于等于oracle数据文件大小 + block 0,如果裸设备需要offset的话,则要保证更大,然后直接用dd就可以。

如:

#源文件大小为10m

[root@suk1 ~]# ls -l /opt/oracle/oradata/test1/users02.dbf

-rw-r----- 1 oracle oinstall 10493952 Nov 30 11:07 /opt/oracle/oradata/test1/users02.dbf

#创建一个20m的裸设备

[root@suk1 ~]# lvcreate -L 20m -n lv20 vgdata

Logical volume "lv20" created

[root@suk1 ~]# raw /dev/raw/raw20 /dev/vgdata/lv20

/dev/raw/raw20: bound to major 253, minor 1

#dd文件到裸设备上

[root@suk1 ~]# dd if=/opt/oracle/oradata/test1/users02.dbf of=/dev/raw/raw20

20496+0 records in

20496+0 records out

注意:从文件系统到裸设备不用设置count

#重命名数据文件,打开数据库

SQL> alter database rename file '/opt/oracle/oradata/test1/users02.dbf' to '/dev/raw/raw20';

Database altered.

SQL> alter database open;

Database altered

从裸设备到文件系统拷贝ORACLE数据文件

这里用用到两个工具:

dbfsize 求出在裸设备或者文件系统上的oracle数据文件的大小,由oracle提高。

blockdev 求出裸设备的大小,操作系统自带。

要计算出要要拷贝的大小,否则报错,如:

[oracle@suk1 soft]$ dbfsize /dev/raw/raw1

Database file: /dev/raw/raw1

Database file type: raw device

Database file size: 44032 8192 byte blocks

[oracle@suk1 soft]$ time dd if=/dev/raw/raw1 of=system01.dbf bs=8k count=44032

SQL> alter database rename file '/opt/oracle/oradata/test1/system01.dbf' to '/soft/system01.dbf';

Database altered.

SQL> alter database open;

alter database open

*

ERROR at line 1:

ORA-01122: database file 1 failed verification check

ORA-01110: data file 1: '/soft/system01.dbf'

ORA-01200: actual file size of 44031 is smaller than correct size of 44032 blocks

--不要忘了block 0

[oracle@suk1 soft]$ rm system01.dbf

[oracle@suk1 soft]$ dd if=/dev/raw/raw1 of=system01.dbf bs=8k count=44033

SQL> startup

ORACLE instance started.

Total System Global Area 167772160 bytes

Fixed Size 1260696 bytes

Variable Size 100664168 bytes

Database Buffers 62914560 bytes

Redo Buffers 2932736 bytes

Database mounted.

Database opened.

SQL> select file_name from dba_data_files;

FILE_NAME

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

/soft/system01.dbf

/opt/oracle/oradata/test1/undotbs01.dbf

/opt/oracle/oradata/test1/sysaux01.dbf

/opt/oracle/oradata/test1/users01.dbf

/opt/oracle/oradata/test1/users02.dbf

是否可以把整个裸设备拷贝到文件中?

有时候可能需要把裸设备的数据文件迁移到文件系统中,那迁移的时候是否可以把整个裸设备拷出来?

不一定,要看裸设备是否有offset,如果有offset,则肯定不能全拷贝出来;如果没有offset,也要分情况:

1)裸设备中的数据文件 + block 0比裸设备小。

如果数据文件大小 + block 0比裸设备小,则不能将整个裸设备拷到文件系统的文件中。

[root@suk1 soft]# dd if=/dev/raw/raw1 of=system01.dbf bs=8k

SQL> startup mount

ORACLE instance started.

Total System Global Area 167772160 bytes

Fixed Size 1260696 bytes

Variable Size 75498344 bytes

Database Buffers 88080384 bytes

Redo Buffers 2932736 bytes

Database mounted.

SQL> alter database rename file '/opt/oracle/oradata/test1/system01.dbf' to '/soft/system01.dbf';

Database altered.

SQL> alter database open;

alter database open

*

ERROR at line 1:

ORA-01157: cannot identify/lock data file 1 - see DBWR trace file

ORA-01110: data file 1: '/soft/system01.dbf'

Errors in file /opt/oracle/admin/test1/bdump/test1_dbw0_9564.trc:

ORA-01157: cannot identify/lock data file 1 - see DBWR trace file

ORA-01110: data file 1: '/soft/system01.dbf'

ORA-27046: file size is not a multiple of logical block size

Additional information: 1

ORA-1157 signalled during: ALTER DATABASE OPEN...

这是因为裸设备已被数据文件使用部分的逻辑块与未使用部分的逻辑块大小不一致。这种情况下,只能拷贝裸设备中数据文件大小 + block 0部分。

2)裸设备中的数据文件 + block 0等于裸设备大小

这种情况是可以完全拷贝的。

[root@suk1 soft]# lvcreate -L 1008k -n test1008 vgdata

Logical volume "test1008" created

[root@suk1 soft]# raw /dev/raw/raw1008 /dev/vgdata/test1008

/dev/raw/raw1008: bound to major 253, minor 0

SQL> create tablespace test blocksize 4k datafile '/dev/raw/raw1008' size 1004k;

Tablespace created.

SQL> select file_name,bytes,bytes/blocks blocksize from dba_data_files;

FILE_NAME BYTES BLOCKSIZE

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

/dev/raw/raw1008 1028096 4096

1028096 + 4096 =1008(k)

SQL> startup mount

ORACLE instance started.

[oracle@suk1 soft]$ dd if=/dev/raw/raw1008 of=test.dbf

2016+0 records in

2016+0 records out

Total System Global Area 167772160 bytes

Fixed Size 1260696 bytes

Variable Size 130024296 bytes

Database Buffers 33554432 bytes

Redo Buffers 2932736 bytes

Database mounted.

SQL> alter database rename file '/dev/raw/raw1008' to '/soft/test.dbf';

Database altered.

SQL> alter database open;

Database altered.

各种拷贝方式的比较

? 裸设备到裸设备

需要考虑裸设备的offset;要保证新设备的大小满足数据文件的需求;不需要精确计算要拷贝的尺寸,保证大于等于数据文件大小+block 0即可(必须从数据字段中才能查出oracle数据文件的大小)

? 裸设备到文件系统

需要考虑裸设备的offset;必须精确计算要拷贝的尺寸,包括的尺寸必须刚好等于数据文件大小+block 0(因为无法通过操作系统命令看数据文件的大小,必须通过oracle数据字典查看)

? 文件系统到裸设备

需要考虑裸设备的offset;不需要精确计算要拷贝的尺寸,把文件全部拷到裸设备即可。

? 文件系统到文件系统

不用考虑offset。不需要精确计算要拷贝的尺寸,把文件全部拷贝过去就可以。

验证备份

Oracle提高dbv工具来验证备份文件是否有损坏:

[oracle@suk1 ~]$ dbv file=/dev/raw/raw300

DBVERIFY: Release 10.2.0.3.0 - Production on Fri Nov 30 16:49:59 2007

Copyright (c) 1982, 2005, Oracle. All rights reserved.

DBVERIFY - Verification starting : FILE = /dev/raw/raw300

DBVERIFY - Verification complete

Total Pages Examined : 2560

Total Pages Processed (Data) : 0

Total Pages Failing (Data) : 0

Total Pages Processed (Index): 0

Total Pages Failing (Index): 0

Total Pages Processed (Other): 8

Total Pages Processed (Seg) : 0

Total Pages Failing (Seg) : 0

Total Pages Empty : 2552

Total Pages Marked Corrupt : 0

Total Pages Influx : 0

Highest block SCN : 487492 (0.487492)

(注意:oracle无法识别的就是block 0 +raw offset 。这里block 0 比较固定,就是一个oracle block size。block1_offset-block 0 =raw offset。

例如,AIX 5.1, AIX5.3 下raw offset=4k=12k-8k=block1_offset-block_blocksize

linux AS3 , windows下raw offset=0=8k-8k=block1_offset-block_blocksize)






欢迎光临 重庆思庄Oracle、Redhat认证学习论坛 (http://bbs.cqsztech.com/) Powered by Discuz! X3.2