RDS for SQL server 空间问题排查汇总

本文涉及的产品
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS SQL Server,基础系列 2核4GB
日志服务 SLS,月写入数据量 50GB 1个月
简介: SQL server的空间问题一直有客户在询问,今天就给大家汇总讲解下SQL server 的全部空间开销

作者:马弓手三菜

SQL server的空间问题一直有客户在询问,今天就给大家汇总讲解下SQL server 的全部空间开销。

SQL server 的空间组成

从文件类型来看,SQL server 的文件类型分数据文件(MDF,NDF),日志文件(LDF)

从数据库来看分为系统数据库和用户数据库,其中系统数据库中,最容易出现空间问题的,就是临时数据库(tempdb)

下面我们将分别来研究下空间的常见问题和解决方法。

用户数据库的数据文件

正常情况下,数据文件是随着数据库使用,正常增长的。

sp_spaceused

image.png

这里给大家解释下,这几个参数。假设我们只有一个MDF,和一个LDF。

那么MDF 的文件大小 = reserved(8142.5MB) + unallocated space (2250.37MB)

Reserved (8337992KB)= DATA(4248352KB) +INDEX_SIZE(4086384KB) + Unused(3256KB)

Database size(10393.94MB) = MDF(10392.94MB) + LDF(1MB)

image.png

但是有时候,因为频繁更改,会带来碎片(fragmentation),碎片度太高,会导致内部的空间浪费。同时,每个SQL 操作,因为碎片,可能要访问更多的页面(page),导致开销变大。

可以通过这个命令查看下当前数据库的索引碎片。

SELECT dbschemas.[name] as 'Schema', 
dbtables.[name] as 'Table', 
dbindexes.[name] as 'Index',
indexstats.avg_fragmentation_in_percent,
indexstats.page_count
FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, NULL) AS indexstats
INNER JOIN sys.tables dbtables on dbtables.[object_id] = indexstats.[object_id]
INNER JOIN sys.schemas dbschemas on dbtables.[schema_id] = dbschemas.[schema_id]
INNER JOIN sys.indexes AS dbindexes ON dbindexes.[object_id] = indexstats.[object_id]
AND indexstats.index_id = dbindexes.index_id
WHERE indexstats.database_id = DB_ID()
ORDER BY indexstats.avg_fragmentation_in_percent desc

通常情况下,碎片度大于30%的索引,我们会选择rebuild index。

ALTER INDEX [idx_name] ON [dbo].[test] REBUILD

当然rebuild 之后,这些碎片空间也不会直接被OS回收,而是作为数据文件的可重用空间。

如果特别想回收这部分空间,可以尝试下这个命令,回收下文件尾部的空间。

dbcc shrinkfile(N'testdb',0,truncateonly)

用户数据库的日志文件

SQL server的redo 段和 undo 段都是记录在 T-Log的,所以很容易被撑大。

我们的SQL Server都是使用 FULL RECOVERY 级别,所以日志空间并不会自动释放。

如何查看LOG 大小

dbcc sqlperf(logspace)

image.png

可以看见testdb 这个库,有15G的日志占用,切使用率99%

Log Reuse 的最常见的两种原因:

1) Log backup

2) Active transaction

那么,如何具体查看LOG 等待 reuse的原因?

select name,log_reuse_wait_desc,* from sys.databases where name='testdb'

原因一:日志产生过快,日志备份频率过低,等待日志备份

image.png

大部分情况,这里应该是log_backup, 这时候,如果日志占用很大且利用率很高,就可以考虑调整下日志备份策略。修改的地址在 备份恢复-> 备份设置-> 编辑,我们这里可以改成30分钟一次,以提高备份频率。

image.png

等到log使用率下降后,我们可以通过这个命令来shrink 日志文件,也可以通过控制台上“收缩事务日志”按钮来收缩日志。

-- 注意,可以通过这里查询下当前数据库的日志文件名,替换下文中的test_log
-- select name,* from sys.database_files where name='dbname'

-- 此处,将尽可能的让testdb_log日志收缩到100MB
dbcc shrinkfile (N'test_log',100)

原因二:有活跃事务阻塞了日志空间释放

image.png

如果是Active transaction, 那么可以这么去查

dbcc opentran

image.png

这里就能看见阻塞者的开始时间,已经SPID。根据SPID,可以再查到这个会话最后一条SQL语句是什么。

dbcc inputbuffer(64)

image.png

把session kill之后,再查下log_reuse_wait_desc ,如果变成log_backup,就可以尝试下shrink 了

tempdb的空间问题

tempdb是一个非常特殊的db,每次实例启动的时候,都会根据tempdb的默认值大小,重建tempdb文件。所以tempdb的空间问题,都可以通过重启解决。重点在于,找到tempdb的开销来自哪里,从根源上优化。

tempdb的空间,主要分为三块:

1) user objects

2) internal objects

3) versioning objects

想要看下当前tempdb的大小,可以试下这个语句

Select 'Tempdb' as DB, getdate() as Time,

    SUM (user_object_reserved_page_count)*8 as user_objects_kb, 

    SUM (internal_object_reserved_page_count)*8 as internal_objects_kb, 

    SUM (version_store_reserved_page_count)*8  as version_store_kb,      

    SUM (unallocated_extent_page_count)*8 as freespace_kb

From sys.dm_db_file_space_usage

Where database_id = 2

这个命令可以查看到当前tempdb的空间开销

如果是user objects占用多,就要考虑下是否使用了大量的临时表,表变量等自建对象。

如果是 internal objects占用多,就要去检查自己的排序内存,hash内存是否不够

如果是versioning 占用多,就要去检查自己是否打开了versioning相关的设置,这个并发程度是否是预期内的。

如果是freespace 最大,就说明问题已经发生过了,需要定期抓取这个数据,等待问题重现来判断是上述三个中的哪一个导致的。

关于versioning可以查询下这里:

select is_read_committed_snapshot_on,snapshot_isolation_state_desc,* 
from sys.databases

image.png

以上就是本期的全部内容,如果有任何疑问,可以在下方留言。

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
相关文章
|
2天前
|
SQL 存储 关系型数据库
【MySQL基础篇】全面学习总结SQL语法、DataGrip安装教程
本文详细介绍了MySQL中的SQL语法,包括数据定义(DDL)、数据操作(DML)、数据查询(DQL)和数据控制(DCL)四个主要部分。内容涵盖了创建、修改和删除数据库、表以及表字段的操作,以及通过图形化工具DataGrip进行数据库管理和查询。此外,还讲解了数据的增、删、改、查操作,以及查询语句的条件、聚合函数、分组、排序和分页等知识点。
【MySQL基础篇】全面学习总结SQL语法、DataGrip安装教程
|
1天前
|
SQL 存储 关系型数据库
MySQL/SqlServer跨服务器增删改查(CRUD)的一种方法
通过上述方法,MySQL和SQL Server均能够实现跨服务器的增删改查操作。MySQL通过联邦存储引擎提供了直接的跨服务器表访问,而SQL Server通过链接服务器和分布式查询实现了灵活的跨服务器数据操作。这些技术为分布式数据库管理提供了强大的支持,能够满足复杂的数据操作需求。
24 12
|
20天前
|
SQL 存储 缓存
MySQL进阶突击系列(02)一条更新SQL执行过程 | 讲透undoLog、redoLog、binLog日志三宝
本文详细介绍了MySQL中update SQL执行过程涉及的undoLog、redoLog和binLog三种日志的作用及其工作原理,包括它们如何确保数据的一致性和完整性,以及在事务提交过程中各自的角色。同时,文章还探讨了这些日志在故障恢复中的重要性,强调了合理配置相关参数对于提高系统稳定性的必要性。
|
18天前
|
SQL 关系型数据库 MySQL
MySQL 高级(进阶) SQL 语句
MySQL 提供了丰富的高级 SQL 语句功能,能够处理复杂的数据查询和管理需求。通过掌握窗口函数、子查询、联合查询、复杂连接操作和事务处理等高级技术,能够大幅提升数据库操作的效率和灵活性。在实际应用中,合理使用这些高级功能,可以更高效地管理和查询数据,满足多样化的业务需求。
56 3
|
21天前
|
SQL 关系型数据库 MySQL
MySQL导入.sql文件后数据库乱码问题
本文分析了导入.sql文件后数据库备注出现乱码的原因,包括字符集不匹配、备注内容编码问题及MySQL版本或配置问题,并提供了详细的解决步骤,如检查和统一字符集设置、修改客户端连接方式、检查MySQL配置等,确保导入过程顺利。
|
23天前
|
SQL 存储 关系型数据库
MySQL进阶突击系列(01)一条简单SQL搞懂MySQL架构原理 | 含实用命令参数集
本文从MySQL的架构原理出发,详细介绍其SQL查询的全过程,涵盖客户端发起SQL查询、服务端SQL接口、解析器、优化器、存储引擎及日志数据等内容。同时提供了MySQL常用的管理命令参数集,帮助读者深入了解MySQL的技术细节和优化方法。
|
24天前
|
SQL Oracle 关系型数据库
SQL(MySQL)
SQL语言是指结构化查询语言,是一门ANSI的标准计算机语言,用来访问和操作数据库。 数据库包括SQL server,MySQL和Oracle。(语法大致相同) 创建数据库指令:CRATE DATABASE websecurity; 查看数据库:show datebase; 切换数据库:USE websecurity; 删除数据库:DROP DATABASE websecurity;
|
1月前
|
SQL 开发框架 .NET
突破T-SQL限制:利用CLR集成扩展RDS SQL Server的功能边界
CLR集成为SQL Server提供了强大的扩展能力,突破了T-SQL的限制,极大地拓展了SQL 的应用场景,如:复杂字符串处理、高性能计算、图像处理、机器学习集成、自定义加密解密等,使开发人员能够利用 .NET Framework的丰富功能来处理复杂的数据库任务。
|
1月前
|
SQL 关系型数据库 MySQL
惊呆:where 1=1 可能严重影响性能,差了10多倍,快去排查你的 sql
老架构师尼恩在读者交流群中分享了关于MySQL中“where 1=1”条件的性能影响及其解决方案。该条件在动态SQL中常用,但可能在无真实条件时导致全表扫描,严重影响性能。尼恩建议通过其他条件或SQL子句命中索引,或使用MyBatis的`<where>`标签来避免性能问题。他还提供了详细的执行计划分析和优化建议,帮助大家在面试中展示深厚的技术功底,赢得面试官的青睐。更多内容可参考《尼恩Java面试宝典PDF》。
|
2月前
|
SQL 运维 关系型数据库
MySQL 运维 SQL 备忘
MySQL 运维 SQL 备忘录
51 1