SQL Server使用sys.master_files计算tempdb大小不正确
一直习惯使用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大小不正确的更多相关文章
- SQL Server 性能调优之--tempdb 之存放路径
在我们的OLAP的实现中,SQL超级复杂,用了很多的临时表,tempdb在安装时默认选择了安装SQLserver的本地磁盘路径,没有使用磁盘阵列. 在学习PostgreSQL时发现很多专家建议把临时表 ...
- 重构sql server的sys.sp_helptext存储
本文目录列表: 1.sys.sp_helptext存储的功能和效果 2.重构sys.sp_helptext存储(命名为dbo.usp_helptext)提供直观的效果 3.sys.sp_helptex ...
- SQL Server 2008 R2——使用计算列为表创建自定义的自增列
=================================版权声明================================= 版权声明:原创文章 谢绝转载 请通过右侧公告中的“联系邮 ...
- SQL Server查看库、表占用空间大小
转自:https://blog.csdn.net/yenange/article/details/50493580 查询数据文件与日志文件占用情况,查看数据大小,查看库大小 1. 查看数据文件占用(权 ...
- SQL Server ->> Computed Column(计算列)
Computed Column(计算列)是自SQL Server 2005开始就有的特性.计算列的定义是一个表达式.表达式可以是非计算列,常量,函数间的组合.但是不可以是子查询. 计算列数据固化 默认 ...
- (转)SQL Server 2005 中的计算字段
在实际工作上遇到的问题: 在订单表中有某项商品是将“订购数量(Quantity)”乘以“单件价格(UnitCost)”等于该项商品的总价(Subtotal). 在数据表中有的列(以下皆改叫为“字段”) ...
- SQL Server清空日志以及查看日志大小语句
为了安全起见,使用的时候,先数据备份一遍 作者hongb:SQL Server:查看SQL日志文件大小命令:dbcc sqlperf(logspace) https://www.cnblogs.com ...
- SQL SERVER 根据地图经纬度计算距离函数
前些天客户提出一个这样的要求:一个手机订餐网,查询当前所在位置的5公里范围的酒店,然后客户好去吃饭. 拿到这个请求后,不知道如何下手,静静地想了一下,在酒店的表中增加两个字段,用来存储酒店所在的经度和 ...
- SQL Server中sys.syslogin中updatedate字段的浅析
在系统视图sys.syslogins中,有createdate与updatedate两个字段,分别表示创建登录名与更新登录名的日期,如果你用updatedate的值来判断一个登录名的权限是否被修改过, ...
随机推荐
- string转QBytearray
最近在程序中遇到要把图片的二进制string存成图片到本地,其实就是写文件 structCameraInfo tmpCameraInfo; string strData = tmpCalibrateR ...
- Mongo之架构部署(Replica Sets+Sharding)
一.环境 要构建一个 MongoDB Sharding Cluster,需要三种角色: •Shard Server: mongod 实例,用于存储实际的数据块. •Config Server: mon ...
- Java 开发常用工具
编译器 IDEA (个人觉得IDEA比较好用) Eclipse MyEclipse IDEA插件 Lombok: 使用注解,免去实体类中get /set/构造器等代码 ,需要引入lombok包 Ali ...
- python --- 冒泡排序算法
别想太多了,这个冒泡排序就是我们脑海中想到的那个冒泡,就好像是气泡一样,较小的元素比较轻,从而要往上浮出来, 冒泡排序算法. 要对‘气泡’序列处理若干遍.所谓一遍处理,就是自底向上检查一遍这个序列,并 ...
- python --- 二分查找算法
二分查找法:在我的理解中这个查找方法为什么会叫二分呢,我认为是将要查询的一个列表分成了两份,然后在利用某个值来进行比较,在一个不断循环的过程中来找出我们要找的某一个值. 废话不多说,先上代码: def ...
- 为什么要重写 hashcode 和 equals 方法?
引言 以前面试的时候被面试官问到过这样一个问题: 你有没有重写过 hashCode 方法? 心里想着我没事重写哪玩意干啥,能不写就不写.嘴上当然没敢这么说,只能略表遗憾的说抱歉,我没写过. 撇了面试官 ...
- 辅助模式最终考验的是想象力,先来看看怎么用!| Accessibility
一.序 Hi,大家好,我是承香墨影! Android 的辅助模式(Accessibility)功能非常的强大.基本上被获取到授权之后,可以监听手机上的任何事件,例如:屏幕点击.窗口的变化.以及模拟点击 ...
- springboot~集成测试里的redis
测试不应该访问外部资源 对于单元测试,集成测试里,如果被测试的方法中使用到了redis,你需要去模拟一个单机环境的redis server,因为只有这样,你的测试才是客观的,即不会因为网络和其它因素影 ...
- Entity Framework 查漏补缺 (一)
明确EF建立的数据库和对象之间的关系 EF也是一种ORM技术框架, 将对象模型和关系型数据库的数据结构对应起来,开发人员不在利用sql去操作数据相关结构和数据.以下是EF建立的数据库和对象之间关系 关 ...
- swagger文档转换为WebApiClient声明式代码
1 swagger简介 Swagger是一个规范且完整的框架,提供描述.生产.消费和可视化RESTful Web Service.其核心是使用json来规范描述RESTful接口,另外有提供UI来查看 ...