你还可以再诡异点吗——SQL日志文件不断增长

你还可以再诡异点吗——SQL日志文件不断增长

 

 

前言

 

今天算是遇到了一个罕见的案例。

SQL日志文件不断增长的各种实例不用多说,园子里有很多牛人有过介绍,如果我再阐述这些陈谷子芝麻,想必已会被无数次吐槽。

但这次我碰到的问题确实比较诡异,其解决方式也是我第一次使用。

下文将为各位看管详细介绍我的解决思路。

 

现象

 

一客户反馈数据库的日志文件不断增长,已分配的磁盘空间快使用完,尝试过事务日志截断(事务日志备份)的操作,但没有任何效果。

 

分析

 

遇到这个问题,我最直接的感受:肯定有大的事务一直在执行,导致日志备份无法截断事务日志的大小。

首先,我在该数据库下运行DBCC loginfo()

clip_image002

                                          图一

从图一的红色框可以看到,数据库的多个VLF的状态都为2,也就是active状态。(如果为0 ,表示为inactive)。

这表明这些日志文件确实都在活动状态,一般而言,导致这种现象的原因主要有三种:长事务的运行、replication和mirroring延迟。

但这个客户没有采用replication和mirroring,所以我初步锁定问题是因为长事务的运行导致。按照常规的方法,我只需分析下这个事务是否遇到阻塞、死锁等情况,然后给出对应的解决方案即可。(但实际情况并非如此)

为保险起见,我运行如下语句来验证下我的判断:

SELECT log_reuse_wait_desc, * FROM sys.databases WHERE NAME='dbname'

image                                                                                           图二

 

显然,我的判断错了,可以看到,目前【log_reuse_wait_desc】的状态为【REPLICATION】。也就是说正是事务日志分发导致日志文件不断增大的原因。

正如前文分析的,这个数据库并没有用作发布订阅,怎么会出现这个状态呢?

经与客户沟通,了解这个数据库其实是从一个发布订阅的数据库中还原过来的,尽管新的数据库并没有采用发布订阅,但数据库中发布订阅的一些配置选项还在,从而导致了数据库的误判,致使日志文件不断增大。

 

方案

 

知道了原因就好办了。

起初我想通过sp_droppublication来完全删除分发订阅的配置,但无法通过sp_helppublication获取到@publication的名字(提示:命令已执行完!),因此这条路走不通了。

在网上找些资料,发现了sp_removedbreplication这个存储过程,执行后再去收缩日志文件,问题果然解决!

EXEC sp_removedbreplication dbname

DBCC SHRINKFILE(Logfilename)

DBCC loginfo()

clip_image007

                                                  图三

 

 

总结

 

尽管本文的场景比较少见,但总体解决的思路与其他(日志文件不断增长)其实是一样的。少许地方不太明白可以通过网络等一些工具获得。这也说明了SQL原理的重要性,借用一本书的序言中的一句话【越接触本质越不会迷茫!】。多接触原理,很多东西都是触类旁通的。

 

 
 
 
 
绿色通道: 好文要顶 关注我 收藏该文与我联系 
26
0
 
(请您对文章做出评价)
 
« 上一篇:SQL Server转发记录指针的坏味道
» 下一篇:数据库错误日志惹的祸
posted @ 2013-08-25 21:36 i6first 阅读(4898) 评论(33编辑 收藏

 

 
#1楼[楼主2013-08-26 08:48 | i6first  
@討論PHP的QQ群223494678
其实你的担心也是很多人对SQL的误解。当然相比oracle而言,SQL肯定存在差距,但并非一无是处。就算是oracle、mysql,同样存在这类问题。像你说的,如果SQL这么容易就崩溃了,那纳斯达克斯、凡客这类怎么现在还都在用这呢。
有些问题不能完全怪在数据库上,日志文件满了,可能跟程序和使用也有关系。我这篇博文其实也说明了导致问题的根本是一个误还原操作。
#2楼 2013-08-26 12:25 | stswordman  
@討論PHP的QQ群223494678
引用如果不是一個網遊,而是一個日進斗金的大項目用他的話豈不是這一下虧損大發了.

现在的数据库还没有那么智能,所以才需要专业的dba去维护
#3楼 2013-08-26 13:11 | 魔都浪子~  
现在连mysql都敢来叫板MSSQL,呵呵
#4楼 2013-08-26 13:17 | 桦仔  
【越接触本质越不会迷茫!】呵呵
#5楼 2013-08-26 13:18 | 桦仔  
顶一个
#6楼 2013-08-26 13:20 | 桦仔  
您今天问的问题啊
http://www.agilesharp.com/showtopic-188.aspx
一般来说,一个VLF可以处于两种物理状态:活动和非活动.但是基于VLF可能不同的行为,我们逻辑上分为四种:

1.活动.--一个VLF处于活动状态是因为他至少包含了活动日志一部分的日志记录,所以可能会被要求回滚或者其他需求.

2.可恢复的.--一个VLF已经处于非活动状态了.但是由于没有进行日志备份或者截断,所以空间不能被重用

3.可重用的.--一个VLF处于非活动状态,并且已经执行截断或者日志备份,空间可以被重用

4.未使用的.--一个VLF处于非活动状态,其中不包含任何一条日志记录.
将一个VLF标记为非活动的操作,按照我们上面介绍的逻辑状态,是从第二个状态变为第三个状态,该操作被称为日志截断.
#7楼 2013-08-26 13:27 | 魔都浪子~  
@討論PHP的QQ群223494678
引用請記住一句話:使用微軟的東西時,不管遇到什麽詭異的問題都請不要驚訝
就像你文章中遇到的日誌不斷增大以前我常常遇到,我開了一個網遊,數據庫就是mssql,突然有一天重啟服務器之後大家都說我回檔了,其實我並沒有回檔,仔細一看日誌滿了,硬盤無法寫入新的遊戲資料.

什么叫日志满了?是日志文件太大导致硬盘被写满,所以无法分配新的extent,是吗? 不过这跟SQL SERVER有什么关系呢?
#8楼 2013-08-26 13:47 | William Jiang  
呵呵(。。。)
#9楼[楼主2013-08-26 14:10 | i6first  
@桦仔
呵呵,经常访问你的博客,这句话在你的主页上看到,感谢你的回复呀。
你说的对,VLF确实有多种状态,特别是可恢复状态,这个应该是日志能够截断的前提之一吧。
#10楼 2013-08-26 14:17 | 罗里罗嗦夫斯基  
自己有不可推卸的责任。
#11楼 2013-08-26 14:19 | 桦仔  
@i6first
引用@桦仔
呵呵,经常访问你的博客,这句话在你的主页上看到,感谢你的回复呀。
你说的对,VLF确实有多种状态,特别是可恢复状态,这个应该是日志能够截断的前提之一吧。


我记得您经常在msdn论坛上提问的,你分享出来大家也学习到了,加油!
#12楼[楼主2013-08-26 14:35 | i6first  
@桦仔
hey,那个正是我,原来是你呀,嘿嘿,这个圈子还真不陌生呀。谢谢支持!
#13楼 2013-08-26 16:01 | 魔都浪子~  
@討論PHP的QQ群223494678
引用@魔都浪子~

引用@討論PHP的QQ群223494678

引用引用請記住一句話:使用微軟的東西時,不管遇到什麽詭異的問題都請不要驚訝
就像你文章中遇到的日誌不斷增大以前我常常遇到,我開了一個網遊,數據庫就是mssql,突然有一天重啟服務器之後大家都說我回檔了,其實我並沒有回檔,仔細一看日誌滿了,硬盤無法寫入新的遊戲資料.
什么叫日志满了?是日志文件太大导致硬盘被写满,所以无法分配新的extent,是吗? 不过这跟SQL SERVER有什么关系呢?
1T的硬盤都寫能寫滿?虧你想得出來.

1T的硬盤写满很正常,特别是在你不做日志备份的情况下,就算10T都能写满。
#14楼 2013-08-26 16:21 | 魔都浪子~  
@討論PHP的QQ群223494678
引用我用過那麼多數據庫,包括mysql;oracle;access;mssql;sqlite
最奇葩的恐怕就是mssql了
好吧,每個人口味不同,既然你們那麼喜歡mssql那就繼續為其搖旗呐喊吧!

你可以对某个产品有误解,但是不能有偏见。如果有误解,那你把你的问题说出来,大家可以帮你,如果是偏见的话,那神仙都没有办法。
#15楼 2013-08-26 16:37 | john23.net  
感谢分享
#16楼 2013-08-26 16:39 | wdwwtzy  
正常的日志文件增大怎么处理呢,我有个数据库的日志文件有奖金100G了……虽然硬盘是1TB的也不觉得怎样,但是不能一直这样下去啊,怎么减少?
#17楼 2013-08-26 18:54 | 吕津  
越接触本质,越不会迷茫-《Microsoft SQL Server企业级平台管理实践》
http://blog.csdn.net/lvjin110/article/details/10360779
#18楼[楼主2013-08-26 19:55 | i6first  
@wdwwtzy
定期做事务日志的备份,这样可以截断日志,使得vlf可以重复循环使用。
#19楼[楼主2013-08-26 19:57 | i6first  
@吕津

是的,这本书确实写得不错,理论和实践都照顾到了。建议配合《深入分析SQL Server2008》这本书看,效果更好。
#20楼 2013-08-27 09:43 | wdwwtzy  
@i6first
呃,肿么截断....大概可以瘦身多少?
#21楼 2013-08-27 16:33 | StevenChennet  
@吕津
引用越接触本质,越不会迷茫-《Microsoft SQL Server企业级平台管理实践》
http://blog.csdn.net/lvjin110/article/details/10360779


----------这书早就绝迹了,整天贴出来有个屁用,徒增口水罢了。
#22楼 2013-08-27 17:05 | sym_cn  
我也曾遇到这个问题,不妨试一下备份两次日志,然后再进行日志收缩。 其他的一些情况《Microsoft SQL Server企业级平台管理实践》也有介绍。
#24楼[楼主2013-08-28 15:17 | i6first  
@wdwwtzy
这.....怎么回答你呢,通过备份事物日志可以截断不活动的VLF,然后再去收缩,这个大小关键是你不活动的VLF有多大,这个没有定量的。
#25楼[楼主2013-08-28 15:21 | i6first  
@sym_cn
我的情况跟你不一样,这个在sys.databases中可以看得出来,我的 log_reuse_wait_desc是replication,你的应该是backup.
#26楼 2013-09-01 21:32 | 手机网站开发  
我在解决服务器CPU使用率过高的问题时,也曾经关注过这个问题。后来好像设定上限就可以解决了。
#27楼 2013-09-01 23:11 | 弥散  
什么意思
#28楼 2013-09-02 23:30 | BangQ  
ฏ๎๎๎๎๎๎๎๎๎ฏฏด้้้้้็็็็็้้้้้็็็็็้้้้้็็็้็็็ฏ๎็็็ 谢谢分享
#29楼 2013-09-03 14:21 | Dean、  
#30楼 2013-09-13 14:27 | CamelOnTheWay  
【越接触本质越不会迷茫!】 最为经典!
#31楼 2013-09-28 11:32 | adym  
确实凡事只要多接触原理,很多东西都是触类旁通的。
#32楼 2013-10-18 17:05 | Bairrfhoinn  
我有几個疑问:1、博主的这個问题是发生在什么类型的数据库上的,Oracle ,SQL Server,DB2 还是 mysql ?
2、DBCC loginfo() 这個命令是干什么用的?
3、sp_removedbreplication 和 sp_droppublication 这两個存储过程是干什么用的?
#33楼[楼主2013-10-18 23:43 | i6first  
@Bairrfhoinn
1、这是SQL Server的数据库;
2、DBCC Loginfo()是查看虚拟日志文件的语句;
3、分别是删除整个分发和删除发布;

 

posted @ 2013-11-26 00:00  小马科技团队博客  阅读(265)  评论(0)    收藏  举报