【问题标题】:SQL Server multiple shrink operationsSQL Server 多次收缩操作
【发布时间】:2011-09-13 16:12:30
【问题描述】:

我正在尝试缩小 SQL Server 2008 R2 中的所有数据库(文件和日志)。

我已经完成了脚本,但问题是,当我遍历所有数据库并执行查询以执行 shrink file 前 3 或 4 个收缩工作时,但它们出现此错误:

消息 0,级别 11,状态 0,行 0
当前命令发生严重错误。结果,如果有的话, 应该被丢弃。

脚本:

declare @db_name as varchar(30)
declare @db_recorvery_model as varchar(30)
declare @db_files_name as varchar(250)
declare @db_files_physical_name as varchar(250)

declare get_files cursor for 
     select b.name, a.name  
     from sys.master_files as a, 
          sys.databases as b 
     where a.database_id = b.database_id  
     order by b.name  

open get_files

fetch next from get_files into @db_files_name, @db_files_physical_name

set @db_files_name = (select @db_files_name)
set @db_files_physical_name = (select @db_files_physical_name)

DECLARE @Command as nvarchar(max)
set @Command=''

while(@@FETCH_STATUS=0)
BEGIN
   if (@db_files_name='master' or @db_files_name='msdb' or @db_files_name='tempdb' or @db_files_name='model')
   BEGIN
      print 'Bases de dados do sql server: '+@db_files_name
   END
   ELSE
   BEGIN
      set @Command = 'USE ' + '[' + @db_files_name + '] DBCC SHRINKFILE ("'+@db_files_physical_name+'", 1 )'
      EXEC sp_executesql @Command
      print @Command
   END

   fetch next from get_files into @db_files_name, @db_files_physical_name

   set @db_files_name = (select @db_files_name)
   set @db_files_physical_name = (select @db_files_physical_name)
END

close get_files
deallocate get_files

有人有什么想法吗?

PS:我知道我不应该缩水,但这是一个非常特殊的环境,没有生产力。

【问题讨论】:

  • 很高兴您添加了最后一行!它在哪个文件上失败?例如,它是否属于离线/只读数据库?您还需要排除 FILESTREAM 文件。
  • 同意@Martin - 也许有一个数据库离线,只读,恢复中,单用户或受限用户模式等......您可以使用 where 子句将那些从游标中过滤出来.另外,select @@version 是什么? SP1 或累积更新修复了许多“严重错误”问题。
  • 它并不总是在同一个数据库上失败。如果我只更改查询以返回 1 个数据库,即 3 个文件,则它可以正常工作。只有在尝试大量 exec 时才会失败。我试过这个codesnippets.joyent.com/posts/show/665 因为他首先构建了所有查询,然后他们一次执行了所有查询。我的问题是我没有足够大的 varchar 或 nvarchar
  • 版本:Microsoft SQL Server 2008 R2 (SP1) - 10.50.2500.0 (X64) 2011 年 6 月 17 日 00:54:03 版权所有 (c) Microsoft Corporation Enterprise Edition (64-bit) o​​n Windows NT 6.1 (内部版本 7601:Service Pack 1)

标签: sql-server sql-server-2008-r2


【解决方案1】:

你能确定哪个数据库标记了错误吗?您可以尝试在有问题的单个数据库上运行脚本,看看它是否始终是触发错误的同一数据库?也许它是一个您错过的特殊数据库,不能以这种方式缩小。

我有一个类似的环境,其中包含不用于长期存储的临时数据库,并且我使用了以下脚本,该脚本已完美地适用于数百个数据库:

CREATE procedure [dbo].[ShrinkLog]
    @DB varchar(200)
as

declare @LogFile varchar(200)
declare @Sql varchar(500)

SELECT @LogFile = name
FROM sys.master_files
where type_desc = 'LOG'
and db_name(database_id) = @DB


set @Sql = '
    Use [' + @DB + ']
    DBCC SHRINKFILE([' + @LogFile + '], 1)
'
print(@sql)
exec(@sql)

请记住,除非您的服务器也有足够的硬盘驱动器/内存空间,否则您不想运行此命令。

最好的问候,

【讨论】:

  • 我试过这个。同样的错误......我认为这是 sql 处理这么多 Exec 的方式......
【解决方案2】:

如果你想做一个日志收缩,这将是最好的代码。我用了一段时间,它从来没有崩溃过。

declare @SQL nvarchar(max)

select @SQL = coalesce(@SQL + char(13) + char(10),'') + N'
Use ' + QUOTENAME(d.[name]) + ';' + CHAR(13) + '
ALTER DATABASE ' + QUOTENAME(d.[name]) + ' SET RECOVERY SIMPLE;
DBCC SHRINKFILE (' + quotename(mf.[name],'''') + ', 1);
ALTER DATABASE ' + QUOTENAME(d.[name]) + ' SET RECOVERY FULL;'
FROM sys.databases d
INNER JOIN sys.master_files mf ON [d].[database_id] = [mf].[database_id]
WHERE
    d.[database_id] > 4 --no sys dbs
    AND d.recovery_model = 1
    AND d.is_read_only = 0
    AND mf.[type] = 1 --log files
ORDER BY d.name

--print @SQL

execute (@SQL)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 2016-06-20
    • 2015-12-21
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 2022-06-13
    相关资源
    最近更新 更多