linux dd
使用dd这个linux命令可以创建一定大小文件。
linux创建文件命令:dd命令
把指定的输入文件拷贝到指定的输出文件中,并且在拷贝的过程中可以进行格式转换。语法:
CODE:[Copy to clipboard]dd 〔选项〕
QUOTE:
if =输入文件(或设备名称)。
of =输出文件(或设备名称)。
ibs = bytes 一次读取bytes字节,即读入缓冲区的字节数。
skip = blocks 跳过读入缓冲区开头的ibs*blocks块。
obs = bytes 一次写入bytes字节,即写 入缓冲区的字节数。
bs = bytes 同时设置读/写缓冲区的字节数(等于设置obs和obs)。
cbs = bytes 一次转换bytes字节。
count = blocks 只拷贝输入的blocks块。
conv = ASCII 把EBCDIC码转换为ASCII码。
conv = ebcdic 把ASCII码转换为EBCDIC码。
conv = ibm 把ASCII码转换为alternate EBCDIC码。
conv = blick 把变动位转换成固定字符。
conv = ublock 把固定们转换成变动位
conv = ucase 把字母由小写变为大写。
conv = lcase 把字母由大写变为小写。
conv = notrunc 不截短输出文件。
conv = swab 交换每一对输入字节。
conv = noerror 出错时不停止处理。
conv = sync 把每个输入记录的大小都调到ibs的大小(用ibs填充)。
fdformat命令
低级格式化软盘。
实例:
创建一个100M的空文件
dd if=/dev/zero of=hello.txt bs=100M count=1
以上是linux创建文件命令:dd的用法。
2.实例分析
2.1.数据备份与恢复
2.1.1整盘数据备份与恢复
备份
将本地的/dev/hdx整盘备份到/dev/hdy :dd if=/dev/hdx of=/dev/hdy
将/dev/hdx全盘数据备份到指定路径的image文件:dd if=/dev/hdx of=/path/to/image
备份/dev/hdx全盘数据,并利用gzip工具进行压缩,保存到指定路径:dd if=/dev/hdx | gzip
>/path/to/image.gz
恢复
将备份文件恢复到指定盘:dd if=/path/to/image of=/dev/hdx
将压缩的备份文件恢复到指定盘 :gzip -dc /path/to/image.gz | dd of=/dev/hdx
2.1.2.利用netcat远程备份
在源主机上执行此命令备份/dev/hda:dd if=/dev/hda bs=16065b | netcat < targethost-IP >
1234在目的主机上执行此命令来接收数据并写入/dev/hdc:netcat -l -p 1234 | dd of=/dev/hdc
bs=16065b
以下两条指令是目的主机指令的变化分别采用bzip2 gzip对数据进行压缩,并将备份文件保存在当
前目录 :
netcat -l -p 1234 | bzip2 > partition.img
netcat -l -p 1234 | gzip > partition.img
2.1.3.备份MBR
备份:
备份磁盘开始的512Byte大小的MBR信息到指定文件:dd if=/dev/hdx of=/path/to/image
count=1 bs=512
恢复:
将备份的MBR信息写到磁盘开始部分:dd if=/path/to/image of=/dev/hdx
2.1.4.备份软盘
将软驱数据备份到当前目录的disk.img文件:dd if=/dev/fd0 of=disk.img count=1 bs=1440k
2.1.5.拷贝内存资料到硬盘
将内存里的数据拷贝到root目录下的mem.bin文件:dd if=/dev/mem of=/root/mem.bin
bs=1024
2.1.6.从光盘拷贝iso镜像
拷贝光盘数据到root文件夹下,并保存为cd.iso文件:dd if=/dev/cdrom of=/root/cd.iso
2.2.增加Swap分区文件大小
创建一个足够大的文件(此处为256M):dd if=/dev/zero of=/swapfile bs=1024 count=262144
把这个文件变成swap文件:mkswap /swapfile
启用这个swap文件:swapon /swapfile
在每次开机的时候自动加载swap文件, 需要在 /etc/fstab 文件中增加一行:/swapfile swap
swap defaults 0 0
2.3.销毁磁盘数据
利用随机的数据填充硬盘:dd if=/dev/urandom of=/dev/hda1
在某些必要的场合可以用来销毁数据。执行此操作以后,/dev/hda1将无法挂载,创建和拷贝操作
无法执行。
2.4磁盘管理
2.4.1.得到最恰当的block size
通过比较dd指令输出中所显示的命令执行时间,即可确定系统最佳的block size大小:
dd if=/dev/zero bs=1024 count=1000000 of=/root/1Gb.filedd if=/dev/zero bs=2048 count=500000 of=/root/1Gb.file
dd if=/dev/zero bs=4096 count=250000 of=/root/1Gb.file
dd if=/dev/zero bs=8192 count=125000 of=/root/1Gb.file
2.4.2测试硬盘读写速度
通过两个命令输出的执行时间,可以计算出测试硬盘的读/写速度:
dd if=/root/1Gb.file bs=64k | dd of=/dev/null
hdd if=/dev/zero of=/root/1Gb.file bs=1024 count=1000000
2.4.3.修复硬盘
当硬盘较长时间(比如一两年年)放置不使用后,磁盘上会产生magnetic flux point。当磁头读到
这些区域时会遇到困难,并可能导致I/O错误。当这种情况影响到硬盘的第一个扇区时,可能导致
硬盘报废。下面的命令有可能使这些数据起死回生。且这个过程是安全,高效的。
dd if=/dev/sda of=/dev/sda
http://hi.baidu.com/iruler/blog/item/1e644a2d652c9636349bf723.html
DD命令使用总结
dd
1.作用
dd命令用来复制文件,并根据参数将数据转换和格式化。
2.格式
dd [options]
3.[opitions]主要参数
bs=字节:强迫 ibs=<字节>及obs=<字节>。
cbs=字节:每次转换指定的<字节>。
conv=关键字:根据以逗号分隔的关键字表示的方式来转换文件。
count=块数目:只复制指定<块数目>的输入数据。
ibs=字节:每次读取指定的<字节>。
if=文件:读取<文件>内容,而非标准输入的数据。
obs=字节:每次写入指定的<字节>。
of=文件:将数据写入<文件>,而不在标准输出显示。
seek=块数目:先略过以obs为单位的指定<块数目>的输出数据。
skip=块数目:先略过以ibs为单位的指定<块数目>的输入数据。
dd命令使用技巧五则 -|jacketzhong 发表于 2006-8-24 9:50:00
dd命令是linux下一个非常有用的磁盘命令。它可以将指定大小的块拷贝成一个文件,
并在拷贝的同时执行指定的转换。由于dd命令允许二进制读写,所以特别适合在原始
物理设备上进行输入/输出操作。下面介绍几则dd命令的使用技巧。
一、为软盘创建镜像文件
使用如下命令创建软盘镜像。
#dd if=/dev/fd0 of=disk.img bs=1440k
使用dd命令制作出的软盘镜像文件能在HD-Copy或winimage下使用。
二、制作优盘启动盘
首先打开linux的安装光盘,将images目录下的diskboot.img文件复制到/root目录下
,然后将优盘挂载到/dev/sdb,然后执行如下命令即可:
#dd if=/root/diskboot.img of=/dev/sdb bs=125682176
优盘需要为引导型并且要分出引导分区。
三、使用windows引导linux
提取引导文件
#dd if=/dev/hdaN of=/bootsect.lnx bs=512 count=1
编辑boot.ini文件
将上面生成的bootsect.lnx文件复制到c:\下,并在boot.ini文件中增加一行:c:\boo
tsect.lnx="Linux"
四、备份还原硬盘主引导记录
1、备份硬盘主引导记录
#dd if=/dev/hda of=/disk.mbr bs=512 count=1
2、还原硬盘主引导记录
#dd if=/disk.mbr of=/dev/hda bs=512 count=1
五、要切割的大文件为DGJD,共98336321字节,则:
dd if=dgjd of=zz1 bs=1 count=20000000
dd if=dgjd of=zz2 bs=1 count=20000000 skip=20000000
dd if=dgjd of=zz3 bs=1 count=20000000 skip=40000000
dd if=dgjd of=zz4 bs=1 count=20000000 skip=60000000
dd if=dgjd of=zz5 bs=1 count=18336321 skip=80000000
其中IF(INPUT FILENAME)是要切割的大文件名,OF(OUTPUT
FILENAME)是切割后的子文件名,BS是指明以多少字节作为一个切割记录单位,COUNT
是要切割的单位记录数,SKIP是说明切割时的起点,单位同样以BS设定值为准。通过
上述五条指令就将
DGJD大文件切割成为4个2千万字节、1个18336321字节的子文件。要注意的是SKIP的值
不能错。
由此也不难看出,DD切割是“非损耗”式的切割,并且支持从任意位置开始的任意大小
的切割。
要将生成的ZZ1、ZZ2、ZZ3、ZZ4四个子文件组装为XDGJD,则:
dd if=zz1 of=xdgjd bs=1 count=20000000
dd if=zz2 of=xdgjd bs=1 count=20000000 seek=20000000
dd if=zz3 of=xdgjd bs=1 count=20000000 seek=40000000
dd if=zz4 of=xdgjd bs=1 count=20000000 seek=60000000
dd if=zz5 of=xdgjd bs=1 count=18336321 seek=80000000
其中SKIP参数改为SEEK参数,指明组装的新大文件XDGJD每次的开始位置是从文件头开
始多少字节。如果缺省,则组装从文件头开始,显然这不是我们每次都希望的,
所以需用SEEK参数明确指出开始位置。通过以上5个指令,即可将5个子文件重新组装
为一个大文件。将切割后生成的子文件重新用FTP传送,结果有的能够顺利传送,
有的仍然导致网络瘫痪,不怕,继续切割,切成每个一千万字节,再传,OK!成功传
送!
http://hll142475.blog.163.com/blog/static/621382009249558136/
dd工具使用
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 BYTESBLOCKSIZE
---------------------------------------- ---------- ----------
/opt/oracle/oradata/test1/system01.dbf360710144 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 Area167772160 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.
从这个测试可以看出:
1)从小裸设备到大裸设备,只需把小裸设备的所有数据块dd到大裸设备即可
2)是否可以把大裸设备上的数据文件dd到小裸设备,取决于位于大裸设备上的数据文件尺寸(+block 0)是否比小裸设备小。如果数据文件小于小裸设备,则可以把数据文件从大裸设备dd到小裸设备上,在dd过程中不需要太准确计算原来数据文件的大小,只要保证dd的总量大于数据文件并小于小裸设备的尺寸即可。
3)如果数据文件大于小裸设备的尺寸,则肯定不能把它从大裸设备拷贝到小裸设备上
4)裸设备之间拷贝数据文件比裸设备到文件系统之间拷贝的有点在于:不需要精确计算要拷贝多少数据,只需要保证覆盖了数据文件+block 0即可;而从裸设备到文件系统拷贝数据文件时,必须准确计算出要拷贝的数据量(数据文件+block 0),dd多一点或者少一点都会报错。
5)如果有offset的话,在裸设备之间拷贝数据文件的时候都要考虑(skip、seek)
从文件系统到裸设备拷贝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 Area167772160 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 Area167772160 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 BYTESBLOCKSIZE
------------------------- ---------- ----------
/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 Area167772160 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)