一、内存数据库出现的背景
在传统的数据库表中,由于磁盘的物理结构限制,OLTP类操作引起的随机查找会给IO系统带来高昂的开销,因此传统的表和索引的结构设计为使用B-Tree而尽量减少随机查找,但由于机械磁盘和数据库锁的存在,B-Tree结构在处理大并发的OLTP环境时就显得非常乏力,虽然有很多办法来解决这类问题,比如说乐观并发控制、应用程序缓存、分布式架构等,但采用上述方案会导致修改引用程序,这不仅成本高且风险极大。而随着这些年硬件的发展,现在服务器拥有几百G内存并不罕见,此外由于硬件NUMA架构的成熟,也消除了多CPU访问内存的瓶颈问题,因此具备了使用新方式来处理更大并发和数据量的条件,这种新的方式就是使用内存计算技术。
内存的学名叫做Random Access Memory(RAM),因此如其特性一样,是随机访问的,因此对于内存,随机查找不会引入额外开销,使用Hash-Index这样的数据结构更符合内存的特性,而对应并发的隔离方式也对应的变成了MVCC(多版本并发控制),从而消除了锁引入的性能瓶颈。因此内存数据库可以在同样的硬件资源下,处理更多的并发和请求,并且不会被锁阻塞,在SQL Server 2014中,集成了这个强大的内存数据引擎,如果结合SSD AS Buffer Pool特性,所产生的效果将会非常值得期待。
二、SQL Server内存数据库的组成和表现形式
在SQL Server 2014的内存数据库引擎由两部分组成:内存优化表和本地编译存储过程。虽然内存数据库集成进入关系数据库引擎,但访问内存数据库的方法对于客户端来说是透明的,这也意味着从客户端应用程序的角度来看,并不会知道内存数据库引擎的存在。如图1所示。
▲图1.客户端APP不会感知Hekaton引擎的存在
首先内存优化表完全不会再存在锁的概念(虽然之前的版本有快照隔离这个乐观并发控制的概念,但快照隔离仍然需要在修改数据的时候加锁),此外内存优化表Hash-Index结构使得随机读写的速度极大提高,内存优化表还可以设置为使用非持久化日志,既数据既不写日志,也不会CheckPoint到磁盘,从而极大的降低了IO压力(适合于ETL中间结果操作,或者其他允许丢失数据的场景),这样一来也可以消除写日志引入的性能瓶颈。
下面来创建一个内存优化表:
首先,内存优化表需要数据库中存在一个特殊的文件组,以供存储内存优化表的CheckPoint文件,与传统的mdf或ldf文件不同的是,该文件组是一个目录而不是一个文件,因为CheckPoint文件只会将新增的数据附加在到新的CheckPoint文件,而不会修改现有的CheckPoint文件,如图2所示。
▲图2.内存优化表所需的特殊文件组
下面再来看一下内存优化文件组在磁盘系统的存储形式,如图3所示。
▲图3.内存优化文件组
创建完内存优化文件组之后,接下来再创建一个内存优化表,如图4所示。
▲图4.创建内存优化表
目前SSMS还不支持UI界面创建内存优化表,因此只能通过T-SQL来创建内存优化表,如图5所示。
▲图5.使用代码创建内存优化表
这里创建一个简单的内存优化表,这里上述设置Hash Bucket为1024,目前SQL Server 2014还不支持动态的Hash Bucket,因此必须手动设置该值。表中设置了Memory_Optimized为ON意味着表是内存优化表,而Durability设置为Schema_And_Data则意味着内存优化表中数据也是持久化,这意味着除非启用了SQL Server 2014的延迟写特性,数据不会由于异常情况导致丢失。
当表创建好之后,就可以查询数据了,值得注意的是,查询内存优化表需要snapshot隔离等级或者hint,这个隔离等级与快照隔离是不同的,如图6所示。
▲图6.查询内存优化表需要加提示