SQL Server 收缩数据库

 

  但凡用过 SQL Server 的同行,都遇到过 SQL Server 的日志文件比其数据文件要大很多倍,这个情况本来是没什么问题的,如果你的同事让你协助查询一个问,并且把数据库发你了,数据文件100M,而日志文件10G 的时候,估计你该发火了“老子的硬盘没地儿了”,你需要腾出点空间来,还要经历漫长的恢复过程,如果事先把日志文件收缩一下,是不是在网络上的传输速度能大大提高,自己恢复的时候也大大缩短呢?答案是肯定的。具体的日志是怎么产生的,这里先不做解释,就收缩日志而言,基本上有两个方法。

1.可以在正常关掉SQL Server 服务的情况下,把 日志文件给重命名(也可删除,但是不建议),再重动SQL Server 的服务,你会发现这个日志文件会被重新生成,大小只有504K,这个方法操作还是比简单的,只是要停掉服务,某些场合是不允许的。

2.SQL Server 本身提供了收缩数据文件和日志文件方法,就是使用 DBCC shrinkdatabase 这样的命令,当然了这个也会极大的影响现在业务的性能,某些情况下,不会一次性的把日志文件收缩到最小,可能需要你多次执行该命令。

这里用的就是这个  DBCC  功能,编写的一个 存储过程,有兴趣的可以拿来研究研究:

 

 

 SQL Server 收缩数据库

/*
功 能 : 收缩数据库
程序员 : 王立进
*/

CREATE proc sp_shrinkdb --fbmis_exp4_ak_2005 , 1 , no_checkdb
@dbname varchar(766) = NULL , -- 要收缩数据库的名称
@dwcount int = 1 , -- 收缩次数 (默认是1次)
@shrinktype varchar(766) = 'All' -- 收缩类型 no_checkdb , no_backup_log
as
declare @dbname2 varchar(766) -- 取出数据库的名称
declare @dwloop int -- 记数器
declare @strreindex varchar(2000) -- 重建索引的 SQL 模版
declare @str varchar(2000) -- 具体的 真正要执行的SQL
set @strreindex = 'declare @tablename varchar(100) '
+ ' declare sss cursor for select ''[#].dbo.'' + name as name from [#].dbo.sysobjects where xtype = ''U'' '
+ ' open sss '
+ ' fetch next from sss into @tablename '
+ ' while @@fetch_status = 0 '
+ ' begin '
+ ' dbcc dbreindex(@tablename , '''' , 0) with no_infomsgs'
+ ' fetch next from sss into @tablename '
+ ' end '
+ ' close sss '
+ ' deallocate sss'

if @dbname is null -- 如果没有指定数据库的名称则是所有数据库
declare mycursor cursor
for
select name from master..sysdatabases
else
declare mycursor cursor
for
select name from master..sysdatabases
where name = @dbname --
open mycursor

FETCH NEXT FROM mycursor into @dbname2
-- print @@FETCH_STATUS
WHILE @@FETCH_STATUS = 0
BEGIN
set @str = replace(@strreindex , '#' , @dbname2)
-- print @str
if @shrinktype != 'no_reindex' -- 如果指定
exec(@str)
set @dwloop = 1
while @dwcount >= @dwloop
begin
if @shrinktype != 'no_backup_log' -- 如果没有指定 'no_backup_log' ,则不 'backup log ' + @dbname
exec('backup log ' + @dbname2 + ' with no_log')
if @shrinktype != 'no_checkdb' -- 如果没有指定 'no_checkdb' ,则不 'dbcc checkdb ' + @dbname
exec('dbcc checkdb(' + @dbname2 + ')')
exec('dbcc shrinkdatabase(' + @dbname2 + ')')
set @dwloop = @dwloop + 1
end
-- print @dbname2
FETCH NEXT FROM mycursor into @dbname2
END -- while

CLOSE mycursor
DEALLOCATE mycursor

exec('sp_helpdb ' + @dbname )
-- end 

 

 



分享到:更多


引用通告: 我要引用此文章
Tags:
相关日志:
评论: 0 | 引用: 0 | 查看次数:
发表评论
昵 称:
邮 箱:
主 页:
内 容: