AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 206234
Accepted
Vorster
Vorster
Asked: 2018-05-10 03:39:11 +0800 CST2018-05-10 03:39:11 +0800 CST 2018-05-10 03:39:11 +0800 CST

使用 sp_MSForEachDB 收缩多个数据库文件

  • 772

我们最近从生产数据库中清除了旧数据。该数据库为 3 TB,其中 1.4 TB 为空,但这给开发和 QA 实例带来了问题,因为我们没有利用空间,因为我们有 6 - 8 个数据库和 1.4 TB 的空空间,尤其是在我们在开发中存在空间限制的情况下。我想设置一个工作来使用下面的代码缩小开发数据库

EXEC sp_MSForEachDB ' USE [?]; DBCC SHRINKFILE  (''?'' , 10)' 

EXEC sp_MSForEachDB ' USE [?]; DBCC SHRINKFILE (''?'' , 0, TRUNCATEONLY)' 

我收到以下错误,“无法在 sys.database_files 中找到数据库 'Test' 的文件 'Test'。该文件不存在或已被删除。” 数据库有多个数据文件。我如何改进我的代码以适应多个数据文件。

sql-server dbcc
  • 3 3 个回答
  • 2953 Views

3 个回答

  • Voted
  1. Erik Darling
    2018-05-10T03:49:33+08:002018-05-10T03:49:33+08:00

    问号将评估为数据库名称,而不是您尝试缩小的文件名。

    例如:

    EXEC master.sys.sp_MSforeachdb ' USE [?]; PRINT N''?''; '; 
    

    将返回(在我的服务器上)

    master
    tempdb
    model
    msdb
    SUPERUSER
    StackOverflow
    StackOverflow_CS
    Crap
    DBAtools
    StackOverflow2010
    SUPERUSER_CX
    ಠ_ಠ
    StackOverflow2010ಠ_ಠ
    

    DBCC SHRINKFILE不将其作为参数:

    DBCC SHRINKFILE (
    { file_name | file_id }
    { [ , EMPTYFILE ]
    | [ [ , target_size ] [ , { NOTRUNCATE | TRUNCATEONLY } ] ]
    } ) [ WITH NO_INFOMSGS ]

    如果您只有一个 .mdf 和一个 .ldf,您可以(可能,但不是绝对)将您的代码替换为:

    EXEC sp_MSForEachDB ' USE [?]; DBCC SHRINKFILE  (1 , 10)' 
    
    EXEC sp_MSForEachDB ' USE [?]; DBCC SHRINKFILE (2 , 0, TRUNCATEONLY)' 
    

    用于查找文件 ID 等的更详细的代码留给读者作为练习。

    如果您只想缩小整个内容,请改用DBCC SHRINKDATABASE。这需要一个数据库名称,并将与您的原始代码一起使用。

    DBCC SHRINKDATABASE (database_name | database_id | 0
    [, target_percent]
    [, { NOTRUNCATE | TRUNCATEONLY }]) [ WITH NO_INFOMSGS]

    当然,这可能会导致各种问题,我不想这样做。

    • 4
  2. Best Answer
    BradC
    2018-05-10T06:51:00+08:002018-05-10T06:51:00+08:00

    @sp_BlitzErik 已经正确识别了问题,但我会提出一个不同的解决方案:使用一次性脚本来创建您的SHRINKFILE语句,检查它们的完整性,然后手动运行它们或将它们放入您的代理作业中:

    SELECT  dbname = DB_NAME(),
            file_name = name, 
            TotalMB = CONVERT(decimal(12,1),size/128.0),
            UsedMB = CONVERT(decimal(12,1),FILEPROPERTY(name,'SpaceUsed')/128.0),
            FreeMB = CONVERT(decimal(12,1),(size - FILEPROPERTY(name,'SpaceUsed'))/128.0),
            Command = CONCAT('USE ', DB_NAME(), '; DBCC SHRINKFILE (name = ',
                  [name], ', size = ', 
                  convert(int,round(1.15 * FILEPROPERTY(name,'SpaceUsed')/128,-1)), 'MB)')
     FROM sys.database_files WITH (NOLOCK)
     WHERE type_desc = 'ROWS'
     ORDER BY file_id;
    

    从每个数据库运行一次,它应该返回每个数据文件的总大小和已用大小(它会跳过日志文件,之后您可以立即手动缩小这些文件),以及一个示例SHRINKFILE语句,为您提供 15% 可用空间的目标该文件,根据当前使用的空间计算:

    USE myDB; DBCC SHRINKFILE (name = myDBData, size = 148910MB)
    

    您需要检查结果的完整性,如果文件的可用空间少于 15%,则该语句将指定比当前更大的大小,因此跳过它(它已经足够小了)。SHRINKFILE

    缩小所有数据文件后,为每个日志文件选择一个目标大小(我通常使用数据文件大小的 10-25%),然后手动缩小它们。这可能取决于恢复模型,以及这些数据库在该环境中获得多少活动。

    • 2
  3. Vorster
    2018-05-11T05:38:54+08:002018-05-11T05:38:54+08:00

    @BradC 这就是我调整您建议的代码的方式

    CREATE TABLE #ShrinkFile
    (
    DBName sysname,
    File_Name sysname,
    TotalMB decimal (18,2),
    UsedMB decimal (18,2),
    FreeMB decimal (18,2),
    Command nvarchar(MAX)
    ) 
    EXEC master.sys.sp_MSforeachdb ' USE [?]; 
        Insert Into #ShrinkFile (DBName, File_Name, TotalMB, UsedMB, FreeMB, 
    Command)
        SELECT  dbname = DB_NAME(),
        file_name = name, 
        TotalMB = CONVERT(decimal(12,1),size/128.0),
        UsedMB = CONVERT(decimal(12,1),FILEPROPERTY(name,''SpaceUsed'')/128.0),
        FreeMB = CONVERT(decimal(12,1),(size - 
        FILEPROPERTY(name,''SpaceUsed''))/128.0),
        Command = CONCAT(''USE '', DB_NAME(), ''; DBCC SHRINKFILE (name = '',
              [name], '', size = '', 
              convert(int,round(1.15 * 
    FILEPROPERTY(name,''SpaceUsed'')/128,-1)), ''MB)'')
    FROM sys.database_files WITH (NOLOCK)
    WHERE type_desc = ''ROWS''
    ORDER BY file_id;'
    
    IF EXISTS (SELECT * FROM  #ShrinkFile WHERE FreeMB > 1000)
    BEGIN
       DECLARE @SQLText nvarchar(max)
       DECLARE Shrink_cursor CURSOR FOR 
       SELECT DISTINCT Command FROM #ShrinkFile
       WHERE FreeMB > 1000
    
       OPEN Shrink_cursor  
       FETCH NEXT FROM Shrink_cursor INTO @SQLText  
    
       WHILE @@FETCH_STATUS = 0  
       BEGIN  
            EXEC (@SQLText)
            FETCH NEXT FROM Shrink_cursor INTO @SQLText 
       END 
    
     CLOSE Shrink_cursor  
     DEALLOCATE Shrink_cursor 
     END
    
     DROP TABLE #ShrinkFile
    
    • 0

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve