一直习惯使用sys.master_files来统计数据库的大小以及使用情况,但是发现sys.master_files不能准确统计tempdb的数据库大小信息。如下所示:

SELECT       database_id                                AS DataBaseId 

            ,DB_NAME(database_id)                       AS DataBaseName 

            ,Name                                       AS LogicalName 

            ,type_desc                                  AS FileTypeDesc 

            ,Physical_Name                              AS PhysicalName 

            ,State_Desc                                 AS StateDesc 

            ,CASE WHEN max_size = 0  THEN N'不允许增长'

                  WHEN max_size = -1 THEN N'自动增长'

             ELSE LTRIM(STR(max_size * 8.0 / 1024 / 1024, 14, 2))

                      + 'G'

             END                                    AS MaxSize 

            ,CASE WHEN is_percent_growth = 1

                 THEN RTRIM(CAST(Growth AS CHAR(10))) + '%'

                 ELSE RTRIM(CAST(Growth*8.0/1024 AS CHAR(10))) + 'M'

            END                                          AS Growth 

            ,Is_Read_Only                                AS IsReadOnly 

            ,Is_Percent_Growth                           AS IsPercentGrowth 

            ,CAST(size * 8.0 / 1024 / 1024 AS DECIMAL(8, 4)) AS [Size(GB)]

FROM     sys.master_files

WHERE database_id =2

ORDER BY 1

在Windows窗口里,你会看到这些文件实际大小为18G多,而不是1G大小,而使用sys.master_files统计的Size(GB)仅仅是tempdb文件的初始化大小,当然,你在SSMS里面使用UI去查看tempdb的属性发现其大小值又是正确的,

如果你用Profile跟踪看看具体SQL如下,你会发现,它统计的数据来源于视图sys.database_files

USE tempdb;

GO

SELECT  s.name AS [Name] ,

        CAST(FILEPROPERTY(s.name, 'SpaceUsed') AS FLOAT) * CONVERT(FLOAT, 8) AS [UsedSpace] ,

        CAST(CASE WHEN s.growth = 0 THEN ( CASE WHEN s.type = 2 THEN 0

                                                ELSE 99

                                           END )

                  ELSE s.is_percent_growth

             END AS INT) AS [GrowthType] ,

        s.physical_name AS [FileName] ,

        s.size * CONVERT(FLOAT, 8) AS [Size] ,

        CASE WHEN s.max_size = -1 THEN -1

             ELSE s.max_size * CONVERT(FLOAT, 8)

        END AS [MaxSize] ,

        s.file_id AS [ID] ,

        'Server[@Name='

        + QUOTENAME(CAST(SERVERPROPERTY(N'Servername') AS sysname), '''')

        + ']' + '/Database[@Name=' + QUOTENAME(DB_NAME(), '''') + ']'

        + '/LogFile[@Name=' + QUOTENAME(s.name, '''') + ']' AS [Urn] ,

        CAST(CASE s.is_percent_growth

               WHEN 1 THEN s.growth

               ELSE s.growth * 8

             END AS FLOAT) AS [Growth] ,

        s.is_media_read_only AS [IsReadOnlyMedia] ,

        s.is_read_only AS [IsReadOnly] ,

        CAST(CASE s.state

               WHEN 6 THEN 1

               ELSE 0

             END AS BIT) AS [IsOffline] ,

        s.is_sparse AS [IsSparse]

FROM    sys.database_files AS s

WHERE   ( s.type = 1 )

ORDER BY [Name] ASC;

sys.database_files的具体定义如下

SET quoted_identifier ON 

SET ansi_nulls ON 

 

go 

 

CREATE VIEW sys.database_files 

AS 

  SELECT file_id = f.fileid, 

         file_guid = f.fileguid, 

         type = f.filetype, 

         type_desc = ft.NAME, 

         data_space_id = f.grpid, 

         NAME = f.lname, 

         physical_name = f.pname, 

         state = CONVERT(TINYINT, CASE f.filestate 

                                    -- Map enum EMDFileState to AvailablityStates 

                                    WHEN 0 THEN 0 

                                    WHEN 10 THEN 0 -- ONLINE 

                                    WHEN 4 THEN 7 -- DEFUNCT 

                                    WHEN 5 THEN 3 

                                    WHEN 9 THEN 3 -- RECOVERY_PENDING 

                                    WHEN 7 THEN 1 

                                    WHEN 8 THEN 1 

                                    WHEN 11 THEN 1 -- RESTORING 

                                    WHEN 12 THEN 4 -- SUSPECT 

                                    ELSE 6 

                                  END),-- OFFLINE 

         state_desc = st.NAME, 

         size = Isnull(Filepropertybyid(f.fileid, 'size'), size), 

         max_size = f.maxsize, 

         f.growth, 

         is_media_read_only = Sysconv(bit, f.status & 8),-- FIL_READONLY_MEDIA 

         is_read_only = Sysconv(bit, f.status & 16),-- FIL_READONLY 

         is_sparse = Sysconv(bit, f.status & 256),-- FIL_SPARSE_FILE 

         is_percent_growth = Sysconv(bit, f.status & 32),-- FIL_PERCENT_GROWTH 

         is_name_reserved = Sysconv(bit, CASE f.filestate 

                                           WHEN 3 THEN 1 

                                           ELSE 0 

                                         END),-- x_efs_DroppedReusePending 

         create_lsn = Getnumericlsn(f.createlsn), 

         drop_lsn = Getnumericlsn(f.droplsn), 

         read_only_lsn = Getnumericlsn(f.readonlylsn), 

         read_write_lsn = Getnumericlsn(f.readwritelsn), 

         differential_base_lsn = Getnumericlsn(f.diffbaselsn), 

         differential_base_guid = f.diffbaseguid, 

         differential_base_time = NULLIF(f.diffbasetime, 0), 

         redo_start_lsn = Getnumericlsn(f.redostartlsn), 

         redo_start_fork_guid = f.redostartforkguid, 

         redo_target_lsn = Getnumericlsn(f.redotargetlsn), 

         redo_target_fork_guid = f.forkguid, 

         backup_lsn = Getnumericlsn(f.backuplsn) 

  FROM   sys.sysprufiles f 

         LEFT JOIN sys.syspalvalues st 

                ON st.class = 'DBFS' 

                   AND st.value = f.filestate 

         LEFT JOIN sys.syspalvalues ft 

                ON ft.class = 'DBFT' 

                   AND ft.value = f.filetype 

  WHERE  filestate NOT IN ( 1, 2 ) -- x_efs_Dummy, x_efs_Dropped 

go 

sys.master_files的具体定义如下:

SET quoted_identifier ON 

SET ansi_nulls ON 

 

go 

 

CREATE VIEW sys.master_files 

AS 

  SELECT database_id = f.dbid, 

         file_id = f.fileid, 

         file_guid = f.fileguid, 

         type = f.filetype, 

         type_desc = ft.NAME, 

         data_space_id = f.grpid, 

         NAME = f.lname, 

         physical_name = f.pname, 

         state = CONVERT(TINYINT, CASE f.filestate 

                                    -- Map enum EMDFileState to AvailablityStates 

                                    WHEN 0 THEN 0 

                                    WHEN 10 THEN 0 -- ONLINE 

                                    WHEN 4 THEN 7 -- DEFUNCT 

                                    WHEN 5 THEN 3 

                                    WHEN 9 THEN 3 -- RECOVERY_PENDING 

                                    WHEN 7 THEN 1 

                                    WHEN 8 THEN 1 

                                    WHEN 11 THEN 1 -- RESTORING 

                                    WHEN 12 THEN 4 -- SUSPECT 

                                    ELSE 6 

                                  END),-- OFFLINE 

         state_desc = st.NAME, 

         f.size, 

         max_size = f.maxsize, 

         f.growth, 

         is_media_read_only = Sysconv(bit, f.status & 8),-- FIL_READONLY_MEDIA 

         is_read_only = Sysconv(bit, f.status & 16),-- FIL_READONLY 

         is_sparse = Sysconv(bit, f.status & 256),-- FIL_SPARSE_FILE 

         is_percent_growth = Sysconv(bit, f.status & 32),-- FIL_PERCENT_GROWTH 

         is_name_reserved = Sysconv(bit, CASE f.filestate 

                                           WHEN 3 THEN 1 

                                           ELSE 0 

                                         END),-- x_efs_DroppedReusePending 

         create_lsn = Getnumericlsn(f.createlsn), 

         drop_lsn = Getnumericlsn(f.droplsn), 

         read_only_lsn = Getnumericlsn(f.readonlylsn), 

         read_write_lsn = Getnumericlsn(f.readwritelsn), 

         differential_base_lsn = Getnumericlsn(f.diffbaselsn), 

         differential_base_guid = f.diffbaseguid, 

         differential_base_time = NULLIF(f.diffbasetime, 0), 

         redo_start_lsn = Getnumericlsn(f.redostartlsn), 

         redo_start_fork_guid = f.redostartforkguid, 

         redo_target_lsn = Getnumericlsn(f.redotargetlsn), 

         redo_target_fork_guid = f.forkguid, 

         backup_lsn = Getnumericlsn(f.backuplsn) 

  FROM   master.sys.sysbrickfiles f 

         LEFT JOIN sys.syspalvalues st 

                ON st.class = 'DBFS' 

                   AND st.value = f.filestate 

         LEFT JOIN sys.syspalvalues ft 

                ON ft.class = 'DBFT' 

                   AND ft.value = f.filetype 

  WHERE  f.dbid < 0x7fff -- consistent with sys.databases 

         AND f.pruid = 0 

         AND f.filestate NOT IN ( 1, 2 ) -- x_efs_Dummy, x_efs_Dropped 

         AND Has_access('MF', 1) = 1 

 

go 

从上面SQL脚本可以看到,统计数据库的大小分别来自于sys.sysprufiles 和master.sys.sysbrickfiles这两个表,然后我们就很难再深入了解具体的原因了。在https://connect.microsoft.com/SQLServer/feedback/details/377223/sys-master-files-does-not-show-accurate-size-information 这个链接里面,对tempdb相关的问题有一些描述:

1. The view sys.master_files is something new and is updated asynchronously. It doesn't updates immediately.

2. When you re-start your SQL Server, SQL Server will re-create tempdb based on sys.master_files.

3. The sys.master_files tell you about any tempdb data file which was there on your system (the number of tempdb files) with which your server have started.

4. While sys.database_files shows currently used tempdb files. Its quite possible that not all tempdb data files came online.

5. You can read the errorlog look for any error meesage did any of the files did not come online.

6. After you started sql server somebody might have executed SQL commands to remove or add tempdb files.

大体意思,sys.master_files中的数据是异步更新的,而不是同步更新的。它不会立即更新。当你重启你的SQL Server时,SQL Server启动时候都会根据sys.master_files中值重新创建、初始化tempdb文件大小。而sys.database_files显示当前使用的tempdb文件。 很可能并非所有的tempdb数据文件都在线。 所以,如果要查询tempdb的准确大小,就要使用sys.database_files来查询!

SQL Server使用sys.master_files计算tempdb大小不正确的更多相关文章

  1. SQL Server 性能调优之--tempdb 之存放路径

    在我们的OLAP的实现中,SQL超级复杂,用了很多的临时表,tempdb在安装时默认选择了安装SQLserver的本地磁盘路径,没有使用磁盘阵列. 在学习PostgreSQL时发现很多专家建议把临时表 ...

  2. 重构sql server的sys.sp_helptext存储

    本文目录列表: 1.sys.sp_helptext存储的功能和效果 2.重构sys.sp_helptext存储(命名为dbo.usp_helptext)提供直观的效果 3.sys.sp_helptex ...

  3. SQL Server 2008 R2——使用计算列为表创建自定义的自增列

    =================================版权声明================================= 版权声明:原创文章 谢绝转载  请通过右侧公告中的“联系邮 ...

  4. SQL Server查看库、表占用空间大小

    转自:https://blog.csdn.net/yenange/article/details/50493580 查询数据文件与日志文件占用情况,查看数据大小,查看库大小 1. 查看数据文件占用(权 ...

  5. SQL Server ->> Computed Column(计算列)

    Computed Column(计算列)是自SQL Server 2005开始就有的特性.计算列的定义是一个表达式.表达式可以是非计算列,常量,函数间的组合.但是不可以是子查询. 计算列数据固化 默认 ...

  6. (转)SQL Server 2005 中的计算字段

    在实际工作上遇到的问题: 在订单表中有某项商品是将“订购数量(Quantity)”乘以“单件价格(UnitCost)”等于该项商品的总价(Subtotal). 在数据表中有的列(以下皆改叫为“字段”) ...

  7. SQL Server清空日志以及查看日志大小语句

    为了安全起见,使用的时候,先数据备份一遍 作者hongb:SQL Server:查看SQL日志文件大小命令:dbcc sqlperf(logspace) https://www.cnblogs.com ...

  8. SQL SERVER 根据地图经纬度计算距离函数

    前些天客户提出一个这样的要求:一个手机订餐网,查询当前所在位置的5公里范围的酒店,然后客户好去吃饭. 拿到这个请求后,不知道如何下手,静静地想了一下,在酒店的表中增加两个字段,用来存储酒店所在的经度和 ...

  9. SQL Server中sys.syslogin中updatedate字段的浅析

    在系统视图sys.syslogins中,有createdate与updatedate两个字段,分别表示创建登录名与更新登录名的日期,如果你用updatedate的值来判断一个登录名的权限是否被修改过, ...

随机推荐

  1. php 通过header下载中文文件名 压缩包损坏或文件不存在的问题

    开发中大家都是使用的utf8编码,昨天遇到一个奇坑,本是一件很小的问题,解决也浪费了个吧小时.废话不多说,植入正题: 文件下载方式:通过header二进制流文件下载需求: 文件上传保留文件名不变数据字 ...

  2. 系统的讲解 - PHP 缓存技术

    目录 概述 浏览器缓存 文件缓存 NoSQL缓存 WEB服务器缓存 Opcode缓存 小结 关于缓存的常见问题 概述 缓存已经成了项目中是必不可少的一部分,它是提高性能最好的方式,例如减少网络I/O. ...

  3. 批量数据复制SqlBulkCopy使用经验点滴(特别是超时处理)

    如果要批量复制大量的数据,用ado.net或者其他orm框架逐条读取并写入,有时会耗时太长,满足不了要求,此时SqlBulkCopy就可以出来大显身手了,相信许多人了解或使用过它. 但实际使用时,还是 ...

  4. 理解Linux文档的默认安全机制、隐藏属性、特殊权限,妈妈在也不用担心你从删库到跑路!!!

    写在前面 前面的章节 详解Linux文档属性.拥有者.群组.权限.差异,介绍了文档的基本权限,包括读写执行(r,w,x),还有文档若干的属性,包括是否为目录(d).文件(-).链接文件(l).拥有者. ...

  5. .NET Core 2.1来了!

    太棒了! .NET Core 2.0正式发布至今已经过去了大半年,这大半年说长不长说短不短,这段时间里,我是充分地体会到了微软的诚意,那就是认认真真打造一个优秀的开源平台.这大半年的时间里,微软一直在 ...

  6. idea中去除重复代码提示的灰色波浪线

    可以看到上面代码中的灰色波浪线,特别影响观感,可以看到是因为有了重复代码.不确定它是怎么确定重复代码的. 解决办法: Setting--Editor--Inspections--General---D ...

  7. vue.js window.removeEventListener 移除

    vue项目中的小坑记录下,想要移除window的addEventListener,需要把后面的function挂在到this上,removeEventListener 和 addEventListen ...

  8. 用github展示自己的网页要做哪些准备(总结)

    以前,如果想建立一个自己的网站,需要买域名,买存储空间,对个人来说维护成本比较高. 并且很多人只是想有一个网页展示自己的作品或者展示个人的简历. 在github越来越成熟的现在,直接使用github托 ...

  9. linux-Navicat 连接数据库 报错10060 & Navicat连接报错1146

    1.mysql数据库设置远程连接权限 GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '密码' WITH GRANT OPTION;[回 ...

  10. python maximum recursion depth exceeded 处理办法

    1.在执行命令 pyinstaller -F D:\py\programe\banksystem.py打包生成.exe文件时报错:python maximum recursion depth exce ...