SQL Server 的体系结构是一个复杂但设计精密的系统,主要可以分为四大核心组件,它们协同工作以管理数据库、处理查询、确保数据安全与一致性。以下是其体系结构的核心组成部分:
核心组件:
-
协议层 (Protocol Layer)
- 作用: SQL Server 与外部世界(客户端应用程序)的“大门”。
- 功能:
- 监听客户端连接请求。
- 解析网络协议(如 TDS - Tabular Data Stream,这是 SQL Server 专用的协议,封装在 TCP/IP、Named Pipes、Shared Memory 等之上)。
- 接收来自客户端的 TDS 数据包(包含 SQL 语句、存储过程调用等)。
- 将数据包解包,提取出其中的命令(Command),并将它们传递给下一层(关系引擎)。
- 接收关系引擎返回的结果集(Result Set)。
- 将结果集打包成 TDS 数据包。
- 将响应数据包发送回客户端。
- 关键元素: 网络库 (Network Libraries/SQL Server Network Interface - SNI)。
-
关系引擎 (Relational Engine / Query Processor)
- 作用: SQL Server 的“大脑”,负责查询的解析、优化和执行计划的管理。它主要处理如何找到数据(逻辑操作)。
- 主要子组件:
- 命令解析器 (Command Parser): 接收来自协议层的命令(SQL 文本)。检查语法和语义错误。生成初步的查询树 (Query Tree) 或代数树 (Algebrized Tree),这是一种逻辑结构,表示查询要执行的操作。
- 查询优化器 (Query Optimizer): SQL Server 的核心智能组件。
- 接收命令解析器生成的查询树。
- 基于统计信息(数据分布、索引信息等)、系统负载、可用索引等因素,分析执行查询的所有可能方式(生成多个候选执行计划)。
- 估算每个候选计划的执行成本(主要是 I/O 和 CPU 开销)。
- 选择它认为成本最低的执行计划。这是一个基于成本的优化器 (CBO)。
- 输出查询执行计划 (Query Execution Plan),这是一个详细说明如何物理地执行查询的蓝图(例如,使用哪个索引、使用哪种连接算法 - Hash Join, Merge Join, Nested Loops)。
- 查询执行器 (Query Executor):
- 负责执行优化器生成的查询执行计划。
- 它本身不直接处理数据,而是作为协调者。
- 根据计划,向下一层(存储引擎)发起请求来获取或修改数据。它会调用存储引擎提供的访问方法(Access Methods)接口。
- 处理执行过程中的数据流(如排序、聚合、连接操作)。
- 将最终的结果集返回给协议层。
- SQL 管理器 (SQL Manager): 管理与存储过程、函数、触发器等执行计划相关的缓存和重用。
-
存储引擎 (Storage Engine)
- 作用: SQL Server 的“肌肉”,负责管理如何物理地存储数据(在磁盘和内存中)、访问数据、维护数据完整性和事务处理。它专注于“数据在哪”和“如何读写”。
- 主要子组件:
- 访问方法 (Access Methods):
- 存储引擎与关系引擎(查询执行器)交互的主要接口。
- 处理查询执行器发出的数据操作请求(SELECT, INSERT, UPDATE, DELETE)。
- 决定是否需要从磁盘读取数据页(触发 Buffer Manager)或是否可以直接操作内存中的数据。
- 管理对行、索引、分配单元等对象的扫描和查找操作。
- 处理锁请求(调用锁管理器)。
- 缓冲管理器 (Buffer Manager / Buffer Pool):
- 管理 SQL Server 最主要的内存区域:缓冲池 (Buffer Pool)。
- 核心职责是实现缓存机制:将数据库的数据文件 (.mdf, .ndf) 中的数据页 (Page)(8KB 的基本单位)读入内存(缓冲池),以及将修改过的页(脏页 - Dirty Pages)写回磁盘。
- 极大减少物理 I/O 操作,提升性能。
- 使用 LRU (Least Recently Used) 等算法管理内存中页的生存周期。
- 包含
CHECKPOINT
进程,负责定期或在需要时将脏页刷写到磁盘(但不保证事务提交)。
- 事务管理器 (Transaction Manager):
- 确保数据库的 ACID 属性:
- 日志管理器 (Log Manager): 负责事务日志(.ldf 文件)的写入。遵循 WAL (Write-Ahead Logging) 原则:在数据页修改本身被写入磁盘之前,必须先保证描述该修改的日志记录被持久化写入事务日志文件。这是保证原子性 (Atomicity) 和持久性 (Durability) 的核心机制。
- 锁管理器 (Lock Manager): 管理并发控制,处理事务对数据资源(行、页、表等)的加锁和释放锁请求。确保事务的隔离性 (Isolation),防止脏读、不可重复读、幻读等问题(具体隔离级别决定防止哪些问题)。
- 协调事务的 BEGIN TRAN, COMMIT TRAN, ROLLBACK TRAN。
- 确保数据库的 ACID 属性:
- 文件管理器 (File Manager): 管理数据库文件(.mdf 主数据文件、.ndf 次要数据文件、.ldf 事务日志文件)在磁盘上的物理布局、增长、收缩等操作。与 Windows 文件系统交互。
- 内存中的数据结构 (In-Memory Structures): 除 Buffer Pool 外,还包括计划缓存 (Plan Cache)、数据缓存 (Data Cache - Buffer Pool 的一部分)、过程缓存 (Procedure Cache - 存储执行计划) 等。
- 访问方法 (Access Methods):
-
SQL Server 操作系统 (SQLOS)
- 作用: SQL Server 的“中枢神经系统和基础平台”,位于 Windows 操作系统之上,为其他引擎组件提供基础服务。它抽象了底层操作系统,并针对数据库工作负载进行了优化。
- 关键服务:
- 调度 (Scheduling): 管理 SQL Server 线程(或纤程)。使用非抢占式调度 (Non-Preemptive Scheduling),任务(如查询执行)在主动让出 CPU (
SOS_SCHEDULER_YIELD
) 或等待资源(I/O、锁)时才会被切换。每个 CPU 核心通常对应一个调度器 (Scheduler),调度器管理 Worker Threads (工作线程) 来执行任务。 - 内存管理 (Memory Management): 整体管理 SQL Server 的内存使用(不只是 Buffer Pool),包括动态分配和回收,与 Windows 的 AWE (Address Windowing Extensions) 或 Lock Pages in Memory 权限交互。
- 资源监控 (Resource Monitoring): 监控 CPU、内存、I/O 等资源的使用情况。检测死锁(Deadlock Detection)。
- 异常处理 (Exception Handling): 处理 SQL Server 内部的错误和异常。
- 同步原语 (Synchronization Primitives): 提供锁、闩锁 (Latches - 保护内存中数据结构的短期轻量锁)、自旋锁 (Spinlocks) 等同步机制,协调多线程并发访问内部数据结构。
- I/O 管理 (I/O Management): 异步 I/O 的实现,优化磁盘访问性能。
- 调度 (Scheduling): 管理 SQL Server 线程(或纤程)。使用非抢占式调度 (Non-Preemptive Scheduling),任务(如查询执行)在主动让出 CPU (
数据存储核心概念:
- 页 (Page): 最基本的存储单元,大小为 8KB。所有数据库操作最终都发生在页级别(读取或写入整个页)。常见的页类型有:数据页、索引页、文本/图像页、全局分配映射 (GAM) / 共享全局分配映射 (SGAM) 页、索引分配映射 (IAM) 页、页可用空间 (PFS) 页等。
- 区 (Extent): 空间分配的基本单元,由 8 个连续的页(64KB)组成。有两种类型:
- 统一区 (Uniform Extent): 所有 8 个页都分配给同一个对象(如表或索引)。
- 混合区 (Mixed Extent): 页可以分配给最多 8 个不同的对象。主要用于小对象初始分配。
- 文件和文件组 (Files & Filegroups):
- 数据库文件 (.mdf/.ndf): 物理存储数据的操作系统文件。
- 文件组 (Filegroup): 逻辑容器,用于组织和放置数据库文件。可以包含一个或多个文件。对象(表、索引)是创建在文件组上的。
PRIMARY
是默认文件组。通过文件组可以实现数据的分区管理、备份恢复策略和性能优化(将对象放置在不同物理磁盘的文件组上)。
关键交互流程示例 (SELECT 语句):
- 客户端通过网络发送 SQL
SELECT
语句(封装在 TDS 包中)。 - 协议层 接收并解包,将命令文本传递给 关系引擎。
- 命令解析器 检查语法,生成查询树。
- 查询优化器 分析查询树,利用统计信息等生成成本估算,选择最优执行计划(可能使用缓存计划)。
- 查询执行器 开始执行计划。如果需要数据,它会向 存储引擎(访问方法) 发起请求。
- 访问方法 确定需要哪些数据页。它请求 缓冲管理器 提供这些页。
- 缓冲管理器 检查所需页是否在 缓冲池 (Buffer Pool) 中:
- 若在(缓存命中),直接返回内存中的页副本。
- 若不在(缓存未命中),则从磁盘(数据文件)读取该页到 Buffer Pool,然后返回该页。
- 访问方法 处理页中的数据(如读取行)。
- 查询执行器 处理结果(如过滤、排序、聚合),形成最终结果集。
- 最终结果集返回给 协议层。
- 协议层 将结果集打包成 TDS 包,通过网络发送回客户端。
总结:
SQL Server 的体系结构是一个高效协作的分层架构:
- 协议层 处理网络通信。
- 关系引擎 负责“思考”:解析、优化、协调查询执行(逻辑操作)。
- 存储引擎 负责“行动”:物理数据存储、访问、事务处理、缓存管理(物理操作)。
- SQLOS 提供基础服务(调度、内存、同步、I/O),作为引擎与 Windows OS 之间的抽象层。
理解这些组件及其交互对于数据库管理(性能调优、故障排除、容量规划)和应用程序开发(编写高效 SQL)至关重要。核心设计围绕着数据页/缓冲池、事务日志/WAL、基于成本的优化器和SQLOS调度这几个支柱展开。