RDS SQL Server空间不足问题

RDS SQL Server实例的空间使用率是日常需要重点关注的监控项之一,实例的存储空间不足,会导致严重后果,例如数据库无法写入、数据库无法备份、存储空间扩容任务耗时过长等。本文介绍如何查看空间使用情况以及排查空间问题。

查看空间使用情况

  • 您可以在实例的基本信息页面查看存储空间使用情况,但是这里只展示当前的空间使用总量,没有展示各类数据分别占用的磁盘空间信息,也没有空间使用的历史信息。基本信息

  • 您可以在控制台的监控与报警页面,单击旧版监控页签内的资源监控,查看实例各类数据占用的磁盘空间信息和历史变化曲线。

    说明

    系统文件空间使用量包括系统数据库master、msdb和model的所有数据文件和日志文件,以及一些系统文件(错误日志、默认跟踪文件、系统扩展事件文件等)。

    磁盘空间
  • 您可以在控制台的自治服务 > 空间管理页面,查看更详细的空间使用情况,包括数据与日志的空间使用对比、空间使用的历史变化趋势、Top数据库和Top表的空间分配明细等。更多信息,请参见空间管理

    说明

    实例不能是RDS SQL Server 2008 R2云盘版。

    空间管理
  • 您也可以使用客户端工具,例如SQL Server Management Studio,查看实例的空间使用信息。

    常用的查看SQL Server数据库空间使用信息的命令如下。

    系统视图或命令

    说明

    sp_helpdb

    查看所有数据库各自的总空间大小(数据文件与日志文件大小之和)。

    sp_spaceused

    查看当前数据库的名称、已使用空间大小和未分配空间大小。

    DBCC SQLPERF(LOGSPACE)

    查看所有数据库的各自日志文件总空间大小以及实际已使用日志空间大小。

    DBCC SHOWFILESTATS

    查看当前数据库的所有数据文件空间大小以及实际已使用数据空间大小。

    select * from sys.master_files

    查看所有数据库各自的数据和日志文件的大小。

    select * from sys.dm_db_log_space_usage

    查看当前数据库的日志文件的总空间大小以及实际已使用日志空间大小。

    说明

    仅适用于SQL Server 2012及以上版本。

    select * from sys.dm_db_file_space_usage

    查看当前数据库的数据文件的总空间大小以及实际已使用数据空间大小。

    说明

    仅适用于SQL Server 2012及以上版本。

如果发现实例的空间使用率过高,首先应该在RDS管理控制台监控与报警页面中检查数据、日志、临时文件、系统文件各部分的空间使用情况,确认是哪种文件的空间增长过快,并进一步评估能否采取措施释放空间或避免空间快速增长。

详细的分析与解决方案请参见下文。

回收和释放数据空间

  • 分析

    数据空间的总大小(即所有数据文件大小总和)是由已分配(Allocated)空间和未分配(Unallocated)空间两部分组成:

    • 已分配空间包括已使用(Used)空间和未使用(Unused)空间,未使用空间只能分配给同一表或索引新增的记录使用,其他数据库对象无法直接使用。

    • 未分配空间是由完全未分配的区(Extent)构成的,每个区是连续的64 KB空间。未分配空间不和任何数据库对象关联,这部分空间可以通过收缩文件的方式释放。

  • 解决方案

    在数据量持续增长的情况下,未分配空间通常很小,所以直接收缩文件效果很差,建议首先对已分配空间进行优化和回收,然后再考虑收缩文件。

    数据空间的回收通常有如下几种方式:

    • 归档数据

      删除数据库中不常用的数据(例如早期的历史数据),或者根据需要迁移到其他数据库实例中,或者以其他形式归档保存,通过直接减少数据量来降低已使用数据空间大小。

      这种方式是控制数据空间增长的有效手段,但是对数据库对象结构及相关应用逻辑的设计有一定要求,需要应用设计和开发人员的参与配合。

    • 压缩数据

      SQL Server 2016及以上版本实例,或2016以下的企业版实例,内置数据压缩功能,您可以在单个表、索引或分区上开启压缩功能,包括行压缩和页压缩。更多信息,请参见Data Compression

      数据压缩比由表结构、列的数据类型和数值分布情况等决定,跨度较大,例如从10%到90%。SQL Server中提供了一个专用的存储过程sp_estimate_data_compression_savings可以帮助您快速评估在指定的表或索引上开启压缩可以节省多少数据存储空间。

      说明
      • 修改表或索引上的压缩选项设置是DDL操作,大表执行此类操作会造成长时间锁表,可能影响业务,建议在业务低峰期修改。

      • RDS SQL Server企业版实例可以设置参数ONLINE为ON,然后执行修改操作,基本不会影响正常业务。

      • 数据压缩会增加CPU开销,因此需要根据实际业务情况进行评估,建议只在大表上启用数据压缩。

    • 整理索引碎片

      索引碎片率较高会导致实际占用的数据存储空间过大,因此对索引执行碎片整理可以降低数据空间大小。

      您可以在控制台的自治服务 > 性能优化页面,单击索引使用率页签,可以查看各表的索引碎片率统计结果,并且自治服务会提供索引重建(Rebuild)或重组(Reorganize)建议。

      整理索引碎片
      • 重建(Rebuild)操作

        优化效果较好,对于碎片率高的情况执行效率更高,默认情况下执行过程中会锁表,企业版中可以设置参数ONLINE为ON避免长时间锁表。

      • 重组(Reorganize)操作

        对于碎片率较低的情况执行效率更高,但优化效果不如重建。

      索引碎片率统计的是逻辑上相邻的索引页在物理位置上不一致的比例,和索引页中的空闲空间比例不是一个概念,只是碎片率较高的索引大概率也是可回收空间比例较大的索引。

      如果需要分析某个索引的页内平均空闲空间比例,可以使用SAMPLED或DETAILED模式查询系统视图sys.dm_db_index_physical_stats,然后参考结果集中avg_page_space_used_in_percent列的值。更多信息,请参见sys.dm_db_index_physical_stats (Transact-SQL)

      说明

      查询过程会读取大量索引页,可能影响数据库性能,请在业务低峰期操作。

      整理索引碎片只适用于更新频率很低的归档数据表,如果有频繁的插入和更新操作,索引碎片率会很快升高,而且重建或重组的过程中,会产生大量事务日志,导致日志空间的增加。

以上操作通常可以有效降低数据空间大小,但是如果实例空间仍然有压力,可以执行DBCC SHRINKFILE命令收缩数据文件,将数据文件中未分配空间释放给操作系统。

案例

以上图为例,一个区(Extent)的大小为64 KB,因此数据文件的总空间大小为104584 MB,已分配空间为82089 MB,即压缩后数据文件空间的总大小不会低于82089 MB。要将该数据文件空间的总大小缩小到90000MB,可以执行如下命令:

DBCC SHRINKFILE(1, 90000)

更多信息,请参见Shrink a DatabaseDBCC SHRINKFILE (Transact-SQL)

回收日志空间

回收日志空间比较简单,使用DBCC SQLPERF(LOGSPACE)命令或自治服务查看数据库的日志文件空间中实际已使用部分的比例,如果已使用部分的比例较高,收缩日志文件几乎没有效果,可以查询系统视图sys.databases,通过log_reuse_waitlog_reuse_wait_desc列的输出信息判断空间为何无法回收。

说明

log_reuse_waitlog_reuse_wait_desc的取值说明请参见sys.databases (Transact-SQL)

绝大部分情况下,您不需要手动对日志文件执行收缩操作,每次自动备份后都会收缩日志文件,如果确实需要尽快收缩日志文件大小,例如日志文件增长导致实例可用存储空间过低,且无法等到下一次的自动备份开始,您可以在实例的备份恢复页面单击收缩事务日志,RDS会自动备份所有的事务日志并收缩日志文件。

说明

收缩事务日志需要等待日志备份完成,因此如果执行该操作时数据库中还有大量未备份过的日志,则需要等待较长时间。

收缩事务日志

回收临时文件空间

  • 分析

    临时文件空间是指系统数据库tempdb占用的空间大小。由于tempdb库总是使用简单恢复模式,因此tempdb库的日志文件通常很小,但是数据文件容易增长地很快,例如创建大量临时表、连接大表或排序等都可能导致tempdb库数据文件空间增加。

  • 解决方案

    • 尽量从数据库应用层面规避,例如减少不必要的临时表、大表连接查询、避免大事务等。

    • 在业务低峰期重启RDS实例,重启后tempdb库占用的空间会恢复到实例创建时的大小。

回收系统文件空间

  • 分析

    系统文件空间是指系统数据库master、msdb、model,以及系统目录下的一些文件占用的空间大小。这些文件通常都很小,但是某些情况下占用的空间会很大,例如:

    • 错误日志较多,错误日志文件大小增长到几 GB甚至更大。

    • 严重异常时自动产生的内存转储(memory dump)文件。

  • 解决方案

    您无法直接获知各类系统文件实际占用的空间大小。

扩容存储空间

如果RDS实例空间使用率过高,且参考上文后无法有效降低空间使用率,应及时扩容实例存储空间。具体操作,请参见变更配置