sqlserver使用简介(SQL Server Page结构深入分析)
sqlserver使用简介
SQL Server Page结构深入分析SQL Server存储数据的基本单元是Page,每一个Page的大小是8KB,数据文件是由Page构成的。在同一个数据库上,每一个Page都有一个唯一的资源标识,标识符由三部分组成:db_id,file_id,page_id,例如,15:1:8733,15是数据库的ID,1是数据文件的ID,8733是Page的编号,Page的编号从0依次递增。8个连续的Page组成一个区(Extent),数据文件中已分配(Allocated)的空间被分割成区的整数倍。一次磁盘IO操作作用于Page级别,而空间分配的最小单元是区。
Page是用于存储数据的,不同类型的Page存储的数据是不同的,Page的结构也是不同的。有些Page是用于存储数据的,叫做Data Page,有些Page是用于存储索引结构中的中间节点的,叫做Index Page,有些Page是SQL Server存储引擎使用的,用于管理Page的,叫做系统页。本文关注的是Data Page和Index Page,跟数据表有关。
日志文件没有Page结构,它是由一系列的日志记录构成的。
一,Page的结构
每一个Page都由 头部(Header),内容(Content)和行偏移量(Offset)组成,头部是在Page的开始处,占用96Bytes,用于存储Page的编号,Page的类型,分配单元(Allocation Unit)等系统信息。注:在单个Page中最多存储8060Bytes的数据。
The maximum amount of data and overhead that is contained in a single row on a page is 8,060 bytes (8 KB).
数据行存储在Page Header之后,数据行在Page中的物理存储是无序的,行的逻辑顺序是由行偏移(Row Offset)确定的,行偏移存储在Page的末尾,每一个行偏移是一个Slot,占用2B。行偏移连续排列在Page的末尾,称作槽数组(Slot Array)。行偏移以倒序方式存储行的偏移量,这意味着,从Page末尾向Page 开头计数,第一行的偏移量存储在Page的末尾Slot中,第二行的偏移量存储在Page末尾的第二个Slot中。
二,查看Page头部信息
Page头部信息存储的是Page的系统信息,可以使用非正式的命令来查看:
DBCC PAGE(['database name'|database id], file_id, page_number, print_option = [0|1|2|3] )
参数:file_id是数据库文件的ID;page_number是Page在当前文件中的编号;print_option是指打印信息的详细程度,默认值是0,只打印Page Header。
例如,查看资源标识符:15:1:8777733 Page的头部信息:
dbcc traceon(3604) dbcc page(15,1,8777733)
在我的数据库中,该Page的头部信息(移除Buffer的数据)如下所示,
PAGE: (1:8777733) PAGE HEADER: Page @0x0000005188B02000 m_pageId = (1:8777733) m_headerVersion = 1 m_type = 1 m_typeFlagBits = 0x0 m_level = 0 m_flagBits = 0x220 m_objId (AllocUnitId.idObj) = 28503 m_indexId (AllocUnitId.idInd) = 256 Metadata: AllocUnitId = 72057595905900544 Metadata: PartitionId = 72057594059423744 Metadata: IndexId = 1 Metadata: ObjectId = 1029578706 m_prevPage = (1:8777732) m_nextPage = (1:8777734) pminlen = 16 m_slotCnt = 2 m_freeCnt = 4513 m_freeData = 3675 m_reservedCnt = 0 m_lsn = (1212327:16:558) m_xactReserved = 0 m_xdesId = (0:799026688) m_ghostRecCnt = 0 m_tornBits = -1518328013 DB Frag ID = 1 Allocation Status GAM (1:8690944) = ALLOCATED SGAM (1:8690945) = NOT ALLOCATED PFS (1:8775480) = 0x40 ALLOCATED 0_PCT_FULL DIFF (1:8690950) = CHANGED ML (1:8690951) = NOT MIN_LOGGED
Page 头部中各个字段的含义:
1,Page的编号
m_pageId = (1:8777733),该Page所在的File ID 和Page ID
2,Page的类型
m_type = 1,Page的类型,常见的类型是数据页和索引页:
1 – data page,用于表示:堆表或聚集索引的叶子节点
2 – index page,用于表示:聚集索引的中间节点或者非聚集索引中所有级别的节点
其他Page类型(系统页是管理Page的Page,例如,GAM,IAM等)如下:
3 – text mix page,4 – text tree page,用于存储类型为文本的大对象数据
7 – sort page,用于存储排序操作的中间数据结果
8 – GAM page,用于存储全局分配映射数据GAM(Global Allocation Map),每一个数据文件被分割成4GB的空间块(Chunk),每一个Chunk都对应一个GAM数据页,GAM数据页出现在数据文件特定的位置处,一个bit映射当前Chunk中的一个区。
9 – SGAM page,用于存储SGAM页(Shared GAM)
10 – IAM page,用于存储IAM页(Index Allocation Map)
11 – PFS page,用于存储PFS页(Page Free Space)
13 – boot page,用于存储数据库的信息,只有一个Page,Page的标识符是:db_id:1:9,
15 – file header page,存储数据文件的数据,数据库的每一个文件都有一个,Page的编号是0。
16 – diff map page,存储差异备份的映射,表示从上一次完整备份之后,该区的数据是否修改过。
17 – ML map page,表示从上一次备份之后,在大容量日志(bulk-Logged)操作期间,该区的数据是否被修改过,This is what allows you to switch to bulk-logged mode for bulk-loads and index rebuilds without worrying about breaking a backup chain.
18 – a page that's be deallocated by DBCC CHECKDB during a repair operation.
19 – the temporary page that ALTER INDEX … REORGANIZE (or DBCC INDEXDEFRAG) uses when working on an index.
20 – a page pre-allocated as part of a bulk load operation, which will eventually be formatted as a ‘real' page.
3,Page在索引中的级数
数据页在索引中的索引级数,m_level=0,表示处于Leaf Level。
对于堆表(Heap),m_level=0表示的是Data Page;
对于聚集索引,m_level=0表示的是Data Page;
对于非聚集索引,m_level=0表示的是叶子节点
4, Page的元数据
Page的元数据十分重要,不仅能够查看处Page所在的Object,甚至能够查看该Page所在的分配单元和分区ID,在死锁进行故障排除时十分有用
Metadata: AllocUnitId =72057595905900544,该Page所在的分配单元ID(allocation_unit_id)
Metadata: PartitionId =72057594059423744,该Page所在的分区的分区ID(partition_id)
Metadata: IndexId = 1,该Page所在的索引ID
Metadata: ObjectId = 1029578706,用于表示Page所属对象的object_id
5,page的链指针
由于数据表的Page并不是单独存在的,而是通过双向链式结构连接在一起的,
m_prevPage = (1:8777732) :用于表示前一个page (FileID : PageID)
m_nextPage = (1:8777734) :用于表示下一个page (FileID:PageID)
6, 其他头部字段
m_slotCnt = 2 :页面中Slot的数量,用于Page中存储的数据行数
m_freeCnt = 4513 :页面中剩余的空间,单位是字节,还剩83字节的空间
m_reservedCnt = 0 :为活动事务保留的存储空间,单位是字节
m_ghostRecCnt = 0 :页面中存在的幽灵记录的总数(ghost record count)
关于Page头部的信息,可以阅读《Inside the Storage Engine: Anatomy of a page》;
三,利用Page的元数据排除死锁
Page的元数据包含分区ID,索引ID和对象ID,用户可以使用这些元数据,分析死锁产生的原因。系统追踪到产生死锁的资源,可能是一个Page的资源标识符,如果能够确认发生死锁是由于数据表或索引的分区不合理导致的,那么可以重新设置分区列,或者设置分区边界值,把单个分区拆分成多个分区,这样就能把竞争的临界资源分配到不同的分区中,避免查询请求对资源的竞争,进而减少死锁的发生。
Metadata: PartitionId ,该Page所在的分区的分区ID(partition_id);
Metadata: IndexId ,该Page所在索引ID;
Metadata: ObjectId,用于表示对象的object_id;
- mysql返回结果集函数(mysql 判断是否为子集的方法步骤)
- mysql整体架构设计(MySQL 整体架构介绍)
- 查看SQL SERVER指定数据库中所有的触发器
- mysql8.0查询操作(MySQL 8.0 redo log的深入解析)
- mysql8修改默认端口(MySQL 8.0新特性 — 管理端口的使用简介)
- mysql的视图和临时表区别(MySQL 内存表和临时表的用法详解)
- mybatis 分页查询配置(mybatis-plus分页传入参数后sql where条件没有limit分页信息操作)
- mysql拼接多字段作为查询条件(Mysql 实现字段拼接的三个函数)
- mysql主从模式与读写分离(磁盘写满导致MySQL复制失败的解决方案)
- 查看mysql执行计划关键字(带你学习MySQL执行计划)
- sqlserver存储过程同步数据(SQL Server存储过程同时返回分页结果集和总数)
- mysqlselect语句汇总(MySQL Select语句是如何执行的)
- sqlserver常用基本数据类型有哪些(浅述SQL Server的语句类别 数据库范式 系统数据库组成)
- mysql 快速迁移到历史表(MySQL 线上日志库迁移实例)
- mysql 查询出来的字段拼接(mysql 多个字段拼接的实例详解)
- SQL Union和Union All的用法和区别
- 浙江省一个县,人口超40万,建县历史超1100年(浙江省一个县人口超40万)
- 五代十国南唐历代国君(五代十国南唐历代国君)
- 飞机引进工程师杨隆 匠人匠心,只争朝夕(飞机引进工程师杨隆)
- 三人行,她们是育人路上的 铁三角 团队(她们是育人路上的)
- 阴阳师 孟婆山兔CP不倒 新皮肤草稿 孟婆兔 让痒痒鼠点赞(阴阳师孟婆山兔CP不倒)
- 阴阳师孟婆御魂推荐 孟婆御魂搭配毕业套(阴阳师孟婆御魂推荐)
热门推荐
- sqlserver如何可视化表(sql server使用公用表表达式CTE通过递归方式编写通用函数自动生成连续数字和日)
- dedecms标签调用(dedecms获取文档当前栏目所在目录链接URL)
- pyqttreeview控件使用详解(GTK treeview原理及使用方法解析)
- mysql常见错误提示及解决办法(MYSQL 无法识别中文的永久解决方法)
- python与气象(使用Python和Prometheus跟踪天气的使用方法)
- serv-u服务器安装(Serv-U搭建FTP服务器教程之建立登录用户和密码)
- SqlServer类似正则表达式的字符处理问题(SqlServer类似正则表达式的字符处理问题)
- 华为云服务器远程登录后怎么办(华为云服务器怎么登陆不上去)
- 云服务器设置方法(怎么配置云服务器)
- sqlserver模糊查询使用定义的字段(SQL Server模糊查询的常见方法总结)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9