您的位置:时时app平台注册网站 > 彩世界网址 > 实验:SQL Server和VMware这对冤家或致命(1)

实验:SQL Server和VMware这对冤家或致命(1)

2019-10-11 01:15

从主机系统的角度来看,当SQL Server在虚拟机里面运行时,会发生什么情况呢?主机系统并不知道“安全沙箱”里面的内容。至于里面运行的是Windows、Linux还是另一款操作系统,主机系统一无所知。这就使得它完全不知道虚拟机里面的操作系统标记。因此,当虚拟机“请求”主机系统写入数据时,满足该请求的方式与普通的非SQL Server应用程序完全一样。写入操作非同步完成,使用高速缓存同样见图1)。

图片 1

0. SQL SERVER MEMORY
(1) SQL SERVER占用服务器内存的一部分,非SQL SERVER占用的内存,供操作系统及服务器上其他应用程序使用;
(2) SQL SERVER内存对象可分为两大类,图中仅标出Buffer Pool中的数据及日志缓存;

为了在Windows上实现这一机制,SQL Server为输入输出操作标上了WRITETHRU和NOBUFFERING这两个标记。SQL Server读取时,它使用自己的高速缓存来读取数据,而不使用操作系统的高速缓存。SQL Server写入时,它要求操作系统等到该操作完成。请注意:SQL Server将一切置于其掌控之下,根本不使用操作系统的高速缓存。这是SQL Server与其他应用程序之间的一个关键区别见图1)。

图片 2

(2) 如果手动开启了一个事务(BEGIN TRAN),则和开启隐式事务(SET IMPLICIT_TRANSACTIONS ON)一样,需要手动提交事务(COMMIT);

在本次试验中,我们使用WMPlayer 2.0.2.作为访客系统,使用Vista惠普作为主机系统。这个问题很有可能不影响ESX服务器,但是我们仍在等待VMware方面给予确认:ESX服务器完全尊重微软SQL Server在输入/输出方面的核心需求。

图片 3

0. 事务开始
(1) 所有DML语句必然是基于事务的,如果没有显式开启事务,即手动写下BEGIN TRAN,SQL Server则把每条语句作为一个事务,并自动提交事务。

图片 4 
图2

【数据恢复故障描述】
故障的虚拟化系统是 ESXi5.0,连接了多个LUN,其中一个1T的LUN上跑有7 台虚拟机,均为Windows Server 2003,管理员因为其它原因误删除了一台虚拟机,此台虚拟机上跑有SQL Server 2000 的数据库,此虚拟机上还存放一些重要的其它格式的数据文件。客户需要恢复此虚拟机上所有文件,并最好能让其正常启动和工作。
【数据恢复故障分析】
图片 5
ESX/ESXi的文件系统:VMFS 是VMWare公司研发的一种高性能文件系统并针对虚拟机这类重负荷工作进行性能优化,性能已接近裸设备的性能。同时顾虑到了虚拟机的备份、迁移,和满足于虚拟机中的分配精简模式的虚拟磁盘等各项事项。由于ESX/ESXi上的虚拟机及其它文件都是存储于VMFS文件系统中,而VMFS文件系统很少为人所知,也缺乏研究资料,造成ESX/ESXi出现数据事故后,很难恢复数据。
我们对VMFS文件系统的早期版本进行研究,目前已完全掌握了VMFS 3.x/5.x的底层结构,对于ESX/ESXi的VMFS损坏,误删除虚拟机,VMFS 跨区卷损坏,底层RAID损坏等VMFS文件系统的数据灾难恢复有着独到的技术和经验,已成功为数十家企业恢复了ESX/ESXi的数据。Frombyte Recovery For ESX 软件是目前世上唯一的一款对外发布的ESX/ESXi服务器的数据恢复软件。
【数据恢复过程】
此例恢复就是由Frombyte Recovery For ESX恢复完成,Frombyte Recovery For ESX 扫描出来的虚拟磁盘中明确给出了原来虚拟磁盘的大小、所属操作系统类型、原来虚拟磁盘的模式(厚/薄)、以及分配状态信息。附图中第一张图就是扫描出来的虚拟磁盘,有两个6GB 大小的虚拟磁盘的分配状态已标志为’NO’,说明这两个很有可能就是客户删除的虚拟机中的虚拟磁盘。 使用Frombyte Recovery For ESX恢复出这两个虚拟磁盘后(这两个虚拟磁盘分别为原系统的C盘和D盘。),传入本地的ESXi5.0 的服务器上,使用特殊手段让虚拟机正常加载传入的虚拟磁盘后,虚拟机已正常启动。
附图2、3 中就是在本地ESXi5.0上启动的客户的虚拟机。

不难发现,SQL SERVER的日志容易成为一个瓶颈(BOTTLENECK),因为在写的同时引入了读,即引入了竞争,而ORACLE用UNDO SEGMENT很好地避免了这个问题,REDO LOG永远只是在被串行写。

现在虚拟机变得越来越流行。它们常常用于在物理机上创建“安全沙箱”。管理员们可能会往这些虚拟机里面装入一些程序,偶尔会装入SQL Server。遗憾的是,将SQL Server装入到虚拟机里面可能会带来灾难!

SQL Server里如要改变这个默认行为,可以在会话里做如下设置,如果没有打开隐式事务,SQL Server会自动提交当前的DML语句,而打开后,需要手动COMMIT才会提交。

考虑到性能监视器工具只是每秒更新一次图表,只好人为减慢输入输出系统的速度,才能观察到其影响。如图所示,写入操作在虚拟机上完成后以垂直的绿线为分界点),物理机上仍然有写入操作。

 

我们不妨短暂回顾一下30年前的数据库状况。所有数据库在拥有存储过程、分区视图、XML及如今的所有其他附加功能之前,它们的一项关键特性是什么?自一开始,所有数据库MySQL等“玩具”数据库除外)都包括某种类型的预写式日志机制,以确保数据完整性。MS SQL中的LDF日志,甲骨文数据库中的Undo撤消)日志和redo重做)日志,它们都确保了执行COMMIT提交)语句后,保证数据保存起来。

也就是说SQL SERVER 默认不开启隐式事务,这点与ORACLE正好相反,ORACLE默认开启了隐式事务,每条DML语句或者语句块,都要手动commit才会提交。

这个区别会带来几个影响,既有好的影响,也有坏的影响。先来说说好的影响,性能监视器Perfmon)工具的数据显示,VMWare下的SQL Server运行起来常常速度更快见图2)!  

5. 刷新数据页
(1) SQL Server数据库遵循预写日志(WAL:Write-Ahead Logging)原则,因为关系型数据库是基于事务的,而日志正是事务ACID属性的保证,也是数据恢复的保证;
(2) 检查点(CHECKPOINT),检查点周期性地将脏页刷新到数据文件中,最终在日志文件打上检查点标记(CHECKPOINT),至此上面事务中修改的数据被正式写到磁盘上的数据文件中。

图片 6 
图1

图片 7
数据读写体系结构图

2.0.2.作为访客系统,使用Vista惠普作为主机系统。这个问题很有可能不影响ESX服务器,但是我们仍在等待V...

4. 事务结束
(1) 提交(COMMIT),此时将当前事务的脏日志刷新到数据库的日志文件中,并打上事务结束标记(COMMIT),脏页有可能暂未被刷新到数据文件;
事务日志结构如下(可通过log explorer等类似工具查看):
BEGIN TRAN
DML
COMMIT TRAN

这带来了不好的影响。请注意:COMMIT提交)语句在虚拟机上执行时,数据并没有送到输入输出系统。数据仅仅发送到了物理机。遗憾的是,SQL Server与VMWare一起运行时,停电等干扰因素会导致你丢失报告为“已提交”的事务数据。更为糟糕的是,万一出现这种干扰因素,高速缓存就会改变写入顺序,导致数据库被损坏!

一. 数据读写流程简要
SQL Server作为一个关系型数据库,自然也维持了事务的ACID特性,数据库的读写冲突由事务隔离级别控制。无论有没有显示开启事务,事务都是存在的。流程图如下:

图片 8
数据读写流程图

二. 数据读写流程深入
试想:
(1) 日志是不是一定要在COMMIT后才写到日志文件?如果有个很长很大的事务,那么提交日志时,日志从缓冲区被写入磁盘,岂不是要等很久?
(2) 数据是不是一定要在日志提交后,发生了CHECKPOINT,才写到数据文件?如果日志一直没提交,那么数据缓冲区岂不是很拥挤?

3. LAZY WRITER
(1) LAZY WRITER周期性扫描缓存(默认1s),维护自由页面(free page)列表,根据LRU算法将已刷新到磁盘的页释放;
(2) 如果是脏页,则Lazy Writer将脏页刷新到磁盘(这时事务可能还未提交),以最终将内存页释放并加入自由页面列表;

考虑到这2点,SQL Server还会通过Log Writer/Lazy Writer不定时的刷新日志/数据到磁盘,至于日志和数据的一致性,在启动或者数据库还原时,SQL Server会去做检查,也即是我们常说的前滚(REDO)和回滚(UNDO)。

2. 数据是否在内存
(1) 在内存中使用HASH算法查找数据,如果找到数据那么记为逻辑读;
(2) 如果数据页不在内存中,则需要从磁盘上的数据文件中,读取相应的数据页到内存中,即物理读,物理读也会被记数为逻辑读,也就是说无论内存中有没有数据,逻辑读是一定有的。

小结:可以发现,数据和日志被写入数据/日志文件,并不是同步的。有可能写入/提交了日志,数据没有写入磁盘;有可能写入了数据,事务未被提交;
(1) 针对有完整事务日志,数据未被写入磁盘的情况,启动/还原数据库时,SQL SERVER做前滚(REDO);
(2) 针对有数据写入数据文件,日志未完整提交的事务,启动/还原数据库时,SQL SERVER做回滚(UNDO)。

1. 事务结束
(1) 事务结束的前提是日志缓存成功写入到日志文件中,也就是说客户端收到COMMIT/ROLLBACK语句运行成功的消息时,日志已被成功写入日志文件(数据还不定是否被写入数据文件);
(2) 不过,日志缓存并不是一定要等到事务结束时才刷新到日志文件的;

3. 修改数据
(1) 在SQL SERVER内存的数据缓冲区中将数据页修改,此时数据页称为脏页(DIRTY PAGE);
(2) 在SQL SERVER内存的日志缓冲区中记录REDO LOG,姑且称为脏日志;

4. CHECKPOINT
(1) CHECKPOINT同LAZY WRITER一样也会刷新脏页到数据文件中(只刷新已提交的事务数据),但不会维护内存自由页面列表;
实验:SQL Server和VMware这对冤家或致命(1)。(2) 可以设置SP_CONFIGURE ‘RECOVERY INTERVAL’选项来改变CHECKPOINT发生的频率,默认为1分钟一次。

--开启隐式事务
SET IMPLICIT_TRANSACTIONS ON

--插入一条记录
CREATE TABLE TEST_TRAN(ID INT)
INSERT INTO TEST_TRAN VALUES(1)

--查看开启的事务
DBCC OPENTRAN()

2. LOG WRITER
(1) 当遇到长事务时,不必等到发出事务结束命令,LOG WRITER也会周期性地将脏日志刷新到日志文件,以保证用户发出COMMIT时快速响应以结束事务;
(2) 微软并没有公布SQL SERVER 除去COMMIT外,LOG WRITER将脏日志刷新到日志文件的周期,这里可以参考ORACLE的:每3秒,或者日志缓冲区1/3满;或者已经包含1M的脏日志;

1. 发起DML
(1) DML通常指的是:INSERT、DELETE、UPDATE;
(2) DDL语句最终是被转化为对系统表的DML,在SQL SERVER中DDL语句也可以被回滚,比如:CREATE/ALTER/DROP/TRUNCATE,在ORACLE里是不可以的,另外SQL Server中的DCL语句:DENY,REVOKE,也可以被回滚;

(2) 回滚(ROLLBACK),此时读REDO LOG得到反向DML操作,反向修改脏页,正向的DML 反向DML都会被记录在数据库的日志文件中,并打上事务结束标记(ROLLBACK),同样,脏页有可能暂未被刷新到数据文件;
事务日志结构如下:
BEGIN TRAN
DML
反向DML
ROLLBACK TRAN

本文由时时app平台注册网站发布于彩世界网址,转载请注明出处:实验:SQL Server和VMware这对冤家或致命(1)

关键词: