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

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


 

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'''+@CurrentlogName+N''' , 0, TRUNCATEONLY)' --这里告诉SQL Server将日志文件收缩为0,也就是让SQL Server能收缩多少就收缩多少

    EXEC sp_sqlexec @ShrinkScript

    DELETE FROM #LogNeedShrink WHERE [dbname]=@CurrentDbName AND [log_logical_name]=@CurrentlogName
END

DROP TABLE #LogNeedShrink

 

转载于:https://www.cnblogs.com/OpenCoder/p/9680640.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值