SQLServer基础之数据页类型:GAM,SGAM,PFS
简介
我们已经知道SQL Server IO最小的单位是页,连续的8个页是一个区。SQL Server需要一种方式来知道其所管辖的数据库中的空间使用情况,这就是GAM页和SGAM页。
GAM页
GAM(全局分配位图)是用于标识SQL Server空间使用的位图的页。位于数据库的第3个页,也就是页号是2的页。下面我们通过新建一个数据库来看其GAM的结构。创建测试数据库的代码如代码所示。
CREATE DATABASE [test] ON PRIMARY
( NAME = N'test', FILENAME = N'C:\Test\test.mdf' , SIZE = 3072KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
LOG ON
( NAME = N'test_log', FILENAME = N'C:\Test\test_log.ldf' , SIZE = 2048KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO
代码1.创建测试数据库
数据库创建成功后,通过查看数据库页号为2的页。我们看到如图1所示的结果。

图1.GAM页示例
我们看到页内的数据通过16进制表示。也就是一个数字是4比特,两个是一字节。其中前4个字节0000381f是系统信息,slot1的后10个字节也是系统信息。其余的每位表示SQL Server的一个区的状态,0表示已分配,1表示未分配。下面我们就通过图1所示的GAM页来计算一下这个数据库所占的空间。
我们可以看到,由于数据库刚刚创建,分配的空间在第4-8个字节就能表示,也就是0001c0ff。下面将0001c0ff由16进制化为2进制。结果是
0000 0000 0000 0001 1100 0000 1111 1111
通过计算,可以看出,上面的bit中有21个0,也就是目前数据库已经分配了21个区,我们知道每个区是8*8k=64K。因此算出这个数据库占用空间(21*64)/1024=1.3125MB≈1.31MB
下面我们通过SSMS来看数据库实际占用的空间,如图2所示。

图2.通过SSMS来看数据库所占的空间
通过上面的计算3-1.69=1.31MB和通过GAM页进行计算的结果完全吻合。
那可能大家会有疑问了,那如果数据库增长超过一个GAM所能表示的区的范围那该怎么办?答案很简单,就是再创建一个GAM页,第二个GAM页的位置也可以通过图1中的信息进行计算。图1中slot1有7992个字节,其中前四个字节用于存储系统信息,后面7988字节用于表示区的情况,因此所能表示的区是7988*8=63904,横跨的页的范围是511232,所以第511232+1页应该是下一个GAM页,而页号就会是511232页。这个区间也就是所谓的GAM Interval,接近4GB。
SGAM页
通过GAM页可知,分配空间的最小单位是区。但假如一个非常小的索引或是表只占1KB,但要分给其64K的空间就显得过于奢侈了。所以当几个表或索引都很小时,可以让几个表或索引公用一个区,这类区就是混合区。而只能让一个表或索引使用的区就是统一区。SGAM位于数据库的第四页,也就是GAM的下一个页。页号为3。通过和GAM相同位置的bit组合,就能知道空间的状态。所能表示的几种状态如表1所示。
| GAM | SGAM位 | |
| 未分配 | 1 | 0 |
| 统一区或空间使用完的混合区 | 0 | 0 |
| 含有可分配空间的混合区 | 0 | 1 |
表1.SGAM和GAM
通过SGAM和GAM的组合,SQL Server就能知道该从哪里分配空间。
第二个SGAM页位于第二个GAM页之后,也就是页号为511233的页。依此类推。
PFS页
PFS表示页可用空间。但是PFS页跟踪的远不止这些。和GAM区间相似,每个数据库文件同样也被分割成(概念上)PFS区间。一个PFS区间是8088页或约64MB。PFS页中不是位图,它是字节图,每个字节表示PFS区间中的一页(不包括PFS页本身)。
字节中每位的含义如下:
1)位0-2:页中有多少可用空间
a)0x00表示空
b)0x01表示1~50%满
c)0x02表示51~80%满
d)0x03表示81~95%满
e)0x04表示96~100%满
2)位3(0x08):页中是否至少有一个ghost记录?
3)位4(0x10):是否为IAM页?
4)位5(0x20):是否为混合页?
5)位6(0x40):页是否已分配?(分配状态位)
比如一个IAM页的PFS字节为0x70(已分配 + IAM页 + 混合页)。你可以使用DBCC PAGE来查看PFS页。
跟踪可用空间只适用于存储LOB值(比如SQL SERVER 2000中的text/image类型;SQL SERVER 2005中再加上varchar(max)/varbinary(max)/XML类型以及行溢出数据)和堆数据页。因为只有这些页存储的数据不用排序,所以可以在任何位置插入。而像索引是有明确的顺序的,所以插入点是没有选择的。
重置PFS字节不是很直观的。如果一个PFS字节为0x04的页,它是如何做到既满而又没有分配的?
答案是:(页释放时)PFS字节不会全部重置,直到该页被重新分配。在页被释放时,PFS字节中只有1位会变化——分配状态位,这样要是回滚的话就很简单了。
IAM页
索引分配映射(Index Allocation Map,IAM)页面我们将在下一篇中详细介绍IAM页。
SQLServer基础之数据页类型:GAM,SGAM,PFS的更多相关文章
- SQL SERVER大话存储结构(1)_数据页类型及页面指令分析
如果转载,请注明博文来源: www.cnblogs.com/xinysu/ ,版权归 博客园 苏家小萝卜 所有.望各位支持! SQLServer的数据页大 ...
- SQL Server 存储(1/8):理解数据页结构
我们都很清楚SQL Server用8KB 的页来存储数据,并且在SQL Server里磁盘 I/O 操作在页级执行.也就是说,SQL Server 读取或写入所有数据页.页有不同的类型,像数据页,GA ...
- SQL Server :理解数据页结构
原文:SQL Server :理解数据页结构 我们都很清楚SQL Server用8KB 的页来存储数据,并且在SQL Server里磁盘 I/O 操作在页级执行.也就是说,SQL Server 读取或 ...
- DBCC page 数据页 堆 底层数据分布大小计算
1.行的总大小: Row_Size = Fixed_Data_Size + Variable_Data_Size + Null_Bitmap + 4(4是指行标题开销) 开销定义: Fixed_Dat ...
- 06006_redis数据存储类型——String
1.概述 (1)字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制安全的,这意味着该类型可以接受任何格式的数据,如JPEG图像数据或Json对象描述信息等: (2)在Redis中 ...
- 直接在安装了redis的Linux机器上操作redis数据存储类型--String类型
一.概述: 字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制安全的,这便意味着该类型可以接受任何格式的数据,如JPEG图像数据或Json对象描述信息等.在Redis中字符串类型 ...
- 已经不再使用的表为什么数据页还在SQLServer的内存缓存中
1. 问题发现 在学习内存调优时,使用如下代码,查询目前内存缓冲区中生产数据库的每个对象缓存页计数 SELECT count(*)AS cached_pages_count ,name ,index_ ...
- [SqlServer] 理解数据库中的数据页结构
这边文章,我将会带你深入分析数据库中 数据页 的结构.通过这篇文章的学习,你将掌握如下知识点: 1. 查看一个 表/索引 占用了多少了页. 2. 查看某一页中存储了什么的数据. 3. 验证在数据库中用 ...
- 读写SQLServer数据库中的image类型数据(简单)
1.将double类型的数据存储于image类型的变量中: (1). char *CManualForecastResultBll::DoubleArray2Binary(std::vector< ...
随机推荐
- solr(五): centos中, 整合 tomcat&solr
前言 虽然windows下, tomcat和solr整合起来灰常的方便, 但是, 一般像这种东西, 都很少部署在windows中, 更多的是部署到linux中去. 其实, 步骤是一样的, 这里, 我在 ...
- kafka配置项host.name advertised.host.name
遇到的问题: 在本机或者其他机器telnet IP 9092,通,使用域名也通,telnet 127.0.0.1 9092不通 host.name:按配置文件说明,是Kafka绑定的interface ...
- LeetCode算法扫题系列19
原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9104677.html LeetCode算法第19题(难度:中等) 题目:给定一个链表,删 ...
- MyBatis源码解析(十)——Type类型模块之类型处理器TypeHandler
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6715063.html 1.回顾 之前的两篇分别解析了类型别名注册器和类型处理器注册器,此二 ...
- 第6章 LVM详解
6.1 LVM相关概念和机制 LVM(Logical Volume Manager)可以让分区变得弹性,可以随时随地的扩大和缩小分区大小,前提是该分区是LVM格式的. lvm需要使用的软件包为lvm2 ...
- 数据库性能测试:sysbench用法详解
1.简介和安装 sysbench是一个很不错的数据库性能测试工具. 官方站点:https://github.com/akopytov/sysbench/ rpm包下载:https://packagec ...
- 【转载】C#将图片以二进制流的方式存入数据库
在C#开发应用程序的过程中,图片一般会存放在文件系统中,当然图片也可以二进制的方式存放到数据库中,不过一般不建议存放在数据库中,因为图片占用的空间还是挺大的,特殊情况下可以考虑将图片存在数据.此文将介 ...
- 【转载】C#工具类:FTP操作辅助类FTPHelper
FTP是一个8位的客户端-服务器协议,能操作任何类型的文件而不需要进一步处理,就像MIME或Unicode一样.可以通过C#中的FtpWebRequest类.NetworkCredential类.We ...
- 从零开始学安全(十一)●IP地址
127 都是本机地址 ip DE 类网段 都是广播网段 它并不指向特定的网络 用不上
- double在输出为字符串的几种方法效率测试
测试结果: double->none 366msdouble->long 161msdouble->long2 188msdouble->format 564msdouble- ...