复杂应用环境下监控Oracle数据库性能(3)
上一篇 /
下一篇 2008-02-29 20:16:24
/ 个人分类:技术文章
(如用grep工具)可能会搜捕不到成形的完整SQL语句,这就要求用一种动态方法来拦截实
际执行的每一个完整的SQL语句,观察PHP中关于ORACLE数据库操作的函数簇,发现OCIParse和Ora_Parse两个函数是SQL语句的入
口,而将这两个函数统一替换为一个用户自定义的函数即可实现对SQL语句的拦截,在笔者涉入的实际系统中,是这样解决的:首先分析该系统中所有的PHP程
序文件,发现凡涉及ORACLE数据库操作的都需要包含一个以*.conf结尾的配置文件,该配置文件是数据库的用户名,密码和连接标识符的定义文件,这
些是开发初期定下的规范,以便于对程序中共用的配置信息进行统一的管理,以下是一个oracle.conf:
<? $oracle_user="oracle_user"; $oracle_password="oracle_password"; $oracle_dbid = "oracle_dbid"; ?> |
在涉及数据库操作的 PHP 程序中,总有一行语句以引入该配置文件:
include("<path_to_file>/oracle.conf"); |
设计一个函数如debug_OCIParse如下,以替换OCIParse,并将该文件放入一个叫debug.conf的别一个配置文件中,如下:
oracle.conf: <? global $impossible_conflit_with_this_oracle,$user,$password,$dbname; if(!$impossible_conflit_with_this_oracle) require("/home/httpd/debug.conf"); $impossible_conflit_with_this_oracle=1; $user="username"; $password="password"; $dbname="dblink"; ?> ========================================================== debug.conf: ========================================================== <? function debug_OCIParse($debug_conn, $debug_sql, $filename, $line) { debug_WriteLog($debug_sql, $filename, $line); return OCIParse($debug_conn, $debug_sql); } function debug_Ora_Parse($debug_conn, $debug_sql, $filename, $line) { debug_WriteLog($debug_sql, $filename, $line); return Ora_Parse($debug_conn, $debug_sql); } function debug_WriteLog($debug_sql, $filename, $line) { #if(!strstr($filename,"message.phtml")) return; $string = date("Y-m-d H:i:s")." $filename:$line\n\t$debug_sql\n"; $fp = fopen("/home/httpd/sql.log", "a"); fwrite($fp, $string, strlen($string)); fclose($fp); } ?> |
然后,统一将所有PHP程序中的OCIParse函数替换为debug_OCIParse函数,并要求PHP程序员以后使用debug_OCIParse函数进行开发,如下将:
$stmt = OCIParse($conn, $sql); |
替换为:
$stmt = debug_OCIParse($conn, $sql, __FILE__, __LINE__); |
这个工作可由系统管理员统一做一次,以后就要要求PHP程序员形成规范。例,可用如下脚本:
find /home/httpd/html -name '*.ph*' | xargs -n1 | while read i do ex -c ':se ic|g/ociparse/s/ociparse/debug_&/|s/); $/,__FILE__,__LINE__&/' -c ':x!' $i done |
这几行脚本并非放之皆准,但对于规范的php文件,一般来说没有问题,笔者的系统中用该方法
维护几百M的PHP程序,少有例外,由于这是只运行一次的脚本,所以只要根据自己具体的系统做适当的调整即可,如上,如果对含有OCIParse的程序行
的内容不太确定,可以用如下方法先进行查看:
find /home/httpd/html -name '*.ph*' | xargs grep -in ociparse > ~/list |
这段脚本中的ex命令稍作解释:ex是vi编辑器的后端工具,可以在命令行上使用一些编辑命令,每个编辑命令以-c选项开头,如上:se ic是改变编辑器对大小写不敏感,全称是:set ignorecase。
|号用来间隔多个编辑命令。
g/ociparse/s/ociparse/debug_&/的编辑语意为:找到含有ociparse的行,对这些行执行如下编辑命令。
s/ociparse/debug_&/,s意为substitute,将
ociparse替换为debug_&,这其中&代表前面找到的匹配字符串,由于是忽略大小写的,所以用&来保留前面找到的不管
是大小写如何混合的字符串的原型。这样,ociparse就会被替换为debug_ociparse,而OCIParse将会被替换为
debug_OCIParse。
接下来的|s/);$/,__FILE__,__LINE__&/是将
ociparse语句的右括号进行替换,将用于调试监控的两个参数(PHP中的宏)加上,$不是指一个真正的字符,而是指一个特定的位置--行尾,以避免
无辜的);被替换掉。另一个命令-c ':x!'是将该文件存盘退出。
打出这么一套组合拳需要你对这些命令了如指掌,如果你对某个文件没有写权,或出了其它岔子,那简直是一场灾难,这种魔法级的指令总是高风险的,搞不好会走火入魔,让你发下毒誓有生之年不再碰它。所以谨慎与备份总是对的。
导入论坛
引用链接
收藏
分享给好友
推荐到圈子
管理
举报
TAG: