简体   繁体   English

用于多个数据库的DBCC SHRINKFILE 1 sproc

[英]DBCC SHRINKFILE 1 sproc for multiple databases

I have a need to execute DBCC SHRINKFILE for multiple db's within the same sproc. 我需要在同一存储过程中为多个数据库执行DBCC SHRINKFILE。 I could create multiple sprocs so it runs within the given context, but I was curious if there were alternatives? 可以创建多个sproc,以便它在给定的上下文中运行,但是我很好奇是否有替代方案?

Here is the code I use to perform this operation to shrink the logs on the databases beginning with 'MPS_' that are simple recovery. 这是我用来执行此操作的代码,以缩小以“ MPS_”开头的简单恢复数据库上的日志。 This can be set as an SQL Execution Task maintenance plan and scheduled as appropriate. 可以将其设置为SQL执行任务维护计划,并进行适当安排。 The current code shrinks the log to 1 GB, which for us does a decent job of avoiding disk fragmentation. 当前代码将日志缩小到1 GB,这对我们来说可以避免磁盘碎片。

Note that these are all volatile databases. 请注意,这些都是易失性数据库。 Never do this to production databases unless you really know what you're doing. 除非您真的知道自己在做什么,否则切勿对生产数据库执行此操作。 Also, do not just do this to every simple recovery model database. 另外, 不要只对每个简单的恢复模型数据库都这样做。 Several of the system databases ( master , for one) are simple recovery! 几个系统数据库( master数据库,一个数据库)很容易恢复!

use [master]

set nocount on

declare @name sysname,
    @file_id int,
    @sqlcmd varchar(max)

DECLARE db_mps_simple_logs_cur CURSOR FOR
select d.name, mf.file_id
from sys.databases d
join sys.master_files mf
    on d.database_id = mf.database_id
where d.[name] like 'MPS_%'
    and d.recovery_model = 3 --simple only
    and mf.type = 1 --0 is data, 1 is log

open db_mps_simple_logs_cur
fetch next from db_mps_simple_logs_cur into @name, @file_id

while @@fetch_status = 0 begin

    set @sqlcmd = 'use ' + QUOTENAME(@name) + '; checkpoint; dbcc shrinkfile ( ' + cast(@file_id as varchar) + ', 1024 );'
    exec ( @sqlcmd )


    fetch next from db_mps_simple_logs_cur into @name, @file_id
end

close db_mps_simple_logs_cur
deallocate db_mps_simple_logs_cur
go

Here is a nice command that will show the current transaction log sized for simple recovery model databases so you can easily see the resuts: 这是一个很好的命令,它将显示针对简单恢复模型数据库的当前事务日志大小,以便您可以轻松查看结果:

select 
    d.database_id,
    d.name,
    d.recovery_model_desc,
    mf.name [file_name],
    mf.size * 8 / 1024 [size_in_mb],
    d.log_reuse_wait_desc
from sys.databases d
join sys.master_files mf
    on d.database_id = mf.database_id
where d.[name] like 'MPS_%'
    and d.recovery_model = 3 --simple only
    and mf.type = 1 --0 is data, 1 is log
order by mf.size desc
EXEC sp_MSForEachDB 'USE ? DBCC SHRINKFILE (fileid, targetsize)'

The undocumented sp_MSForEachDB is your friend here 未记录的sp_MSForEachDB是您的朋友在这里

Edit, after Raj's comment 编辑,Raj发表评论后

EXEC sp_MSForEachDB '
    USE ?
    IF DB_NAME() IN (''DB1'', ''DB1'', ''DB1'')
       DBCC SHRINKFILE (fileid, targetsize)
     '

Edit 编辑

Note to downvoters, the dynamic SQL in the highest voted answer is basically a cut down sp_MSForEachDB 向下注者注意,投票率最高的答案中的动态SQL本质上是减少了sp_MSForEachDB

Your best approach is, by far, to never write a script that shrinks a database file . 到目前为止,最好的方法是永远不要编写收缩数据库文件的脚本 From the million destructive things you can do with a database, shrinking it is right there in top 3. See Auto-shrink – turn it OFF! 使用数据库可以完成的上百万项破坏性工作, 将其紧缩在前3位。请参见自动收缩–将其关闭! .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM