dd命令詳解

dd指令使用
語法格式
dd   [option]
dd指令選項詳解

if=file:輸入文件名,缺省爲標準輸入

of=file:輸出文件名,缺省爲標準輸出
ibs=bytes:一次讀入 bytes 個字節(即一個塊大小爲 bytes 個字節)
obs=bytes:一次寫 bytes 個字節(即一個塊大小爲 bytes 個字節)
bs=bytes:同時設置讀寫塊的大小爲 bytes ,可代替 ibs 和 obs
cbs=bytes:一次轉換 bytes 個字節,即轉換緩衝區大小
skip=blocks:從輸入文件開頭跳過 blocks 個塊後再開始複製
seek=blocks:從輸出文件開頭跳過 blocks 個塊後再開始複製。(通常只有當輸出文件是磁盤或磁帶時纔有效)
count=blocks:僅拷貝 blocks 個塊,塊大小等於 ibs 指定的字節數
conv=ASCII:把EBCDIC碼轉換爲ASCIl碼。
conv=ebcdic:把ASCIl碼轉換爲EBCDIC碼。
conv=ibm:把ASCIl碼轉換爲alternate EBCDIC碼。
conv=block:把變動位轉換成固定字符。
conv=ublock:把固定位轉換成變動位。
conv=ucase:把字母由小寫轉換爲大寫。
conv=lcase:把字母由大寫轉換爲小寫。
conv=notrunc:不截短輸出文件。
conv=swab:交換每一對輸入字節。
conv=noerror:出錯時不停止處理。
conv=sync:把每個輸入記錄的大小都調到ibs的大小(用NUL填充)。
注意:指定數字的地方若以下列字符結尾乘以相應的數字:b=512, c=1,  k=1024, w=2, xm=number  m,kB=1000,K=1024,MB=1000*1000,M=1024*1024,GB=1000*1000*1000,G=1024*1024*1024
dd使用實例
假設了如下的情況:
要備份的數據文件:30720KB
block 0 =8 KB.
raw offset 64 KB.
設定 bs=8k
1、從raw設備備份到raw設備
dd if=/dev/rsd1b of=/dev/rsd2b bs=8k skip=8 seek=8 count=3841
2、裸設備到文件系統
dd if=/dev/rsd1b of=/backup/df1.dbf bs=8k skip=8 count=3841
3、文件系統到裸設備
dd if=/backup/df1.dbf of=/dev/rsd2b bs=8k seek=8
4、文件系統到文件系統,你可以爲了提升I/O把bs設爲較高的數值
dd if=/oracle/dbs/df1.dbf of=/backup/df1.dbf bs=1024k
5、備份/dev/hdx全盤數據,並利用gzip工具進行壓縮,保存到指定路徑(bzip2工具也一樣可使用)
dd  if=/dev/hdx  |  gzip > /path/to/p_w_picpath.gz

6、生成1G的虛擬塊設備Sparse File(稀疏文件)
dd if=/dev/zero of=1G.img bs=1M seek=1000 count=0

Sparse File是什麼,稀疏文件,也就是說,是一個擁有空的空間的文件,磁盤塊將並沒分配給這些文件。如果這些空的空間填滿ASCII的NULL字符,那麼文件纔會是實際的大小。
7、拷貝光盤數據到backup文件夾下,並保存爲cd.iso文件,再進行刻錄
dd  if=/dev/cdrom  of=/backup/cd.iso
cdrecord -v cd.iso

8、將內存裏的數據拷貝到backup目錄下的mem.bin文件
dd if=/dev/mem of=/backup/mem.bin bs=1024
9、將軟驅數據備份到當前目錄的disk.img文件
dd if=/dev/fd0 of=disk.img count=1 bs=1440k
10、將備份文件恢復到指定盤
dd if=/backup/df1.dbf of=/dev/rsd1b
11、將壓縮的備份文件恢復到指定盤
gzip -dc /path/to/p_w_picpath.gz | dd of=/dev/hdx

12、測試磁盤寫能力

time dd if=/dev/zero of=/test.dbf bs=8k count=300000
因爲/dev/zero是一個僞設備,它只產生空字符流,對它不會產生IO,所以,IO都會集中在of文件中,of文件只用於寫,所以這個命令相當於測試磁盤的寫能力。
13、測試磁盤讀能力
time dd if=/dev/sdb1 of=/dev/null bs=8k
因爲/dev/sdb1是一個物理分區,對它的讀取會產生IO,/dev/null是僞設備,相當於黑洞,of到該設備不會產生IO,所以,這個命令的IO只發生在/dev/sdb1上,也相當於測試磁盤的讀能力。
14、測試同時讀寫能力
time dd if=/dev/sdb1 of=/test1.dbf bs=8k
這個命令下,一個是物理分區,一個是實際的文件,對它們的讀寫都會產生IO(對/dev/sdb1是讀,對/test1.dbf是寫),假設他們都在一個磁盤中,這個命令就相當於測試磁盤的同時讀寫能力

15、備份磁盤開始的512Byte大小的MBR信息到指定文件
dd  if=/dev/hdx  of=/path/to/p_w_picpath  count=1  bs=512
16、恢復MBR
dd if=/mnt/windows/linux.lnx of=/dev/hda bs=512 count=1

17、  得到最恰當的block size。 通過比較dd指令輸出中所顯示的命令執行時間(選時間最少的那個),即可確定系統最佳的block size大小
dd if=/dev/zero bs=1024 count=1000000 of=/root/1Gb.file
dd 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

Oracle數據庫的dd備份

說明,以下實驗操作系統版本爲RHEL 5.4沒有offset

Raw offset
在一些os上,在裸設備上的文件的開頭是被os使用的。這些存儲空間被叫做raw offset,Oracle不會備份和恢復這些內容(字節)。因此,備份的時候要跳過含有offset的字節。 目前只有AIX和Tru64系統的裸設備存在offset,詳細信息如下
UNIX     OS Reserved Size
------------ ----------------
SUN Solaris          0
HP-UX               0
IBM AIX             4k   
Tru64 UNIX          64k
Linux              0

在 Aix環境中,如果是使用了原始VG,或者是Big VG,但是創建LV的時候沒有指定-T  O標籤,創建出來的LV都帶有4K保留空間,如果把這些LV作爲裸設備使用,則需要注意這個4K的問題。如果是使用了Scalable-type  VG,或者是使用Big VG,而且在創建VG的時候使用了-T O標籤,則創建的LV沒有4K保留空間,稱爲DS_LVZ類型的LV。

在AIX平臺下,我們可以使用$ORACLE_HOME/bin路徑下的dbfsize命令確認裸設備是否包含offset
下面是包含offset的裸設備
#dbfsize /dev/rlv_data01_10g
Database file: /dev/rlv_data01_10g
Database file type:raw device
Database file size: 1048448 8192 byte blocks

下面是不包含offset的裸設備
#dbfsize /dev/rlv_data01_10g
Database file: /dev/rlv_data01_10g
Database file type:raw device without 4K starting offset
Database file size: 1048448 8192 byte blocks

block 0
在 每個oracle文件的開頭,os系統放置了一個塊叫做block 0。 這個塊的大小和其所在數據文件的oracle塊大小相同。 一般的oracle  代碼不能識別這個塊,但是這個塊是包含在os上的文件大小裏面的。就是說oracle認爲datafile1大小爲100塊,但是os看來,datafile1大小爲101塊(100+block 0). 注意,利用dd備份時,需要包含block 0。因爲block  0位於offset之後,而block 0是所有數據文件都需要的,無論它是基於裸備還是文件系統,且block 0的大小隻與oracle的block size有關,所以,把block 0也dd出來是必要的,不需要skip數據文件的block 0。

計算數據文件的佔用的實際空間大小
實際的數據文件大小是在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

在操作系統查看文件大小:
# 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、創建裸設備

# fdisk /dev/sdd
The number of cylinders for this disk is set to 25856.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
   (e.g., DOS FDISK, OS/2 FDISK)

Command (m for help): n
Command action
   l   logical (5 or over)
   p   primary partition (1-4)
l
First cylinder (4201-4485, default 4201):
Using default value 4201
Last cylinder or +size or +sizeM or +sizeK (4201-4485, default 4485): +10M

Command (m for help): n
Command action
   l   logical (5 or over)
   p   primary partition (1-4)
l
First cylinder (4212-4485, default 4212): 
Using default value 4212
Last cylinder or +size or +sizeM or +sizeK (4212-4485, default 4485): +20M

Command (m for help): n
Command action
   l   logical (5 or over)
   p   primary partition (1-4)
l
First cylinder (4232-4485, default 4232):
Using default value 4232
Last cylinder or +size or +sizeM or +sizeK (4232-4485, default 4485): +30M

Command (m for help): n
Command action
   l   logical (5 or over)
   p   primary partition (1-4)
l
First cylinder (4262-4485, default 4262):
Using default value 4262
Last cylinder or +size or +sizeM or +sizeK (4262-4485, default 4485): +40M


Command (m for help): p

Disk /dev/sdd: 27.1 GB, 27111981056 bytes
64 heads, 32 sectors/track, 25856 cylinders
Units = cylinders of 2048 * 512 = 1048576 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sdd1               1        3816     3907568   83  Linux
/dev/sdd4            3817        4485      685056    5  Extended
/dev/sdd5            3817        3912       98288   83  Linux
/dev/sdd6            3913        4008       98288   83  Linux
/dev/sdd7            4009        4104       98288   83  Linux
/dev/sdd8            4105        4200       98288   83  Linux
/dev/sdd9            4201        4211       11248   83  Linux
/dev/sdd10           4212        4231       20464   83  Linux
/dev/sdd11           4232        4261       30704   83  Linux
/dev/sdd12           4262        4300       39920   83  Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
The new table will be used at the next reboot.
Syncing disks.

# partprobe

# raw /dev/raw/raw3 /dev/sdd9
/dev/raw/raw3:  bound to major 8, minor 57
# raw /dev/raw/raw4 /dev/sdd10
/dev/raw/raw4:  bound to major 8, minor 58
# raw /dev/raw/raw5 /dev/sdd11
/dev/raw/raw5:  bound to major 8, minor 59
# raw /dev/raw/raw6 /dev/sdd12
/dev/raw/raw6:  bound to major 8, minor 60

2、基於裸設備創建表空間
SQL>create tablespace mytest datafile '/dev/raw/raw3' size 5m,'/dev/raw/raw6' size 10m;
Tablespace created.

3、從小裸設備到大裸設備
# dd if='/dev/raw/raw3' of='/dev/raw/raw4'
22496+0 records in
22496+0 records out
11517952 bytes (12 MB) copied, 104.599 seconds, 110 kB/s

4、從大裸設備到小裸設備,但數據文件比小裸設備小
# dd if='/dev/raw/raw6' of='/dev/raw/raw5' bs=1024k count=12
12+0 records in
12+0 records out
12582912 bytes (13 MB) copied, 3.34273 seconds, 3.8 MB/s

注意:這裏bs*count要大於原裸設備上的數據文件尺寸
5、重啓數據庫至mount狀態
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount;
ORACLE instance started.
Total System Global Area  369098752 bytes
Fixed Size                  1219472 bytes
Variable Size             125830256 bytes
Database Buffers          239075328 bytes
Redo Buffers                2973696 bytes
Database mounted.

6、重命名數據文件,並打開數據庫
SQL> alter database rename file '/dev/raw/raw3' to '/dev/raw/raw4';
Database altered.

SQL> alter database rename file '/dev/raw/raw6' to '/dev/raw/raw5';
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就可以。
1、創建表空間,數據文件大小爲5m

SQL> create tablespace  mytest1 datafile '/home/oracle/mytest1.dbf' size 5m;
Tablespace created.
# ls -l /home/oracle/mytest1.dbf
-rw-r----- 1 oracle oinstall 5251072 Dec 16 21:37 /home/oracle/mytest1.dbf
2、dd文件到裸設備上

# dd if='/dev/zero' of='/dev/raw/raw3' bs=1024k
dd: writing `/dev/raw/raw3': No space left on device
11+0 records in
10+0 records out
11517952 bytes (12 MB) copied, 7.63555 seconds, 1.5 MB/s
# dd if=/home/oracle/mytest1.dbf of=/dev/raw/raw3
10256+0 records in
10256+0 records out
5251072 bytes (5.3 MB) copied, 35.9816 seconds, 146 kB/s

注意:從文件系統到裸設備不用設置count
3、重命名數據文件,打開數據庫
SQL> alter database rename file '/home/oracle/mytest1.dbf' to '/dev/raw/raw3';
Database altered.
SQL> alter database open;
Database altered

從裸設備到文件系統拷貝ORACLE數據文件

這裏不並不是所有情況都能把整個裸設備拷貝到文件中,要看裸設備是否有offset,如果有offset,則肯定不能全拷貝出來,需要使用skip參數跳過offset,以下演示沒有offset的情況

1、在mytest1表空間上創建表,並填充數據,然後將整個裸設備備份到文件系統

SQL> create table test tablespace mytest1
  2  as
  3  select * from dba_users;
Table created.

#dd if='/dev/raw/raw3' of='/home/oracle/mytest2.dbf' bs=512k
21+1 records in
21+1 records out
11517952 bytes (12 MB) copied, 0.804403 seconds, 14.3 MB/s

2、重啓數據庫,並充命名數據文件

SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount;
ORACLE instance started.
Total System Global Area  369098752 bytes
Fixed Size                  1219472 bytes
Variable Size             134218864 bytes
Database Buffers          230686720 bytes
Redo Buffers                2973696 bytes
Database mounted.
SQL> alter database rename file '/dev/raw/raw3' to '/home/oracle/mytest2.dbf';
Database altered.
SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-01113: file 9 needs media recovery
ORA-01110: data file 9: '/home/oracle/mytest2.dbf'
可以看到數據庫無法打開,這是因爲裸設備已被數據文件使用部分的邏輯塊與未使用部分的邏輯塊大小不一致。這種情況下,只能拷貝裸設備中數據文件大小 + block 0部分。這裏用到兩個工具
dbfsize 求出在裸設備或者文件系統上的oracle數據文件的大小,由oracle提供。
blockdev 求出裸設備的大小,操作系統自帶。
要計算出要要拷貝的大小,否則報錯,如:
$ dbfsize /dev/raw/raw3
Database file: /dev/raw/raw3
Database file type: raw device
Database file size: 640 8192 byte blocks

$ blockdev --getsize /dev/raw/raw3
22496

一般一個OS BLOCK大小是512字節,所以22496*512/1024/1024= 10.9(m) 就是裸設備的大小。

$ rm /home/oracle/mytest2.dbf
$ dd if='/dev/raw/raw3' of='/home/oracle/mytest2.dbf' bs=8k count=641

SQL> alter database open;
Database altered

 

參考至:http://hi.baidu.com/linuxtrip/item/9d2b32261dc8b7dfa417b646
              http://blog.csdn.net/wenbingcai/article/details/6250756
               http://www.2cto.com/os/201201/116333.html
               http://blog.licess.org/linux-dd/
               http://space.itpub.net/8242091/viewspace-619756
               http://www.2cto.com/os/201201/116333.html
               http://www.233.com/linux/fudao/20100226/092633340.html
                http://wenku.baidu.com/view/1d341cd076eeaeaad1f330c8.html
                 http://hll142475.blog.163.com/blog/static/621382009249558136/
                  http://www.itpub.net/thread-868663-1-1.html
                   http://oracle.chinaitlab.com/serial/393799.html
                    http://www.cnblogs.com/rootq/articles/1487267.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章