【问题标题】:Programmatically determine available free space on a database?以编程方式确定数据库上的可用空间?
【发布时间】:2010-10-29 21:15:47
【问题描述】:

好的,我已经尝试四处寻找这个答案,但没有运气。我在工作中的 SQL Server 上有大约 50 个数据库,我几乎每天都必须检查这些数据库,看看是否可以通过收缩来释放任何空间。我们的驱动器往往会填满很多,所以这就是为什么它几乎是每天的任务。

有没有一种快速的方法来检查哪些数据库实际上有可用空间?有谁知道可以生成每个数据库列表的系统/自定义存储过程或系统视图,以及可以在该数据库上缩小多少可用空间?

顺便说一下,使用sql server 2005。

【问题讨论】:

    标签: sql-server-2005 shrink


    【解决方案1】:

    可能在 WMI 或 SQL 视图中。但我得问一下 - 与购买一些磁盘驱动器相比,您每天花在这上面的时间成本如何?

    【讨论】:

    • 这就是我所要求的,但显然它的成本低于购买空间:)。此外,如果我们购买更多空间,我们的用户很可能会再次快速消耗它,即使我们告诉他们删除旧表等。这是一种恶性循环。
    • 我同意 Ryanulit。虽然有些问题可以通过更多的空间来解决,但你只是隐藏了最初的问题,即可用空间的管理。
    【解决方案2】:

    答案是不必担心数据库中有多少可用空间,而是运行每晚或每周的维护任务来运行压缩。很可能你没有压缩你的日志文件(这是我通常增长最快的地方)。

    运行完整备份,然后使用 TRUNCATE_ONLY 运行事务日志备份,完成后,对日志文件和数据库运行 DBCC SHRINKFILE()。

    那么您只需监控总可用磁盘空间,而不是单个数据库的增长。

    SQL Server Shrink Database。在此之前,您绝对必须执行完整备份和事务日志备份。

    您可以通过运行“select * from master.dbo.sysdatabases”和运行“select * from [dbname]..sysfiles”来获取有关加载的各个文件的信息。我不是 100%,我几乎一年没有接触过 SQL Server 实例,sysfiles 可能在“主”数据库中。

    【讨论】:

    【解决方案3】:

    为每个数据库运行 sp_spacedused

    --temporary table to hold database names
    CREATE TABLE #Databases (name varchar(255))
    
    INSERT INTO #Databases
    SELECT name FROM master..sysdatabases
    
    DECLARE abc CURSOR FOR
       SELECT name FROM #Databases
    
    DECLARE @name varchar(255)
    DECLARE @sql nvarchar(1024)
    
    OPEN abc
    
    FETCH NEXT FROM abc INTO @name
    
    WHILE @@FETCH_STATUS = 0 
    BEGIN
       --build sql to switch to that database...
       SET @sql = 'USE '+@name
       PRINT @sql
       EXECUTE (@sql)
    
       --and run spaceused on it
       SET @sql = 'EXECUTE sp_spaceused @UpdateUsage=True'
       PRINT @sql
       EXECUTE (@sql)
    
       FETCH NEXT FROM ABC INTO @name
    END
    
    CLOSE abc
    DEALLOCATE abc
    DROP TABLE #Databases
    

    样本奇异结果

    执行 T-SQL:

    USE Contoso
    EXECUTE sp_spaceused @UpdateUsage=True
    

    结果:

    database_name: Contoso
    database_size:     85.13 MB
    unallocated_space: 15.41 MB
    
    reserved:         70,368 KB (68.7 MB)
    data:             42,944 KB (41.9 MB)
    index_size:       24,200 KB (23.6 MB)
    unused:            3,224 KB ( 3.1 MB)
    

    收缩:

    DBCC SHRINKDATABASE (Contoso)
    

    再次检查空间:

    EXECUTE sp_spaceused @UpdateUsage=True
    

    结果:

    database_name: Contoso
    database_size:     69.81 MB
    unallocated_space:  0.20 MB
    
    reserved:         70,256 KB (68.6 MB)
    data:             43,024 KB (42.0 MB)
    index_size:       24,200 KB (23.6 MB)
    unused:            3,032 KB ( 3.0 MB)
    

    【讨论】:

    • 代码没有完全运行,但它让我朝着正确的方向前进。谢谢。很抱歉延迟选择最佳答案。
    【解决方案4】:

    您可以使用 sp_spaceused 并使用其结果,也可以查看 sys.allocations_units 表并计算已使用的总页数。您不应该查看“数据库”级别,而是查看文件级别,因为有些可能有多个 NDF。从 sys.database_files 开始查看数据库文件中的所有文件。 size 列将包含数据库中的总页数。将 sys.allocation_units 中的总页数相加得到已使用的页数:

    with sum_au as (
    select data_space_id
        , sum(total_pages) as total_pages
        from sys.allocation_units au 
        group by data_space_id)
    select ds.name
        , df.size
        , total_pages as in_use 
        from sys.database_files df
        join sys.data_spaces ds on df.data_space_id = ds.data_space_id
        join sum_au au on au.data_space_id = ds.data_space_id
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 2011-10-30
      • 2014-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-14
      相关资源
      最近更新 更多