第一次接触终极事务处理——Hekaton

本文涉及的产品
云数据库 RDS SQL Server,独享型 2核4GB
简介:

在这篇文章里,我想给出如何与终极事务处理(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里运行。

复制代码
1 -- Create new database
2 CREATE DATABASE TestDatabase
3 GO
4 
5 --Add MEMORY_OPTIMIZED_DATA filegroup to the database.
6 ALTER DATABASE TestDatabase
7 ADD FILEGROUP XTPFileGroup CONTAINS MEMORY_OPTIMIZED_DATA
复制代码

 点击【数据库属性】【文件组】,可以看到【内存优化数据】。

 在你创建新FILESTREAM文件组后,你还需要添加一个新的文件到这个文件组。

复制代码
1 -- Add a new file to the previous created file group
2 ALTER DATABASE TestDatabase ADD FILE
3 (
4    NAME = N'HekatonFile1',
5    FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\HekatonFile1'
6 )
7 TO FILEGROUP [XTPFileGroup]
8 GO
复制代码

在我们已经准备好用于XTP的数据库后,最后我们可以添加我们的内存优化表(Memory Optimized Table)——这个名字就是SQL Server所指的XTP表:

 看到这个截屏,估计你很期待一个非常酷的表创建向导,但事实上我们只看到一个T-SQL脚本模板——没别啥东东。希望微软对此在后续版本会有所改进……下面是创建一个XTP表的必需脚本:

复制代码
 1 USE TestDatabase
 2 -- Let's create a new Memory Optimized Table
 3 CREATE TABLE TestTable
 4 (
 5    Col1 INT NOT NULL,
 6    Col2 VARCHAR(100) NOT NULL,
 7    Col3 VARCHAR(100) NOT NULL
 8    CONSTRAINT chk_PrimaryKey PRIMARY KEY NONCLUSTERED HASH (Col1) WITH (BUCKET_COUNT = 1024)
 9 ) WITH (MEMORY_OPTIMIZED = ON)
10 GO
复制代码

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

看来对中文字符的支持还不是很好,我们可以换用数据类型 nchar(n) 或 nvarchar(n)。

复制代码
 1 USE TestDatabase
 2 -- Let's create a new Memory Optimized Table
 3 CREATE TABLE TestTable
 4 (
 5    Col1 INT NOT NULL,
 6    Col2 NVARCHAR(100) NOT NULL,
 7    Col3 NVARCHAR(100) NOT NULL
 8    CONSTRAINT chk_PrimaryKey PRIMARY KEY NONCLUSTERED HASH (Col1) WITH (BUCKET_COUNT = 1024)
 9 ) WITH (MEMORY_OPTIMIZED = ON)
10 GO
复制代码

在XTP里额每个表都必须要有一个非聚集哈希索引(Non-Clustered Hash Index)的约束。聚集哈希索引(Clustered Hash Index)目前尚不支持。你还要用BUCKET_COUNT子句来指定桶数。最后你要为数据库标上MEMORY_OPTIMIZED。恭喜您,你已经创建了您的第一个内存优化表——这个一点都不难!

使用这个新表非常简单。我们来插入几条记录:

1 -- Let's insert a simple record into the new table
2 INSERT INTO TestTable (Col1, Col2, Col3) VALUES (1, 'Woody', 'Tu')
3 GO

但是XTP的真正威力是在处理并发用户的时候,因为没有锁/阻塞/封锁(Locking/Blocking/Latching)。连排它锁(Exclusive Locks (X) )也米有了。平常当我们在“普通”表上运行INSERT语句时,在表上会有IX锁,在数据页,在记录本身会有一个X锁。但在XTP里,这些锁全不见了。来看下面的查询: 

复制代码
 1 -- Make an insert in an explicit transaction
 2 BEGIN TRANSACTION
 3 
 4 INSERT INTO TestTable (Col1, Col2, Col3) VALUES (2, 'Smart', 'GZ')
 5 
 6 -- No IX, X locks anymore!
 7 SELECT * FROM sys.dm_tran_locks
 8 WHERE request_session_id = @@SPID
 9 
10 COMMIT
11 GO
复制代码

sys.dm_tran_locks的输出结果可以看到,只有在表本身有一个模式稳定锁(Schema Stability Lock (Sch-S) ),但IX和X锁都消失了——非常酷!

当你运行刚才的脚本不马上提交事务:

1 BEGIN TRANSACTION
2 
3 INSERT INTO TestTable (Col1, Col2, Col3) VALUES (3, 'Cn', 'Blog')

你仍然可以从另外一个会话通过SELECT语句无锁的获得最新数据,在执行查询之前,我们在工具栏点击显示实际的执行计划:

1 SELECT * FROM dbo.TestTable

 

SQL Server在执行计划里使用了Index Scan (NonClusteredHash) 运算符。

在XTP之前,这个行为在数据库里只能通过启用乐观并发控制(Optimistic Concurrency)来建立——在SQL Server 2005后才引入了Read Committed Snapshot IsolationSnapshot Isolation

我们来试下UPDATE语句:

1 UPDATE TestTable SET Col2 = 'Test' WHERE Col1 = 1
2 GO

当我们看UPDATE执行计划时,除了Index Seek (NonClusteredHash)运算符,这里没啥特别的地方。因此XTP能扫描和查找哈希索引(Hash Indexes)。我们来试下显示事务里的UPDATE语句:

复制代码
 1 -- Let's try the UPDATE statement in an explicit transaction
 2 BEGIN TRANSACTION
 3 
 4 UPDATE TestTable SET Col2 = 'Test' WHERE Col1 = 1
 5 
 6 SELECT * FROM sys.dm_tran_locks
 7 WHERE request_session_id = @@SPID
 8 
 9 COMMIT
10 GO
复制代码

这一次,SQL Server给我们了下列错误信息:

因此当你使用显示事务时,我们要提示SQL Server。但是WITH (SNAPSHOT)SNAPSHOT事务隔离级别(Transaction Isolation Level)不一样,因为当我更改隔离级别为SNAPSHOT,并尝试回滚事务时:

复制代码
1 SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
2 BEGIN TRANSACTION
3 
4 UPDATE TestTable  SET Col2 = 'Test' WHERE Col1 = 1
5 
6 ROLLBACK 
复制代码

我会收到如下的错误信息:

 

因此,我们给查询本身加上查询提示:

复制代码
1 BEGIN TRANSACTION
2 
3 UPDATE TestTable WITH (SNAPSHOT) SET Col2 = 'Test' WHERE Col1 = 1
4 
5 SELECT * FROM sys.dm_tran_locks
6 WHERE request_session_id = @@SPID
7 
8 COMMIT
9 GO
复制代码

现在事务已经提交,sys.dm_tran_locks 再一次只显示了Sch-S锁。下一步我想做的是尝试并行执行2个UPDATE语句,但不提交第1个事务。因此我们在2个不同的会话执行下列语句,并确保2个事务都不提交。

1 BEGIN TRANSACTION
2 
3 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存储过程是啥样的:

复制代码
 1 CREATE PROCEDURE HekatonProcedure
 2 (
 3    @Param INT
 4 )
 5 WITH NATIVE_COMPILATION, SCHEMABINDING, EXECUTE AS OWNER
 6 AS
 7 BEGIN
 8    ATOMIC WITH
 9    (
10       TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english'
11    )
12 
13    INSERT INTO dbo.TestTable (Col1, Col2, Col3) VALUES (@param, N'Woody', N'Tu')
14 
15    SELECT Col1, Col2, Col3 FROM dbo.TestTable
16 END
17 GO
复制代码

有几个属性必须要知道:

  • 存储过程必须用SCHEMABINDINGEXECUTE AS来创建;
  • 存储过程必须标记为NATIVE_COMPILATION
  • 你必须指定ATOMIC代码块,这里设置事务隔离级别和所用语言。

当你完成存储过程创建后,你就可以执行它了:

1 EXEC HekatonProcedure 5
2 GO

因为现在你用的是本机代码,那就没有执行计划了!好好享受这执行速度……ALTER PROCEDURE也不支持了(没意义,因为是本地生成代码(native generated code)),意味如果你想修改这个存储过程的话,你还不能再次DROPCREATE



本文转自Woodytu博客园博客,原文链接:http://www.cnblogs.com/woodytu/p/4603293.html,如需转载请自行联系原作者

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
相关文章
|
3月前
|
消息中间件 Dubbo 应用服务中间件
分布式事物【Hmily实现TCC分布式事务、Hmily实现TCC事务、最终一致性分布式事务解决方案】(七)-全面详解(学习总结---从入门到深化)
分布式事物【Hmily实现TCC分布式事务、Hmily实现TCC事务、最终一致性分布式事务解决方案】(七)-全面详解(学习总结---从入门到深化)
83 0
|
Dubbo 应用服务中间件 微服务
分布式事物【Hmily实现TCC分布式事务、Hmily实现TCC事务、最终一致性分布式事务解决方案】(七)-全面详解(学习总结---从入门到深化)(上)
分布式事物【Hmily实现TCC分布式事务、Hmily实现TCC事务、最终一致性分布式事务解决方案】(七)-全面详解(学习总结---从入门到深化)
47 1
|
2月前
|
存储 Java 应用服务中间件
【分布式技术专题】「架构实践于案例分析」盘点互联网应用服务中常用分布式事务(刚性事务和柔性事务)的原理和方案
【分布式技术专题】「架构实践于案例分析」盘点互联网应用服务中常用分布式事务(刚性事务和柔性事务)的原理和方案
54 0
|
4月前
|
消息中间件 RocketMQ 微服务
分布式事物【Hmily实现TCC分布式事务、Hmily实现TCC事务、最终一致性分布式事务解决方案】(七)-全面详解(学习总结---从入门到深化)(下)
分布式事物【Hmily实现TCC分布式事务、Hmily实现TCC事务、最终一致性分布式事务解决方案】(七)-全面详解(学习总结---从入门到深化)
53 1
|
12月前
|
存储 SQL 缓存
滴滴滴,请看MYSQL事务的四大特征(ACID)的实现原理:晓其原理而通其实现。
滴滴滴,请看MYSQL事务的四大特征(ACID)的实现原理:晓其原理而通其实现。
|
SQL 关系型数据库 MySQL
数据库的事务四大特性&&隔离级别总结(面试高频)
数据库的事务四大特性&&隔离级别总结(面试高频)
175 0
|
存储 SQL 关系型数据库
步步为营,剖析事务中最难的——隔离性
步步为营,剖析事务中最难的——隔离性
112 0
步步为营,剖析事务中最难的——隔离性
|
关系型数据库 MySQL 测试技术
软件测试mysql面试题:事物的四大特性(ACID)介绍一下?
软件测试mysql面试题:事物的四大特性(ACID)介绍一下?
97 0
|
缓存 NoSQL Java
让人头痛的大事务问题到底要如何解决?
让人头痛的大事务问题到底要如何解决?
让人头痛的大事务问题到底要如何解决?
|
存储 负载均衡 前端开发
一口气说出 4 种分布式一致性 Session 实现方式,面试杠杠的~(上)
阿粉公司有一个 Web 管理系统,使用 Tomcat 进行部署。由于是后台管理系统,所有的网页都需要登录授权之后才能进行相应的操作。 起初这个系统的用的人也不多,为了节省资源,这个系统仅仅只是单机部署。后来随着用的人越来越多,单机已经有点扛不住了,于是阿粉决定再部署了一台机器。
一口气说出 4 种分布式一致性 Session 实现方式,面试杠杠的~(上)