当前位置:首页 > 问答 > 正文

mssql日志文件终于清理完了,教你怎么快速把log清掉不留痕迹

(来源:CSDN博客《一次惊心动魄的MSSQL日志文件清理实战记录》)行,既然你急着想把SQL Server那个越涨越大、快把C盘撑爆的日志文件(.ldf)给清理掉,又不希望留下什么后遗症,那我就不扯那些复杂的原理了,直接上干货,这是我之前一次惨痛经历后总结出来的,保证快,而且力求干净。

你得明白为啥日志文件会这么大。(来源:博客园《SQL Server日志文件膨胀原因浅析》)简单说,就像你记日记,如果只写新内容,不整理,本子肯定越来越厚,数据库也一样,特别是如果你的数据库恢复模式是“完整(FULL)”模式,那么所有操作(比如增删改)都会被详细记录下来,以便出问题时能恢复到任意时间点,但如果你不做“日志备份”,这些日志记录就会一直堆在.ldf文件里,只增不减,直到占满你的硬盘。

清理的核心思路就两点:一是把没用的日志记录截断删除,二是想办法把日志文件本身占用的磁盘空间缩小。 注意,是“缩小文件大小”,而不是简单地把.ldf文件删掉!直接删文件?数据库百分百会挂掉,千万别干!

第一步:检查状态,知己知彼

(来源:MSDN官方文档)动手前,先搞清楚状况,用管理员账号登录SQL Server Management Studio (SSMS),新建一个查询窗口,执行下面这句,看看你的日志文件现在多大,以及已经用了多少空间:

mssql日志文件终于清理完了,教你怎么快速把log清掉不留痕迹

USE [你的数据库名]; -- 把‘你的数据库名’换成实际名字
GO
SELECT name, size/128.0 AS Size_MB, -- 文件总大小(MB)
    FILEPROPERTY(name, 'SpaceUsed')/128.0 AS Used_Space_MB, -- 已用空间(MB)
    size/128.0 - FILEPROPERTY(name, 'SpaceUsed')/128.0 AS Free_Space_MB -- 剩余空间(MB)
FROM sys.database_files
WHERE type_desc = 'LOG';

看到那个Used_Space_MB了吗?那就是日志实际占用的空间,如果它很大,而Free_Space_MB很小,说明日志文件确实臃肿。

第二步:改变模式,释放枷锁

(来源:CSDN博客《MSSQL日志清理最有效的方法》)如果你的数据库不需要恢复到某个精确的时间点(比如测试环境,或者可以接受少量数据丢失的应用),最快的方法就是改变它的恢复模式,这相当于告诉数据库:“不用记那么详细的流水账了”。

ALTER DATABASE [你的数据库名] SET RECOVERY SIMPLE WITH NO_WAIT;

把模式从“FULL”改成“SIMPLE”后,数据库就不会再为了支持事务日志备份而无限期保留日志记录了,这是为下一步清理做准备的关键操作。

mssql日志文件终于清理完了,教你怎么快速把log清掉不留痕迹

第三步:执行清理,释放空间

模式改成SIMPLE后,就可以执行日志截断了,这个操作会标记那些不再需要的日志空间为“可重用”。

CHECKPOINT; -- 先做一个检查点,将内存中的数据写入磁盘,确保日志一致性
GO
DBCC SHRINKFILE (N'你的日志文件逻辑名' , 0, TRUNCATEONLY); -- 老版本SQL Server可能用这个,但不太推荐了
-- 更通用的方法是:
DBCC SHRINKFILE (N'你的日志文件逻辑名', 目标大小_MB); -- 例如想缩小到100MB,就写100

等等,这里的“你的日志文件逻辑名”是啥?不是文件名!它是在数据库内部定义的逻辑名称,你可以通过右键数据库 -> 属性 -> 文件,在“逻辑名称”那一列找到,通常跟数据库名差不多,后面可能跟个_log,或者直接运行sys.database_files查询,name列就是逻辑名。

执行DBCC SHRINKFILE可能会花点时间,取决于日志大小和服务器性能,完成后,再跑一遍第一步的查询,你会发现Used_Space_MBSize_MB应该都大大减小了。

mssql日志文件终于清理完了,教你怎么快速把log清掉不留痕迹

第四步:收缩文件,归还磁盘

(来源:IT之家某技术社区帖子)即使执行了清理,.ldf文件的物理大小(Size_MB)可能还是没变,只是里面的空闲空间变多了,这时候需要显式地“收缩”文件,把未使用的磁盘空间还给操作系统。

其实上一步的DBCC SHRINKFILE已经包含了收缩操作,但如果你发现文件大小没变,可以尝试指定一个更小的目标大小,或者多次执行,不过要注意,剧烈收缩文件会产生大量碎片,可能影响性能,所以目标大小别设得太小,留点余量。

第五步:(可选)改回原模式

如果你之后还需要完整备份策略,清理完后可以把恢复模式改回去,但切记,改回去之后,必须定期做事务日志备份,否则日志又会很快涨起来。

ALTER DATABASE [你的数据库名] SET RECOVERY FULL;

重要提醒和“不留痕迹”的要点:

  1. 备份先行:在对生产数据库进行任何重要操作前,务必先做一个完整的数据库备份!这是你的救命稻草。
  2. 业务低峰期操作:收缩文件是I/O密集型操作,可能会暂时影响数据库性能,选在半夜或者没人用的时候搞。
  3. 根治之道:上面这套“SIMPLE模式+SHRINK”组合拳是救急的猛药,要想从根本上避免这个问题,最好的方法是:如果使用FULL恢复模式,请建立并严格执行定期的事务日志备份计划任务,让备份作业自动帮你截断和清理日志,这才是最健康、最“不留痕迹”的长久之计。
  4. 警惕复制/镜像:如果你的数据库配置了事务复制、镜像等高可用性功能,日志清理会复杂很多,不能简单地改用SIMPLE模式,需要先处理这些依赖关系,这种情况就比较棘手了,需要更专业的步骤。

好了,这套流程走下来,只要你的数据库没有那些复杂的依赖,基本上就能快速、相对安全地把日志清理干净,让硬盘喘口气,清理不是目的,建立良好的维护习惯才是关键。