事务处理
定义
没有特殊设置,每个SQL语句都被认为一个事务。
有特殊设置时,有 事务开始transaction,成功结束transaction,异常结束transaction。
成功的事务
begin transaction;
......
commit transaction
失败的事务
begin transaction
...
rollback transaction
ACID
Atomicity(原子性)
要么都执行,要么都放弃
Consistency(一致性)
从一个正确状态转换到另一个正确状态
Isolation(隔离性)
每个事务与其它并发事务互不影响
Durability(持久性)
结果持久有效
并发控制
数据竞争
当两个并发访问都是写,或者一个读一个写
可串行化
并行的结果与某个顺序的串行执行结果一致
这也是判断一组并行事务是否正确执行的标准
注意:只是一组并行事务。并不是说事务一定正确,事务可以有多种顺序。
数据冲突引起的问题
读脏数据
在T2 commit之前,T1读了T2已经修改了的数据。
不可重复读
在T2提交之前,T1写了T2已经读的数据。若T2两次读取同一个数据,会发现不一致。
更新丢失
在T2提交之前,T1重写了T2已经修改的数据
在T1提交之前,T2读取了已经被T1修改过的X=101,应当读取到T1修改之前的100或提交之后的数据。
在T2提交之前,T1读取了已经被T2修改过的Y=102,应当读取到T2修改之前的200或提交之后的数据。
原本T2想提交的Y是102,但是在提交之前Y被T1修改了,改成103提交了,导致T2之前做的更新丢失了。
T2读取到X为100,T1将X修改成了101,导致T2修改Y的时候,Y成了102,原本应该是根据读取到的100上增加1变成101。
并发控制锁
悲观锁
假设:数据竞争经常出现
采用机制保证数据竞争不会出现。
2阶段锁(集中加锁+集中解锁)
算法:
-
-
-
-
-
- 对每个需要访问的数据加锁
- 执行事务
- 在提交事务之前集中解锁
- Commit
-
-
-
-
实现方法:
-
-
-
-
-
- 使用不同的读写锁
- 使用不同的加锁粒度
-
-
-
-
死锁
最重要的条件:循环等待。
解决方法为死锁避免(如按顺序请求lock),死锁检测(周期性检查长时间等待的事务是否死锁,死锁了就放弃一个事务)
乐观锁
假设:数据竞争很少见
先执行,提交前检查是否有数据竞争。优点是冲突少时加锁的开销小,缺点是冲突多时,可能不断重试,浪费大量资源。
三阶段:读,验证,写
快照方式实现(某些情况下不是可串行的)
在开始时保存快照
读快照的数据,
改变后临时保存
提交时候比较有无写冲突。
崩溃恢复
事务日志
记录一个写操作的全部信息
写操作——事务日志记录。
commit——commit日志记录。
abort——abort日志记录。
日志特点是append-only的,只可追加,日志按照LSN(日志序列号)顺序添加,LSN递增。
Write-Ahead Logging
特点
先记录意向,在实际操作。
对于写操作,先logging,再执行写操作。
对于commit操作,先记录commit日志记录,再commit。
优点
因为只有存在日志记录,相应的操作才可能发生
好处是当出现断电的时候,可能根据日志发现所有写操作。若出现断电导致没有提交,会根据日志记录,对每个写操作检查和恢复。
开辟缓冲区的目的是减小IO开销
数据变更时操作顺序:变更内容记录 -> 预写日志缓冲区,更新后的数据 -> 数据缓冲区。
commit时操作顺序:预写日志缓冲区 -> Disk,数据缓冲区->硬盘
当提交时,若write+flush log buffer,会导致脏页被写回硬盘;断电后,硬盘上的数据已经修改,但是log没有记录
在页头部分记录本页最新的LSN,当Buffer Pool要替代写回一个页时,要保证此LSN之前的所有日志都已经被flush。
要保证日志记录一定是先于修改后的数据出现在硬盘。事务日志一定要先于实际数据出现在硬盘上。
检查点
作用:当崩溃时,使得时间可控,而不用读整个日志来恢复,只要从上一个检查点开始。
使用方法:定期执行检查点。
检查点内容:当前活动的事务表(事务的最新日志的LSN),当前脏页表(每个页最早的尚未协会Disk的LSN)。
Log Truncation
产生原因:因为日志文件不能无限增长。
作用:某个LSN之前的日志都不需要了,那么就可以删除LSN之前的所有Log。
什么时候该放弃日志文件:对应的事务完成,对应的写操作都在硬盘上。
但是有时候难以进行,因为可能某个page在buffer pool中经常被更新,很长时间没有写会回。此时LSN就等于 最早的尚未写回硬盘的LSN中最小的一个,在此之前的所有日志都可以丢弃。
崩溃恢复
分析:找最后一个检查点和日志崩溃点。确定是崩溃的时候活跃的事务和脏页。
Redo:将系统恢复到崩溃前瞬间的状态;找到所有脏页最早的LSN,从这个LSN向后读日志进行修正。数据页LSN>日志页LSN,可以跳过,应为数据比日志多,肯定数据也包含了修改。涉及的页不在脏页中也可以跳过。
Undo:清除未提交事务的修改。
介质故障恢复
单个Disk坏了就无法恢复,可以使用RAID(冗余盘阵列),为了避免RAID整个损坏,也用定期备份数据库。
数据仓库
什么是数据仓库
读取大量数据的分析操作(主要是数据分析)
数据仓库与事务处理的区别
数据仓库 事务处理
少量数据分析操作 vs 大量的并发事务
每个操作访问大量数据 vs 每个事务访问很少数据
分析操作以读取为主 vs 读写都可能
结构
OLAP(联机分析处理)
数据立方
二维
三维
多维度表示优势
适合对趋势的分析,从宏观到微观,从微观到宏观。
数据立方常用操作
rollup(上卷):在某个维度上求和,降维,从细粒度到粗粒度。
rowdown(下钻):对某个维度上求和的结果分解到求和前状态,增维,从粗粒度到细粒度。
slice(切片):单独截取某维度上一个值。
dice(切块):在多个维度上选择多个值。
切片: 切块:
行存储
结构
每个记录中把所有的列相邻地存放
优点
一个数据的多个列,一次IO可以读取到,适合OLTP
列存储
结构
每个列产生一个文件
优点
数据容易压缩,比行存储有更高的压缩比
缺点
若用到了一个表的多个列,拼接代价太大。
分布式数据库
系统架构
Shared memory:多核多芯片
Shared disk:多个主机连接相同的存储设备
Shared nothing:以太网连接的服务器集群。
Shared nothing架构
-
-
- coordinator运行前端产生并行的查询计划
- 每台worker服务器上都有后端,coordinator协调worker服务器执行
-
Shared nothing架构关键技术
Partitioning(划分)
数据分布在多台服务器上。划分方式通常为Horizontal Partitioning,也就是不同的数据分布在不同的服务器上。
Replication(备份)
提高可靠性,可并行读,但是为写带来了额外代价。
Horizontal Partitioning划分
可以使哈希划分到不同服务器上。machine ID = hash(key) % MachineNumber
也可以让每台服务器负责一个区间。所有区间不重叠。
分布式查询处理
并行执行
Filter和投影都可以并行执行,只需要将每个服务器的数据拿出来即可。但是Join没有那么简单。
分布式事务处理
2阶段提交
协调者向每个参与者发送query to commit消息,让参与者投票是否提交事务。
参与者根据本地情况回答 Yes or No
提交情况:当所有的回答都是yes,事务将被提交。协调者向所有参与者发送commit消息。协调者发回ackownladgment消息确认。
放弃情况:有一个回答是No,协调者向所有参与者发送abort消息通知放弃事务。
通讯问题解决方法
参考并行与分布式计算中分布式事务章节
标签:事务,LSN,T2,关系数据库,提交,日志,数据 From: https://www.cnblogs.com/RedNoseBo/p/17203435.html