SQLServer存储引擎——01.数据库如何读写数据
一、引言
在SQL Server数据库中,数据是如何被读写的?日志里都有些什么?和数据页之间是什么关系?数据页又是如何存放数据的?索引又是用来干嘛的?
一起看看SQL Server的存储引擎。
二、SQL Server的存储引擎
大致分为以下几部分:
1. 数据库如何读写数据
2. 内存
3. 日志
4. 数据
5. 索引的结构和分类
6.索引的遍历和维护
下面一 一详细介绍:
1. 数据库如何读写数据
1.1. 数据读写流程简要
SQL Server作为一个关系型的数据库,自然也维持了事务的ACID特性,数据库的读写冲突由事务的隔离级别控制。无论有没有显式开启事务,事务都是存在的。
(1)事务开始
(1.1)所有DML语句必然是基于事务的,如果没有显式开启事务(即手动写下begin tran),则事务处理的最小单位是每一条DML语句,并自动提交事务。
(1.2)如果手动开启一个事务(begin tran),或开启隐式事务(set implicit_transactions on),才需要手动提交事务(commit tran),否则SQL Server自动提交事务。
(2)发起DML
(2.1)DML语句包括:insert、delete、update;
(2.2)DDL语句最终是被转化为对系统表的DML,在SQL SERVER中DDL语句也可以被回滚,比如:CREATE/ALTER/DROP/TRUNCATE,在ORACLE里是不可以的,另外SQL Server中的DCL语句:DENY,REVOKE,也可以被回滚;
(3)数据是否在内存
(3.1)在内存中使用hash算法查找数据,如果找到记为逻辑读;
(3.2)如果数据页不在内存中,则需要从磁盘上的数据文件中,读取相应的数据页到内存中,即物理读,物理读也会被记数为逻辑读,也就是说无论内存中有没有数据,逻辑读是一定有的。
(4)修改数据
(4.1)在SQL Server内存的数据缓冲区中将数据页修改,此时数据页称为脏页(Dirty Page);
(4.2)在SQL Server内存的日志缓冲区中记录REDO LOG,暂称为脏日志;
(5)事务结束
(5.1)提交(COMMIT),此时将当前事务的脏日志刷新到数据库的日志文件中,并打上事务结束标记(COMMIT),脏页有可能暂未被刷新到数据文件中;
事务日志结构如下(可通过log explorer等工具查看)
BEGIN TRAN
DML
COMMIT TRAN
(5.2)回滚(ROLLBACK),此时读REDO LOG得到反向DML操作,反向修改脏页,正向DML 与 反向DML都会被记录在数据库的日志文件中,并打上事务结束标记(ROLLBACK),同样,脏页有可能暂未被刷新到数据文件;
事务日志结构如下:
BEGIN TRAN
DML
反向DML
ROLLBACK TRAN
不难发现,SQL SERVER的日志容易成为一个瓶颈,因为在写的同时引入了读,即引入了竞争,而ORACLE用UNDO SEGMENT很好地避免了这个问题,REDO LOG永远只是在被串行写。
(6)刷新数据页
(6.1)SQL Server数据库遵循预写日志(WAL:Write-Ahead Logging)原则,因为关系型数据库是基于事务的,而日志正是事务ACID特性的保证,也是数据恢复的保证。
(6.2)检查点(Checkpoint),检查点周期性的将脏页刷新到数据库的数据文件中,最终在日志文件上打上检查点标记(Checkpoint),至此上面事务中修改的数据被正式写入 到磁盘上的数据文件中。
-------------------------------------------------------------------------------------------------------------------------------
1.2 数据读写流程深入
试想:
(1) 日志是不是一定要在COMMIT后才写到日志文件?如果有个很长很大的事务,那么提交日志时,日志从缓冲区被写入磁盘,岂不是要等很久?
(2) 数据是不是一定要在日志提交后,发生了CHECKPOINT,才写到数据文件?如果日志一直没提交,那么数据缓冲区岂不是很拥挤?
考虑到这2点,SQL Server还会通过Log Writer/Lazy Writer不定时的刷新日志/数据到磁盘,至于日志和数据的一致性,在启动或者数据库还原时,SQL Server会去做检查,也即是我们常说的前滚(REDO)和回滚(UNDO)。
(1)SQL SERVER MEMORY
(1.1) SQL SERVER 占用服务器内存的一部分,非SQL SERVER 占用的内存,供操作系统及服务器上的其他应用程序使用;
(1.2) SQL SERVER 内存结构可分为两大块,关于内存结构参见下面说的内存部分,图中仅标出Buffer Pool中的数据及日志缓存;
(2) 事务结束
(2.1)事务结束的前提是日志缓存成功写入到日志文件中,此时,数据库才会返回事务结束的响应。也就是说客户端收到COMMIT/ROLLBACK语句运行成功的消息时,日志已被成功写入日志文件(数据还不定是否被写入数据文件);
(2.2)日志缓存并不是一定要等到事务结束时才刷新到日志文件的。
(3) LOG WRITER
(3.1)当遇到长事务时,不必等到发出事务结束命令,LOG WRITER也会周期性地将脏日志刷新到日志文件,以保证用户发出COMMIt时快速响应并结束;
(3.2)微软公司并没有公布SQL SERVER除去COMMIT外,LOG WRITER将脏日志刷新到日志文件的周期,这里可以参考ORACLE的,每3秒;或者日志缓冲区1/3满;或者包含1M的脏日志。
(4) LAZY WRITER
(4.1)LAZY WRITER周期性扫描缓存(默认1s),维护自由页面列表(free page),根据LRU算法将已刷新到磁盘的页释放;
(4.2)如果是脏页则刷新到磁盘(这时事务可能还未提交),同样也是先将日志刷新到日志文件中,然后再将脏页刷新到数据文件中,最终内存页释放并加入自由页面列表;
(5)CHECKPOINT
(5.1)CHECKPOINT同LAZY WRITER一样也会刷新脏页到数据文件中(只刷新已提交的事务数据),但不会维护内存自由页面列表;
(5.2)可以设置SP_CONFIGURE ‘RECOVERY INTERVAL’选项来改变CHECKPOINT发生的频率,默认为1分钟一次。
小结:可以发现,数据和日志被写入数据/日志文件,并不是同步的。有可能写入/提交了日志,数据没有写入磁盘;有可能写入了数据,事务未被提交;
(1) 针对有完整事务日志,数据未被写入磁盘的情况,启动/还原数据库时,SQL SERVER做前滚(REDO);
(2) 针对有数据写入数据文件,日志未完整提交的事务,启动/还原数据库时,SQL SERVER做回滚(UNDO)。
SQLServer存储引擎——01.数据库如何读写数据的更多相关文章
- SQLServer存储引擎——03.日志
3. SQLServer存储引擎之日志篇 (3.1)日志结构 (3.1.1)物理日志 (0)物理日志即数据库的.ldf文件, 当然后缀名是可以自定义的,默认是.ldf (1)一个SqlServer数据 ...
- SQLServer存储引擎——02.内存
SQLServer存储引擎之内存篇: (1)SQL SERVER 内存结构 SQL SERVER 内存结构简图 SQL SERVER 内存空间主要可分为两部分: (1.1)可执行代码(E ...
- SQLServer存储引擎——05.索引的结构和分类
5. SQLServer存储引擎——索引的结构和分类 关系型数据库中以二维表来表达关系模型,表中的数据以页的形式存储在磁盘上,在SQL SERVER中,数据页是磁盘上8k的连续空间,那么,一个表的所有 ...
- mysql数据库 myisam数据存储引擎 表由于索引和数据导致的表损坏 的修复 和检查
一.mysqlcheck 进行表的检查和修复 1.检查mysqlisam存储引擎表的状态 #mysqlcheck -uuser -ppassword database table -c #检查单 ...
- SQLServer存储引擎——04.数据
4. SQL SERVER存储引擎之数据篇 (4.1)文件 (0)主数据文件.mdf初始文件大小至少为3MB,次要数据文件.ndf初始大小,同日志文件一样至少为512KB: (1)SQL SERVER ...
- Android数据存储引擎---SQLite数据库
目标:是否可以在PC端桌面上使用SQLite数据库制作一个财务文件? 目录: 来源: 实践: 总结和比较: SQLite数据简介 是什么,内部结构是怎样的,数据库和表的关系是什么 有什么用 常用的操作 ...
- Learning-MySQL【2】:MySQL存储引擎及数据库的操作管理
一.存储引擎 存储引擎实际上就是如何存储数据.如何为存储的数据建立索引和如何更新.查询数据.存储引擎也可以称为表类型. MySQL提供了插件式(pluggable)的存储引擎,存储引擎是基于表的.同一 ...
- MySQL存储引擎及数据库的操作管理
一.存储引擎 存储引擎实际上就是如何存储数据.如何为存储的数据建立索引和如何更新.查询数据.存储引擎也可以称为表类型. MySQL提供了插件式(pluggable)的存储引擎,存储引擎是基于表的.同一 ...
- 使用SQL-Server分区表功能提高数据库的读写性能
首先祝大家新年快乐,身体健康,万事如意. 一般来说一个系统最先出现瓶颈的点很可能是数据库.比如我们的生产系统并发量很高在跑一段时间后,数据库中某些表的数据量会越来越大.海量的数据会严重影响数据库的读写 ...
随机推荐
- 2、Monkey简单使用
1.使用Monkey测试,前提是有虚拟机或者真机设备,查看是否有设备存在:adb devices (需要先进入SDK的tool目录下才执行该操作) 2.查看设备上各个包名 adb shell pm l ...
- 蓝桥杯 算法训练 ALGO-126 水仙花
算法训练 水仙花 时间限制:1.0s 内存限制:256.0MB 水仙花数 问题描述 判断给定的三位数是否 水仙花 数.所谓 水仙花 数是指其值等于它本身 每位数字立方和的数.例 153 就是一 ...
- 蓝桥杯 基础练习 BASIC-22 FJ的字符串
基础练习 FJ的字符串 时间限制:1.0s 内存限制:512.0MB 问题描述 FJ在沙盘上写了这样一些字符串: A1 = “A” A2 = “ABA” A3 = “ABACABA” A4 = ...
- Java基础--注解Annotation
Annotation是给类,方法或域上加的一种特殊的标记,可以通过反射取到注解的类型和值,从而完成某种特定的操作. 定义注解需要使用元注解,元注解有@Retention和@Target //@Rete ...
- VS编译linux项目生成静态库并在另一个项目中静态链接的方法
VS2017也推出很久了,在单位的时候写linux的服务端程序只能用vim,这让用惯了IDE的我很难受. 加上想自己撸一套linux上的轮子,决定用VS开工远程编写调试linux程序. 在window ...
- 机器学习:模型泛化(岭回归:Ridge Regression)
一.基础理解 模型正则化(Regularization) # 有多种操作方差,岭回归只是其中一种方式: 功能:通过限制超参数大小,解决过拟合或者模型含有的巨大的方差误差的问题: 影响拟合曲线的两个因子 ...
- 网络监控之一:ss(Socket Statistics)
ss是Socket Statistics的缩写. 顾名思义,ss命令可以用来获取socket统计信息,它可以显示和netstat类似的内容.但ss的优势在于它能够显示更多更详细的有关TCP和连接状态的 ...
- Idea编译器 报@Override错误
据说这是jdk的问题,@Override是JDK5就已经有了,但有个小小的Bug,就是不支持对接口的实现,认为这不是Override 而JDK6修正了这个Bug,无论是对父类的方法覆盖还是对接口的实现 ...
- BigDecimal的equals与compareTo
equals方法的话会不仅会比较值的大小,还会比较两个对象的精确度, compareTo方法则不会比较精确度,只比较数值的大小
- python中not的用法
python中的not具体表示是什么: 在python中not是逻辑判断词,用于布尔型True和False,not True为False,not False为True,以下是几个常用的not的用法: ...