免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4896 | 回复: 17
打印 上一主题 下一主题

!求助!在线等!SQL error = -244 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-01-04 17:12 |只看该作者 |倒序浏览
各位大侠,今天有个问题求教:
现有两套INFORMIX数据库系统,每套上都有一张表tmp_basetab,(表结构见附件一)因为业务需要的原因,这个表的数据都是每天更新的,而且要使用存储过程sp_prestate(存储过程见附加二)进行细化更新。以前一直好好的,直到前几天,其中一套突然在运行存储过程sp_prestate时只能更新前一条(即只能把accounstate=3更新为state=5),其他更新都报失败,失败日志如下:
trace on


update tmp_basetab set
    (state) = ("5"
  where (= accountstate, 3);

update tmp_basetab set
(state) = ("1"
  where (and (and (or (= accountstate, 1), (= accountstate, 2)), (>= callservice
stop, i_ttime)), (= lock, "1");
exception : looking for handler
SQL error = -244 ISAM error = -134  error string =  = "tmp_basetab"
exception : no appropriate handler

然后我使用finderr查找原因:具体情况如下
-244    Could not do a physical-order read to fetch next row.

The database server cannot read the disk page that contains a row of a
table. Check the accompanying ISAM error code for more information. A
hardware problem might exist, or the table or index file might have
been corrupted. Unless the ISAM error code or an operating-system
message points to another cause, run the bcheck or secheck utility to
verify file integrity.

-134    ISAM error: no more locks.

The ISAM processor needs to lock a row or an index page, but no locks
are available. The number of locks that an operation requires depends
primarily on the number of rows that a single transaction modifies. You
can reduce the number of locks that an operation needs by doing less in
each transaction or by locking entire tables instead of locking rows.
Depending on the implementation that you are using, the number of locks
that is available is configured in one of three places: the
operating-system kernel, the shared-memory segment, or the database
server. Consult your database server administrator about making more
locks available.
好像是表的锁不够,可我的数据库水平太差,实在不知道怎么解决这个问题,怎么才能让这个存储过程,正确的在此表上使用?谢谢各位的尽快回复,谢谢了!
附件一:tmp_basetab的表结构:
{ TABLE "scu".tmp_basetab row size = 65 number of columns = 11 index size = 0 }
create table "scu".tmp_basetab
  (
    msisdn char(10) not null ,
    usertype integer,
    accountstate char(1),
    servicestart char(,
    servicestop char(,
    callservicestop char(,
    preaccountstop char(,
    accountstop char(,
    prefreezestop char(,
    lock char(1),
    state char(1)
  ) extent size 16 next size 16 lock mode row;
revoke all on "scu".tmp_basetab from "public";


附件二:存储过程sp_prestate:
CREATE PROCEDURE "scu".sp_prestate(  
   i_ttime varchar(                                          
)                                                                           
RETURNING                                                                  
                                                                           
    int;                                                                    
                                                                           
BEGIN                                                                       
    set debug file to '/tellin/scu/eform/log/sp_Prestate.log';           
    trace on;                                                               
    --PIB state
    update tmp_basetab set state='5'
          where accountstate=3;
    --active state
     update tmp_basetab set state='1'
       where
           (accountstate=1 or  accountstate=2)
       and
           CallServiceStop>=i_ttime
       and
         lock='1';
   --incoming state
    update tmp_basetab set state='2'
       where
           (accountstate=1 or  accountstate=2)
      and
         CallServiceStop<i_ttime and PreAccountStop>i_ttime
      and
         lock='1';
  --balance state
    update tmp_basetab set state='3'
      where (accountstate=1  or  accountstate=2)
      and
         PreAccountStop<=i_ttime and AccountStop>i_ttime
      and
         lock='1';
  --subscriber state
    update tmp_basetab set state='4'
       where
          (accountstate=1 or  accountstate=2)
      and
         ((AccountStop<=i_ttime and PreFreezeStop>i_ttime)or
         (AccountStop[1,4]=2005 and PreFreezeStop>i_ttime))
      and
         lock='1';
  --lock state
   update tmp_basetab set state='6'
      where
          (accountstate=4  or
         lock='0');
   --free
    update tmp_basetab set state='7'
      where
          (accountstate=1 or  accountstate=2)
      and

         PreFreezeStop<=i_ttime
      and
         lock='1';
   trace off;
END
END PROCEDURE;

论坛徽章:
0
2 [报告]
发表于 2007-01-04 21:47 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
3 [报告]
发表于 2007-01-04 23:51 |只看该作者
谢谢版主,锁是在$INFORMIXDIR/etc/onconfig 设置吗?我检查过了,这里锁的设置是5000000。改了这个应该要重启数据库才能生效吧?但我这里要求不能重启数据库阿,晕!以前没提示说锁不够阿?郁闷!

论坛徽章:
0
4 [报告]
发表于 2007-01-05 09:01 |只看该作者
看错误是得加locks 。但500万锁也不是小数目了。
你那表没索引是不是记录数多了 update 就会慢了 导致多个进程修改它互锁了。
建议加索引,改成记录锁。
把各条update 语句用set explain on 看看结果。
生产环境的存储过程里把trace 都关了。

论坛徽章:
0
5 [报告]
发表于 2007-01-05 13:36 |只看该作者
谢谢,您看给那些字段加上索引比较好?我看了看资料,上面说在做更新操作时(我的理解是update语句)要先把索引删去,我又糊涂了。到底该怎么办才能解决这个问题,狂急!

论坛徽章:
0
6 [报告]
发表于 2007-01-06 01:33 |只看该作者
更新整个表的记录时暂时的去掉索引会缩短更新时间!!

论坛徽章:
0
7 [报告]
发表于 2007-01-06 23:17 |只看该作者
1。具体需要在什么字段上加索引,需要看你的取值是怎么样的,这个你可以到网上搜下,建索引一般要建在哪些字段上,不过建索引要锁表的,可能要影响到应用。
2。wenlq说的很对“把各条update 语句用set explain on 看看结果”,你分析下各条语句的消耗情况,然后把结果贴出来,让大家给你看看。
3。至于你说的更新操作,先删索引,不大明白,是不是指在大批量数据更新的时候,可以先删索引,然后更新操作完成之后,再加索引,如果数据量比较大,这样还是可以,你还是先分set explian on 看看吧。

论坛徽章:
0
8 [报告]
发表于 2007-01-07 14:21 |只看该作者

谢谢大家伙

我刚才把出错的存储过程sp_prestate中的每条update语句都执行了一下,没有发现报错,而且表结构里也未加任何索引。具体情况如下:
1.未头次使用状态PIB:

set explain on;
update tmp_basetab set state="5" where accountstate="3";

QUERY:
------
update tmp_basetab set state="5" where accountstate="3"

Estimated Cost: 2
Estimated # of Rows Returned: 1

1) scu.tmp_basetab: SEQUENTIAL SCAN

    Filters: scu.tmp_basetab.accountstate = '3'
2.激活状态ACTIVE:
set explain on;
update tmp_basetab set state='1' where (accountstate="1" or accountstate="2") and callservicestop>i_ttime and lock="1";

QUERY:
------
update tmp_basetab set state='1' where (accountstate="1" or accountstate="2") and callservicestop>20070105 and lock="1"

Estimated Cost: 2
Estimated # of Rows Returned: 1

1) scu.tmp_basetab: SEQUENTIAL SCAN

    Filters: ((scu.tmp_basetab.accountstate = '1' OR scu.tmp_basetab.accountstate = '2' ) AND (scu.tmp_basetab.callservicesto
p > 20070105.0000000000000000 AND scu.tmp_basetab.lock = '1' ) )


3.做被叫状态incoming state:
set explain on;
update tmp_basetab set state="2" where (accountstate="1" or accountstate="2") and callservicestop<"20070105" and preaccoutstop>"20070105" and lock="1";

QUERY:
------
update tmp_basetab set state="2" where (accountstate="1" or accountstate="2") and callservicestop<"20070105" and preaccountst
op>"20070105" and lock="1"

Estimated Cost: 2
Estimated # of Rows Returned: 1

1) scu.tmp_basetab: SEQUENTIAL SCAN

    Filters: ((scu.tmp_basetab.accountstate = '1' OR scu.tmp_basetab.accountstate = '2' ) AND (scu.tmp_basetab.callservicesto
p < '20070105' AND (scu.tmp_basetab.preaccountstop > '20070105' AND scu.tmp_basetab.lock = '1' ) ) )

4.查询余额状态:balancestate

set explain on;
update tmp_basetab set state="3" where (accountstate="1" or accountstate="2") and preaccoutstop<"20070105"  and accountstop>"20070105" and lock="1";

QUERY:
------
update tmp_basetab set state="3" where (accountstate="1" or accountstate="2") and preaccountstop<"20070105"  and accountstop>
"20070105" and lock="1"

Estimated Cost: 2
Estimated # of Rows Returned: 1

1) scu.tmp_basetab: SEQUENTIAL SCAN

    Filters: ((scu.tmp_basetab.accountstate = '1' OR scu.tmp_basetab.accountstate = '2' ) AND (scu.tmp_basetab.preaccountstop
< '20070105' AND (scu.tmp_basetab.accountstop > '20070105' AND scu.tmp_basetab.lock = '1' ) ) )

5.保号状态 subscriber state

set explain on;
update tmp_basetab set state="4" where (accountstate="1" or accountstate="2") and ((accountstop<="20070105" and prefreezestop>"20070105") or (accountstop[1,4]=2005 and prefreezetstop>"20070105")) and lock="1";
update tmp_basetab set state="4" where (accountstate="1" or accountstate="2") and ((accountstop<="20070105" and prefreezestop
>"20070105") or (accountstop[1,4]=2005 and prefreezestop>"20070105")) and lock="1"

Estimated Cost: 2
Estimated # of Rows Returned: 1

1) scu.tmp_basetab: SEQUENTIAL SCAN

    Filters: ((scu.tmp_basetab.accountstate = '1' OR scu.tmp_basetab.accountstate = '2' ) AND (((scu.tmp_basetab.accountstop
<= '20070105' AND scu.tmp_basetab.prefreezestop > '20070105' ) OR (scu.tmp_basetab.accountstop[1,4] = '2005' AND scu.tmp_base
tab.prefreezestop > '20070105' ) ) AND scu.tmp_basetab.lock = '1' ) )

6.锁定状态 lock state

set explain on;
update tmp_basetab set state="6" where (accountstate="4" or lock="0");

QUERY:
------
update tmp_basetab set state="6" where (accountstate="4" or lock="0")

Estimated Cost: 2
Estimated # of Rows Returned: 2

1) scu.tmp_basetab: SEQUENTIAL SCAN

    Filters: (scu.tmp_basetab.accountstate = '4' OR scu.tmp_basetab.lock = '0' )
7.消耗状态 --free

set explain on;
update tmp_basetab set state="7" where (accountstate="1" or accountstate="2") and prefreezestop<="20070105" and lock="1";
QUERY:
------
update tmp_basetab set state="7" where (accountstate="1" or accountstate="2") and prefreezestop<="20070105" and lock="1"

Estimated Cost: 2
Estimated # of Rows Returned: 1

1) scu.tmp_basetab: SEQUENTIAL SCAN

    Filters: ((scu.tmp_basetab.accountstate = '1' OR scu.tmp_basetab.accountstate = '2' ) AND (scu.tmp_basetab.prefreezestop
<= '20070105' AND scu.tmp_basetab.lock = '1' ) )

  而且我要把全表用update tmp_basetab set state="0",依然报错:

执行

set lock mode to wait 5;
update tmp_basetab set state="0";

报错:244,134 no more locks;


于是我打开跟踪开关;

set explain on;
set lock mode to wait 5;
update tmp_basetab set state="0";

QUERY:
------
update tmp_basetab set state="0"

Estimated Cost: 2
Estimated # of Rows Returned: 10

1) scu.tmp_basetab: SEQUENTIAL SCAN

存储过程sp_prestate执行也是在报错,日志如下:


整个存储过程的执行,

set explain on;
excute procedure sp_prestate(20070105);

----------
     3  Procedure: scu.sp_prestate
     4
     5          update "scu".tmp_basetab set "scu".tmp_basetab.state = '5'  where (accountstate = '3' )
     6
     7  QUERY:
     8  ------
     9
    10
    11  Estimated Cost: 2
    12  Estimated # of Rows Returned: 1
    13
    14  1) scu.tmp_basetab: SEQUENTIAL SCAN
    15
    16      Filters: scu.tmp_basetab.accountstate = '3'
    17
    18
    19  ----------
    20  Procedure: scu.sp_prestate
    21
    22          update "scu".tmp_basetab set "scu".tmp_basetab.state = '1'  where ((((accountstate = '1' ) OR (accountstate =
'2' ) ) AND (callservicestop >= ? ) ) AND (lock = '1' ) )
    23
    24  QUERY:
    25  ------
    26
    27
    28  Estimated Cost: 2
    29  Estimated # of Rows Returned: 1
    30
    31  1) scu.tmp_basetab: SEQUENTIAL SCAN
    32
    33      Filters: ((scu.tmp_basetab.accountstate = '1' OR scu.tmp_basetab.accountstate = '2' ) AND (scu.tmp_basetab.callse
rvicestop >= '20070105' AND scu.tmp_basetab.lock = '1' ) )

我现在怀疑是不是由于执行存储过程时,update语句不是按顺序一条一条执行,而是同时执行,所以会出错。

真不知道该怎么办了,实在不行我就在每条update语句后面各加条set lock mode to wait 5;看看。、

谢谢各位的指教,HELP ME!

论坛徽章:
0
9 [报告]
发表于 2007-01-07 14:22 |只看该作者

谢谢大家关心

我刚才把出错的存储过程sp_prestate中的每条update语句都执行了一下,没有发现报错,而且表结构里也未加任何索引。具体情况如下:
1.未头次使用状态PIB:

set explain on;
update tmp_basetab set state="5" where accountstate="3";

QUERY:
------
update tmp_basetab set state="5" where accountstate="3"

Estimated Cost: 2
Estimated # of Rows Returned: 1

1) scu.tmp_basetab: SEQUENTIAL SCAN

    Filters: scu.tmp_basetab.accountstate = '3'
2.激活状态ACTIVE:
set explain on;
update tmp_basetab set state='1' where (accountstate="1" or accountstate="2") and callservicestop>i_ttime and lock="1";

QUERY:
------
update tmp_basetab set state='1' where (accountstate="1" or accountstate="2") and callservicestop>20070105 and lock="1"

Estimated Cost: 2
Estimated # of Rows Returned: 1

1) scu.tmp_basetab: SEQUENTIAL SCAN

    Filters: ((scu.tmp_basetab.accountstate = '1' OR scu.tmp_basetab.accountstate = '2' ) AND (scu.tmp_basetab.callservicesto
p > 20070105.0000000000000000 AND scu.tmp_basetab.lock = '1' ) )


3.做被叫状态incoming state:
set explain on;
update tmp_basetab set state="2" where (accountstate="1" or accountstate="2") and callservicestop<"20070105" and preaccoutstop>"20070105" and lock="1";

QUERY:
------
update tmp_basetab set state="2" where (accountstate="1" or accountstate="2") and callservicestop<"20070105" and preaccountst
op>"20070105" and lock="1"

Estimated Cost: 2
Estimated # of Rows Returned: 1

1) scu.tmp_basetab: SEQUENTIAL SCAN

    Filters: ((scu.tmp_basetab.accountstate = '1' OR scu.tmp_basetab.accountstate = '2' ) AND (scu.tmp_basetab.callservicesto
p < '20070105' AND (scu.tmp_basetab.preaccountstop > '20070105' AND scu.tmp_basetab.lock = '1' ) ) )

4.查询余额状态:balancestate

set explain on;
update tmp_basetab set state="3" where (accountstate="1" or accountstate="2") and preaccoutstop<"20070105"  and accountstop>"20070105" and lock="1";

QUERY:
------
update tmp_basetab set state="3" where (accountstate="1" or accountstate="2") and preaccountstop<"20070105"  and accountstop>
"20070105" and lock="1"

Estimated Cost: 2
Estimated # of Rows Returned: 1

1) scu.tmp_basetab: SEQUENTIAL SCAN

    Filters: ((scu.tmp_basetab.accountstate = '1' OR scu.tmp_basetab.accountstate = '2' ) AND (scu.tmp_basetab.preaccountstop
< '20070105' AND (scu.tmp_basetab.accountstop > '20070105' AND scu.tmp_basetab.lock = '1' ) ) )

5.保号状态 subscriber state

set explain on;
update tmp_basetab set state="4" where (accountstate="1" or accountstate="2") and ((accountstop<="20070105" and prefreezestop>"20070105") or (accountstop[1,4]=2005 and prefreezetstop>"20070105")) and lock="1";
update tmp_basetab set state="4" where (accountstate="1" or accountstate="2") and ((accountstop<="20070105" and prefreezestop
>"20070105") or (accountstop[1,4]=2005 and prefreezestop>"20070105")) and lock="1"

Estimated Cost: 2
Estimated # of Rows Returned: 1

1) scu.tmp_basetab: SEQUENTIAL SCAN

    Filters: ((scu.tmp_basetab.accountstate = '1' OR scu.tmp_basetab.accountstate = '2' ) AND (((scu.tmp_basetab.accountstop
<= '20070105' AND scu.tmp_basetab.prefreezestop > '20070105' ) OR (scu.tmp_basetab.accountstop[1,4] = '2005' AND scu.tmp_base
tab.prefreezestop > '20070105' ) ) AND scu.tmp_basetab.lock = '1' ) )

6.锁定状态 lock state

set explain on;
update tmp_basetab set state="6" where (accountstate="4" or lock="0");

QUERY:
------
update tmp_basetab set state="6" where (accountstate="4" or lock="0")

Estimated Cost: 2
Estimated # of Rows Returned: 2

1) scu.tmp_basetab: SEQUENTIAL SCAN

    Filters: (scu.tmp_basetab.accountstate = '4' OR scu.tmp_basetab.lock = '0' )
7.消耗状态 --free

set explain on;
update tmp_basetab set state="7" where (accountstate="1" or accountstate="2") and prefreezestop<="20070105" and lock="1";
QUERY:
------
update tmp_basetab set state="7" where (accountstate="1" or accountstate="2") and prefreezestop<="20070105" and lock="1"

Estimated Cost: 2
Estimated # of Rows Returned: 1

1) scu.tmp_basetab: SEQUENTIAL SCAN

    Filters: ((scu.tmp_basetab.accountstate = '1' OR scu.tmp_basetab.accountstate = '2' ) AND (scu.tmp_basetab.prefreezestop
<= '20070105' AND scu.tmp_basetab.lock = '1' ) )

  而且我要把全表用update tmp_basetab set state="0",依然报错:

执行

set lock mode to wait 5;
update tmp_basetab set state="0";

报错:244,134 no more locks;


于是我打开跟踪开关;

set explain on;
set lock mode to wait 5;
update tmp_basetab set state="0";

QUERY:
------
update tmp_basetab set state="0"

Estimated Cost: 2
Estimated # of Rows Returned: 10

1) scu.tmp_basetab: SEQUENTIAL SCAN

存储过程sp_prestate执行也是在报错,日志如下:


整个存储过程的执行,

set explain on;
excute procedure sp_prestate(20070105);

----------
     3  Procedure: scu.sp_prestate
     4
     5          update "scu".tmp_basetab set "scu".tmp_basetab.state = '5'  where (accountstate = '3' )
     6
     7  QUERY:
     8  ------
     9
    10
    11  Estimated Cost: 2
    12  Estimated # of Rows Returned: 1
    13
    14  1) scu.tmp_basetab: SEQUENTIAL SCAN
    15
    16      Filters: scu.tmp_basetab.accountstate = '3'
    17
    18
    19  ----------
    20  Procedure: scu.sp_prestate
    21
    22          update "scu".tmp_basetab set "scu".tmp_basetab.state = '1'  where ((((accountstate = '1' ) OR (accountstate =
'2' ) ) AND (callservicestop >= ? ) ) AND (lock = '1' ) )
    23
    24  QUERY:
    25  ------
    26
    27
    28  Estimated Cost: 2
    29  Estimated # of Rows Returned: 1
    30
    31  1) scu.tmp_basetab: SEQUENTIAL SCAN
    32
    33      Filters: ((scu.tmp_basetab.accountstate = '1' OR scu.tmp_basetab.accountstate = '2' ) AND (scu.tmp_basetab.callse
rvicestop >= '20070105' AND scu.tmp_basetab.lock = '1' ) )

我现在怀疑是不是由于执行存储过程时,update语句不是按顺序一条一条执行,而是同时执行,所以会出错。

真不知道该怎么办了,实在不行我就在每条update语句后面各加条set lock mode to wait 5;看看。、

谢谢各位的指教,HELP ME!

论坛徽章:
0
10 [报告]
发表于 2007-01-08 00:55 |只看该作者
1.select count(*)  from tmp_basetab where accountstate=3;
把各个状态的都统计下看数量有多大.
2.select count(*) from tmp_basetab 这张表究竟多大.
3.onstat -k |wc -l看究竟占用了多少锁,执行存储过程时看能达到多少
4.存储过程里面的update 语句每一个单独拿到dbaccess里执行,也报锁不够吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP