perl查询空表引起的bug
浏览:1201次 出处信息
在ali集团对数据库的数据采集、监控、分析等由xxagent完成,所以对xxagent运行稳定非常重要。下面介绍xxagent一个bug,导致数据查询异常。
1、数据库的lijie表中没有记录:
root@xx 10:28:26>show create table lijie \G;
*************************** 1. row ***************************
Table: lijie
Create Table: CREATE TABLE `lijie` (
`id` int(11) DEFAULT NULL,
`name` varchar(32) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=gbk;
root@xx 10:28:30>select count(*) from lijie;
+----------+
| count(*) |
+----------+
| 0 |
+----------+2、执行以下代码:
my $sql3 = "select id,name from lijie";
my @sql3re = DB::query($sql3);
$Common::log->debug("luoxuansun3->@sql3re->") if (@sql3re);
$Common::log->debug("luoxuansun4") if (DB::query($sql3));
my $sql3n = scalar @sql3re;
my $sql3nn = @sql3re;
my $sql3nnn = DB::query($sql3);
$Common::log->debug("luoxuansun5"."->".$sql3n."->".$sql3nn."->".$sql3nnn."aa");3、log信息
$xxagent logf|grep luoxuansun 2013-07-28 10:39:50 [DEBUG] luoxuansun3->-> 2013-07-28 10:39:50 [DEBUG] luoxuansun5->1->1->aa 2013-07-28 10:39:52 [DEBUG] luoxuansun3->-> 2013-07-28 10:39:52 [DEBUG] luoxuansun5->1->1->aa
4、现象
通过执行DB模块的query函数返回给@sql3re后,里面既然有了记录(实际是没有记录),但直接执行”DB::query($sql3)”却是没有数据,前后矛盾
5、写入一条记录
root@xx 10:28:57>insert into lijie values(1,'a'); Query OK, 1 row affected (0.00 sec) log信息 2013-07-28 10:44:39 [DEBUG] luoxuansun3->HASH(0x1bbb1f8)-> 2013-07-28 10:44:39 [DEBUG] luoxuansun4 2013-07-28 10:44:39 [DEBUG] luoxuansun5->1->1->1aa 注意:结果"luoxuansun5->1->1->1aa"并没有发生变化,但"luoxuansun4"打印出来,说明的确有数据存在
6、再写一条记录
root@xx 10:44:35>insert into lijie values(1,'b'); Query OK, 1 row affected (0.00 sec) log信息 2013-07-28 10:46:53 [DEBUG] luoxuansun3->HASH(0x1bd6628) HASH(0x1bd7df8)-> 2013-07-28 10:46:53 [DEBUG] luoxuansun4 at 2013-07-28 10:46:53 [DEBUG] luoxuansun5->2->2->2aa 注意:结果集中有两条记录了,变化符合预期
7、排查DB的query函数
sub query {
my $sql = join '', @_;
if ( !defined($dbh) ) {
$dbh = _connect;
}
for ( my $count = 1 ; $count <= $connect_retries ; $count++ ) {
if ( defined($dbh) ) {
my @res = $dbh->query($sql);
my $x = scalar @res;
$Common::log->debug("luoxuansat>$sql->$x");
if ( scalar(@res) ) {
$Common::log->debug("luoxuansat2->$sql->$x");
return @res;
} else {
$dbh = _connect;
$Common::log->error("query retires $count $sql");
next;
}
} else {
$dbh = _connect;
$Common::log->error("query retires $count $sql");
next;
}
}
}
问题是出在空表时,先把记录删除,看一下log信息
root@xx 10:46:44>delete from lijie;
Query OK, 2 rows affected (0.00 sec)
log信息
$xxagent logf|grep luoxuansat|grep lijie
2013-07-28 10:53:31 [DEBUG] luoxuansat>select id,name from lijie->0
2013-07-28 10:53:31 [DEBUG] luoxuansat>select id,name from lijie->0
注意:调用$dbh->query返回记录集为0,那说问题就出在DB的query函数上了
log信息
$xxagent logf|grep "query retires"|grep lijie
2013-07-28 10:56:18 [ERROR] query retires 1 select id,name from lijie
2013-07-28 10:56:18 [ERROR] query retires 2 select id,name from lijie
2013-07-28 10:56:18 [ERROR] query retires 3 select id,name from lijie
注意:结果为0的情况下,却走到了:
else {
$dbh = _connect;
$Common::log->error("query retires $count $sql");
next;
}
而没有结果集返回8、bug fixed:
但没有结果返回时,应该明确返回空数组给调用方或对空结果做特殊处理
sub query {
my $sql = join '', @_;
my @nores; --设置空数组
if ( !defined($dbh) ) {
$dbh = _connect;
}
for ( my $count = 1 ; $count <= $connect_retries ; $count++ ) {
if ( defined($dbh) ) {
my @res = $dbh->query($sql);
my $x = scalar @res;
$Common::log->debug("luoxuansat>$sql->$x");
if ( scalar(@res) ) {
$Common::log->debug("luoxuansat2->$sql->$x");
return @res;
} else {
$dbh = _connect;
$Common::log->error("query retires $count $sql");
next;
}
} else {
$dbh = _connect;
$Common::log->error("query retires $count $sql");
next;
}
return @nores;--无结果集时返回
}9、修改效果
$xxagent logf|grep luoxuansun
2013-07-28 11:06:45 [DEBUG] luoxuansun5->0->0->0aa
2013-07-28 11:06:48 [DEBUG] luoxuansun5->0->0->0aa
2013-07-28 11:07:30 [DEBUG] luoxuansun5->0->0->0aa
下面代码不再执行打印
$Common::log->debug("luoxuansun3->@sql3re->") if (@sql3re);
写入一条记录
root@xx 11:11:05>insert into lijie values(1,'a');
Query OK, 1 row affected (0.00 sec)
log信息
$xxagent logf|grep luoxuansun
2013-07-28 11:12:14 [DEBUG] luoxuansun3->HASH(0x212f5f0)->
2013-07-28 11:12:14 [DEBUG] luoxuansun4 at
2013-07-28 11:12:14 [DEBUG] luoxuansun5->1->1->1aa
#xxagent logf|grep luoxuansat|grep lijie
2013-07-28 11:12:14 [DEBUG] luoxuansat>select id,name from lijie->1
2013-07-28 11:12:14 [DEBUG] luoxuansat2->select id,name from lijie->1
再写入一条
root@xx 11:11:11>insert into lijie values(1,'b');
Query OK, 1 row affected (0.00 sec)
log信息
$xxagent logf|grep luoxuansun
2013-07-28 11:14:51 [DEBUG] luoxuansun3->HASH(0x2140e58) HASH(0x21408a0)->
2013-07-28 11:14:51 [DEBUG] luoxuansun4 at
2013-07-28 11:14:51 [DEBUG] luoxuansun5->2->2->2aa
#xxagent logf|grep luoxuansat|grep lijie
2013-07-28 11:14:51 [DEBUG] luoxuansat>select id,name from lijie->2
2013-07-28 11:14:51 [DEBUG] luoxuansat2->select id,name from lijie->210、小结
上面把很多代码都省略,其实原本的代码函数之间调用还要复杂,为了把问题尽量简单,没有例出。问题总是有它的原因,只要你坚持。
建议继续学习:
- perl更新/修改/删除文本文件内容 (阅读:10183)
- perl大牛flw传说 (阅读:7155)
- perl模块Getopt::Std用法及实例-从命令行读取参数模块 (阅读:6569)
- [Perl] Template::Toolkit 模板技术. (阅读:5909)
- 在perl中连接和使用sqlite做数据存储 (阅读:5479)
- Perl命令行常见用法及技巧 (阅读:5483)
- Perl 倒行分析文件方法。perl读文本文件,从末尾往前读. (阅读:5176)
- perl的expect使用方法,实现非交互式登录。 (阅读:5136)
- perl模块之MIME::Lite发送有附件的邮件 (阅读:4977)
- perl大牛唐凤传说 (阅读:4822)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:玩转robots协议
后一篇:7个示例科普CPU Cache >>
文章信息
- 作者:STRUCTURED DATA UNSTRUCTURED DATA 来源: STRUCTURED DATA UNSTRUCTURED DATA
- 标签: perl
- 发布时间:2013-07-28 15:27:54
建议继续学习
近3天十大热文
-
[869] WordPress插件开发 -- 在插件使用 -
[136] 解决 nginx 反向代理网页首尾出现神秘字 -
[57] 整理了一份招PHP高级工程师的面试题 -
[56] 分享一个JQUERY颜色选择插件 -
[54] 用 Jquery 模拟 select -
[54] 如何保证一个程序在单台服务器上只有唯一实例( -
[54] CloudSMS:免费匿名的云短信 -
[53] Innodb分表太多或者表分区太多,会导致内 -
[53] 全站换域名时利用nginx和javascri -
[51] jQuery性能优化指南
