本节主要讲维持数据的元数据,以及数据库框架结构、内存管理、系统配置等。这些技术点在我们使用数据库时很少接触到,但如果要深入学习Sql Server这一章节也是不得不看。本人能力有限不能把所有核心的知识点理解透,所以有些描述的也不是很清楚。但当接下来的几个章节学习后再复习这些知识点应该能更容易理解。
数据库对象
数据库维持了一系列表存储所有对象、数据类型/约束/配置项/资源等,在2008种我们叫他们为system base tables,并且这些表我们默认是看不到的。我们可以通过管理员登陆数据库,然后执行脚本:
USE master;
SELECT name FROM sys.objects
WHERE type_desc = 'SYSTEM_TABLE';
能查看到几十条数据。一般我们是不能查看到这些表里边的任何数据,只有通过DAC方式连接数据库才能查看到数据。这些数据主要被数据库引擎使用。
目录视图
什么是目录视图,目录视图作为常规接口用来维持系统的原数据。所有的目录视图命名都是以sys开始。例如,sys.objects;
SELECT * FROM sys.objects;
从表中我们可以看出,包含了定义的系统表以及用户表以及表的外键、约束等。为了直观说明,我们创建两张表:
create table hvi_Customer(
id int not null identity(1, 1) primary key,
[name] nvarchar(20) not null
)
create table [hvi_Order](
id int not null identity(1, 1) primary key,
createtime date not null,
cus_id int not null foreign key references hvi_Customer(id)
)
再执行SELECT * FROM sys.objects where type_desc <> 'SYSTEM_TABLE'。结果如图:
可以看出我们定义的外间主键都是一个对象实例。
系统函数
系统函数也叫做属性函数,属性函数从数据库对象提供给我们某些属性的值。在sql server 2008中包括以下系统函数:
■SERVERPROPERTY
■ COLUMNPROPERTY
■ DATABASEPROPERTY
■ DATABASEPROPERTYEX
■ INDEXPROPERTY
■ INDEXKEY_PROPERTY
■ OBJECTPROPERTY
■ OBJECTPROPERTYEX
■ SQL_VARIANT_PROPERTY
■ FILEPROPERTY
■ FILEGROUPPROPERTY
■ TYPEPROPERTY
■ CONNECTIONPROPERTY
■ ASSEMBLYPROPERTY
例如我们想查看msdb数据库的Recovery属性,可执行语句SELECT DATABASEPROPERTYEX('msdb', 'Recovery')。结果如下:
然后我们从sys.databases中查找:SELECT name, recovery_model, recovery_model_desc FROM sys.databases。结果如下:
可以看出通过系统函数DATABASEPROPERTYEX查询msdb中Recovery属性的值即为SIMPLE。系统函数也提供了一些缩写函数方便我们访问目录视图。例如DB_ID函数通过插入数据库名查看数据库的ID。使用下面的语句查看数据库ID
SELECT database_id
FROM sys.databases
WHERE name = 'heavi_case1';
同样我们也可以使用DB_ID函数来查看数据库ID:
SELECT DB_ID('heavi_case1');
数据库引擎组件
首先给大家看一张图看看数据库引擎包括哪些组件。
通过上图可以看出数据库四个主要的组件分别是查询处理器(query processor)、存储引擎(Storage engin)、数据库操作系统(SQLOS)、协议层(Protocol Layer,没有在图中展示出来)。这四个组件分别有什么用?
(1)协议层:把接收到的请求翻译到一张表中以至于查询处理器能处理。也可以把把最终的执行结果返回给客户端;
(2)查询处理器:转换、编译、优化、处理查询;
(3)存储引擎:如果请求的sql包含数据,需要保存到存储引擎。管理所有数据访问。
(4)SQLOS:通常执行系统职责,例如线程管理、同步机制、死锁处理、内存管理、缓存管理等;
接下来分别对这四个组件作介绍。
数据库协议
数据库通过协议层提供编程接口API,并且数据传递格式采用微软自定义的表数据流包(tabular data stream (TDS) packet),客户端也是通过TDS包和数据库交互数据。数据库包含的协议有:
1)Shared Memory:共享内存,只能在同一台
2)Named Pipes:在local area networks (LANs)下使用的协议。命名管道协议可以把消息从一个进程传递到另一个进程中。并且这两个进程可以在同一台PC或者不同的PC上。
3)TCP/IP:数据库使用最广泛的协议。
4)Virtual Interface Adapter (VIA)
查询优化器(Query Optmizer)
查询优化器从内存、CPU、I/O操作数来优化处理查询语句,检查数据表的影响次数、查找表索引和关联列等。
存储引擎(Storage engin)
存储引擎主要由访问方法、锁以及事物服务、工具命令三部分组成。
(1)访问方法: 当数据库定位数据时需要使用“访问方法”。随后访问方法预览数据页和索引页,把查询的数据返回给查询处理器。相似的,访问方法也接收从客户端传来的数据,打开表然后更新数据。
(2) 事物服务:说道事物就不得不说事物的ACID特性。Atomicity:原子性。要么都提交,要么都不提交;Consistency,一致性;Isolation:隔离性;Durability:持久性。当要给事务正在执行时数据库发生异常。那么该事务不会执行。
(3)锁操作:是多用户数据库的关键功能,从不同的隔离级别保证数据的同步性;
SQLOS(SQL 操作系统)
SQLOS运行于数据库引擎最底层,计划和内存管理是SQLOS最重要的两个功能。其他功能包括:
(1) 同步器:同步对象包括互斥锁、读写锁、旋转锁等;
(2)内存管理器:为不同的Component分配内存;
(3)数据库异常处理器:解决处置用户错误;
(4)死锁检测器:不解决死锁而是检查死锁情况;
(5)I/O异步处理器:请求调用I/O操作时保证系统能继续执行;
Sql Server 2008的NUMA框架
NUMA(non Uniform Memory Access Architecture)叫做非统一内存访问框架。 NUMA框架好处是可量化,遵循对称性架构(SMP),所有的内存访问都通过同一个内存栈,如果CPU比较少时这么模式工作还好。但如果多CPU都集中访问共一个系统栈就非常影响性能。NUMA限制了一个内存栈的CPU数量,每组进程有自己的内存和I/O通道。每一个组叫做NUMA节点,节点之间通过一条高速部内连接器交互,每一个节点的CPU数量依赖于具体的硬件设备。NUMA框架结构图如下:
内存管理
默认情况下,Sql Server 2008几乎是完全动态的管理内存资源。当分配内存时数据库差不多一直保持和SQLOS交互。所以说SQLOS是数据库非常重要的底层组件。
缓冲池和数据缓存
数据库主要的内存组件是缓存池(Buffer Pool)。缓存池中的所有内存被用作缓存从磁盘上读取的页数据。缓存管理器管理磁盘操作,把数据和索引页保存到数据缓存,以至于数据能够被用户共享。当其他组件需要内存时要从缓存池中申请。一个缓存在数据库中也是按照页形式存储,和数据以及索引页有相同的尺寸。你可以理解为一个缓存区是处理数据库中页的一个框架。很多的缓存区减少其他内存组件的缓存池然后转变成各种内存缓存。例如缓存存储过程和执行计划的缓存我们经常称为计划缓存。
访问内存数据页
访问数据缓存中的页的速度必须非常快,数据缓存中的页我们通过hash方式快速访问。hash表包含了一组指针数据映射到真实的缓冲页上。如果所有的指针映射不能存放到一张hash页上,则这些指针被串联到一个hash页中。hash的主键一般是一个dbid-fi leno-pageno identifier(数据库ID、文件Number、页面Number的组合体),hash表维持了一个索引和特殊页的关联关系。通过hash方法,即使存在大量的内存数据,数据库也能快速从内存中找到特殊的数据页。同理,仅仅少量内存读取就可以决定期望的页面是否存在缓存中,是否需要从磁盘中读取。
管理数据缓存中的页
你能使用一张数据页或者索引页如果它存在内存中。因此,数据缓存中必须存在一个缓冲区用来读取页。保持有效缓存的即时供应是重要的性能优化。如果一个缓存区不能有效读取,许多内存页不得不查找一个缓存区清空用来作为工作区。
Sql Server 2008提供一个单机制用来负责保存改动页到磁盘上,标记那些一段时间没有被引用的页。数据库维持了一个空页面的地址链表。任何工作者可从这个链表第一页获取空缓存页。
Sql Server 2008配置
配置网络协议
想要连接数据库服务,SQL Native Client必须安装在客户端机器上并且配置了连接协议。它被用来访问OLEDB和ODBC。数据库配置可以设置数据库支持一种或者多种协议。比如配置成Shared Memory protocol,那客户端和服务必须在同一台电脑上。我们也可以通过动态管理视图(DMV)的sys.dm_exec_connections来查看当前连接的协议。执行指令:
SELECT net_transport FROM sys.dm_exec_connections WHERE session_id = @@SPID;
返回结果:。因为我们在同一台电脑上访问,直接通过共享内存协议速度最快。如果通过不同的电脑访问,改协议就不支持。Sql Server 2008开发、评估、Express版本默认是没有开启TCP/IP协议。下图展示了2008各个版本的默认协议设置
Sql Server浏览器(Sql Server Brower)
数据库预览器是特别重要服务之一,它用来监听数据库资源请求,提供数据库实体的信息。在sql server 2000时,数据库仅仅监听1433端口,同一时间一个端口只能被一个连接使用,没有多实体的概念。sql server 2000后来推出SQL Server Resolution Protocol (SSRP)支持多实例。SSRP监听1434的UDP端口,监听器使用实体的名称回应客户端,从sql server2005之后一直使用 SQL Server Browser service代替SSRP。
如果Sql Server预览器服务没有启动,你不能连接数据库除非你提供了正确的端口。但以下的连接是不能正常工作:
1)连接命名实体,没有提供端口号或者通道;
2)使用DAC连接命名的实体或者默认实体,但它没有使用TCP/IP 1433端口;
3)在Managment Studio、Enterprise Manager或者Query Analyzer中列举服务;
Sql Server 配置设置
sql server2008可通过目录试图sys.confi gurations查看到68个配置项。我们可以通过is_advanced查找高级配置。执行sql语句:
SELECT * FROM sys.configurations WHERE is_advanced = 1;
GO
我们也可以通过属性窗口来设置配置项。如下图:
修改属性后必须执行RECONFIGURE命令才能让修改生效。属性分为动态和静态属性,如果是静态属性修改后必须重启数据库。通过is_dynamic属性查看属性是否是动态属性。例如:
SELECT * FROM sys.configurations WHERE is_dynamic = 1;
GO
用户连接数。如果用户连接数设置为0,数据动态调整并发的连接数。当数据库启动后,数据库为数据库用户连接建立一个指针队列按照设置的连接数。所以你不应该设置太大,每一个连接占用差不多28K内存,并且不管连接是否在用。也不能设置太小,这样经常出现连接数满的异常。必须注意的是,用户连接数并不是指连接的用户数,在一个应用中一个用户可以打开多个连接。因此,建议不设置该属性,让数据库动态分配。