In-Memory:内存优化数据的持久化和还原
数据持久化是还原的前提,没有数据的持久化,就无法还原内存优化表的数据,SQL Server In-Memory OLTP的内存数据能够持久化存储,这意味着内存数据能够在SQL Server实例重启之后自动还原。在创建持久化的内存优化表时,必须设置选项:memory_optimized=on,durability=schema_and_data。内存优化表的持久化由两个进程实现:Checkpoint和事务日志记录,在服务器重启之后,SQL Server通过存储在磁盘上的事务日志和Checkpoint数据,能够将内存优化表还原到任意一个事务一致性的时间点。Checkpoint进程用于将数据更新写入CheckPoint文件,缩短数据还原的时间;将数据更新写入事务日志文件实现事务的持久化存储,由于任何已经提交的数据更新都被持久化存储,因此,内存数据库通过Checkpoint和事务日志,能够将数据写入到持久化存储设备,实现数据持久化,并能通过已存储的数据还原内存优化表。
一,数据持久化的特性
流(Stream)是数据的Bytes流,以Append-Only方式写入数据,这意味着,流写入文件只能在流的末尾写入数据。内存优化表的Checkpoint流和事务日志流都是流写入文件,流写入方式的特点是写入速度极快,减少了持久化数据的时间延迟。SQL Server通过把内存优化表的Checkpoint数据流和事务日志流写入Disk,实现数据的持久化存储。
日志流是在执行数据行版本的更新(插入和删除)操作时,由已经提交的事务更新产生的Log Records,事务日志流有如下特性:
- 事务日志写入到事务日志文件(.ldf)中;
- 和硬盘表(Disk-based Table)不同的是,内存优化表的事务日志经过优化,减少日志记录的数量,只存储已提交的事务日志,用于事务的redo操作,不存储undo的事务日志;
- 在事务提交时,产生事务日志,只记录插入和删除的行版本事务;
- 不记录内存优化表的Index Operation的事务日志,除了Columnstore Index的压缩阶段;所有的Index都在还原时重新创建;
Checkpoint数据流由三部分组成:
- Data Stream包含插入操作的行版本数据;
- Delta Stream包含删除操作的行版本数据;
- LOB流(Large Data Stream)包含创建ColumnStore Index时,对LOB Column进行压缩的数据;
内存优化表数据存储在一个单独的FileGroup中,在该FileGroup下创建的File实际上是一个Directory或Container,用于存储Checkpoint流文件;Checkpoint流文件在文件尾端顺序写入新的数据;在SQL Server中,Checkpoint文件以 FileStream方式存储,由SQL Server负责管理文件的创建,删除和归并。
二,事务日志的优化
内存优化表产生的事务日志经过优化,减少了日志记录的数量和写入次数。SQL Server只将最小数量的日志写入到事务日志文件(.ldf)中,这体现在,事务日志只执行Redo操作,不记录undo事务;SQL Server把一组事务日志合并,在一个大的Log Record中包含多条更新操作,减少了日志写入的次数。
1,事务日志文件只能执行Redo操作,不记录undo事务
SQL Server对于内存内存优化表,只将已提交事务更新写入事务日志文件,这样,行版本的插入和删除操作都被写入到磁盘文件中,用于执行事务的redo操作,还原数据库。由于日志记录在事务提交时产生,未提交的事务日志没有不会产生日志记录,事务日志文件也不会记录undo事务,这就减少日志记录的数量。
2,合并事务日志,在一个Log Record中包含多个数据更新操作
对于内存优化表事务,SQL Server不使用预写日志机制(WAL,Write-Ahead Logging),日志记录只在事务提交时产生。对于WAL,SQL Server在将数据更新写入Disk之前,先将Log Record写入到事务日志文件;在Checkpoint事件发生时,SQL Server会将尚未提交的事务日志写入到事务日志文件中;对于内存优化表,未提交的日志记录永远不可能写入到磁盘,这是对日志记录的一个优化;此外,内存优化对多个数据更新分组,在一个log record中记录多条数据更新操作,这样做,既减少了事务日志的总体大小和管理开销,也减少事务日志的写入次数。
三,Checkpoint进程
对于硬盘表(Disk-Based Table),Checkpoint操作的作用是减少数据库还原的时间,保持事务日志中活动事务尽可能少;对于持久化的内存优化表,Checkpoint进程的作用是使数据更新被持久化写入到磁盘,这样,在服务器重启时,SQL Server能够利用存储在Disk上的数据还原内存优化表。在查询处理的过程中,事务不会去读取Disk上的数据,Disk上的数据只有一个作用,就是当服务器重启时,将数据填充到内存中,还原内存优化表。
Checkpoint进程的特点:
- 持续性(Continuous):Checkpoint 关联的IO操作随着日志活动积累而持续增加;
- 流IO(Streaming I/O):Checkpoint文件使用流写入方式,将数据顺序写入到文件的末尾;
Checkpoint进程同时作用在硬盘表和内存优化表上,执行Checkpoint操作的方式有两种:
- 手动执行Checkpoint操作:在SSMS中显式执行checkpoint命令,SQL Server同时对硬盘表(Disk-Based Table)和内存优化表(Memory-Optimized Table)执行Checkpoint操作;
- 自动执行Checkpoint操作:从上一次Checkpoint事件结束后,如果事务日志的Size增长大约1.5GB,那么SQL Server执行一次Checkpoint操作;事务日志的增长用于记录新的Log Records,在事务对硬盘表和内存优化表执行更新操作产生的日志记录;有可能,Checkpoint事件完全是由硬盘表数据的更新触发的;
四,Checkpoint 文件
SQL Server将Checkpoint数据存储在四种类型的文件中,分别是Data文件,Delta文件,Large Object文件和Root文件,这些文件存储在Checkpoint文件的Container中,这个Container实际上是一个包含Memory_Optimized_Data的FileGroup的"File"。在第一次创建内存优化表时,SQL Server预先创建16个不同大小的空闲文件(Free Files),大小是2MB的N次方,最小8MB,最大1GB,这些文件的初始State是PreCreated。当需要使用文件时,SQL Server从Free Files集合中获取一个大小适当的Free File,将文件的状态由PreCreated转换为适当的State。如果文件的State是PreCreated,文件的类型是Free。
1,初始文件的大小
在初始状态下,SQL Server为每个文件类型至少创建3个足够大小的Free files,共12个Free Files,每个文件类型的初始大小取决于跟服务器的配置,不同文件的初始大小如图:
2,Data/Delta文件对
Data 文件 和 Delta 文件是最主要的Checkpoint文件,包含了对内存优化表执行操作的所有更新操作的信息。由于它们总是成对出现,称作data/delta文件对,也称作CFP(Checkpoint File Pair),CFP只会在文件末尾顺序写入新的数据,即以Append-Only方式写入数据,唯一的区别是写入的行版本数据不同:
- Data 文件只存储数据行的插入版本,在执行Insert 和Update操作时,会产生插入版本数据;
- Delta文件只存储数据行的插入版本,在执行Delete和Update操作,会产生删除版本数据;
Data文件和Delta文件都会覆盖一定的时间戳范围,从begin timestamp开始的所有行版本数据都包含在相同的Data文件和Delta文件中,在还原阶段,从Data文件中读取数据,同时,从Delta文件读取数据,用于从Data文件中过滤数据行,避免将已经删除的行版本重新加载到内存中。由于data文件和delta文件是1:1对应的,数据还原的最小单位是data/delta文件对,不同的data/delta文件对能够并发处理。
3,LOB文件和Root文件
Large Data 文件用于存储LOB Column的数据值,或者ColumnStore Index的行组(RowGroup)内容,如果没有LOB column或 Columnstore Index,SQL Server仍然会预先创建Large Data文件,但是,这些文件将保持FREE状态。
Root文件用于追踪Checkpoint事件,每当发生Checkpoint事件时,一个新的Active root 文件将会被创建。
4,Checkpoint文件的状态
Checkpoint 文件的5种状态分别是:PRECREATED,UNDER CONSTRUCTION,ACTIVE,MERGE TARGET和WAITING FOR LOG TRUNCATION。SQL Server预先创建12个Free Files,初始状态是PreCreated。在使用这些文件时,SQL Server将文件的状态转换为Under Construction 或 Merge Target,文件状态的转换过程如下图:
通过DMV:sys.dm_db_xtp_checkpoint_files (Transact-SQL) 查看Checkpoint文件的State和类型。
五,Checkpoint文件的归并和删除
每次Checkpoint操作发生时,Checkpoint文件都会增加,然而,随着时间的积累,内存优化表插入越来越多的行版本,越来越多的行版本被删除,导致Data 文件和Delta文件记录的数据量越来越多,使得读取Data/Delta文件对的时间消耗越来越大,这会严重影响数据库还原操作,增加还原的时间。
解决该问题的方案是把时间戳范围相邻的,未删除数据行比例低于指定阈值的多个Checkpoint文件归并到一个新的Checkpoint文件对中。例如,有两个Data文件,DF1和DF2,它们的timestamp范围相邻,并且未被删除的数据行比例低于指定阈值,把这两个文件合并成一个新的data文件,DF3,该文件的时间戳范围覆盖原始文件DF1和DF2,是DF1和DF2时间戳范围的并集;在做数据归并时,核对数据文件DF1和DF2对应的delta文件,从DF1和DF2中删除所有被标记为Delted的行版本,使DF3中只存储Inserted的行版本数据,在归并结束后,DF3对应的delta文件是空的。
1,自动归并(Merge)
Checkpoin文件对归并操作是自动进行的,SQL Server内部创建一个后台进程,周期性地检查所有的Data/Delta文件对,将能够归并的Checkpoint文件对划分到一个集合中,使每个集合包含两个或多个时间戳范围连续的data/delta文件对,位于相同集合中的多个文件对必须能够存储在单个128MB的Data文件中,归并的策略如下表所示:
如果两个时间戳范围相邻的数据文件60%是满的(60% Full,40%的数据行是deleted的),那么它们不会被Merge,每个Checkpoint文件中40%的空间将不会被使用。因此,持久化的内存优化表占用的总磁盘空间,比内存优化数据实际占用的存储空间要大。在最差的情况下,实际占用的磁盘空间是内存优化数据的两倍。
2,自动垃圾回收(Garbage Collection)
一旦Mege操作完成,原始的Checkpoint文件对将不再使用,转换到 WAITING FOR LOG TRUNCATION 状态,只要相应的事务日志被截断,那么垃圾回收进程就开始执行清理操作,物理删除不再使用的Checkpoint文件对。在一个Checkpoint文件对删除之前,SQL Server必须保证这些文件不再被使用;垃圾回收进程是自动执行的,不需要任何干预,事务日志的截断发生的时机是:
- 备份事务日志:进行事务日志备份时,将截断事务日志文件;
- 数据库处于auto_truncate模式:事务日志文件只记录活动事务的日志,一旦事务完成,将自动截断;
六,内存优化表的还原
在SQL Server实例重启时,SQL Server 以并发执行的方式还原内存优化表和硬盘表数据。每一个data文件存储的是插入的行版本数据,但是插入的行版本数据受到delta文件的过滤,每一个delta文件中存储不需要从对应的data文件加载的数据行。SQL Server对每一个data/delta文件对进行优化配置,使数据加载进程能够在多个IO流(IO Steam)中并发执行,每一个IO流都能单独处理一个data/delta文件对,多个IO流同时加载数据,提高数据还原的速度。
每一个内存数据库都仅有一个包含Memory_Optimized_Data的文件组(FileGroup),在该FileGroup下创建的每一个File,叫做一个Container,主要用于存储data/delta文件对,SQL Server为每一个Container创建一个delta-map,映射每一个Data 文件中被Delta 文件过滤的数据,这样,被删除的数据就不会重新插入到内存优化表中。还原操作是流并发的,在对Container下的所有Data/Delta文件对进行流处理时,SQL Server将数据加载任务分配给所有的CPU内核,根据delta-map,并发式处理Data/Delta文件对。
一旦Checkpoint 文件加载完成,SQL Server开始读取尾事务日志,从上一次Checkpoing结束的时间戳(timestamp)开始,重新执行事务日志中记录的Insert和Delete操作,等到所有的事务日志重新执行完成,数据库就还原到服务器停机的时刻,或备份操作开始的时间。在SQL Server 2016中,事务日志的读取和Redo操作是并发执行的,所以,数据和事务日志都是并发操作,数据还原的过程是非常快的。
参考文档:
SQL Server In-Memory OLTP Internals for SQL Server 2016
In-Memory:内存优化数据的持久化和还原的更多相关文章
- SQLServer2014内存优化表评测
SQLServer2014内存优化表评测 分类: SQL内存表2014-06-20 11:49 1619人阅读 评论(11) 收藏 举报 目录(?)[-] SQLServer2014的使用基本要求 内 ...
- Android内存优化(二)解析Memory Monitor、Allocation Tracker和Heap Dump
前言 要想做好内存优化工作,就要掌握两大部分的知识,一部分是知道并理解内存优化相关的原理,另一部分就是善于运用内存分析的工具.本篇就来介绍内存分析工具:Memory Monitor.Allocatio ...
- 内存泄漏 Memory Leaks 内存优化 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- Android内存优化(四)解析Memory Monitor、Allocation Tracker和Heap Dump
相关文章 Android性能优化系列 Java虚拟机系列 前言 要想做好内存优化工作,就要掌握两大部分的知识,一部分是知道并理解内存优化相关的原理,另一部分就是善于运用内存分析的工具.本篇就来介绍内存 ...
- [WP8.1UI控件编程]Windows Phone大数据量网络图片列表的异步加载和内存优化
11.2.4 大数据量网络图片列表的异步加载和内存优化 虚拟化技术可以让Windows Phone上的大数据量列表不必担心会一次性加载所有的数据,保证了UI的流程性.对于虚拟化的技术,我们不仅仅只是依 ...
- redis内存数据的持久化方式
转: http://blog.csdn.net/wzqzhq/article/details/64920996 概述 Redis的强大性能很大程度上都是因为所有数据都是存储在内存中的,然而当Redis ...
- 使用内存映射文件MMF实现大数据量导出时的内存优化
前言 导出功能几乎是所有应用系统必不可少功能,今天我们来谈一谈,如何使用内存映射文件MMF进行内存优化,本文重点介绍使用方法,相关原理可以参考文末的连接 实现 我们以单次导出一个excel举例(csv ...
- In-Memory:内存优化表的事务处理
内存优化表(Memory-Optimized Table,简称MOT)使用乐观策略(optimistic approach)实现事务的并发控制,在读取MOT时,使用多行版本化(Multi-Row ve ...
- Sql server2014 内存优化表 本地编译存储过程
参考文献:http://www.infoq.com/cn/news/2013/09/Compiled-Queries http://www.bianceng.cn/database/SQLServer ...
随机推荐
- Windows在结构objective C开发环境
对于近期打算iPhone.iPod touch和iPad开发一些应用程序,所以.需要开始学习Objective C(苹果推出的类似C语言的开发语言).因为苹果的自我封闭的产业链发展模式(从芯片.机器. ...
- selenium2入门 断言失败自动截图 (四)
一般web应用程序出错过后,会抛出异常.这个时候能截个图下来,当然是极好的. selenium自带了截图功能. //获取截图file File scrFile= ((TakesScreenshot)d ...
- PHP 12 :字符串的操作
原文:PHP 12 :字符串的操作 本章介绍字符串的操作.之所以要把字符串单独拿出来讲,是因为字符串在每种语言里都是非常重要的.并且也是大家关心的.我们从以下几个方面介绍字符串: 字符串的表现形式. ...
- Asterisk 未来之路3.0_0004
原文:Asterisk 未来之路3.0_0004 Asterisk Wiki asterisk 的Wiki是很多启迪和困惑的发源地,另外一个最重要的VOIP知识库www.voip-info.org ...
- LinQ—扩展方法
概述 本节主要解说扩展方法,涉及LinQ的详细知识不多. 扩展方法的描写叙述 .net framework为编程人员提供了非常多的类,非常多的方法,可是,不论.net framework在类中为我们提 ...
- Binder机制,从Java到C (8. ServiceManager in Native)
在第三篇 Binder机制,从Java到C (3. ServiceManager in Java) 中,讲到ServiceManager的Stub端在Native,Proxy端在Java.实际上,还要 ...
- 应用facebook .net sdk
1.本博客主要介绍如何应用facebook .net SDK,实现发帖.点赞.上传照片视频等功能,更多关于facebook API,请参考:https://developers.facebook.co ...
- android获取存储卡使用情况
package com.aib.com; import java.io.File; import android.app.Activity; import android.os.Bundle; imp ...
- iOS制作Static Library(静态库),实现多工程的连编
在iOS开发中,我们会发现一些偏底层或基础代码是直接可以复用的,当我们换一个项目,改变的只需要是偏上层的业务逻辑代码,所以我们可以把这部分基础代码制作为一个静态库static library,并不断扩 ...
- ios7学习之路七(隐藏虚拟键盘,解决键盘挡住UITextField问题)
再正式开始之前,先来介绍一下IOS的键盘类型: 一.键盘风格 UIKit框架支持8种风格键盘 typedef enum { UIKeyboardTypeDefault, // 默认键盘:支持所有字符 ...