最近查看服务器运行情况,发现磁盘剩余容量每过一日就会缩小一大截,
眼看就不够数据库备份文件的大小了,必须处理!

一开始以为是服务器上后台应用产生的日志太多,但也不至于那么夸张啊?
每天减小几个G!

检查了一遍服务器中的文件的大小,发现数据库的一个文件占到了300+G的空间。
文件名:DCWLW_Log.ldf,跟它一块的一个文件:DCWLW.mdf,也占到40+G的空间。

其中,DCWLW.mdf是数据文件,DCWLW_Log.ldf是数据库的事务日志。

数据文件不能动,但日志文件倒是可以删除的。

方案1:分离数据库

在网上查询如何缩小数据库日志的方法,发现有几种,其中最推荐的一种是

  • 先分离数据库
  • 删除日志文件
  • 再附加数据库,附加时找不到数据库日志,所以选择删除,管理软件会自动生成新的日志

但分离数据库,首先数据库得没有客户端连接,因为本例中的服务器在生产环境中,因此不能草率地断开连接。

本来想着是不是等半夜夜深人静之时,再进行此操作,可是考虑到晚上可能因为懒而搞不了,所以还是再看看还有没有别的好方法。

在过程中,发现很多例子中 SHRINKFILE 函数用来缩减文件大小,因此查询它用法,发现microsoft官网中在 DBCC SHRINKFILE 一节中本来就有缩减日志的例子!!!

使用例子后确实完美解决了日志过大的问题,将332G日志收缩到了1M。

此次实践再次提醒了自己,遇到任何问题,最好的解答永远在官网!
(当然,如果没有一开始的查询,甚至我都不知道 SHRINKFILE 这个词)

如果想深入的学习,或要处理一些复杂的问题,查看官网资料永远是第一选择。

方案2:官网例子

附上官网上的例子:
地址:
https://docs.microsoft.com/zh-cn/sql/t-sql/database-console-commands/dbcc-shrinkfile-transact-sql?view=sql-server-ver15

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

--将数据文件收缩到指定的目标大小
--以下示例将 UserDB 用户数据库中名为 DataFile1 的数据文件的大小收缩到 7 MB。
USE UserDB;
GO
DBCC SHRINKFILE (DataFile1, 7);
GO

--将日志文件收缩到指定的大小
--以下示例将 AdventureWorks 数据库中的日志文件收缩到 1 MB。 若要允许 DBCC SHRINKFILE 命令收缩文件,首先需要通过将数据库恢复模式设置为 SIMPLE 来截断该文件。
USE AdventureWorks2012;
GO
-- Truncate the log by changing the database recovery model to SIMPLE.
ALTER DATABASE AdventureWorks2012
SET RECOVERY SIMPLE;
GO
-- Shrink the truncated log file to 1 MB.
DBCC SHRINKFILE (AdventureWorks2012_Log, 1);
GO
-- Reset the database recovery model.
ALTER DATABASE AdventureWorks2012
SET RECOVERY FULL;
GO

--截断数据文件
--需要查询 sys.database_files 目录视图以获得数据文件的 file_id。
USE AdventureWorks2012;
GO
SELECT file_id, name
FROM sys.database_files;
GO
DBCC SHRINKFILE (1, TRUNCATEONLY);

--清空文件
--下面的示例展示了如何清空文件,这样文件就能从数据库中删除。 为了方便此示例进行展示,先创建包含数据的数据文件。
USE AdventureWorks2012;
GO
-- Create a data file and assume it contains data.
ALTER DATABASE AdventureWorks2012
ADD FILE (
NAME = Test1data,
FILENAME = 'C:\t1data.ndf',
SIZE = 5MB
);
GO
-- Empty the data file.
DBCC SHRINKFILE (Test1data, EMPTYFILE);
GO
-- Remove the data file from the database.
ALTER DATABASE AdventureWorks2012
REMOVE FILE Test1data;
GO

其它的一些语句:

1
2
3
4
5

--查询日志文件名
select * from [DB]..sysfiles
where charindex('LDF',filename)>0