当前位置:首页 > 问答 > 正文

SQL Server里怎么盯着数据文件变化还有怎么看那些文件到底长啥样

要盯着SQL Server数据文件的变化,最简单直接的方法就是使用系统动态管理视图,特别是sys.dm_io_virtual_file_stats,这个视图就像是SQL Server的实时监控器,能告诉你每个数据文件和日志文件到底有多忙。(来源:Microsoft Learn官方文档,sys.dm_io_virtual_file_stats 视图)

你不用懂太深奥的原理,可以这样理解:每次SQL Server需要读或写数据时,它都会记录下这次操作花了多长时间、读写了多少数据。sys.dm_io_virtual_file_stats这个视图就是把这些零散的信息汇总起来给你看,你可以通过一个简单的查询来查看从SQL Server启动到现在,每个文件的总体IO情况:

SELECT 
    DB_NAME(database_id) AS [数据库名],
    file_id, 
    io_stall_read_ms AS [读取总等待时间(毫秒)],
    num_of_reads AS [读取总次数],
    io_stall_write_ms AS [写入总等待时间(毫秒)],
    num_of_writes AS [写入总次数],
    size_on_disk_bytes / 1024 / 1024 AS [文件在磁盘上的大小(MB)]
FROM 
    sys.dm_io_virtual_file_stats(NULL, NULL);

这个查询结果里,“读取总等待时间”和“写入总等待时间”是两个非常关键的指标,如果某个文件的等待时间特别长,就意味着程序在读写这个文件时遇到了瓶颈,感觉“卡”住了,你可以定期(比如每隔几分钟)运行这个查询,然后把两次的结果相减,就能得到这段时间内的IO压力情况,如果file_id是1,那通常是主数据文件(.mdf),如果是2及以上,则是次要数据文件(.ndf),而日志文件(.ldf)的file_id通常是2(如果只有一个数据文件的话)或更大。(来源:对SQL Server文件类型的通用认知)

上面这个方法看的是历史累计值,如果你想“实时”地盯着,看看此时此刻谁在读写文件,那就需要用到扩展事件(Extended Events),扩展事件是SQL Server里一个非常强大且对性能影响很小的跟踪工具,你可以创建一个事件会话来捕捉sqlserver.file_writesqlserver.file_read事件。(来源:Microsoft Learn官方文档,Extended Events)

操作步骤大致是这样的:在SQL Server Management Studio (SSMS)的对象资源管理器里,找到“管理”->“扩展事件”,然后新建一个会话,在“事件”页面里,你搜索并添加file_write(捕获写操作)和file_read(捕获读操作)这两个事件,在“数据存储”页面,你可以选择将事件数据保存到一个文件里,方便以后分析,或者选择“event_file”目标,启动这个会话后,它就会像摄像头一样开始记录所有对数据文件的读写活动,你甚至可以在会话运行时直接“查看实时数据”,这样就能看到一条条读写操作在刷刷地滚动,非常直观,每个事件都会告诉你哪个数据库、哪个文件、由哪个SQL语句在什么时候被读写了。

接下来是第二部分:怎么看这些数据文件到底长啥样。

数据文件(.mdf, .ndf)在物理上是由一个个8KB大小的“页”组成的,可以想象成一本书的一页页纸,日志文件(.ldf)的结构完全不同,它是由一条条日志记录顺序组成的,我们主要看数据文件。

虽然你不能用记事本直接打开这些文件(那样会看到乱码),但SQL Server提供了专门的命令来窥探文件内部,最常用的命令是DBCC PAGE。(来源:Microsoft Learn官方文档,DBCC PAGE 命令)

这个命令可以让你查看文件中指定页面的详细内容,使用前,你需要先知道想查看哪个数据库的哪个文件的哪一页,获取这些信息需要一些技巧,一个常用的方法是先开启跟踪标志3604,让结果输出到消息窗口,然后执行DBCC PAGE

-- 先切换到目标数据库
USE YourDatabaseName;
GO
-- 告诉DBCC把结果返回给客户端
DBCC TRACEON(3604);
GO
-- 查看指定页的内容
-- 参数分别是:数据库名,文件号,页码,输出模式(3表示详细输出)
DBCC PAGE('YourDatabaseName', 1, 123, 3);
GO

DBCC PAGE非常详细,但对于初学者可能有点复杂,它会将8KB的页分解成几个部分:

  • 页头(Header):就像一页书的页眉,包含了页的基础信息,比如这个页属于哪个表、页的类型(是存数据的还是存索引的)、上一页和下一页的指针(对于索引页很重要)等等。
  • 数据行(Data Rows):这是页的主体部分,真正存储你表里数据的地方,在输出中,你会看到每一行的数据,但可能是以十六进制和字符串混合的形式显示的,对于字符串类型的列,你通常能直接看到内容;对于数字类型的列,你可能需要理解一下十六进制表示。
  • 行偏移量表(Offset Array):在页的末尾,像一个目录,告诉你每一行数据在这个8KB的页里是从哪个位置开始的。

通过仔细查看DBCC PAGE的输出,你就能真正“看到”数据在磁盘上是如何组织的,你可以验证你插入的一条记录是否真的存在于预期的位置。

除了DBCC PAGE,还有一个更高级但也更危险的工具叫DBCC CHECKDB,这个命令主要用于检查和修复数据库的一致性错误,但它在检查过程中也会读取文件的几乎所有结构。(来源:Microsoft Learn官方文档,DBCC CHECKDB 命令)你可以使用DBCC CHECKDB (‘你的数据库名’) WITH NO_INFOMSGS;来做一个快速检查(NO_INFOMSGS是为了屏蔽多余的信息),如果它没有报错,说明文件的基本结构是完好无损的,如果它报告了错误,那说明文件内部出现了严重的逻辑或物理损坏,比如页面的校验和不正确等。注意: 除非你非常清楚后果,否则不要轻易使用DBCC CHECKDB的修复选项(如REPAIR_ALLOW_DATA_LOSS),因为它可能会导致数据丢失。

盯着文件变化主要靠sys.dm_io_virtual_file_stats看宏观压力,用扩展事件做实时精细跟踪,而查看文件长相则主要依靠DBCC PAGE这个“显微镜”来深入观察数据页的微观结构,用DBCC CHECKDB来做个全面的“体检”,这些工具组合起来,就能让你对SQL Server的数据文件有一个从宏观到微观的深入理解。

SQL Server里怎么盯着数据文件变化还有怎么看那些文件到底长啥样