DTrace是一款动态跟踪设备,可用于Mac OS X、FreeBSD和Solaris等操作系统,它为我们提供了一种观测MySQL内部工作的独特方式。 与我们大多数人想象的不同,DTrace用于MySQL时不需对MySQL做任何更改。DTrace最强大的“提供器”(provider,是一组可观测的探测器)是FBT(Functional Boundary Tracing,函数边界跟踪)提供器。我们可以把它与PID提供器结合起来,用于深入观测userland过程。
只需要对MySQL代码有一些基本了解,我们就可以开发挖掘这些功能了。 那么,我们如何才能了解MySQL代码呢?有两种方……
我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。
我原创,你原创,我们的内容世界才会更加精彩!
【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】
微信公众号
TechTarget
官方微博
TechTarget中国
DTrace是一款动态跟踪设备,可用于Mac OS X、FreeBSD和Solaris等操作系统,它为我们提供了一种观测MySQL内部工作的独特方式。
与我们大多数人想象的不同,DTrace用于MySQL时不需对MySQL做任何更改。DTrace最强大的“提供器”(provider,是一组可观测的探测器)是FBT(Functional Boundary Tracing,函数边界跟踪)提供器。我们可以把它与PID提供器结合起来,用于深入观测userland过程。只需要对MySQL代码有一些基本了解,我们就可以开发挖掘这些功能了。
那么,我们如何才能了解MySQL代码呢?有两种方法。第一,你可以买一本好点儿的相关书籍,如MySQL Internals。如果你很重视MySQL相关知识,一定要买这本书。第二种方法是通过DTrace本身来了解MySQL代码。DTrace最好的一个功能是一个叫做“flowindent”的编译指示选项。这个函数会相应地显示entry和return并生成一个逻辑树,以便用户能了解其内部的函数调用关系。实际上,我们可以通过这种方式了解到MySQL的内部情况。
下面是代码(mysqlflow.d):
#!/usr/sbin/dtrace -s
#pragma D option flowindent
pid$target:mysqld::entry
{
}
pid$target:mysqld::return
{
}
将这段代码放到一个文本文件中,然后将该文件改为可执行文件。这里,我们使用PID提供器来观测“mysqld”过程。因为我们指定的不是一个函数(请记住,探测器格式是PROBIDER:MODULE:FUNCTION:NAME),所以它是作为wildcard被翻译的。因此,我们会看见所有的函数,所有函数的entry和return名都为初始探测器名。
在运行该文件时,我们需要使用DTrace –p来指定mysql daemon的PID(过程id)。在Solaris中,通过如下“pgrep”命令我们可以很方便地获得PID。
# ./mysqlflow.d -p `pgrep -x mysqld`
0 -> sync_array_get_nth_cell
0 <- sync_array_get_nth_cell
0 <- sync_array_print_long_waits
0 -> os_thread_sleep
2 <- os_thread_sleep
2 -> sync_arr_wake_threads_if_sema_free
2 -> sync_array_enter
2 -> os_mutex_enter
2 -> os_fast_mutex_lock
2 <- os_fast_mutex_lock
2 <- os_mutex_enter
2 <- sync_array_enter
2 -> sync_array_exit
2 -> os_mutex_exit
2 -> os_fast_mutex_unlock
2 <- os_fast_mutex_unlock
2 <- os_mutex_exit
2 <- sync_array_exit
2 <- sync_arr_wake_threads_if_sema_free
...
使用^C可以结束跟踪。单单是这些就可能够你折腾几个小时了。
首先你会发现的是InnoDB非常“健谈”,即使数据库非常清闲时也是如此。这个看似恒定“sync_array_get_nth_cell()”函数流实际上是InnoDB检查点的结果。
上述例子向我们展示了DTrace实时监视MySQL函数进出情况的能力。但是,要想发挥它的作用,我们还需要了解都有哪些东西进入了这些函数。我们需要看看某些特定的函数和它们的引数(argument)。我们谁都喜欢监视别人,对吧?如果我告诉你我不需要登录数据库也不需要查看任何日志文件就可以看到MySQL处理的每一个查询,你会怎么想呢?其实很简单,通过跟踪“dispatch_command()”的引数,你就可以做到了。
如下是需要用到的脚本(query_watch.d):
#!/usr/sbin/dtrace -s
#pragma D option quiet
pid$target:mysqld:*dispatch_command*:entry
{
printf("Query: %sn", copyinstr(arg2));
}
同样,将该脚本保存到一个文本文件中并将它改为可执行文件,利用“-p PID”执行它,使用^C停止跟踪。
# query_watch.d -p `pgrep -x mysqld`
Query: show tables
Query: select * from Country LIMIT 10
Query: explain user
...
既然我们可以实时查看所有进入MySQL dispatcher的查询,因此我们可以很轻易地看出查询的情况和趋势。不知道你注意到没有,每秒钟你的CRM都会执行几百个相同的查询。
你可能意识到了我想暗示你的安全性问题,只有root用户(或Solaris中明确指定的特权用户)才能运行DTrace。如果你的本能反应是害怕DTrace系统中的MySQL,我们可以把DTrace这样用于Oracle、PostgreSQL、Mozilla或其它任何应用。DTrace可以看见所有的一切。如果你还不了解DTrace的威力,我希望你了解一下。
下面,我们再深入地看看这个例子。重复的查询可能会导致严重的问题,通常会引发客户端存储缓慢或应用逻辑性差等问题。我们可以用DTrace计算一下所有重复的查询,并报告每个查询在特定时间段被执行过多少次。
使用如下脚本(querycounts.d):
#!/usr/sbin/dtrace -s
#pragma D option quiet
dtrace:::BEGIN
{
printf("Tracing... Hit Ctrl-C to end.n");
}
pid$target::*dispatch_command*:entry
{
@query[copyinstr(arg2)] = count();
}
在运行该脚本时,它会开始收集数据,直到完成才会输出报告。合并计算函数count()将通过“dispatch_command”函数的arg2的结果赋给@query。
# querycounts.d -p `pgrep -x mysqld`
Tracing... Hit Ctrl-C to end.
^C
select * from CountryLanguage LIMIT 5 1
show tables 4
select * from City 10
显然,这个例子的输出结果并不是真正的生产系统的结果。如果在生产中使用,你得到的结果会远远大于该输出结果。
这里所讨论的例子仅仅是冰山一角。如果你结合一本好的MySQL internal参考书,很快你会发现你的理解方式是以前想都没想到过的。你能够将DTrace利用到生产代码中的各个部分。
我希望这篇文章能帮助你稳步前进,一步一个脚印。你可以用它来学习,吸引你的同事,节约时间。最后,祝您跟踪愉快!
特别感谢Derek Crudginton。
关于作者:Ben Rockwood是云计算基础架构Joyent公司的系统经理。他是Solaris方面的专家,也是Sun推广者。
翻译
相关推荐
-
RHEL 5.10将于今年Q4发布 MySQL、OpenSCAP获更新
RHEL 5.10目前处于测试阶段。如果进展顺利的话,今年第四季度将会发布。RHEL 5.10包括多种更新功能,如新版本的MySQL、改进的管理工具和增强的安全性等。
-
使用WAMPStack快速部署Apache、MySQL与PHP
大多数服务器管理员都熟悉术语LAMP和WAMP。建立一个WAMP栈是很麻烦而且不直观的。您要下载什么?您要安装什么?顺序是否有关系?
-
甲骨文与Sun的交易引发欧盟对MySQL的关注
作为对欧盟委员会关注甲骨文收购Sun以及甲骨文可能拥有MySQL的回应,甲骨文作出了大量承诺。甲骨文持续致力于……
-
Oracle收购Sun将终结MySQL?
尽管我不是Sun的粉丝,还是感觉不太痛快。这次收购意味着又有若干产品有可能被打入冷宫。而大家比较关心的MySQL可谓命运不济……