数据持久化是还原的前提,没有数据的持久化,就无法还原内存优化表的数据,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:内存优化数据的持久化和还原的更多相关文章

  1. SQLServer2014内存优化表评测

    SQLServer2014内存优化表评测 分类: SQL内存表2014-06-20 11:49 1619人阅读 评论(11) 收藏 举报 目录(?)[-] SQLServer2014的使用基本要求 内 ...

  2. Android内存优化(二)解析Memory Monitor、Allocation Tracker和Heap Dump

    前言 要想做好内存优化工作,就要掌握两大部分的知识,一部分是知道并理解内存优化相关的原理,另一部分就是善于运用内存分析的工具.本篇就来介绍内存分析工具:Memory Monitor.Allocatio ...

  3. 内存泄漏 Memory Leaks 内存优化 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  4. Android内存优化(四)解析Memory Monitor、Allocation Tracker和Heap Dump

    相关文章 Android性能优化系列 Java虚拟机系列 前言 要想做好内存优化工作,就要掌握两大部分的知识,一部分是知道并理解内存优化相关的原理,另一部分就是善于运用内存分析的工具.本篇就来介绍内存 ...

  5. [WP8.1UI控件编程]Windows Phone大数据量网络图片列表的异步加载和内存优化

    11.2.4 大数据量网络图片列表的异步加载和内存优化 虚拟化技术可以让Windows Phone上的大数据量列表不必担心会一次性加载所有的数据,保证了UI的流程性.对于虚拟化的技术,我们不仅仅只是依 ...

  6. redis内存数据的持久化方式

    转: http://blog.csdn.net/wzqzhq/article/details/64920996 概述 Redis的强大性能很大程度上都是因为所有数据都是存储在内存中的,然而当Redis ...

  7. 使用内存映射文件MMF实现大数据量导出时的内存优化

    前言 导出功能几乎是所有应用系统必不可少功能,今天我们来谈一谈,如何使用内存映射文件MMF进行内存优化,本文重点介绍使用方法,相关原理可以参考文末的连接 实现 我们以单次导出一个excel举例(csv ...

  8. In-Memory:内存优化表的事务处理

    内存优化表(Memory-Optimized Table,简称MOT)使用乐观策略(optimistic approach)实现事务的并发控制,在读取MOT时,使用多行版本化(Multi-Row ve ...

  9. Sql server2014 内存优化表 本地编译存储过程

    参考文献:http://www.infoq.com/cn/news/2013/09/Compiled-Queries http://www.bianceng.cn/database/SQLServer ...

随机推荐

  1. Windows在结构objective C开发环境

    对于近期打算iPhone.iPod touch和iPad开发一些应用程序,所以.需要开始学习Objective C(苹果推出的类似C语言的开发语言).因为苹果的自我封闭的产业链发展模式(从芯片.机器. ...

  2. selenium2入门 断言失败自动截图 (四)

    一般web应用程序出错过后,会抛出异常.这个时候能截个图下来,当然是极好的. selenium自带了截图功能. //获取截图file File scrFile= ((TakesScreenshot)d ...

  3. PHP 12 :字符串的操作

    原文:PHP 12 :字符串的操作 本章介绍字符串的操作.之所以要把字符串单独拿出来讲,是因为字符串在每种语言里都是非常重要的.并且也是大家关心的.我们从以下几个方面介绍字符串: 字符串的表现形式. ...

  4. Asterisk 未来之路3.0_0004

    原文:Asterisk 未来之路3.0_0004 Asterisk Wiki   asterisk 的Wiki是很多启迪和困惑的发源地,另外一个最重要的VOIP知识库www.voip-info.org ...

  5. LinQ—扩展方法

    概述 本节主要解说扩展方法,涉及LinQ的详细知识不多. 扩展方法的描写叙述 .net framework为编程人员提供了非常多的类,非常多的方法,可是,不论.net framework在类中为我们提 ...

  6. Binder机制,从Java到C (8. ServiceManager in Native)

    在第三篇 Binder机制,从Java到C (3. ServiceManager in Java) 中,讲到ServiceManager的Stub端在Native,Proxy端在Java.实际上,还要 ...

  7. 应用facebook .net sdk

    1.本博客主要介绍如何应用facebook .net SDK,实现发帖.点赞.上传照片视频等功能,更多关于facebook API,请参考:https://developers.facebook.co ...

  8. android获取存储卡使用情况

    package com.aib.com; import java.io.File; import android.app.Activity; import android.os.Bundle; imp ...

  9. iOS制作Static Library(静态库),实现多工程的连编

    在iOS开发中,我们会发现一些偏底层或基础代码是直接可以复用的,当我们换一个项目,改变的只需要是偏上层的业务逻辑代码,所以我们可以把这部分基础代码制作为一个静态库static library,并不断扩 ...

  10. ios7学习之路七(隐藏虚拟键盘,解决键盘挡住UITextField问题)

    再正式开始之前,先来介绍一下IOS的键盘类型: 一.键盘风格 UIKit框架支持8种风格键盘 typedef enum { UIKeyboardTypeDefault, // 默认键盘:支持所有字符 ...