+ -
当前位置:首页 → 问答吧 → 锁已经配到100万了为什么数据库经常报1204错误?

锁已经配到100万了为什么数据库经常报1204错误?

时间:2010-07-29

来源:互联网

数据库锁为100万,有一张千万级的表,做带条件的select 查询,结果集是1或是几百,有并发,但是我不知道并发量是多少,经常出现1204的错误,用户的隔离级别是Read Commited,为什么呢,怎么样才能避免这个错误呢?

作者: 1038345   发布时间: 2010-07-29

增加一下说明

这个表的锁方案是:所有页
数据库版本是sybase 15.0.3

我在log中查到的第一个出现1204错误的是select,但是会不会在这个select 之前有别的操作,把锁用光了,所以到select 的时候就锁不够了呢

[ 本帖最后由 1038345 于 2010-7-29 14:50 编辑 ]

作者: 1038345   发布时间: 2010-07-29

检查一下你的select语句是否用到索引,如果没有的话,table scan会消耗大量的锁。

得到SQL语句的查询计划:

set showplan on
set noexec on
your_sql

作者: jarjar   发布时间: 2010-08-05



QUOTE:原帖由 1038345 于 2010-7-29 14:47 发表
增加一下说明

这个表的锁方案是:所有页
数据库版本是sybase 15.0.3

我在log中查到的第一个出现1204错误的是select,但是会不会在这个select 之前有别的操作,把锁用光了,所以到select 的时候就锁不够了呢

对,是select的时候就已经没有锁资源了,所以select要申请的一个sh_page都没有,就报错了

作者: 5个周   发布时间: 2010-08-06



QUOTE:原帖由 jarjar 于 2010-8-5 09:51 发表
检查一下你的select语句是否用到索引,如果没有的话,table scan会消耗大量的锁。

得到SQL语句的查询计划:

set showplan on
set noexec on
your_sql

这个我稍微不赞同一下。以我的测试,在做table scan的时候,ASE只在当时要读的那条记录上加一个sh_page或者sh_page,不会占用很多锁资源的。

作者: 5个周   发布时间: 2010-08-06



QUOTE:原帖由 5个周 于 2010-8-6 15:44 发表


这个我稍微不赞同一下。以我的测试,在做table scan的时候,ASE只在当时要读的那条记录上加一个sh_page或者sh_page,不会占用很多锁资源的。

强烈同意。 都是表锁了, 一个表全部锁了,还要那么多锁干什么? 又不是行锁。 

问题不在这里。 

作者: andkylee   发布时间: 2010-08-06

sp_lock  看看锁都干什么了~

作者: andkylee   发布时间: 2010-08-06



QUOTE:原帖由 andkylee 于 2010-8-6 17:29 发表




强烈同意。 都是表锁了, 一个表全部锁了,还要那么多锁干什么? 又不是行锁。 

问题不在这里。 

唉,我再次不赞同一下,不是表锁,就是sh_page或者sh_row。

作者: 5个周   发布时间: 2010-08-06



QUOTE:原帖由 andkylee 于 2010-8-6 17:30 发表
sp_lock  看看锁都干什么了~

100W的sp_lock可能输出不了,只能有一个抓一个了。

作者: 5个周   发布时间: 2010-08-06



QUOTE:原帖由 5个周 于 2010-8-6 15:44 发表


这个我稍微不赞同一下。以我的测试,在做table scan的时候,ASE只在当时要读的那条记录上加一个sh_page或者sh_page,不会占用很多锁资源的。

当update语句也是table scan的时候,请检查锁的情况。

sp_lock输出太多,可以用select  * from master.dbo.syslocks。

如果12.5.3以上,select top 100 * from master.dbo.syslocks
否则
set rowcount 100
select * from master.dbo.syslocks

作者: jarjar   发布时间: 2010-08-07

什么版本?BUG可能性大哦

作者: qzwsf   发布时间: 2010-08-09

数据库版本是15.0.3


select  * from master.dbo.syslocks,我在系统不忙时查到只有几条记录,在系统忙时这个表的数据太多了,数据库响应不过来了.

作者: 1038345   发布时间: 2010-08-10

查询计划用到索引了

作者: 1038345   发布时间: 2010-08-10



QUOTE:原帖由 jarjar 于 2010-8-7 18:15 发表


当update语句也是table scan的时候,请检查锁的情况。

sp_lock输出太多,可以用select  * from master.dbo.syslocks。

如果12.5.3以上,select top 100 * from master.dbo.syslocks
否则
set rowcount 100
select * from master.dbo.syslocks

这位朋友,请问update语句用table scan的时候锁是怎么使用的,扫描经过的地方都会上锁吗?

作者: 1038345   发布时间: 2010-08-13

只有需要被update的记录才会被加锁,你这问题只能通过总结出现的规律从业务上来分析。

作者: 5个周   发布时间: 2010-08-13



QUOTE:原帖由 1038345 于 2010-8-10 15:56 发表
数据库版本是15.0.3


select  * from master.dbo.syslocks,我在系统不忙时查到只有几条记录,在系统忙时这个表的数据太多了,数据库响应不过来了.

有个笨办法:做个脚本,每5分钟连到数据库里面把sp_lock或者syslocks输出,如果输出文件的尺寸开始增大,则打开输出文件找到持锁最多的进程spid,然后赶快连进去,dbcc traceon(3604) dbcc sqltext(spid),观察个一天两天也就知道是什么业务产生大量的锁了。

自动一点呢,就写个循环执行的程序:开始select spid,max(count(spid)) from syslocks(大概就就这意思),然后dbcc traceon(3604) dbcc sqltext(spid)输出到一张表或者其他地方去,晚了order by一下这张表就完了呗。

还有一个可能性,就是你的业务用了很多临时表,因为ASE 15的系统表开始用行锁了,所以临时表消耗了很多锁资源,这种情况的话可能就要稍麻烦一点,要在创建临时表的时候指定用allpage而不是用缺省的allrows。

作者: 5个周   发布时间: 2010-08-13

怪不得看不懂了
原来是sybase

作者: lifesunson   发布时间: 2011-08-26