第一次接触终极事务处理——Hekaton
在这篇文章里,我想给出如何与终极事务处理(Extreme Transaction Processing (XTP) )的第一次接触,即大家熟知的Hakaton。如果你想对XTP有个很好的概况认识,我推荐Kalen Delaney写的关于它的白皮书,中文版本点此下载,另外微软研究院也发布了题为“对于内存数据库的高性能并发控制机制(High-Performance Concurrency Control Mechanisms for Main-Memory Databases)”的研究白皮书,点此下载。
XTP明确为你指出:对于你的SQL Server数据库,在后台是存储在文件流(FILESTREAM) 文件组里。因此当你想要使用XTP,首先你要做的是,增加一个新的文件流(FILESTREAM) 文件组到你对应的数据库。新的文件组也必须标上MEMORY_OPTIMIZED_DATA属性。以下脚本请在64位系统里的SQL Server 2014里运行。
-- Create new database
CREATE DATABASE TestDatabase
GO --Add MEMORY_OPTIMIZED_DATA filegroup to the database.
ALTER DATABASE TestDatabase
ADD FILEGROUP XTPFileGroup CONTAINS MEMORY_OPTIMIZED_DATA
点击【数据库属性】【文件组】,可以看到【内存优化数据】。

在你创建新FILESTREAM文件组后,你还需要添加一个新的文件到这个文件组。
-- Add a new file to the previous created file group
ALTER DATABASE TestDatabase ADD FILE
(
NAME = N'HekatonFile1',
FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\HekatonFile1'
)
TO FILEGROUP [XTPFileGroup]
GO
在我们已经准备好用于XTP的数据库后,最后我们可以添加我们的内存优化表(Memory Optimized Table)——这个名字就是SQL Server所指的XTP表:

看到这个截屏,估计你很期待一个非常酷的表创建向导,但事实上我们只看到一个T-SQL脚本模板——没别啥东东。希望微软对此在后续版本会有所改进……下面是创建一个XTP表的必需脚本:
USE TestDatabase
-- Let's create a new Memory Optimized Table
CREATE TABLE TestTable
(
Col1 INT NOT NULL,
Col2 VARCHAR(100) NOT NULL,
Col3 VARCHAR(100) NOT NULL
CONSTRAINT chk_PrimaryKey PRIMARY KEY NONCLUSTERED HASH (Col1) WITH (BUCKET_COUNT = 1024)
) WITH (MEMORY_OPTIMIZED = ON)
GO

哎呀,报错了。因为俺们用的是中文版本的SQL Server 2014,排序规则是:Chinese_PRC_CI_AS

看来对中文字符的支持还不是很好,我们可以换用数据类型 nchar(n) 或 nvarchar(n)。
USE TestDatabase
-- Let's create a new Memory Optimized Table
CREATE TABLE TestTable
(
Col1 INT NOT NULL,
Col2 NVARCHAR(100) NOT NULL,
Col3 NVARCHAR(100) NOT NULL
CONSTRAINT chk_PrimaryKey PRIMARY KEY NONCLUSTERED HASH (Col1) WITH (BUCKET_COUNT = 1024)
) WITH (MEMORY_OPTIMIZED = ON)
GO
在XTP里额每个表都必须要有一个非聚集哈希索引(Non-Clustered Hash Index)的约束。聚集哈希索引(Clustered Hash Index)目前尚不支持。你还要用BUCKET_COUNT子句来指定桶数。最后你要为数据库标上MEMORY_OPTIMIZED。恭喜您,你已经创建了您的第一个内存优化表——这个一点都不难!
使用这个新表非常简单。我们来插入几条记录:
-- Let's insert a simple record into the new table
INSERT INTO TestTable (Col1, Col2, Col3) VALUES (1, 'Woody', 'Tu')
GO
但是XTP的真正威力是在处理并发用户的时候,因为没有锁/阻塞/封锁(Locking/Blocking/Latching)。连排它锁(Exclusive Locks (X) )也米有了。平常当我们在“普通”表上运行INSERT语句时,在表上会有IX锁,在数据页,在记录本身会有一个X锁。但在XTP里,这些锁全不见了。来看下面的查询:
-- Make an insert in an explicit transaction
BEGIN TRANSACTION INSERT INTO TestTable (Col1, Col2, Col3) VALUES (2, 'Smart', 'GZ') -- No IX, X locks anymore!
SELECT * FROM sys.dm_tran_locks
WHERE request_session_id = @@SPID COMMIT
GO

从sys.dm_tran_locks的输出结果可以看到,只有在表本身有一个模式稳定锁(Schema Stability Lock (Sch-S) ),但IX和X锁都消失了——非常酷!
当你运行刚才的脚本不马上提交事务:
BEGIN TRANSACTION INSERT INTO TestTable (Col1, Col2, Col3) VALUES (3, 'Cn', 'Blog')
你仍然可以从另外一个会话通过SELECT语句无锁的获得最新数据,在执行查询之前,我们在工具栏点击显示实际的执行计划:
SELECT * FROM dbo.TestTable


SQL Server在执行计划里使用了Index Scan (NonClusteredHash) 运算符。
在XTP之前,这个行为在数据库里只能通过启用乐观并发控制(Optimistic Concurrency)来建立——在SQL Server 2005后才引入了Read Committed Snapshot Isolation、Snapshot Isolation。
我们来试下UPDATE语句:
UPDATE TestTable SET Col2 = 'Test' WHERE Col1 = 1
GO

当我们看UPDATE执行计划时,除了Index Seek (NonClusteredHash)运算符,这里没啥特别的地方。因此XTP能扫描和查找哈希索引(Hash Indexes)。我们来试下显示事务里的UPDATE语句:
-- Let's try the UPDATE statement in an explicit transaction
BEGIN TRANSACTION UPDATE TestTable SET Col2 = 'Test' WHERE Col1 = 1 SELECT * FROM sys.dm_tran_locks
WHERE request_session_id = @@SPID COMMIT
GO
这一次,SQL Server给我们了下列错误信息:

因此当你使用显示事务时,我们要提示SQL Server。但是WITH (SNAPSHOT)和SNAPSHOT事务隔离级别(Transaction Isolation Level)不一样,因为当我更改隔离级别为SNAPSHOT,并尝试回滚事务时:
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
BEGIN TRANSACTION UPDATE TestTable SET Col2 = 'Test' WHERE Col1 = 1 ROLLBACK
我会收到如下的错误信息:

因此,我们给查询本身加上查询提示:
BEGIN TRANSACTION UPDATE TestTable WITH (SNAPSHOT) SET Col2 = 'Test' WHERE Col1 = 1 SELECT * FROM sys.dm_tran_locks
WHERE request_session_id = @@SPID COMMIT
GO

现在事务已经提交,sys.dm_tran_locks 再一次只显示了Sch-S锁。下一步我想做的是尝试并行执行2个UPDATE语句,但不提交第1个事务。因此我们在2个不同的会话执行下列语句,并确保2个事务都不提交。
BEGIN TRANSACTION UPDATE TestTable WITH (SNAPSHOT) SET Col2 = 'Test' WHERE Col1 = 1
没有XTP,第2个事务会阻塞,因为X锁正被第1个事务拿着:
很遗憾SQL Server在第2个会话里给我们下列的错误信息:

我们的执行进入更新冲突(Update Conflict),SQL Server回滚了第2个事务。我并没有料到这点,但我需要对此仔细思考下。
在当前SQL Server 2014 CTP1版本里,XTP提供给你的另一个东西叫做 本机编译的存储过程(Natively Compiled Stored Procedures):

又一次,没有向导,只有你要用到的T-SQL脚本模板。本机编译(Native Compilation)意味这SQL Server在后台将整个存储过程编译至C/C++代码——这个性能将会是卓越的,因为现在我们在SQL Server内部直接执行本机代码(native code)。下面脚本展示了一个简单的XTP存储过程是啥样的:
CREATE PROCEDURE HekatonProcedure
(
@Param INT
)
WITH NATIVE_COMPILATION, SCHEMABINDING, EXECUTE AS OWNER
AS
BEGIN
ATOMIC WITH
(
TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english'
) INSERT INTO dbo.TestTable (Col1, Col2, Col3) VALUES (@param, N'Woody', N'Tu') SELECT Col1, Col2, Col3 FROM dbo.TestTable
END
GO
有几个属性必须要知道:
- 存储过程必须用SCHEMABINDING和EXECUTE AS来创建;
- 存储过程必须标记为NATIVE_COMPILATION;
- 你必须指定ATOMIC代码块,这里设置事务隔离级别和所用语言。
当你完成存储过程创建后,你就可以执行它了:
EXEC HekatonProcedure 5
GO

因为现在你用的是本机代码,那就没有执行计划了!好好享受这执行速度……ALTER PROCEDURE也不支持了(没意义,因为是本地生成代码(native generated code)),意味如果你想修改这个存储过程的话,你还不能再次DROP和CREATE。
这是我第一次安装SQL Server 2014体验XTP的简短过程。更多的信息和内容,我定会在接下来的文章里和大家一起分享。请继续关注!
参考文章:
第一次接触终极事务处理——Hekaton的更多相关文章
- 终极事务处理(XTP,Hekaton)——万能大招?
在SQL Server 2014里,微软引入了终极事务处理(Extreme Transaction Processing),即大家熟知的Hekaton.我在网上围观了一些文档,写这篇文章,希望可以让大 ...
- [译]与TensorFlow的第一次接触(三)之聚类
转自 [译]与TensorFlow的第一次接触(三)之聚类 2016.08.09 16:58* 字数 4316 阅读 7916评论 5喜欢 18 前一章节中介绍的线性回归是一种监督学习算法,我们使用数 ...
- 第一次接触FPGA至今,总结的宝贵经验
从大学时代第一次接触FPGA至今已有10多年的时间,至今记得当初第一次在EDA实验平台上完成数字秒表.抢答器.密码锁等实验时那个兴奋劲.当时由于没有接触到HDL硬件描述语言,设计都是在MAX+plus ...
- Hybird App(一)----第一次接触
App你知道多少 一 什么是Native App 长处 缺点 二 什么是Web App 长处 缺点 三 什么是Hybrid App 长处 缺点 四 Web AppHybrid AppNative Ap ...
- 第一次接触C++------感触
2018/09/24 上大学第一次接触C++,感觉还挺有趣的. C语言是计算机的一门语言,顾名思义,语言嘛,有它自己独特的语法. 第一次用C++敲代码,觉得还挺不错的,可以从中找到乐趣.咏梅老师布置的 ...
- 孤荷凌寒自学python第五十天第一次接触NoSql数据库_Firebase
孤荷凌寒自学python第五十天第一次接触NoSql数据库_Firebase (完整学习过程屏幕记录视频地址在文末) 之前对关系型数据库的学习告一段落,虽然能力所限没有能够完全完成理想中的所有数据库操 ...
- 百度地图API的第一次接触
因为项目的需求,第一次接触了百度API. 第一步:引用百度地图API的脚本 如果在局域网环境中,要把地图文件和js文件都要下载下来 <script type="text/javascr ...
- 第一次接触数据库(SQLite)
第一次接触,学了创建列表 + 行的删除 + 内容的更改 + 删除列表 第一次接触要知道一些基本知识 NULL(SQL) = Nnoe(python) #空值 INTEGER = int #整数 R ...
- 今天第一次接触到typescript,看了第一个知识点就是变量的声明,来回忆回忆,做做笔记
以前只用过JavaScript原生写网站特效,今天还是第一次听说typescript的,然后看了一下它的基本知识,感觉很像Java,真的太像了,但是又有不同点.很让我惊奇看到的第一个知识点就和以前不同 ...
随机推荐
- jQuery选择器和选取方法
我们已经使用了带有简单Css选择器的jQuery选取函数:$().现在是时候深入了解jQuery选择器语法,以及一些提取和扩充选中元素集的方法了. 一.jQuery选择器 在CSS3选择器标淮 ...
- GTD时间管理(3)---时间特区图
最近在网上看到一副时间特区图,想象非常深,特点想分享给大家. 从上图可以看出 说明一个人全天的状况 说明: 全天时段 状态 7:30-8:00 是处于起床,穿衣,刷牙,吃早餐 8:00-9:00 是处 ...
- Android 源码获取-----在Windows环境下通过Git得到Android源代码
在学习Android的过程中,深入其源代码研究对我们来说是非常重要的,这里将介绍如何通过在Windows环境下使用Git来得到我们的Android源代码. 1.首先确保你电脑上安装了Git,这个通过 ...
- SQL Server死锁
SQL Server死锁 多个事务之间互相等待对方的资源,导致这些事务永久等待 注意是永久等待,而非长事务 死锁的4个条件 互斥条件(Mutual exclusion):资源不能被共享,只能由一个进程 ...
- Oracle Essbase入门系列(四)
成员存储类型 除了大纲计算,维度成员的另一项重要属性是存储类型,存储类型决定维度成员相关单元格的物理存储方式.在维库中编辑成员的[Data Storage]属性,下拉菜单中可选的5种,再加上Share ...
- Enclosure POJ
0:Enclosure http://poj.openjudge.cn/challenge3/0/ 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 131072kB 描述 为了防止 ...
- webpack处理非模块化的几方法
webpack处理非模块化文件有几方法,主要分为外链和webpack打包二种情况: 一.使用CDN外部链接的方法 官网文档External: https://webpack.github.io/doc ...
- ooofc.com域名备案问题导致无法正常访问临时解决方案
各位尊敬的easyradius用户: 由于临时收到ooofc.coom域名备案被删除的消息,之后ooofc.com就无法访问.导致用户无法访问控制台oa.ooofc.com,及用户中心user.ooo ...
- github 使用记录
安装客户端tortoiseGit 是服务端,要想在自己电脑上使用git我们还需要一个git客户端,我这里选用TortoiseGit,他给我们提供了图形界面的操作.在安装之前首先需要安装git,下载地址 ...
- LoadRunner性能测试结果分析
LoadRunner性能测试结果分析http://www.docin.com/p-793607435.html