In-Memory:内存优化数据的持久化和还原

本文涉及的产品
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS SQL Server,基础系列 2核4GB
日志服务 SLS,月写入数据量 50GB 1个月
简介:

数据持久化是还原的前提,没有数据的持久化,就无法还原内存优化表的数据,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







本文转自悦光阴博客园博客,原文链接:http://www.cnblogs.com/ljhdo/p/5146423.html,如需转载请自行联系原作者
相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
2月前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
|
4天前
|
缓存 NoSQL 算法
14)Redis 在内存用完时会怎么办?如何处理已过期的数据?
14)Redis 在内存用完时会怎么办?如何处理已过期的数据?
9 0
|
5天前
|
存储 弹性计算 网络协议
阿里云ECS内存型实例规格族特点、适用场景、指标数据参考
阿里云ECS提供了多样化的内存型实例规格族,专为需要高性能内存资源的应用场景设计。从最新的r8a系列到经过优化的re6p系列,旨在提供稳定、高效且安全的计算环境。这些实例不仅具备强大的计算性能与内存配比,还通过支持ESSD云盘和高效网络协议,显著提升了存储I/O能力和网络带宽,适用于大数据分析、高性能数据库、内存密集型应用等多种场景,为用户带来卓越的计算体验。本文将详细解析阿里云ECS中的多个内存型实例规格族,包括它们的核心特点、适用场景、实例规格及具体指标数据,为用户在云计算资源选型时提供参考。
|
2月前
|
编译器 C++
virtual类的使用方法问题之C++类中的非静态数据成员是进行内存对齐的如何解决
virtual类的使用方法问题之C++类中的非静态数据成员是进行内存对齐的如何解决
|
2月前
|
存储 算法 大数据
小米教你:2GB内存搞定20亿数据的高效算法
你好,我是小米。本文介绍如何在2GB内存中找出20亿个整数里出现次数最多的数。通过将数据用哈希函数分至16个小文件,每份独立计数后选出频次最高的数,最终比对得出结果。这种方法有效解决大数据下的内存限制问题,并可应用于更广泛的场景。欢迎关注我的公众号“软件求生”,获取更多技术分享!
150 12
|
2月前
内存的数据
va的ava的va的ava的内存需要划分成为5个部分: 1.栈(Stack)存放的都是方法中的局部变量。方法的运行一定要在栈当中运行。 2.堆(Heap)凡是new出来的东西,都是在堆当中 堆内存的东西都有一个地址值:16进制 堆内存的数据,都有默认值。规则: 整数 默认是0 浮点 默认0.0 字符 默认'\u0000'
32 3
|
3月前
|
缓存 NoSQL Redis
Redis性能优化问题之当Redis内存达到maxmemory后,淘汰数据的逻辑是怎样的
Redis性能优化问题之当Redis内存达到maxmemory后,淘汰数据的逻辑是怎样的
|
2月前
|
C++ 容器
curl使用小记(三)——获取远端数据到内存缓冲区
curl使用小记(三)——获取远端数据到内存缓冲区
43 0
|
2月前
|
存储 编译器 C语言
数据在内存中的存储
数据在内存中的存储
|
3月前
|
存储 安全 Java
Java面试题:如何在Java应用中实现有效的内存优化?在多线程环境下,如何确保数据的线程安全?如何设计并实现一个基于ExecutorService的任务处理流程?
Java面试题:如何在Java应用中实现有效的内存优化?在多线程环境下,如何确保数据的线程安全?如何设计并实现一个基于ExecutorService的任务处理流程?
40 0

热门文章

最新文章

下一篇
无影云桌面