通过定时任务自动清理长时间挂着没commit的事物

SYBASE ASE 的每一个数据库,无论是系统数据库(master,model, sybsystemprocs, tempdb),还是用户数据库,都有自己的transaction log,每个库都有syslogs表。Transaction Log记录用户对数据库修改的操作。以下对一些日志满的常见例子进行分析。 

一、数据库日志空间建的太小 


日志大小主要与事务的大小,并发,数据量的大小有关。如果事务日志建立太小,数据库日志满,导致事务被挂起。 

当出现日志空间不够时,在数据库的错误日志里面会出现1105的错误报告。 

对于这种情况,管理员可以通过alter database命令来扩大数据库的日志空间。 

二、数据库日志长时间没有删除 

如果不用命令清除, log会一直增长直至占满空间。 

清除log可用dump transaction 命令,可以将上述命令放在系统的定时命令中,让系统自动执行来定期清除日志。 

开放数据库自动清日志选项,sp_dboption 'dbname','trunc log on checkpoint','true',数据库会每隔一段间隔自动清除log。不过设置改数据库选项会对数据库的性能有不利的影响,所以建议采用定期删除日志的办法。 

三、存在不完整的事务 

有时候虽然采用了定期删除日志或是将开放了自动清日志的数据库选项,但仍然出现了日志满的情况。 

出现这种情况是由于不完整的事务引起的。引起不完整的事务主要有两个方面的原因:第一是网络质量不佳,如果在客户端向ASE服务端进行事务时,如果网络突然中断,会导致事务的不完整。第二是应用程序存在不完整的事务,例如存储过程中某一出口没有提交事务,导致事务的不完整。 

如果存在不完整的事务,在该事务之后的所有事务都不能被清除,导致数据库日志满。 

解决这类问题,主要是根据引起不完整事务的原因来解决,如解决网络问题,检查引起不完整事务的程序。 

在网络问题不能解决,或是应用程序一时不好修改的情况下,通过以下存储过程自动清除不完整的事务,也可以避免日志满: 

create proc proc_kill 

@last_min int 

AS 

/* 

** kill the processes that does'nt commit during the period that you think it's impossible  ** 

** the parameter' time unit is minute 

*/ 

declare @spid int 

declare @cspid       char(20) 

select  spid  into #killtab from  master..syslogshold where datediff(mi,starttime,getdate()) >@last_min and spid>0 

declare spid_cur  cursor for select *  from  #killtab 

open  spid_cur 

fetch spid_cur into @spid 

while @@sqlstatus!=2 

begin 

       select  @cspid=convert(char(20),@spid) 

       select  "kill  "+@cspid 

       exec("kill "+@cspid) 

       fetch spid_cur into @spid 

end 

将以上存储过程放在系统的定时命令中,让它定期检查不完整的事务,并将不完整的事务kill。 

你可能感兴趣的:(通过定时任务自动清理长时间挂着没commit的事物)