【问题标题】:SQL Server database file not being truncatedSQL Server 数据库文件未被截断
【发布时间】:2011-07-07 13:25:06
【问题描述】:

我有一个大小约为 4GB 的数据库。我已经复制了该数据库并删除了其中 99% 的数据,因为我需要一个仅包含架构和基本数据的数据库(保留大部分静态数据)。

现在的问题是 MDF 文件的大小仍然约为 4GB。如果我读取表格的大小(例如,使用this),它们的总和不到 20 MB。日志文件已经缩小,但我运行的脚本都没有用于缩小数据库文件。

注意:我通常不这样做,但这次我需要收缩数据库(我知道不建议这样做)

编辑:+有用的信息

命令:

exec sp_spaceused

输出:

database_name       database_size   unallocated_space
AccudemiaEmptyDb    3648.38 MB      4.21 MB

命令:

select object_name(id) as objname, SUM(dpages*8) as dpages, COUNT(*) as cnt
from sysindexes
group by id
order by dpages desc

输出:

object_name(id)            sum(dpages*8)    count(*)
sysdercv                   675328           1
sysxmitqueue               359776           1
sysdesend                  72216            1
sysconvgroup               47704            1
sysobjvalues               4760             5
sec_OperationAccessRule    3472             5
sec_PageAccessRule         2232             5
syscolpars                 656              11
AuditObjects               624              2
sysmultiobjrefs            408              5
HelpPage                   376              8
sysschobjs                 352              9
syssoftobjrefs             328              7
sysidxstats                272              10
sysrscols                  200              1
Translation                160              3
sysallocunits              128              3
sysiscols                  128              8
syssingleobjrefs           96               5
sysrowsets                 80               4

【问题讨论】:

  • 我在互联网上找到的所有解决方案... DBCC SHRINKDATABASE,更改为 RECOVERY SIMPLE,然后更改为 DBCC,所有表上的 DBCC DBREINDEX,碎片整理索引和更新统计信息,然后是 DBCC,备份/恢复,分离/attaching、DBCC CLEANTABLE 以及其他脚本...

标签: sql-server sql-server-2008 shrink


【解决方案1】:

您可以使用 DBCC 命令来收缩数据库。

这里是对DBCC SHRINKDATABASEDBCC SHRINKFILE的引用

【讨论】:

    【解决方案2】:

    编辑:所以看起来空间仍然分配在某个地方。你可以试试这个查询(基于sp_spaceused)吗?

    select OBJECT_NAME(p.object_id),
     reservedpages = sum(a.total_pages),
        usedpages = sum(a.used_pages),
        pages = sum(
                CASE
                    -- XML-Index and FT-Index internal tables are not considered "data", but is part of "index_size"
                    When it.internal_type IN (202,204,211,212,213,214,215,216) Then 0
                    When a.type <> 1 Then a.used_pages
                    When p.index_id < 2 Then a.data_pages
                    Else 0
                END
            )
    from sys.partitions p join sys.allocation_units a on p.partition_id = a.container_id
        left join sys.internal_tables it on p.object_id = it.object_id
    GROUP BY p.object_id
    with rollup
    

    【讨论】:

    • 检查“不是答案”(底部)评论stackoverflow.com/questions/5172686/…
    • @Richard - 是的,只是在 Profiler 中查看。该查询返回的值与DBCC FILEHEADER ('AdventureWorks2008', 1); 中以MinSize 返回的值不同,因此仍然不确定DBCC SHRINKDATABASE 将它们中的哪一个视为最小大小
    • 好的。保留空间较多的对象是“NULL” :(,之后是 sysxmitqueue、sysdercv、sysdesend 等等……
    • @Diego - NULL 的大行只是因为我添加了一个 rollup 以获得总计。
    【解决方案3】:

    第一次运行

    exec sp_spaceused
    

    在数据库中检查您可以恢复多少。如果您发现它显示没有未使用的空间,那么您误解了空间分配。

    这就是我通常缩小test1 db 的方式,这是我在其中播放所有 StackOverflow 查询的地方。我只是将它从 3GB 减少到 8MB。

    use test1;
    exec sp_spaceused;
    checkpoint;
    alter database test1 set recovery simple;
    alter database test1 set recovery full;
    dbcc shrinkfile(1,1);
    dbcc shrinkfile(2,1);
    

    对于它的价值,这是我用来按表检查分配大小的方法。也许你检查不正确?这包括索引。

    select object_name(id), SUM(dpages*8), COUNT(*)
    from sysindexes
    group by id
    

    编辑 - 基于占用已编辑空间的表格

    Martin 的评论转而回答:所涉及的表是 Service Broker 对话。 http://social.msdn.microsoft.com/Forums/en/sqlservicebroker/thread/03180f45-cd83-4913-8f0e-3d8306f01f06 该链接有解决方法。

    还有一个选择;使用你已经缩减的数据库

    1. 生成脚本 - 所有对象 - 包括所有选项(键、全文、默认值等)
    2. 包括脚本数据的选项
    3. 创建一个新数据库并从脚本中填充它

    (回想起来,SSSB 队列不包含在生成数据脚本中)

    【讨论】:

    • 好的。它说数据库大小 = 3.6GB,未分配 = 8 MB --- 我如何找到正在使用的空间?原始问题中提到的脚本说这些表的大小只有约 20 MB。
    • @Diego 你检查了这个答案中的最后一个查询吗?
    • 好酷!前 5 行是 sysdercv、sysxmitqueue、sysdesend、sysconvgroup、sysobjvalues。这是什么意思?我如何从那里清空空间?谢谢!
    • @Diego - 请使用 (1) sp_spaceused (2) 此答案中最后一个查询的输出编辑问题
    • 看起来像 Remus Rusanu dealt with here 的服务代理问题
    【解决方案4】:

    如果你复制数据库怎么办?右键单击数据库并执行任务,复制数据库。只是一个可能很容易尝试的想法。

    【讨论】:

      【解决方案5】:

      谢谢你们,主要是 Richard 提供的所有信息!

      为了解决这个问题,我不得不放弃并重新创建我的服务:

      DROP SERVICE [//Audit/DataWriter] 
      GO
      
      CREATE SERVICE [//Audit/DataWriter] 
          AUTHORIZATION dbo 
      ON QUEUE dbo.TargetAuditQueue ([//Audit/Contract])
      

      一旦我这样做了,数据库就有 5GB 了!但是这次我提出的第二个查询显示 sysxmitqueue 作为第一个结果。 在互联网上挖掘更多,我能够这样做清除大表:

      ALTER DATABASE [your_database] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
      GO
      ALTER DATABASE [your_database] SET NEW_BROKER WITH ROLLBACK IMMEDIATE
      GO
      ALTER DATABASE [your_database] SET MULTI_USER
      GO
      

      然后,运行 DBCC SHRINKFILE 即可! =) 现在只有 40MB

      谢谢你们!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-31
        • 2011-09-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多