一,找到每个数据库的日志文件大小


SQL Server:查看SQL日志文件大小命令:dbcc sqlperf(logspace)

DBA 日常管理工作中,很重要一项工作就是监视数据库文件大小,及日志文件大小。如果你管理数据库的有很多的话,每天一个一个数据库的去查看文件大小就太费神了,那就写个SQL脚本吧,放到 SQL Agent 中,每天自动去查看各个数据库文件及日志文件的大小,然后再通过数据库邮件,Email 到我们手中,岂不快哉!当然,可以把每天的记录存放到数据库中去,这样数据库及日志文件的增长趋势,我们也就一目了然了。

这里,介绍下获取数据库日志文件大小的方法。其实很简单,就是执行 SQL Server DBCC 命令:dbcc sqlperf(logspace)

dbcc sqlperf(logspace) 可以获取实例中每个数据库日志文件大小,及使用情况。如果要保存SQL日志文件大小,则需要先创建一个数据表,然后动态执行dbcc sqlperf(logspace)命令:

--创建数据库日志文件信息表
CREATE TABLE [Control].[DatabaseLogSize](
[dbname] [nvarchar](100) NULL,
[dbid] [int] NULL,
[log_logical_name] [nvarchar](100) NULL,
[logsize] [decimal](30, 2) NULL,
[logused] [decimal](30, 2) NULL,
[status] [int] NULL
) ON [PRIMARY]
GO --借助dbcc sqlperf(logspace)将数据插入上面新建的表
INSERT INTO [Control].[DatabaseLogSize]([dbname],[logsize],[logused],[status])
EXECUTE('dbcc sqlperf(logspace)')

之后我们在表[DatabaseLogSize]中就有了 [dbname]、[logsize]、[logused]、[status]四列数据了

二、将每个数据库的日志文件逻辑名找出来


因为后面我们要使用DBCC SHRINKFILE命令执行日志收缩,这个命令必须提供数据库日志文件的逻辑名,所以现在我们要想办法将[DatabaseLogSize]表中的[log_logical_name]这一列值填上去,要找到数据库文件的日志逻辑名,首先要找到数据库的dbid。我们可以使用下面的语句找到[DatabaseLogSize]表中每个数据库的dbid:

SELECT dbid,name
FROM master..sysdatabases
WHERE
[name] IN (SELECT [dbname] FROM [Control].[DatabaseLogSize])

使用Update语句更新[DatabaseLogSize]表的[dbid]列即可:

UPDATE [Control].[DatabaseLogSize]
SET
[dbid]=T_DB_ID.[dbid]
FROM
[Control].[DatabaseLogSize]
INNER JOIN
(
SELECT [dbid],[name]
FROM master..sysdatabases
) AS T_DB_ID
ON [DatabaseLogSize].[dbname]=T_DB_ID.[name]

这样[DatabaseLogSize]表的[dbid]列就有值了:

接下来我们可以通过下面的语句根据每个数据库的dbid来找到每个数据库日志文件的逻辑名称,在本例中因为我们的每个数据库只有一个日志文件所以每个数据库只会找到一个日志文件逻辑名,如果你的情况是有数据库有多个日志文件,那么有些数据库就会找出多个日志文件逻辑名。

SELECT name,database_id
FROM sys.master_files
WHERE
database_id IN (SELECT [dbid] FROM [Control].[DatabaseLogSize])
AND
type = 1--这里的1表示我们要找的是.ldf日志文件,如果你要找的是.mdf数据库文件将这里改为0即可

这里补充一个知识点:SQL Server中一个数据库虽然可以通过创建多个数据文件组(FileGroup)来存放不同的.mdf和.ndf数据文件,但是日志文件组一个数据库有且只能有一个,也就是说一个数据库的所有.ldf日志文件都只能属于一个文件组,在下图中我们可以看到在SQL Server的SMSS管理器中如果你新建的是一个.ldf日志文件,那么其文件组这一列显示的是不适用,说明我们无法将SQL Server的.ldf日志文件放到多个文件组中,SQL Server只允许每个数据库拥有一个日志文件组,所有该数据库的.ldf日志文件都放在这个默认的日志文件组中:

之后同样我们用Update更新[DatabaseLogSize]表的[log_logical_name]列即可:

UPDATE [Control].[DatabaseLogSize]
SET
[log_logical_name]=T_DB_LOGNAME.[name]
FROM
[Control].[DatabaseLogSize]
INNER JOIN
(
SELECT [name],database_id
FROM sys.master_files
WHERE type = 1
) AS T_DB_LOGNAME
ON [DatabaseLogSize].[dbid]=T_DB_LOGNAME.database_id

这样[DatabaseLogSize]表的[log_logical_name]列也就有值了:

三、收缩数据库日志文件


接下来我们就可以根据[DatabaseLogSize]表的值来收缩数据库日志文件了,这里我们使用循环判断如果[DatabaseLogSize]表中的数据库日志文件大小超过100MB了,我们就使用DBCC SHRINKFILE指令来收缩这个日志文件:

CREATE TABLE #LogNeedShrink
(
[dbname] NVARCHAR(100)
,[log_logical_name] NVARCHAR(100)
) INSERT INTO #LogNeedShrink
SELECT [dbname],[log_logical_name]
FROM [Control].[DatabaseLogSize]
WHERE [logsize]>100 --收缩超过100MB大小的日志文件 WHILE (SELECT COUNT(1) FROM #LogNeedShrink)>0
BEGIN
DECLARE @CurrentDbName NVARCHAR(100)
DECLARE @CurrentlogName NVARCHAR(100) SELECT TOP 1 @CurrentDbName=[dbname],@CurrentlogName=[log_logical_name] FROM #LogNeedShrink DECLARE @ShrinkScript NVARCHAR(1000); SET @ShrinkScript=N'
USE '+QUOTENAME(@CurrentDbName,N'[')+N'
DBCC SHRINKFILE (N'''+REPLACE(@CurrentlogName,N'''',N'''''')+N''' , 0, TRUNCATEONLY)' --这里如果不加TRUNCATEONLY参数,就是在告诉SQL Server将日志文件收缩为0,也就是让SQL Server能收缩多少就收缩多少
--这里要转义数据库日志文件名称中的单引号字符,因为DBCC SHRINKFILE的第一个参数本身就是在一个SQL字符串中,如果不转义单引号字符会使得SQL字符串意外结束而报错。另外我们用了QUOTENAME函数来转义数据库名称中的非法字符 BEGIN TRY
EXEC sp_executesql @ShrinkScript
END TRY
BEGIN CATCH
--如果SQL语句报错,输出显示报错的SQL语句
PRINT @ShrinkScript RAISERROR (50001, -- Message id.
12, -- Severity,
1, -- State,
N'Error occurred in above query.');
END CATCH DELETE FROM #LogNeedShrink WHERE [dbname]=@CurrentDbName AND [log_logical_name]=@CurrentlogName
END DROP TABLE #LogNeedShrink

参考文献:

DBCC SHRINKFILE (Transact-SQL)

DBCC SHRINKDATABASE (Transact-SQL)

SQL Server中怎么查看每个数据库的日志大小,以及怎么确定数据库的日志文件,怎么用语句收缩日志文件的更多相关文章

  1. sql server中如何查看执行效率不高的语句

    sql server中,如果想知道有哪些语句是执行效率不高的,应该如何查看呢?下面就将为您介绍sql server中如何查看执行效率不高的语句,供您参考.   在测量功能时,先以下命令清除sql se ...

  2. [SQL] sql server中如何查看执行效率不高的语句

    sql server中,如果想知道有哪些语句是执行效率不高的,应该如何查看呢?下面就将为您介绍sql server中如何查看执行效率不高的语句,供您参考.在测量功能时,先以下命令清除sql serve ...

  3. SQL Server 中怎么查看一个字母的ascii编码或者Unicode编码

    参考文章:微信公众号文章 在sql中怎么查看一个字符的ascii编码,so easy !! select ASCII('a') SELECT CHAR(97) charNum SELECT UNICO ...

  4. SQL Server 中怎么查看一个字母的ascii编码或者Unicode编码(转载)

    在sql中怎么查看一个字符的ascii编码或Unicode编码: SELECT ASCII('a') AS [AsciiNum]--字符获取ASCII码 SELECT UNICODE(N'a') AS ...

  5. SQL Server中创建sde数据库

    在ArcCatalog或者ArcMap中打开ArcToolBox工具箱. 在工具箱中,找到创建企业级地理数据库工具,依次为数据管理工具→地理数据库管理→创建企业级地理数据库,如图所示. 双击打开创建企 ...

  6. 第十七周翻译-SQL Server中事务日志管理的阶梯,级别5:以完全恢复模式管理日志

    SQL Server中事务日志管理的阶梯,级别5:以完全恢复模式管理日志 作者:Tony Davis,2012/01/27 翻译:赖慧芳 译文: 该系列   本文是Stairway系列的一部分:SQL ...

  7. 使用T-SQL导入多个文件数据到SQL Server中

    在我们的工作中,经常需要连续输入多个文件的数据到SQL Server的表中,有时需要从相同或者不同的目录中,同时将文件中的数据倒入.在这篇文章中,我们将讨论如何同时把一个目录中的文件的数据倒入到SQL ...

  8. SQL Server中数据库文件的存放方式,文件和文件组

    原文地址:http://www.cnblogs.com/CareySon/archive/2011/12/26/2301597.html   SQL Server中数据库文件的存放方式,文件和文件组 ...

  9. SQL Server中通用数据库角色权限处理

    SQL Server中通用数据库角色权限处理   最近和同事在做数据库权限清理的事情,主要是删除一些账号:取消一些账号的较大的权限等,例如,有一些有db_owner权限,我们取消账号的数据库角色db_ ...

随机推荐

  1. 如何查找SHELL的进程号并杀死

    一.shell查找进程并杀死 #!/bin/sh tomcat_id=`ps -ef | grep tomcat | grep -v "grep" | awk '{print $2 ...

  2. 两台Mysql数据库数据同步实现

    两台Mysql数据库数据同步实现 做开发的时候要做Mysql的数据库同步,两台安装一样的系统,都是FreeBSD5.4,安装了Apache 2.0.55和PHP 4.4.0,Mysql的版本是4.1. ...

  3. 【详解】核心组件之UserDetailService

    简介 UserDetails => Spring Security基础接口,包含某个用户的账号,密码,权限,状态(是否锁定)等信息.只有getter方法. Authentication => ...

  4. windows7(64位) PHP APACHE MYSQL

    - 一.安装软件准备软件版本以本人安装为例,其他版本同理,软件到各官网下载      1.Apache(httpd-2.2.19-win64)      2.PHP(php-5.3.6-Win32-V ...

  5. window对象方法之setTimeout(),setInterval()

    window中的这两个方法是比较重要的,在许多的设计中会使用到这两个方法.比如使用在倒计时抢购中. 首先来说说这两个方法的用法吧! 一:window.setTimeout(); setTimeout( ...

  6. JDK并发包中ExecutorCompletionService使用

    相信大家都知道,jdk中ExecutorService是并发编程时使用很频繁的接口,并且使用很方便,那么想在有这么一个场景: 一批任务使用线程池处理,并且需要获得结果,但是不关心任务执行结束后输出结果 ...

  7. 微信支付开发 c# SDK JSAPI支付开发的流程和微信大坑

    微信支付开发流程 1. 开通微信支付功能 省略 2. 下载微信的C#版的微信SDK 下载连接:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chap ...

  8. activiti工作流

    画图->定义监听事件->给任务赋值->部署(zip部署.文件部署)->使用

  9. Java的接口和抽象类

    对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的时候会以为它们可以随意互换使用, ...

  10. LOJ#505. 「LibreOJ β Round」ZQC 的游戏(最大流)

    题意 题目链接 Sol 首先把第一个人能吃掉的食物删掉 然后对每个人预处理出能吃到的食物,直接限流跑最大流就行了 判断一下最后的最大流是否等于重量和 注意一个非常恶心的地方是需要把除1外所有人都吃不到 ...