block_dump观察Linux IO写入的具体文件(mysqld)
一、使用方法:
需要先停掉syslog功能,因为具体IO数据要通过printk输出,如果syslog存在,则会往message产生大量IO,干扰正常结果
12 | suse:~ # service syslog stopShutting down syslog services done |
然后启动block_dump
1 | suse:~ # echo 1 > /proc/sys/vm/block_dump |
先说效果:
12345678910111213141516 | suse:~ # dmesg | taildmesg(3414): dirtied inode 9594 (LC_MONETARY) on sda1dmesg(3414): dirtied inode 9238 (LC_COLLATE) on sda1dmesg(3414): dirtied inode 9241 (LC_TIME) on sda1dmesg(3414): dirtied inode 9606 (LC_NUMERIC) on sda1dmesg(3414): dirtied inode 9350 (LC_CTYPE) on sda1kjournald(506): WRITE block 3683672 on sda1kjournald(506): WRITE block 3683680 on sda1kjournald(506): WRITE block 3683688 on sda1kjournald(506): WRITE block 3683696 on sda1kjournald(506): WRITE block 3683704 on sda1kjournald(506): WRITE block 3683712 on sda1kjournald(506): WRITE block 3683720 on sda1kjournald(506): WRITE block 3683728 on sda1kjournald(506): WRITE block 3683736 on sda1kjournald(506): WRITE block 3683744 on sda1 |
通过dmesg信息可以看到IO正在写那些文件,有进程号,inode号,文件名和磁盘设备名;但每个文件写了多少呢,仅仅通过dirtied inode就看不出来了,还需要分析WRITE block,后面的数字并不是真正的块号,而是内核IO层获取的扇区号,除以8即为块号,然后根据debugfs工具的icheck和ncheck选项,就可以获取该文件系统块属于哪个具体文件,具体请google之。
二、基本原理:block_dump的原理其实很简单,内核在IO层根据标志block_dump在IO提交给磁盘的关口卡主过关的每一个BIO,将它们的数据打出来:
12345678910111213141516171819202122232425262728293031 | void submit_bio(int rw, struct bio *bio){ int count = bio_sectors(bio); bio->bi_rw |= rw; /* * If it‘s a regular read/write or a barrier with data attached, * go through the normal accounting stuff before submission. */ if (bio_has_data(bio) && !(rw & REQ_DISCARD)) { if (rw & WRITE) { count_vm_events(PGPGOUT, count); } else { task_io_account_read(bio->bi_size); count_vm_events(PGPGIN, count); } if (unlikely(block_dump)) { char b[BDEVNAME_SIZE]; printk(KERN_DEBUG "%s(%d): %s block %Lu on %s (%u sectors)n", current->comm, task_pid_nr(current), (rw & WRITE) ? "WRITE" : "READ", (unsigned long long)bio->bi_sector, bdevname(bio->bi_bdev, b), count); } } generic_make_request(bio);} |
具体WRITE block块号和文件系统块号之间的对应关系在submit_bh函数中决定
1 | bio->bi_sector = bh->b_blocknr * (bh->b_size >> 9); |
inode的block_dump实现是通过block_dump___mark_inode_dirty搞定的,这次把关口架在inode脏数据写回的路上,把每个过关的inode信息打出来:
12345678910111213141516171819202122232425262728 | void __mark_inode_dirty(struct inode *inode, int flags){ if (unlikely(block_dump))block_dump___mark_inode_dirty(inode); } static noinline void block_dump___mark_inode_dirty(struct inode *inode){if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev")) {struct dentry *dentry;const char *name = "?"; dentry = d_find_alias(inode);if (dentry) {spin_lock(&dentry->d_lock);name = (const char *) dentry->d_name.name;}printk(KERN_DEBUG"%s(%d): dirtied inode %lu (%s) on %sn",current->comm, task_pid_nr(current), inode->i_ino,name, inode->i_sb->s_id);if (dentry) {spin_unlock(&dentry->d_lock);dput(dentry);} } |
三、总结
1.内核由很多合适的关口来截获获取的IO信息,不改动内核,也可以用jprobe抢劫很多东西。
2.debugfs在大量的block–>file转换过程总太慢,自己用ext2fs写一个,效率应该能提高很多。
—结束—
block_dump观察Linux IO写入的具体文件–OenHan
http://www.oenhan.com/block-dump-linux-io
[root@server-mysql log]# echo 5 > /proc/sys/vm/block_dump
[root@server-mysql log]# dmesg -c |grep mysqldmysqld(11780): dirtied inode 1069049 (ib_logfile0) on sda3mysqld(11780): dirtied inode 1069049 (ib_logfile0) on sda3mysqld(11780): WRITE block 8236616 on sda3mysqld(9674): dirtied inode 1069048 (ibdata1) on sda3mysqld(9674): dirtied inode 1069048 (ibdata1) on sda3mysqld(9674): WRITE block 8144896 on sda3mysqld(9674): WRITE block 8144904 on sda3mysqld(9674): WRITE block 8144912 on sda3mysqld(9674): WRITE block 8144920 on sda3mysqld(9674): WRITE block 8144928 on sda3mysqld(9674): WRITE block 8144936 on sda3mysqld(9674): WRITE block 8144944 on sda3mysqld(9674): WRITE block 8144952 on sda3mysqld(9674): dirtied inode 1071023 (kk.ibd) on sda3mysqld(9674): dirtied inode 1071023 (kk.ibd) on sda3mysqld(9663): WRITE block 32762104 on sda3mysqld(9663): WRITE block 32762112 on sda3mysqld(9663): WRITE block 32762120 on sda3mysqld(9663): WRITE block 32762128 on sda3mysqld(9663): WRITE block 16177376 on sda3mysqld(9663): WRITE block 16177384 on sda3mysqld(9663): WRITE block 16177392 on sda3mysqld(9663): WRITE block 16177400 on sda3mysqld(9658): WRITE block 8175616 on sda3
block_dump观察Linux IO写入的具体文件(mysqld)
标签:
小编还为您整理了以下内容,可能对您也有帮助:
linuxmysqld
mysqld与mysql的关系到底是怎么样,请说的详细点?
mysqld是服务,mysql是客户端。mysqld其实是SQL后台程序(也就是MySQL服务器),它是关于服务器端的一个程序,mysqld意思是mysqldaemon,在后台运行,监听3306端口,如果你想要使用客户端程序,这个程序必须运行,因为客户端是通过连接服务器来访问数据库的。
你只有启动了mysqld.exe,你的mysql数据库才能工作。mysql是一个客户端软件,可以对任何主机的mysql服务(即后台运行的mysqld)发起连接,mysql自带的客户端程序一般都在cmd或者终端下进行操作
linux下怎么启动mysql服务?
Linux启动/停止/重启Mysql数据库的方法
1、查看mysql版本
方法一:status;
方法二:selectversion();
2、Mysql启动、停止、重启常用命令
a、启动方式
1、使用service启动:
#servicemysqldstart(5.0版本是mysqld)
#servicemysqlstart(5.5.7版本是mysql)
2、使用mysqld脚本启动:
/etc/inint.d/mysqldstart
3、使用safe_mysqld启动:
safe_mysqld
b、停止
1、使用service启动:
servicemysqldstop
2、使用mysqld脚本启动:
/etc/inint.d/mysqldstop
3、mysqladminshutdown
c、重启
1、使用service启动:
servicemysqldrestart
servicemysqlrestart(5.5.7版本命令)
2、使用mysqld脚本启动:
/etc/init.d/mysqldrestart
如何修改linux服务器上的mysql数据库密码?
1.首先用管理员权限登陆Linux;
2.输入:vi/etc/my.cnf回车。然后按“i”键盘,在这个文件中的最后一行输入:skip-grant-tables然后按esc键,然后输入“:wq”保存并退出;
3.重启MySQL服务输入:servicemysqldrestart回车;
4.输入mysql-uroot-p;然后提示你输入密码,直接回车就可以进入mysql数据库了!
Linux上MySQL优化提升性能哪些可以优化的关闭NUMA特性?
Linux上MySQL优化提升性能,可以优化关闭NUMA特性如下:
这些其实都源于CPU最新的技术:节能模式。操作系统和CPU硬件配合,系统不繁忙的时候,为了节约电能和降低温度,它会将CPU降频。
为了保证MySQL能够充分利用CPU的资源,建议设置CPU为最大性能模式。这个设置可以在BIOS和操作系统中设置,当然,在BIOS中设置该选项更好,更彻底。
然后我们看看内存方面,我们有哪些可以优化的。
i)我们先看看numa
非一致存储访问结构(NUMA:Non-UniformMemoryAccess)也是最新的内存管理技术。它和对称多处理器结构(SMP:SymmetricMulti-Processor)是对应的。
我们可以直观的看到:SMP访问内存的都是代价都是一样的;但是在NUMA架构下,本地内存的访问和非本地内存的访问代价是不一样的。对应的根据这个特性,操作系统上,我们可以设置进程的内存分配方式。目前支持的方式包括:
--interleave=nodes
--membind=nodes
--cpunodebind=nodes
--physcpubind=cpus
--localalloc
--preferred=node
简而言之,就是说,你可以指定内存在本地分配,在某几个CPU节点分配或者轮询分配。除非是设置为--interleave=nodes轮询分配方式,即内存可以在任意NUMA节点上分配这种方式以外。其他的方式就算其他NUMA节点上还有内存剩余,Linux也不会把剩余的内存分配给这个进程,而是采用SWAP的方式来获得内存。
所以最简单的方法,还是关闭掉这个特性。
关闭特性的方法,分别有:可以从BIOS,操作系统,启动进程时临时关闭这个特性。
a)由于各种BIOS类型的区别,如何关闭NUMA千差万别,我们这里就不具体展示怎么设置了。
b)在操作系统中关闭,可以直接在/etc/grub.conf的kernel行最后添加numa=off,如下所示:
kernel/vmlinuz-2.6.32-220.el6.x86_64roroot=/dev/mapper/VolGroup-rootrd_NO_LUKS.UTF-8rd_LVM_LV=VolGroup/rootrd_NO_MDquietSYSFONT=latarcyrheb-sun16rhgbcrashkernel=autord_LVM_LV=VolGroup/swaprhgbcrashkernel=autoquietKEYBOARDTYPE=pcKEYTABLE=usrd_NO_DMnuma=off
另外可以设置vm.zone_reclaim_mode=0尽量回收内存。
c)启动MySQL的时候,关闭NUMA特性:
numactl--interleave=allmysqld
当然,最好的方式是在BIOS中关闭。
ii)我们再看看vm.swappiness。
vm.swappiness是操作系统控制物理内存交换出去的策略。它允许的值是一个百分比的值,最小为0,最大运行100,该值默认为60。vm.swappiness设置为0表示尽量少swap,100表示尽量将inactive的内存页交换出去。
具体的说:当内存基本用满的时候,系统会根据这个参数来判断是把内存中很少用到的inactive内存交换出去,还是释放数据的cache。
linux中mysql的客户端和服务器指什么?
0mysql和其他数据库系统一样,体系是分布式的,因此都存在服务器端和客户端两个系统。
1服务器端系统包括一组在服务器主机上运行的程序(如mysqld,mysqld_safe等)和相关文件(数据文件、配置文件、日志文件等),通过运行程序启动后,即启动了数据库服务,也称为运行了数据库服务器。服务器端安装程序则一般是mysql-server-version,如果是使用编译安装,一般是mysql-version.src,一般安装时会同时安装服务器端软件和客户端软件;
2客户端系统则是连接数据库服务器,用来执行查询、修改和管理数据库中的数据的程序。客户端系统也由一组软件组成,如mysql命令行工具、mysqlmp导出工具等;安装包一般为mysql-client-version。
3其它mysql安装时还包含其它包,如开发包mysql-devel-version、测试包mysql-test-version。
怎么查看linux的哪个进程占用磁盘io较多
1.使用iotop命令
使用该命令有个条件,Linux内核要高于2.6.20的版本,版本过低则没有此命令,执行效果如下图所示:
2:block_mp方法
首先,关闭syslog服务,然后开启block_mp,最后正则表达式提取dmesg信息。
/etc/init.d/syslog stop
echo 1 > /proc/sys/vm/block_mp
dmesg | egrep "READ|WRITE|dirtied" | egrep -o '([a-zA-Z]*)' | sort | uniq -c | sort -rn | head
执行结果如下图所示:
注意:操作完成后请关闭block_mp和启动syslog
echo 0 > /proc/sys/vm/block_mp #关闭block_mp
/etc/init.d/syslog start #启动syslog
如何查看Linux下进程的IO活动状况 00 Hey,Linux
前段时间,几台测试服务器的Web应用响应速度非常慢,系统负载也比较高,> 10, 但CPU和内存却很闲,于是怀疑是磁盘的性能瓶颈,通过vmstat和iostat看到IO的读写量非常大,尤其是用iostat -x 1命令可以很直观的看到IO的使用率一直在100%。
但究竟是什么进程导致的高IO呢,由于每台服务器上都有JBoss和MySQL的存在,JBoss会不停的产生很多小的数据文件和生成文本数据库的数据,而MySQL则会不停的从Master同步新的数据。因此我们怀疑是这两个进程导致的高IO,通过停止了JBoss和MySQL之后,IO立刻降为0%. 但我们还是不能确定谁是主因,于是寻找可以查看特定进程IO的方法。
最后,找到了两个方法可以查看进程IO的活动状况。
1. 第一个方法是通过一个python脚本来实现。
方法是将以下内容另存为一个叫io.py的脚本中,然后直接以root身份执行脚本,就可以看到如下图所示的信息(由于我们已经通过升级到SSD硬盘解决了MySQL的IO问题,所以不能提供关于MySQL的截图了),其中出现次数最多,数据最大的进程,就是导致高IO的主因。不过比较遗憾的是这个脚本并不能显示进程在每一秒的准确的IO读写。
# vim io.py
# chmod +x io.py
# ./io.py
#!/usr/bin/python
# Monitoring per-process disk I/O activity
# written by http://www.vpsee.com
import sys, os, time, signal, re
class DiskIO:
def __init__(self, pname=None, pid=None, reads=0, writes=0):
self.pname = pname
self.pid = pid
self.reads = 0
self.writes = 0
def main():
argc = len(sys.argv)
if argc != 1:
print "usage: ./iotop"
sys.exit(0)
if os.getuid() != 0:
print "must be run as root"
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
os.system('echo 1 > /proc/sys/vm/block_mp')
print "TASK PID READ WRITE"
while True:
os.system('dmesg -c > /tmp/diskio.log')
l = []
f = open('/tmp/diskio.log', 'r')
line = f.readline()
while line:
m = re.match(\
'^(\S+)\((\d+)\): (READ|WRITE) block (\d+) on (\S+)', line)
if m != None:
if not l:
l.append(DiskIO(m.group(1), m.group(2)))
line = f.readline()
continue
found = False
for item in l:
if item.pid == m.group(2):
found = True
if m.group(3) == "READ":
item.reads = item.reads + 1
elif m.group(3) == "WRITE":
item.writes = item.writes + 1
if not found:
l.append(DiskIO(m.group(1), m.group(2)))
line = f.readline()
time.sleep(1)
for item in l:
print "%-10s %10s %10d %10d" % \
(item.pname, item.pid, item.reads, item.writes)
def signal_handler(signal, frame):
os.system('echo 0 > /proc/sys/vm/block_mp')
sys.exit(0)
if __name__=="__main__":
main()
2. 另一个方法是将Linux的内核升级到 >=2.6.20,然后安装一个iotop软件来实现。
不过这种改动并不适用于生产环境,因为在RHEL5.6和5.7上,内核都在 2.6.20以下。但是它所显示的结果是非常准确的,所以对于新上线的机器以及测试环境,非常值得一试,具体方法如下:
下载和升级新内核(>=2.6.20),编译时打开 TASK_DELAY_ACCT 和 TASK_IO_ACCOUNTING 选项。
解压内核后进入配置界面:
# wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.39.tar.gz
# tar jxvf linux-2.6.39.tar.gz
# mv linux-2.6.39 /usr/src/
# cd /usr/src/linux-2.6.39
# make oldconfig //使用make oldconfig可以继承老的kernel的配置,为自己的配置省去很多麻烦。
# make menuconfig
把General setup - Enable per-task storage I/O accounting这个选项选上。
# vim .config
将#CONFIG_SYSFS_DEPRECATED_V2 is not set的注释去掉的,将其改为y,即修改为CONFIG_SYSFS_DEPRECATED_V2=y。
保存内核后编译内核:
# make
# make moles
# make moles_install
# make install
修改默认以新的内核启动:
# vi /boot/grub/grub.conf
default=0
将新的内核配置文件复制到/boot目录:
# cp /usr/src/linux-2.6.39/.config /boot/config-2.6.39
重启服务器:
# reboot
# uname –r
2.6.39
重启完成后确认内核版本是否正确。
源码安装iotop所需的Python 2.7.2(>= 2.5):
# wget http://www.python.org/ftp/python/2.7.2/Python-2.7.2.tgz
# tar xzvf Python-2.7.2.tgz
# cd Python-2.7.2
# ./configure
# make; make install
下载并安装iotop:
# wget http://guichaz.free.fr/iotop/files/iotop-0.4.4.tar.bz2
# tar -xjvf iotop-0.4.4.tar.bz2
# cd iotop-0.4.4
# python setup.py build
# python setup.py install
然后就可以使用iotop看到如下图所示的信息:
linux下mysql中各个文件夹的作用详解。
详细的你可以去mysql官网读参考手册,有简体中文的哦,第2章:安装MySQL,2.1.5. 安装布局
1、bin目录里面存放的是命令,有2进制文件(比如mysql,mysqld)和shell脚本文件(比如mysqld_multi ,mysqld_safe服务器启动脚本)
2、data目录存放数据库数据,table数据,数据存放位置可以自己定义,不一定存在这个路径
3、etc,tmp,var目录一般mysql里面不存在,/etc一般是存放系统配置文件的路径 /tmp是存放临时文件的,/var里面存放进程id和日志的地方
4、include包含(头)文件,提供其他程序连接mysql的API接口,比如你要编译postfix或php支持mysql,需要告诉其mysql的include路径位置
5、docs 文档,ChangeLog等
6、lib:库
7、mysql-test目录有README,This directory contains a test suite for the MySQL daemon.
8、scripts路径里面包含的mysql_install_db能初始化数据目录和初始数据库数据库,如果你第一次编译运行mysql,这个脚本必须执行的哦
9、sql-bench基准程序和crash-me测试
10、 support-files目录是配置的文件的模板