zoukankan      html  css  js  c++  java
  • SQLServer日志无法收缩原因分析及解决

    SQL Server中的事务日志无疑是SQL Server中最重要的部分之一。因为SQL SERVER利用事务日志来确保持久性(Durability)和事务回滚(Rollback)。从而还部分确保了事务的ACID属性.在SQL Server崩溃时,DBA还可以通过事务日志将数据恢复到指定的时间点。当SQL Server运转良好时,多了解一些事务日志的原理和概念显得并不是那么重要。但是,一旦SQL SERVER发生崩溃时,了解事务日志的原理和概念对于快速做出正确的决策来恢复数据显得尤为重要.本系列文章将会从事务日志的概念,原理,SQL Server如何使用日志来确保持久性属性等方面来谈SQL Server的事务日志。

    事务日志一般情况下是不需要进行收缩的,在一些情况下导致了日志占用空间极大情况下需要DBA手工进行收缩维护。

    查看日志大小:

    dbcc sqlperf(logspace)

    image

    如果有数据库日志文件非常大,就需要通过检查日志的VLF使用情况来进行诊断:

    DBCC LOGINFO('数据库名称')

    image

    日志文件是通过重用VLF文件来实现事务日志按照lsn顺序写入到日志文件的,如果当前VLF的状态都是已使用(2使用0未用),那么收缩文件是无法收缩这些文件的。

    查看日志无法收缩的具体原因:

    SELECT name,log_reuse_wait_desc FROM sys.databases where name='数据库名称'
    log_reuse_wait_desc的值解释如下:

    NOTHING

    当前有一个或多个可重复使用的虚拟日志文件。

    CHECKPOINT

    自上次日志截断之后,尚未出现检查点,或者日志头部尚未跨一个虚拟日志文件移动(所有恢复模式)。这是日志截断延迟的常见原因。

    LOG_BACKUP

    需要日志备份,以将日志的头部前移(仅适用于完整恢复模式或大容量日志恢复模式)。

    注意:日志备份不会妨碍截断。

    完成日志备份后,日志的头部将前移,一些日志空间可能变为可重复使用。

    ACTIVE_BACKUP_OR_RESTORE

    数据备份或还原正在进行(所有恢复模式)。

    数据备份与活动事务的运行方式相同。数据备份在运行时,将阻止截断。

    ACTIVE_TRANSACTION

    事务处于活动状态(所有恢复模式)。一个长时间运行的事务可能存在于日志备份的开头。在这种情况下,可能需要进行另一个日志备份才能释放空间。

    事务被延迟(仅适用于 SQL Server 2005 Enterprise Edition及更高版本)。“延迟的事务” 是有效的活动事务,因为某些资源不可用,其回滚受阻。

    DATABASE_MIRRORING

    数据库镜像暂停,或者在高性能模式下,镜像数据库明显滞后于主体数据库(仅限于完整恢复模式)。

    REPLICATION

    在事务复制过程中,与发布相关的事务仍未传递到分发数据库(仅限于完整恢复模式)。

    DATABASE_SNAPSHOT_CREATION

    正在创建数据库快照(所有恢复模式)。

    这是日志截断延迟的常见原因,通常也是主要原因。

    LOG_SCAN

    正在进行日志扫描(所有恢复模式)。

    这是日志截断延迟的常见原因,通常也是主要原因。

    针对延迟日志截断原因的部分解决方案,

    针对不同的情况有不同的处理方法,我曾经遇到过NOTHING和REPLICATION

    我遇到的虽然是NOTHING,但是有大量正在使用的VLF,所以采用将正在使用的VLF通过发生check point写入到日志文件,具体如下:

    DBCC OPENTRAN (dbname)   
    CHECKPOIN
    最棘手的是之前遇到过REPLICATION的情况,已经确认没有replication的数据库,最后通过禁用发布和分发来删除复制功能,但还是没有解决。网上说这是SQL Server的一个bug,需要通过如下命令来删除发布:
    EXEC sp_removedbreplication 数据库名称

    最后通过执行语句进行收缩。因为是从库,不需要复制、备份等操作,所以可以将恢复模式改成简单日志模式,如果是主库,建议备份日志后进行收缩。

    USE [数据库名称]  
    GO  
    ALTER DATABASE 数据库名称 SET RECOVERY SIMPLE WITH NO_WAIT  
    GO  
    DBCC SHRINKFILE (N'数据库名称_log' , 400, TRUNCATEONLY)  
    GO  
    DBCC SHRINKDATABASE(N'数据库名称' )  
    GO
    ALTER DATABASE 数据库名称 SET RECOVERY full WITH NO_WAIT  
    GO 

    相关连接:
    浅谈SQL Server中的事务日志(一)----事务日志的物理和逻辑构架

    浅谈SQL Server中的事务日志(二)----事务日志在修改数据时的角色

    浅谈SQL Server中的事务日志(三)----在简单恢复模式下日志的角色

    浅谈SQL Server中的事务日志(四)----在完整恢复模式下日志的角色

    浅谈SQL Server中的事务日志(五)----日志在高可用和灾难恢复中的作用

    浅谈SQL Server中的事务日志(一)----事务日志的物理和逻辑构架

    浅谈SQL Server中的事务日志(二)----事务日志在修改数据时的角色

    SqlServer 数据库日志无法收缩处理过程

    TFS:TF30042 数据库已满 处理方法

  • 相关阅读:
    5. java 的类和对象
    java 的变量以及构造方法
    idea运行Test时为啥会运行两次
    MYSQL(三)
    MYSQL(二)
    MySql密码操作
    MYSQL(一)
    【数据结构】2.线性表及其结构
    【数据结构】1.数据结构及算法的入门
    推荐四款可视化工具,解决99%的可视化大屏需求
  • 原文地址:https://www.cnblogs.com/datazhang/p/5238677.html
Copyright © 2011-2022 走看看