zoukankan      html  css  js  c++  java
  • 110.dd命令

    1.dd命令

    1.介绍
        dd命令介绍
        作用是用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换。可以用于测试磁盘命令、数据备份或恢复等。
    
        dd命令用于复制文件并对原文件的内容进行转换和格式化处理。用的比较多的还是用dd来备份裸设备。但是不推荐,如果需要备份oracle裸设备,可以使用rman备份,或使用第三方软件备份,使用dd的话,管理起来不太方便。建议在有需要的时候使用dd 对物理磁盘操作,如果是文件系统的话还是使用tar backup cpio等其他命令更加方便。另外,使用dd对磁盘操作时,最好使用块设备文件。
    
        语法格式:
        dd [bs=<字节数>][cbs=<字节数>][conv=<关键字>][count=<区块数>][ibs=<字节数>][if=<文件>][obs=<字节数>][of=<文件>][seek=<区块数>][skip=<区块数>][--help][--version]
    
        dd if=path/to/input_file of=/path/to/output_file bs=block_size count=number_of_blocks
    
    2.命令简介
        if=file         
        #输入文件名,缺省为标准输入。 从file读取,如if=/dev/zero,该设备无穷尽地提供0,(不产生读磁盘IO)
        of=file         
        #输出文件名,缺省为标准输出。 向file写出,可以写文件,可以写裸设备。如of=/dev/null,"黑洞",它等价于一个只写文件. 所有写入它的内容都会永远丢失. (不产生写磁盘IO)
        ibs=bytes        
        #一次读入 bytes 个字节(即一个块大小为 bytes 个字节)。 
        obs=bytes        
        #一次写 bytes 个字节(即一个块大小为 bytes 个字节)。 
        bs=bytes        
        #同时设置读写块的大小为 bytes ,可代替 ibs 和 obs。如bs=8k 每次读或写的大小,即一个块的大小为8K。 
        cbs=bytes        
        #一次转换 bytes 个字节,即转换缓冲区大小。 
        skip=blocks      
        #从输入文件开头跳过 blocks 个块后再开始复制。 (其中的块大小是ibs设置的大小,默认512)
        seek=blocks        
        #从输出文件开头跳过 blocks 个块后再开始复制。(通常只有当输出文件是磁盘或磁带时才有效)。 (其中的块大小是ibs设置的大小,默认512)
        count=blocks     
        #仅拷贝 blocks 个块,块大小等于 ibs 指定的字节数。 (其中的块大小是ibs设置的大小,默认512)
        iflag=FLAGS      
        #指定读的方式FLAGS,参见“FLAGS参数说明”
        oflag=FLAGS     
        # 指定写的方式FLAGS,参见“FLAGS参数说明”
        
        conv对应参数
        	格式:conv=conversion:用指定的参数转换文件
            ascii:转换ebcdic为ascii 
            ebcdic:转换ascii为ebcdic 
            ibm:转换ascii为alternate ebcdic 
            block:把每一行转换为长度为cbs,不足部分用空格填充 
            unblock:使每一行的长度都为cbs,不足部分用空格填充 
            lcase:把大写字符转换为小写字符 
            ucase:把小写字符转换为大写字符 
            swab:交换输入的每对字节 
            noerror:出错时不停止 
            notrunc:不截短输出文件 
            sync:将每个输入块填充到ibs个字节,不足部分用空(NUL)字符补齐。
            excl:如果文件存在就停止操作
            nocreat:不创建输出文件
            notrunc:不截断输出文件
            noerror:跳过报错信息,继续执行
            fdatasync:在完成之前物理写入输出文件数据
            fsync:同上,但是写入元数据信息
       flag参数:
        	append:追加模式,仅对输出有效,建议使用conv=notrunc
            diret: 使用直接io方式处理数据
            directory: 必须是一个目录,否则失败
            dsync: 使用同步id方式处理数据
            sync: 同上,还可以对元数据使用
            fullbolck: 使用数据块方式输入(仅对iflag有效)
            nonblock: 使用非阻塞io处理数据
            noatime: 不更行访问时间
            nocache: 删除缓存信息
            noctty: 不要从文件分配控制终端
            nofollow: 不同步符号链接
            conut_bytes: 将'count = N'视为字节计数(仅iflag有效)
            skip_bytes: 将'skip=N'视为字节计数(仅iflag有效)
      	    seek_bytes: 将'seek=N'视为字节计数(仅iflag有效)
    3.测试
        测试方式:使用dd指令,对磁盘进行连续写入,不使用内存缓冲区,每次写入8k的数据,总共写入20万次,产生1.6G大小的文件。
    
        测试指令:dd if=/dev/zero of=/data01/test.dbf bs=8k count=200k conv=fdatasync 
        1) dd用于复制,从if读出,写到of;
        2) if=/dev/zero(产生字符)不产生IO,因此可以用来测试纯写速度;
        3) bs是每次读或写的大小,即一个块的大小,count是读写块的数量;
        4)conv=fdatasync表示只把文件的“数据”写入磁盘
        5)会在/data01下生成一个文件test.dbf,count * bs 等于最终大小。
    
        从if读出写到of,不同的设备表示的不同
        从源 /dev/zero 读取写入到驱动盘的时候(测试写),当从驱动盘读取时写入到/dev/null(测试读)。在整个操作过程中,DD 命令会跟踪数据传输的速度并且报告出结果。
    
    4./dev/null和/dev/zero的区别
        /dev/null,它是空设备,也称为位桶(bit bucket)、回收站、无底洞,可以向它输出任何数据。任何写入它的输出都会被抛弃。如果不想让消息以标准输出显示或写入文件,那么可以将消息重定向到位桶。
        /dev/zero,是一个输入设备,可用它来初始化文件。该设备无穷尽地提供0,可以使用任何需要的数目——设备提供的要多的多。他可以用于向设备或文件写入字符串0。
    
    5.sync、fsync、fdatasync参数
        dd bs=8k count=4k if=/dev/zero of=test.log conv=fsync 
        dd bs=8k count=4k if=/dev/zero of=test.log conv=fdatasync
        dd bs=8k count=4k if=/dev/zero of=test.log oflag=dsync
        dd bs=8k count=4k if=/dev/zero of=test.log  默认“写缓存”启作用
        dd bs=8k count=4k if=/dev/zero of=test.log conv=sync   “写缓存”启作用
        dd bs=8k count=4k if=/dev/zero of=test.log; sync   “写缓存”启作用
    
        1)dd bs=8k count=4k if=/dev/zero of=test.log conv=fsync 
        加入这个参数后,dd命令执行到最后会真正执行一次“同步(sync)”操作,这样算出来的时间才是比较符合实际使用结果的。conv=fsync表示把文件的“数据”和“metadata”都写入磁盘(metadata包括size、访问时间st_atime & st_mtime等等),因为文件的数据和metadata通常存在硬盘的不同地方,因此fsync至少需要两次IO写操作,fsync 与fdatasync相差不大。(重要,最有参考价值)
        2)dd bs=8k count=4k if=/dev/zero of=test.log conv=fdatasync
    加入这个参数后,dd命令执行到最后会真正执行一次“同步(sync)”操作,,这样算出来的时间才是比较符合实际使用结果的。conv=fdatasync表示只把文件的“数据”写入磁盘,fsync 与fdatasync相差不大。(重要,最有参考价值)
        3)dd bs=8k count=4k if=/dev/zero of=test.log oflag=dsync
    加入这个参数后,dd在执行时每次都会进行同步写入操作。每次读取8k后就要先把这8k写入磁盘,然后再读取下面一个8k,一共重复4K次,生成一个32M文件。这是最慢的一种方式了,基本上没有用到写缓存(write cache)。也是比较准确的。
    	conv=fdatasync与oflag=dsync的区别在于:sync函数只是将所有修改过的块缓冲区排入写队列,然后就返回,它并不等待实际写磁盘操作结束。fsync函数只对由文件描述符filedes指定的单一文件起作用,并且等待写磁盘操作结束,然后返回。所以看到的fdatasync速度比dsync好。
        4)dd bs=8k count=4k if=/dev/zero of=test
    没有加任何参数,dd默认的方式不包括“同步(sync)”命令(没加关于操作系统“写缓存”的参数,默认“写缓存”启作用),也就是说,dd命令完成前并没有让系统真正把文件写到磁盘上。dd先把数据写到操作系统“写缓存”,就完成了写操作。所以以上命令只是单纯地把数据读到内存缓冲当中(写缓存[write cache])。通常称为update的系统守护进程会周期性地(一般每隔30秒)调用sync函数,把“写缓存”中的数据刷入磁盘。
    	因为“写缓存”起作用,会测试出一个超快的性能。因为dd给的只是读取速度,直到dd完成后系统才开始真正往磁盘上写数据,但这个速度是看不到了。
    	如:163840000 bytes (164 MB) copied, 0.742906 seconds, 221 MB/s
        5)dd bs=8k count=4k if=/dev/zero of=test conv=sync  
    	conv=sync参数明确“写缓存”启作用,默认值就是conv=sync
        6)dd bs=8k count=4k if=/dev/zero of=test; sync 
    	和默认的不加参数一样,分号隔开的只是先后两个独立的命令。当sync命令准备开始往磁盘上真正写入数据的时候,前面dd命令已经把错误的“写入速度”值显示在屏幕上了。所以还是得不到真正的写入速度。
    
    6.设备测试
        1)裸设备到文件系统
        dd if=/dev/rsd1b of=/backup/df1.dbf bs=8k skip=8 count=3841
        2)文件系统到裸设备
        dd if=/backup/df1.dbf of=/dev/rsd2b bs=8k seek=8
        
    7.关于io方式
    	正常系统调用read/write流程
        硬盘->内核缓冲区->用户缓冲区
        用户缓冲区->内核缓冲区->硬盘
        Direct IO
        跨过内核缓冲区,从用户缓冲区直接写盘,在Oracle里应该是跨过SGA,从PGA——>datafile
        SYNC IO
        会话发起IO请求时,整个会话阻塞,直到IO完成,在Oracle里比较典型的是lgwr,用户commit后必须等待lgwr写完才能返回
        ASYNC IO
        发出IO请求后,丢给内核去做,在Oracle表现为设置了dbwr_io_slaves,dbwr收集脏块后丢给slave进程去写盘
        
    8.测试磁盘读写速度
        测试时常会加上time计时
        1)只测试磁盘写能力
        time dd if=/dev/zero of=test.log bs=64k,count=4k
        因为/dev//zero是一个伪设备,它只产生空字符流,对它不会产生IO,所以,IO都会集中在of文件中,of文件只用于写,所以这个命令相当于测试磁盘的写能力。命令结尾添加oflag=direct将跳过内存缓存,添加oflag=sync将跳过hdd缓存。
    
        2)只测试磁盘读能力
        time dd if=/dev/sdb of=/dev/null bs=64k
        因为/dev/sdb是一个物理分区,对它的读取会产生IO,/dev/null是伪设备,相当于黑洞,of到该设备不会产生IO,所以,这个命令的IO只发生在/dev/sdb上,也相当于测试磁盘的读能力。(Ctrl+c终止测试)
        读取某个文件测试磁盘读能力时,要首先清除内存的缓存,以确保这个文件确实是从驱动盘读取的。否则是从page cache里取的值。
        运行下面的命令来清除内存缓存
        $ sudo sh -c "sync && echo 3 > /proc/sys/vm/drop_caches"
        执行完后再执行dd命令,如dd if=./test.log of=/dev/null bs=4k
        实际测试,写入一个文件128M,查看free -m里cached增加128M,执行读取命令结果2.7GB,再执行清缓存命令后,同样命令读取速度变为135MB。
    
        3)测试同时读写能力
        time dd if=/dev/sdb of=/testrw.dbf bs=64k
        一个是物理分区,一个是实际的文件,对它们的读写都会产生IO(对/dev/sdb是读,对/testrw.dbf是写),假设它们都在一个磁盘中,这个命令就相当于测试磁盘的同时读写能力。
    
        4)测试纯写入性能
        dd if=/dev/zero of=test bs=8k count=10000 oflag=direct
        
        5)测试纯读取性能
        dd if=test of=/dev/null bs=8k count=10000 iflag=direct 
        注意:dd 只能提供一个大概的测试结果,而且是连续 I/O(顺序IO) 而不是随机 I/O,理论上文件规模越大,测试结果越准确。 同时,iflag/oflag 提供 direct 模式,direct 模式是把写入请求直接封装成 I/O 指令发到磁盘,非 direct 模式只是把数据写入到系统缓存就认为 I/O 成功,并由操作系统决定缓存中的数据什么时候被写入磁盘。
        还可以监控下dd执行的进度:https://blog.csdn.net/xyz846/article/details/7367962
            
    9.
    疑问1:fdatasync 、fsync 、dsync 几种方式,建议用哪种呢?
    建议dd bs=8k count=4k  if=/dev/zero of=test.log conv=fdatasync 
    因为这种方式最接近计算机实际操作,所以测出来的数据最有参考价值。??
      1. dd if=/dev/zero of=test bs=64k count=16k
      这个很不准确的,因为命令结束的时候数据还没有真正写到磁盘上去
    
      2. dd if=/dev/zero of=test bs=64k count=16k conv=fsync
      这个还算准确,数据已经写入磁盘
    
      3. dd if=/dev/zero of=test bs=64k count=4k oflag=dsync
      这个可以当成是模拟数据库插入操作,所以很慢  
    -dsync 可以当成是模拟数据库插入操作,在/dev/zone中读出一条数据就立即写入硬盘
    -fsync 同样也是将数据已经写入磁盘,但是是在经过缓存后最后再写入硬盘
    
    疑问2:同一块磁盘,不同bs与count的组合,测试结果不同?
    测试结果磁盘写速度肯定不同。
    同一块磁盘,同一命令每次结果都可能会不同,需要多采样几次,取平均值。
    
    疑问3:bs表示一个块大小,count为次数。应该如何设置bs、count的值,测试更准确?
    常用的有bs=64k,count=4k
    bs的大小:1M的大小实际上是相当大的。小尺寸如 64K 甚至是 4K 的。
    常用命令
    dd if=/dev/zero of=test bs=64k count=4k oflag=dsync
    dd if=/dev/zero of=test bs=8k count=256k conv=fdatasync
    
    转载:
        https://www.cnblogs.com/sylar5/p/6649009.html
    参考:
        https://www.iteye.com/blog/elf8848-2089055
        https://www.cnblogs.com/sylar5/p/6649009.html
    
  • 相关阅读:
    Linux 命令查找文件中某个字段所存在的位置
    PHP in_array() 函数
    php一维数组如何追加到二维数组
    电脑切换窗口
    微擎前端逻辑判断的时弹框
    JDBC批量处理
    数据库事务
    处理BLOB
    JDBC自动生成主键值
    JDBC的元数据
  • 原文地址:https://www.cnblogs.com/liuzhanghao/p/13936914.html
Copyright © 2011-2022 走看看