前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux的dd指令

Linux的dd指令

作者头像
bisal
发布2021-09-06 15:37:44
4.5K0
发布2021-09-06 15:37:44
举报
文章被收录于专栏:bisal的个人杂货铺

当我们碰到数据库响应慢的时候,除了数据库自己的问题,磁盘读写可能是其中一个值得怀疑的因素,此时就可以用dd来测试磁盘的读写速度。

Linux的dd指令,可以用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换。

man的说明,言简意赅,

dd - convert and copy a file

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=conversion[,conversion…] 用指定的参数转换文件。 iflag=FLAGS 指定读的方式FLAGS,参见“FLAGS参数说明” oflag=FLAGS 指定写的方式FLAGS,参见“FLAGS参数说明”

其中conv参数,可转换的值如下,

ascii 转换 EBCDIC 为 ASCII。 ebcdic 转换 ASCII 为 EBCDIC。 ibm 转换 ASCII 为 alternate EBCDIC。 block 把每一行转换为长度为 cbs 的记录,不足部分用空格填充。 unblock 使每一行的长度都为 cbs ,不足部分用空格填充。 lcase 把大写字符转换为小写字符。 ucase把小写字符转换为大写字符。 swab 交换输入的每对字节。 noerror出错时不停止。 notrunc不截短输出文件。 sync 把每个输入块填充到ibs个字节,不足部分用空(NUL)字符补齐。

FLAGS参数说明,

append -append  mode  (makes  sense  only  for output; conv=notrunc sug-gested) direct 读写数据采用直接IO方式。 directory 读写失败除非是directory。 dsync 读写数据采用同步IO。 sync 同上,但是针对是元数据。 fullblock 堆积满block(accumulate full blocks of input)(iflag only)。 nonblock 读写数据采用非阻塞IO方式。 noatime 读写数据不更新访问时间。

一看这些参数,有点懵了,直接来点儿硬菜,为了测试磁盘的写能力,可以执行这个,因为/dev/zero是一个伪设备,他只产生空字符流,对他不会产生IO,所以,IO都会集中在of文件中,of文件只用于写,所以这个命令相当于测试磁盘的写能力,写入100000个4k数据块,

代码语言:javascript
复制
[root@bisal opt]# time dd if=/dev/zero of=/opt/testrw.dbf bs=4k count=100000
100000+0 records in
100000+0 records out
409600000 bytes (410 MB) copied, 1.92835 s, 212 MB/s
real  0m1.929s
user  0m0.000s
sys  0m1.444s

P.S. count是指读多少个bs,可以直接写count=16G,规避文件系统cache,直接读写,不直接使用buffer cache。

如果要测试磁盘读的能力,可执行这个,因为/dev/sda1是一个物理分区,对他的读取会产生IO,/dev/null是伪设备,相当于黑洞,of到该设备不会产生IO,所以,这个命令的IO只发生在/dev/sda1,相当于测试磁盘的读能力,

代码语言:javascript
复制
[root@bisal ~]# time dd if=/dev/sda1 of=/dev/null bs=4k
^C140287+0 records in
140286+0 records out
574611456 bytes (575 MB) copied, 12.62 s, 45.5 MB/s
real  0m12.621s
user  0m0.037s
sys  0m12.340s

如果要同时测试读写,一个是物理分区,一个是实际的文件,对他们的读写都会产生IO(对/dev/sda1是读,对/opt/testrw.dbf是写,会实际生成文件,因此要确认磁盘空间充足),假设他们都在一个磁盘中,这个命令就相当于测试磁盘的同时读写能力,

代码语言:javascript
复制
[root@bisal opt]# time dd if=/dev/sda1 of=/opt/testrw.dbf bs=4k
^C56537+0 records in
56537+0 records out
231575552 bytes (232 MB) copied, 3.891 s, 59.5 MB/s
real  0m3.892s
user  0m0.000s
sys  0m2.522s

另外,注意一下,dd只能提供一个大概的测试结果,而且是连续I/O而不是随机I/O,理论上文件规模越大,测试结果越准确。同时,iflag/oflag提供direct模式,direct模式是把写入请求直接封装成I/O指令发到磁盘,非direct模式只是把数据写入到系统缓存就认为I/O成功,并由操作系统决定缓存中的数据什么时候被写入磁盘。

借了这个例子,可以看下缓存对读写的影响,

https://blog.csdn.net/rong11417/article/details/102654966

带缓存的读写,

每次清缓存的读写,

不用缓存,直接的读写,

如上提到的/dev/null和/dev/zero,还是有点儿区别,我们经常在脚本中或者crontab定义中使用到/dev/null。

/dev/null,外号叫无底洞,你可以向他输出任何数据,他通吃,并且不会撑着。他是空设备,也称为位桶(bit bucket)。任何写入他的输出都会被抛弃。如果不想让消息以标准输出显示或写入文件,那么可以将消息重定向到位桶。

/dev/zero,是一个输入设备,你可用他来初始化文件。该设备无穷尽地提供0,可以使用任何你需要的数目,他可以用于向设备或文件写入字符串0。主要的用处是用来创建一个指定长度用于初始化的空文件,就像临时交换文件。

例如,禁止标准输出,

代码语言:javascript
复制
cat $filename >/dev/null #文件内容丢失,而不会输出到标准输出.

禁止标准错误,

代码语言:javascript
复制
rm $filename 2>/dev/null #这样错误信息[标准错误]就被丢了

禁止标准输出和标准错误的输出,

代码语言:javascript
复制
cat $filename 2>/dev/null >/dev/null

参考链接,

https://www.cnblogs.com/sylar5/p/6649009.html

https://blog.csdn.net/xizaihui/article/details/53307578

https://blog.csdn.net/rong11417/article/details/102654966

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/07/22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档