第一期:SQL Server 基础架构与核心组件

0 阅读5分钟

第一期:SQL Server 基础架构与核心组件

1. 实例(Instance)—— SQL Server 的“进程容器”

  • 定义:一个独立的 SQL Server 服务进程(sqlservr.exe),包含自己的一套系统数据库、用户数据库、配置和端口。
  • 关键点
    • 一台机器可以装多个实例(默认实例 + 命名实例),彼此隔离,通过不同端口(默认 1433)区分。
    • 每个实例有自己的内存、线程、调度器,但共享操作系统资源。
  • 现象解释:为什么重启实例能清空某些缓存?因为实例重启会释放所有内存区域(如缓冲池、计划缓存)。

2. 系统数据库 —— SQL Server 自己的“控制面板”

数据库作用
master记录实例级别信息(登录账号、链接服务器、配置、其他数据库位置)
msdb存储作业、备份历史、维护计划、SQL Agent 相关信息
tempdb全局工作空间:存放临时表、排序、哈希连接、行版本、重建索引时的中间数据。每次实例重启会重新创建。
model任何新数据库的“模板”
resource(只读隐藏)存储系统存储过程、视图等定义,升级时覆盖
  • 现象解释tempdb 负载过高导致全实例变慢?因为所有用户的排序、哈希、临时表都在抢同一个数据库。

3. 数据库(Database)与文件组(Filegroup)

  • 数据库物理组成
    • .mdf(主数据文件,1个)
    • .ndf(次数据文件,0~N个)
    • .ldf(事务日志文件,至少1个)
  • 文件组:一组数据文件的逻辑容器。表和索引可以指定放在哪个文件组
  • 关键规则
    • 一个数据文件只属于一个文件组。
    • 主文件组(PRIMARY)永远包含主数据文件。
    • 文件组内部采用比例填满策略(按空闲空间比例循环分配)。
  • 现象解释:为什么把大表放到另一个文件组能改善 I/O?因为可以让多个物理硬盘并发读写,绕开主文件组的 I/O 瓶颈。

4. 执行引擎(Relational Engine)—— 负责“编译与执行”

主要处理 T-SQL 的整个生命周期:

  • Parser:语法检查,生成查询树。

  • Algebrizer:绑定到具体对象(视图、列、数据类型),生成逻辑树。

  • Optimizer:基于代价生成最优执行计划(关键:统计信息)。

  • Query Executor:调用存储引擎提供的数据访问方法,执行计划。

  • 现象解释

    • 第一次执行慢,第二次快?——计划缓存在起作用(属于执行引擎的组件)。
    • 参数嗅探问题?——优化器基于第一次传入的参数值生成计划,复用时可能不是最优。

5. 存储引擎(Storage Engine)—— 负责“数据怎么放、怎么取”

  • 缓冲池(Buffer Pool):内存中最大区域,缓存数据页(8KB/页)。所有读/写最终都经过这里。

    • 读:先查缓冲池 → 命中则直接返回;未命中则从磁盘读入缓冲池。
    • 写:修改内存中的页(脏页),由 CheckpointLazyWriter 异步写回磁盘。
  • 事务日志与 WAL(Write-Ahead Logging)

    • 修改数据前,必须先写日志(日志刷盘后才允许修改内存页)。
    • 保证 Crash Recovery 能回滚或重做。
  • 数据访问方法:堆、B-Tree、聚集索引扫描、查找等。

  • 锁与闩锁

    • :事务隔离,协调用户并发(行、页、表锁)。
    • 闩锁:保护内存结构(如缓冲池里的页),比锁更轻量、时间短。
  • 现象解释

    • 为什么内存占满(不释放给 OS)?因为 SQL Server 把缓冲池当“缓存”,主动占用内存以减少磁盘 I/O。
    • 为什么突然大量写磁盘?可能是 Checkpoint 或内存压力导致 LazyWriter 批量刷脏页。
    • 为什么被阻塞?事务获得了锁不释放(例如更新未提交),另一个查询等待同样资源。

6. 完整工作流(一个 SELECT 语句从下发到返回)

客户端 → TDS 协议 → 实例端口(1433)

1. 协议层(SNI/Tabular Data Stream):解析请求,分发给执行引擎。
2. 执行引擎:解析→绑定→优化→生成执行计划(缓存)。
3. 存储引擎:
   - 访问方法:根据计划调用“查找/扫描”接口。
   - 缓冲池管理器:检查所需数据页是否在内存。
   - 若不在 → 发起异步 I/O 从磁盘(.mdf/.ndf)读入缓冲池。
4. 存储引擎返回数据行给执行引擎。
5. 执行引擎处理聚合、排序等,最后通过协议层返回客户端。

更新语句(UPDATE) 则多走一步:

1. 在缓冲池修改数据页 → 标记为脏页。
2. 日志记录写入 `.ldf`(强刷盘)。
3. 事务提交时:日志被硬化,但脏页可能仍在内存(后续由 Checkpoint 写回)。

7. 常见“现象”与架构关联对照表

现象直接原因涉及架构组件
重启实例后第一次查询很慢缓冲池为空,大量物理读缓冲池、存储引擎
相同查询有时快有时慢参数嗅探导致不同执行计划优化器、计划缓存
大量临时表操作造成磁盘 I/O 瓶颈tempdb 争用或空间不足tempdb、存储引擎
查询被长时间阻塞某事务持有行/表锁未释放锁管理器 + 隔离级别
内存占用过高且不释放SQL Server 主动缓存数据页缓冲池
突然长时间写盘任务Checkpoint / LazyWriter 刷脏页检查点、缓冲池

第一期小结
SQL Server 的基础架构可以概括为:实例内有多个数据库(含系统库),每个数据库由文件组划分物理文件。执行引擎负责 T-SQL 的编译与优化,存储引擎管理内存(缓冲池)、磁盘 I/O、事务日志和并发控制。理解这些组件间的协作,就能解释或预判大多数性能问题。

下一期预告:深入 缓冲池与内存架构 —— 为什么缓存命中率决定性能?如何监控和调优内存压力?