MyException - 我的异常网
当前位置:我的异常网» Sql Server » 内存中OLTP(Hekaton)里的事宜日志记录

内存中OLTP(Hekaton)里的事宜日志记录

www.MyException.Cn  网友分享于:2015-08-12  浏览:0次
内存中OLTP(Hekaton)里的事务日志记录

在今天的文章里,我想详细讨论下内存中OLTP里的事务日志如何写入事务日志。我们都知道,对于你的内存优化表(Memory Optimized Tables),内存中OLTP提供你2个持久性(durability)选项:

  • SCHEMA_ONLY
  • SCHEMA_AND_DATA

今天我不想更多讨论SCHEMA_ONLY,因为使用这个选项,在事务日志里没有发生任何日志(SQL Server 重启后你的数据会丢失)。今天我们会专门讲解下SCHEMA_AND_DATA选项的持久性。

SCHEMA_AND_DATA

使用SCHEMA_AND_DATA持久性选项,SQL Server必须记录你的事务到事务日志,因为每个内存中OLTP事务必须总是持久的。这个和传统基于硬盘表是一样的。但是内存中OLTP里写入事务日志比传统表更优化。内存中OLTP支持多个并发日志流(在SQL Server 2014里当前未实现),内存中OLTP只记录发生的逻辑事务(logical transaction)

逻辑事务是什么意思呢?假设你有5个非聚集索引定义的聚集表。如果你往表里插入1条记录,SQL Server必须记录插入到聚集索引,还有5个额外的插入非聚集索引。在你表上定义的非聚集索引越多,SQL Server需要的日志越多。而且SQL Server只能和事务日志一样快。

使用内存中OLTP事情就变了。内存中OLTP,SQL Server只记录在你事务里发生的逻辑修改。SQL Server对在你哈希或范围索引里的修改不记录。因此1条日志记录只描述发生的逻辑INSERT/UPDATE/DELETE语句。结果是,内存中OLTP写入更少的数据到你的事务日志,因此你的事务可以更快的提交。

我们来验证它!

我想用1个简单的例子向你展示下,当你首先插入10000条记录到传统基于硬盘表(Disk Based Table),然后插入内存优化表(Memory Optimized Table),SQL Server会有多少的数据写入你的事务日志。下列代码创建1个简单表,在while循环里插入10000条记录。然后我用sys.fn_dblog系统函数(未文档公开)来看事务日志。 

 1 -- Create a Disk Based table
 2 CREATE TABLE TestTable_DiskBased
 3 (
 4     Col1 INT NOT NULL PRIMARY KEY,
 5     Col2 VARCHAR(100) NOT NULL INDEX idx_Col2 NONCLUSTERED,
 6     Col3 VARCHAR(100) NOT NULL
 7 )
 8 GO
 9 
10 -- Insert 10000 records into the table
11 DECLARE @i INT = 0
12 
13 BEGIN TRANSACTION
14 WHILE (@i < 10000)
15 BEGIN
16     INSERT INTO TestTable_DiskBased VALUES (@i, @i, @i)
17 
18     SET @i += 1 
19 END
20 COMMIT
21 GO
22 
23 -- SQL Server logged more than 20000 log records, because we have 2 indexes
24 -- defined on the table (Clustered Index, Non-Clustered Index)
25 SELECT * FROM sys.fn_dblog(NULL, NULL)
26 WHERE PartitionId IN
27 (
28     SELECT partition_id FROM sys.partitions
29     WHERE object_id = OBJECT_ID('TestTable_DiskBased')
30 )
31 GO

从系统函数的输出你可以看到,你有比20000多一点的日志记录。这是正确的,因为我们在表上有2个索引定义(1个聚集索引,1个非聚集索引)。

现在我们来看下用内存优化表(Memory Optimized Table)日志记录有啥改变。下列代码展示了为内存中OLTP数据库必备工作:我们只加了1个新的内存优化文件组(Memory Optimized File Group),给它加了个容器:

 1 --Add MEMORY_OPTIMIZED_DATA filegroup to the database.
 2 ALTER DATABASE InMemoryOLTP
 3 ADD FILEGROUP InMemoryOLTPFileGroup CONTAINS MEMORY_OPTIMIZED_DATA
 4 GO
 5 
 6 USE InMemoryOLTP
 7 GO
 8 
 9 -- Add a new file to the previously created file group
10 ALTER DATABASE InMemoryOLTP ADD FILE
11 (
12     NAME = N'InMemoryOLTPContainer', 
13     FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\InMemoryOLTPContainer'
14 )
15 TO FILEGROUP [InMemoryOLTPFileGroup]
16 GO

下一步我创建了1个新的内存优化表(Memory Optimized Table)。这里我在哈希索引上选择了16384的桶数来避免哈希碰撞(hash collisions)的可能。另外我在Col2和Col3列上创建了2个范围索引(Range Indexes)。

 1 -- Creates a Memory Optimized table
 2 CREATE TABLE TestTable_MemoryOptimized
 3 (
 4     Col1 INT NOT NULL PRIMARY KEY NONCLUSTERED HASH WITH (BUCKET_COUNT = 16384),
 5     Col2 VARCHAR(100) COLLATE Latin1_General_100_Bin2 NOT NULL INDEX idx_Col2,
 6     Col3 VARCHAR(100) COLLATE Latin1_General_100_Bin2 NOT NULL INDEX idx_Col3
 7 ) WITH
 8 (
 9     MEMORY_OPTIMIZED = ON, 
10     DURABILITY = SCHEMA_AND_DATA
11 )
12 GO

在那个表上合计有3个索引(1个哈希索引(Hash Index)和2个范围索引(Range Indexes))。当你往表里插入10000条记录,传统表会生成近30000的日志记录——每个索引里每个插入1条日志。

 1 -- Copy out the highest 'Current LSN'
 2 SELECT * FROM sys.fn_dblog(NULL, NULL)
 3 GO
 4 
 5 -- Insert 10000 records into the table
 6 DECLARE @i INT = 0
 7 
 8 BEGIN TRANSACTION
 9 WHILE (@i < 10000)
10 BEGIN
11     INSERT INTO TestTable_MemoryOptimized VALUES (@i, @i, @i)
12 
13     SET @i += 1 
14 END
15 COMMIT
16 GO
17 
18 -- Just a few log records!
19 SELECT * FROM sys.fn_dblog(NULL, NULL)
20 WHERE [Current LSN] > '0000002f:000001c9:0032' -- Highest LSN from above
21 GO

但现在当你看事务日志时,你会看到10000条插入只生成了很少日志记录——这里是17条!

 魔法发生在LOP_HK日志记录里。在这个特定日志记录里,内存中OLTP捆绑了多个修改到你的内存优化表(Memory Optimized Table)。你也可以通过使用sys.fn_dblog_xtp系统函数分解LOP_HK日志记录: 

1 -- Let's look into a LOP_HK log record
2 SELECT * FROM sys.fn_dblog_xtp(NULL, NULL)
3 WHERE [Current LSN] > '0000002f:000001c9:0032' AND Operation = 'LOP_HK'
4 GO

从图中你可以看到,内存中OLTP只生成了近10000条LOP_HK日志记录——在这个表上发生的每个逻辑插入对应1条记录。 

小结

内存中OLTP提供你惊艳的性能提升,因为它是基于全新原理,例如MVCC和Lock-Free Data Structrues。另外它只生成少量事务日志记录,因为只有逻辑改变被记录写入事务日志。我希望这个文章已给你更好的理解:内存中OLTP如何提升你的事务日志吞吐量。

感谢关注!

文章评论

5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
代码女神横空出世
代码女神横空出世
程序员应该关注的一些事儿
程序员应该关注的一些事儿
程序员必看的十大电影
程序员必看的十大电影
编程语言是女人
编程语言是女人
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
程序员的鄙视链
程序员的鄙视链
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
如何成为一名黑客
如何成为一名黑客
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
中美印日四国程序员比较
中美印日四国程序员比较
Java程序员必看电影
Java程序员必看电影
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
每天工作4小时的程序员
每天工作4小时的程序员
总结2014中国互联网十大段子
总结2014中国互联网十大段子
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
鲜为人知的编程真相
鲜为人知的编程真相
漫画:程序员的工作
漫画:程序员的工作
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
老程序员的下场
老程序员的下场
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
程序员和编码员之间的区别
程序员和编码员之间的区别
我的丈夫是个程序员
我的丈夫是个程序员
旅行,写作,编程
旅行,写作,编程
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
程序员都该阅读的书
程序员都该阅读的书
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
我是如何打败拖延症的
我是如何打败拖延症的
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
 程序员的样子
程序员的样子
一个程序员的时间管理
一个程序员的时间管理
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
为什么程序员都是夜猫子
为什么程序员都是夜猫子
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有