你还可以再诡异点吗——SQL日志文件不断增长
你还可以再诡异点吗——SQL日志文件不断增长
前言
今天算是遇到了一个罕见的案例。
SQL日志文件不断增长的各种实例不用多说,园子里有很多牛人有过介绍,如果我再阐述这些陈谷子芝麻,想必已会被无数次吐槽。
但这次我碰到的问题确实比较诡异,其解决方式也是我第一次使用。
下文将为各位看管详细介绍我的解决思路。
现象
一客户反馈数据库的日志文件不断增长,已分配的磁盘空间快使用完,尝试过事务日志截断(事务日志备份)的操作,但没有任何效果。
分析
遇到这个问题,我最直接的感受:肯定有大的事务一直在执行,导致日志备份无法截断事务日志的大小。
首先,我在该数据库下运行DBCC loginfo()

图一
从图一的红色框可以看到,数据库的多个VLF的状态都为2,也就是active状态。(如果为0 ,表示为inactive)。
这表明这些日志文件确实都在活动状态,一般而言,导致这种现象的原因主要有三种:长事务的运行、replication和mirroring延迟。
但这个客户没有采用replication和mirroring,所以我初步锁定问题是因为长事务的运行导致。按照常规的方法,我只需分析下这个事务是否遇到阻塞、死锁等情况,然后给出对应的解决方案即可。(但实际情况并非如此)
为保险起见,我运行如下语句来验证下我的判断:
SELECT log_reuse_wait_desc, * FROM sys.databases WHERE NAME='dbname'
显然,我的判断错了,可以看到,目前【log_reuse_wait_desc】的状态为【REPLICATION】。也就是说正是事务日志分发导致日志文件不断增大的原因。
正如前文分析的,这个数据库并没有用作发布订阅,怎么会出现这个状态呢?
经与客户沟通,了解这个数据库其实是从一个发布订阅的数据库中还原过来的,尽管新的数据库并没有采用发布订阅,但数据库中发布订阅的一些配置选项还在,从而导致了数据库的误判,致使日志文件不断增大。
方案
知道了原因就好办了。
起初我想通过sp_droppublication来完全删除分发订阅的配置,但无法通过sp_helppublication获取到@publication的名字(提示:命令已执行完!),因此这条路走不通了。
在网上找些资料,发现了sp_removedbreplication这个存储过程,执行后再去收缩日志文件,问题果然解决!
EXEC sp_removedbreplication dbname
DBCC SHRINKFILE(Logfilename)
DBCC loginfo()
图三
总结
尽管本文的场景比较少见,但总体解决的思路与其他(日志文件不断增长)其实是一样的。少许地方不太明白可以通过网络等一些工具获得。这也说明了SQL原理的重要性,借用一本书的序言中的一句话【越接触本质越不会迷茫!】。多接触原理,很多东西都是触类旁通的。
http://www.agilesharp.com/showtopic-188.aspx
一般来说,一个VLF可以处于两种物理状态:活动和非活动.但是基于VLF可能不同的行为,我们逻辑上分为四种:
1.活动.--一个VLF处于活动状态是因为他至少包含了活动日志一部分的日志记录,所以可能会被要求回滚或者其他需求.
2.可恢复的.--一个VLF已经处于非活动状态了.但是由于没有进行日志备份或者截断,所以空间不能被重用
3.可重用的.--一个VLF处于非活动状态,并且已经执行截断或者日志备份,空间可以被重用
4.未使用的.--一个VLF处于非活动状态,其中不包含任何一条日志记录.
将一个VLF标记为非活动的操作,按照我们上面介绍的逻辑状态,是从第二个状态变为第三个状态,该操作被称为日志截断.
http://blog.csdn.net/lvjin110/article/details/10360779



浙公网安备 33010602011771号
其实你的担心也是很多人对SQL的误解。当然相比oracle而言,SQL肯定存在差距,但并非一无是处。就算是oracle、mysql,同样存在这类问题。像你说的,如果SQL这么容易就崩溃了,那纳斯达克斯、凡客这类怎么现在还都在用这呢。
有些问题不能完全怪在数据库上,日志文件满了,可能跟程序和使用也有关系。我这篇博文其实也说明了导致问题的根本是一个误还原操作。