dd工具使用
参数
含义
if
输入设备或者文件
of
输出设备或文件
bs
dd缓冲区。设定dd时一次io拷贝多少数据,它与输入文件和输出文件的block size都没有直接联系。
一般来说,bs越大,拷贝速度越快
skip
设定dd时从输入文件中跳过多少个dd缓冲区开始拷贝数据。一般在裸设备有offset时使用
seek
设定dd时从输出文件中跳过多少个dd缓冲区开始写入数据。一般在裸设备有offset时使用
count
设置dd的io数量。如果省略了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一次io的buffer大小
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的大小只与oracle的block size有关,所以,把block 0也dd出来是必要的,不需要skip数据文件的block 0。
是否所有系统都有offset?不是。aix和Turbo 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,操作系统裸设备的offset为f,数据文件所在表空间的blocksize是b,则数据文件的最大大小为:
d=r – f – b*1 (1为block 0)
如裸设备大小为1008k,offset为0,表空间的blocksize为4k,则在此裸设备的数据文件的最大大小为:
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.