- 下载并解压 参考资料 一节中的示例代码。
- 设置开放数据库连接(ODBC),指向想要监视的数据库。
- 配置 PHP,以使用 JpGraph 包绘图。
- 根据环境修改 “goqc” 脚本。
- 使用 JMeter 或 Rational® Performance 测试程序为数据库提供一个负载。
- 配置一个远程代理,以便将本地连接性能与网络性能进行比较。
DBA 对能为公司提供可靠的数据库服务而深感自豪。然而,毫不奇怪,当被指责数据库存在性能问题或应用程序运行中断时,他们也会倍感压力。本文展示如何为数据库提供一个实时状态图(见图 1),以减少错误的指责,并发现问题,从而快速解决问题。
图 1. 实时数据库状态
X 轴是时间,左边的 Y 轴是响应时间,单位为秒,右边的 Y 轴是用户连接的数量。图 1 清楚地表明,数据库虽然承载着将近 300 个用户,但是仍然运行得很好,响应时间快于 1.5 秒。 由于是在只有一个磁盘的笔记本电脑上进行模拟的,所以性能比较突出。 当看到这种图时,就表明数据库没有问题。相反,如果哪个地方运行中断,那么很快就可以知道,并且可以更快地发现根本原因。
为了产生图 1 中显示的图,需要关于服务器状态的数据。通过在 Statistical Process Control 中执行简单的一步,很容易收集数据并通过 Web 页面发布数据。要了解关于 Statistical Process Control 的更多信息,请参阅 参考资料 小节。由 Dr. Demming 倡导的质量改进运动,使 “日本制造” 一改质量低下的形象,如今已成为优质代名词。
在收集数据时,存在两个易出错的地方:
例如,根据奈奎斯原理,为了得到发生时间为 20 秒的事件的准确样本,那么必须每 10 秒进行一次抽样。如果要在 1 分钟内评测数据库运行中断事件,那么必须每 30 秒进行一次抽样。在本文提供的示例脚本中,抽样频率是每 2 秒抽样一次,这样可以提供快速的反馈,但是在短时间内会产生较多的样本数据。
那么,抽样方式对抽样结果有什么影响呢?海森堡测不准原理表明,当我准确地计算出汽车钥匙的动量时,这些钥匙可能处在宇宙中的任何一个地方。 海森堡实际上说的是基本粒子的位置和动量,但是从中可以得到一个思想。 当一个数据库服务器的速度降低时,为进行测试和排除故障而增加的工作负载很可能使问题变得更严重。这个例子中的监测工具将状态 Web 页面的显示卸载到另一台不同的服务器上。这种架构使 “旁观者” 与数据库服务器分离,以便它们能够在不使问题加重的情况下查看状态。
质量控制抽样代理(QC 抽样代理)的任务是简单地度量数据库的状态,并将该数据记录在一个数据库表中。通过非常丰富的 DB2® 表函数 或者 Informix® sysmaster 数据库,几乎可以获得关于数据库服务器的任何数据。
图 2 中显示了抽样代理的部署架构。代理分为本地代理和远程代理。示例代码实现一个单独的代理。若要部署两个代理,则需要修改模式和代码。
图 2. 抽样代理部署架构
为什么使用通过网络进行通信的一个本地代理和一个远程代理?您的目的是尽量找出故障,修复问题,避免受到指责,而如果本地与远程代理响应时间有任何差别,则立刻可以确定是网络速度降低。设想一下,如果一个 DBA 打电话给网络小组帮助他们发现一个问题,他们会多么地感激啊。
下载 一节提供了代理的两种实现。Informix 目录包含一个本地 esql/c 代理。ODBC 目录包含该代理的一个 DB2 实现,为了取得最佳的可移植性,该实现是用 PHP 编写的。
该程序执行以下步骤:
- 启动一个计时器。
- 连接到数据库。
- 度量连接到数据库的时间。
- 用时间戳、惟一键和连接时间在 transtimes 表中创建一个新行。
- 收集关于数据库的任何感兴趣的统计信息,并模拟一个简单的事务。
- 更新步骤 4 中创建的行,记录步骤 5 中收集的统计信息和完成步骤 5 所花费的时间。
图 1 中的图显示了连接的数量、连接时间和插入-更新时间。该代理的 Informix 端口中使用的表的实际模式(清单 1)包括分配和使用多少虚拟内存。这个图说明 Informix sysmaster 或 DB2 表函数如何为监测服务器状态提供方便的界面。您不必对大量 onstat 或快照数据进行 sed、awk、grep 和 perl 操作。
上面的步骤 5 包括模拟系统中一个代表典型工作负载的简单事务。 这个简单事务使数据样本能够代表典型用户在使用系统时体验到的情况。 对于处理电话定购的联机事务处理系统(Online Transaction Processing System,OLTP),模拟的交换可以是客户查询。如果要监视的数据库系统是用于决策支持(DSS)的,查询比较长而且比较复杂,那么不要让质量控制(QC)代理运行大型的查询。请参阅前面关于 海森堡测不准原理的讨论。QC 代理运行的大型 DSS 查询会浪费 CPU 周期,从而降低其他查询的速度。
清单 1. 用于 Informix esqlc 版本的 QC 代理的模式
-- (c)2006 copyright Martin Lurie, sample code, not supported
create database oltpqc;
database oltpqc;
drop table transtimes;
-- the DB2 identity datatype is similar to Informix serial
-- in the php version of the code a simple integer was used and
-- php increments the transkey, this gives maximum portability
create table transtimes ( transkey serial primary key,
timestamp datetime year to second,
connect_time float,
session_count integer,
vblkused integer,
vblkfree integer ,
query_insert_time float
);
|
清单 2 显示了和一个 PHP 代理一起使用的 DB2 模式。
清单 2. 用于 DB2 PHP 版本的 QC 代理的模式
-- (c)2006 copyright Martin Lurie, sample code, not supported
create database oltpqc;
connect to oltpqc;
drop table transtimes;
create table transtimes ( transkey int primary key,
timestamp date,
connect_time float,
session_count integer,
query_insert_time float
);
|
用于收集数据的模式并不限于此。无论用这个代理检测什么数据,都可以将其包括在数据样本表中。 这个项目的最初原因是应用程序开发人员与数据库管理员之间 “互相推卸责任”。经过监测用户数量和消耗的总内存,表示出了内存消耗的线性关系。这样就结束了争执,而应用程序被修改为当检测到响应时间变慢时,不再继续生成新的到数据库的连接。
清单 3 显示了用于发现连接到 DB2 的用户数的表函数。关于如何使用其他表函数,以及如何在 Informix 中使用 sysmaster 数据库,请参阅 参考资料 小节。
清单 3. 从 DB2 表函数中获取并发用户数的查询
-- (c)2006 copyright Martin Lurie, sample code, not supported
select local_cons +rem_cons_in from table (snapshot_dbm (-1))as snapshot_dbm
|
Informix 使用 sysmaster 数据库而不是表函数来提供关于服务器状态的信息。清单 4 显示了用于获得用户数量的 Informix 查询。
清单 4. 从 Informix sysmaster 中获取并发用户数的查询
/* this sql is from the esqlc program, so the result set is
stored in a host variable. */
select count(*)
into :sessioncount
from sysmaster:syssessions;
|
代理代码很简单。获得 PHP 平台独立版本的 ODBC 数据库连接的 “秘诀” 就是 odbc.ini 文件。关于获得 PHP ODBC 连接的文档很多,请参阅 参考资料 一节。清单 5 显示了用于 DB2 的 odbc.ini,清单 6 显示了 Informix 清单。如果愿意花时间,也可以用直接的驱动程序替代 ODBC 来构建 PHP。对于这个例子,ODBC 的性能已经足够了,这里我们不但将 ODBC 用于客户机,还用于收集数据,以描绘响应时间结果的图形。
清单 5. Linux 上用于 ODBC 配置的 DB2 odbc.ini 文件
[ODBC Data Sources]
SAMPLE=IBM DB2 ODBC DRIVER
[SAMPLE]
Driver=/home/db2inst1/sqllib/lib32/libdb2.so
Description=DB2 Sample database
|
清单 6. Linux 上用于 ODBC 配置的 Informix odbc.ini 文件
[ODBC Data Sources]
SAMPLE=INFORMIX DB2 ODBC DRIVER
Driver=/home/db2inst1/sqllib/lib32/libdb2.so
Description=Informix smaple odbc.ini
[ODBC Data Sources]
Infdrv1=IBM INFORMIX ODBC DRIVER
Infdrv2=IBM INFORMIX ODBC DRIVER
;
; Define ODBC Database Driver's Below - Driver Configuration Section
;
[Infdrv1]
Driver=/home/informix/lib/cli/iclit09b.so
Description=IBM INFORMIX ODBC DRIVER
Database=stores_demo
LogonID=odbc
pwd=odbc
Servername=ids_server1
[Infdrv2]
Driver=/home/informix/lib/cli/iclit09b.so
Description=IBM INFORMIX ODBC DRIVER
Database=oltpqc
LogonID=informix
pwd=useYourOwnPassword
Servername=k_ids
Trace=0
TraceFile=/tmp/odbctrace.out
InstallDir=/home/informix
|
当响应时间变慢时,DBA 如果能在接到操作中心的电话之前就知道这一点就好了。这关系到 DBA 的责任,同时,能意识到何时会出现问题也是值得自豪的事情。DBA 需要早点知道有问题存在。这不是谁负责任的问题,而是为了交付高质量的数据库服务。
oltpqc 代码需要从命令行中提供一个位置参数,用于表示警报阈值。这个值单位为毫秒。如果响应时间低于这个值,就会触发一个 Unix/Linux 脚本。 清单 7 和清单 8 分别显示了报警功能的 esqlc 实现和 PHP 实现。
清单 7. 当响应时间超过阈值时生成警报的 ESQLC 代码
/* code to capture the positional paramter from the command line */
if (argc == 2 ) {
thresholdms = atoi ( argv[1] );
#ifdef PRTDIAG
printf( "argv[1] %s thresholdms %d \n", argv[1], thresholdms );
#endif
printf( "(c)copyright 2005 - alarm %d milli-seconds \n", thresholdms );
}
else
{
printf(
"(c)copyright 2005 - USAGE: %s threshold_millisec\n", argv[0] );
printf( "example: %s 1500\n" , argv[0] );
printf( "generates an alarm when response time is over 1.5 seconds\n" );
return -1 ;
}
/* ... lines deleted .... */
/* logic to run a shell script and pass in the response time data
to the shell script */
asprintf ( &alarmstring , "./slowalarm.sh %f %f " ,
elapsed_con, elapsed_wrk );
if ( ( elapsed_wrk+elapsed_con ) > (float)thresholdms/(float)1000 )
system ( alarmstring);
#ifdef PRTDIAG
printf ( "times elapsed_wrk %f , elapsed_con %f , thres %f \n",
elapsed_wrk,elapsed_con, ( (float)thresholdms/(float)1000 ) );
#endif
|
清单 8. 当响应时间超过阈值时生成警报的 PHP 代码
//check to see if alarm should be sounded
if (($third_time - $first_time)*1000 > $thresholdms)
{
echo "DATABASE SLOW ALERT - CONNECT AND QUERY TIMES" ;
echo "GREATER THAN $thresholdms MILISECONDS\n\n";
system ("alert.sh");
}
|
这个项目需要在 Web 页面上发布数据。 如果不进行报告和发布,样本数据就没有什么价值。电子表格技术只能用于显示实时数据。而且通过电子邮件发送关于数据库状态的电子表格也十分麻烦。如果使电子表格动态刷新和重连数据库,那么每个监视数据库的电脑上进行的每次刷新都会消耗 CPU 周期,这是个代价很高的办法。图 3 展示了用电子表格分析用户和响应时间的方法,这只是为了完整起见,实际上这种方法不值得推荐。
图 3. 使用电子表格显示质量样本 - 注意 Y 轴表示的日志规模
发布由质量控制代理收集的状态信息的一种很好的技术是 Web 站点。 图 4 中显示的图形基于 JpGraph 包(要获得更多信息,请参阅 参考资料 一节)。这个用 PHP 编写的包是非常棒的一组绘图工具。在使用这个包之前,需要安装一些先决条件,包括 gd 和 php-gd。为 DB2 数据绘制 Informix 非常简单,只需改变连接语句。这正是使用 PHP 和到数据库的 ODBC 连接来取得可移植性的优雅之处。
图 4. 使用 PHP 绘图包 JpGraph 绘制数据库状态图
注意,JpGraph 包允许在图形背后放一个 jpg 图像。图 4 显示了作为背景的 Informix 赞助的赛车图像。
状态图实现了自动刷新。一个包含实时状态的页面如果不刷新,其作用就会大打折扣。这并没有用到 AJAX 之类的特殊技术,只是使用简单的 HTML。看看清单 9 和清单 10,您能说出为什么一个是 “糟糕” 的页面,而另一个是 “良好” 的页面吗? 清单 9 假设有一个守护任务在周期性地运行,并执行:php qcgraph.php > foo.jpg
清单 9. “良好” 的自动刷新 HTML 页面
<META >-EQUIV=Refresh CONTENT="3; URL=index.html">
<h1>Database Real Time Status</h1>
Click the refresh button if the graph does not appear below.
<hr>
<img src="foo.jpg">
<hr>
<!-- this page assumes a cron job is running periodically that
performs the following: php qcgraph.php > foo.jpg -->
|
清单 10. “糟糕” 的自动刷新页面的清单,它可以运行,但是不能像清单 9 那样运行
<META HTTP-EQUIV=Refresh CONTENT="10; URL=auto.html">
<h1>Database Real Time Status</h1>
<img src="qcgraph.php">
<hr>
|
您可能已经发现,如果有很多人想查看数据库状态,那么 “糟糕” 的自动刷新代码将在服务器上产生很大的工作负载。这就是海森堡测不准原理和墨菲定律在起作用。为了检测数据库的状态,却增加了数据库上的负载。如果大量好奇的人打开浏览器来查看服务器,那么当什么地方 “出现问题” 时,问题本身已经受到由此带来的额外工作负载的影响。
清单 9 显示了 “良好” 的实现,该实现尽量避免增加数据库上的工作负载。所有偷窥者共享状态图 jpg 图像,而用于支持状态探测器的工作负载可以隔离在一个 Web 服务器上。这个 Web 服务器甚至不必与数据库在同一台机器上。对 JpGraph .jpg 输出进行周期性的刷新是必要的。如果使用 Linux watch 命令,那么可以在示例代码中的守护任务中进行刷新。
服务器性能描述:用 Apache JMeter 进行负载测试
现在将所有代码并入到一个脚本中。为了得到一个令人感兴趣的图形,并确认该图形将报告您想看到的东西,需要在数据库上生成一些工作负载。 Apache 的 JMeter 就是一个很好的选择,当然 IBM 的 Rational Performance Tester 也提供了一些高级的功能。本文中的所有图形都是使用 JMeter 作为负载生成器(也称 “测试用具”)的情况下生成的。
创建一个测试用具,对数据库进行负载测试。即使您没有实现任何性能监视或绘图,仍然可以进行负载测试。如果您从本文学到的惟一一件事情就是在将应用程序投入生产之前进行负载测试,那么本文就已经很值得撰写了。
将负载加到最大,直到服务器运行中止,这样做可以发现系统的性能极限。用户数量、查询或事务的复杂度以及应用程序的其他方面都应该描述出来。有了性能极限图,加上对服务器工作负载增长趋势的跟踪,就可以在出现重大危机之前升级服务器,轻松赢得这场战争。
清单 11 中的脚本启动性能监视器的所有组件和负载测试环境。对于复杂的启动序列,强烈建议使用一个 shell 脚本,以最小化 typos 和 “thinkos”。
这段脚本看上去有些恐怖,不过每一步都有注释加以解释。
清单 11. 包含自动负载测试的完整脚本
# (c)copyright 2006 Martin Lurie Sample code, not supported
echo must run as root... so we can restart the httpd and informix
# read foo just makes the script pause till you hit enter
# todo: automate a user id check instead of this prompt
read foo
# everyone tails the server log on the screen, right ?
xterm -exec tail -f /opt/informix/online.log &
. /opt/informix/iunset
# pick up the ids v10 env
. /opt/informix/ifx_env
# stop the server in case it is active
su informix -c "onmode -yuk"
# start the server
su informix -c oninit
# now pick up the csdk 2.8x environment - better yet - get
# the bug fixed version of the 2.9 csdk
. /opt/informix/iunset
. /home/informix/ifx_env
/etc/init.d/httpd restart
# must install php graph libraries
cd /var/www/html/
xterm -exec watch -d -n4 "php ./qcgraph.php > foo.jpg" &
mozilla http://karmiel/index.html&
cd /home/lurie/edrive/src/esql/oltpqc
xterm &
xterm -exec watch -d -n 5 ./oltpqc 1500 &
cd /home/lurie/tmp/jakarta-jmeter-2.2/bin/
./gojm &
|
图 5 显示了正在处理 JDBC 请求 JMeter。这个图显示平均响应时间为 573 毫秒。有些人可能对这个响应时间感到满意。但是,如果注意到 796 毫秒的标准偏差,用户就不会像一开始看到这个平均响应时间那么高兴了。好消息是,用红线表示的标准偏差呈现下降趋势。 所以当用户按 Enter 键时,响应时间的偏差更小。通过更仔细地观察黑色虚线表示的平均响应时间以及工作负载,可以发现服务器正处在启动暂态。当从 JMeter 建立连接池时,服务器会提供更加一致的工作负载响应时间。
图 5. JMeter 负载生成,图形结果页面
图 6 显示周期性地出现连接时间较长的现象。大多数 DBA 认为这是一个较长的检查点,但是令人惊讶的是,online.log 中的所有检查点都是 0 秒。那么,问题出在哪里呢?
图 6. 周期性较长响应时间问题
最终表明,这个问题与数据库无关。每当发现一个系统会先 “挂起” 8 到 10 秒钟,然后又能正常运行一段时间,最值得怀疑的地方是 DNS 网络问题。在解决了一个临时性的 DNS 问题之后(这个问题是通过将笔记本电脑重新连接到 LAN,使之能访问 DNS 服务器而得到解决的),周期性地出现连接过长的问题迎刃而解。
您已经看到过很多用于数据库监视的技术。这些技术包括使用标准 API(ODBC)提高代码可移植性,以及使用 JpGraph 绘制结果并将其在 Web 上发布。为了有效管理服务器,而不是为它们而头疼,使用一个测试用具体现环境的性能十分重要。
构建还是购买,我们总会面临这个问题。如果觉得难于创建本文中描述的实时监视器,那么可以试试 IBM Tivoli® Monitor。它有很多预定义的代理,还有一个控制台,允许钻取不同的问题。图 7 是 Tivoli 监视的一个例子。
图 7. Tivoli 监视,如果您更愿意购买,而不是构建,那么可以使用它
如果实现示例代码,那么有很多增强是有用的。如果网络或数据库出故障,oltpqc 客户机会继续等待一个响应。限制这个等待时间,并发送关于一个错误返回码的警报,是非常有必要增加的一个功能。
当发现与服务器或网络相关的问题时,有很多工具可用来诊断问题,并发现问题的起因。在操作系统级,sar、vmstat 和 top 命令都非常适合检查基本的系统健康状况。注意过高的 CPU 利用率和内存分页或交换 —— 这些都是性能杀手。ping、netstat、nmap 和 ethereal 实用程序提供了很多用于理解网络问题的功能。
如果操作系统运行正常,那么可以使用 Informix onstat 和 DB2 snapshot
实用程序挖掘与数据库相关的诊断信息。Internet 上有很多关于这些实用程序的文档和实例 -- 只需用 google 搜索一下,就可以发现很多参考资料。
希望您已经发现本文对您有用,并帮助您更好地进行问题隔离。当实时数据库状态报告帮助发现实际问题时,就无需浪费时间去追究责任了。
| 描述 | 名字 | 大小 | 下载方法 |
|---|---|---|---|
| 监视器源代码 | oltpqc.zip | 10KB | HTTP |
更多下载
- 演示: 运行数据库监视器页面的示例
学习
- 您可以参阅本文在 developerWorks 全球站点上的 英文原文 。
-
Deming and Statistical Process Control (wikipedia.org):通过 statistical process control 了解更多关于 W. Edwards Deming 及其工作的信息。
-
Sampling rate and 奈奎斯 frequency (wikipedia.org):发现更多关于奈奎斯特频率的信息。
-
Heisenberg uncertainty principle -- Why my car keys can be anywhere in the universe (wikipedia.org):阅读关于海森堡测不确定原理的信息。
-
"对 DB2 监控数据的 SQL 访问: 捕获快照" (developerWorks,2003 年 5 月):发现关于如何使用 SQL 表函数捕捉数据库系统监视器数据快照的细节。
-
“将 PHP 应用程序连接到 IBM DB2 通用数据库”(developerWorks,2001 年 7 月):结合使用 PHP 和 IBM DB2 Universal Database 创建 Web 应用程序。
-
JpGraph - An awesome PHP based graphing package:深入阅读关于 JpGraph 的信息。
-
developerWorks Information Management 专区:了解关于 DB2 的更多知识。获得广泛的技术文档、how-to 文章、培训、下载、产品信息等等。
-
随时关注 developerWorks
技术活动和网络广播。
获得产品和技术
-
下载
IBM 产品测试版,熟悉使用 DB2、Informix、Lotus®、Rational®、Tivoli 和 WebSphere® 的应用程序开发工具和中间件产品。
-
用可直接从 developerWorks 下载的
IBM 试用软件 构建您的下一个开发项目。
讨论
- 参与论坛讨论。
-
通过参与 developerWorks blog 加入 developerWorks 社区。
Marty Lurie 的计算机生涯始于纸带孔屑时期,那时他正在 IBM 1130 上尝试编写 Fortran 程序。他的日常工作是在 IBM 的 WebSphere Systems Engineering 领域,不过如果再追问几句,他就会承认他主要和计算机打交道。他最喜欢的程序是他自己编写的把便携式计算机连接到 Nordic Track 的程序(这台便携式计算机的重量减轻了两磅,少了 20% 的“胆固醇”)。Marty 是 IBM 认证的 Advanced WebSphere Administrator、Certified DB2 DBA、Certified Business Intelligence Solutions Professional、Informix-certified Professional、Linux+ Certified,他还训练他的狗打篮球。您可以通过 lurie@us.ibm.com 与 Marty 联系。