首页 cmu 15-445

数据库停电了怎么办,内存是不会存储数据的

就算数据库停电,也要保证数据库的ACID

所以在没有停电的时候就要多做一些事情来防患于未然

任务:

  • failure classification 故障级别
  • buffer pool policies 缓冲池策略
  • shadow paging 影子页
  • write-ahead log WAL预写日志
  • logging schemes 日志的架构
  • checkpoints 检查点

failure classification

  • txn failures 事务级
  • system failures 系统级
  • storage media failures 存储介质的故障

txn failures

  • logical errors 逻辑错误,回滚
  • internal state errors 内部状态错误,死锁

这个级别的错误是必须要考虑的

system failures

  • software failures 数据库的bug
  • hardware failure 硬件故障 断电

也是要考虑的

storage media failures

  • non-repairable hardware failure 无法修复的故障

不用管,但是运维要管

我们要跟用户保证,只要commit,数据就不能丢

如果abort了,那这个事务就是没有发生一样

undo 撤销操作

redo 重做操作

首先,数据库要选择在commit时,数据库用不用讲数据从内存刷入磁盘中,而且刷的时候是刷整个tuple还是只刷新更新的数据

steal policy 是否会产生脏页

steal,可以刷脏页的

no-steal,不可以刷脏的

no-steal+force 非窃取+强制

先copy干净页,只修改自己的,然后刷进磁盘

优点好实现,没有redo和undo操作,缺点就是性能上的,数据过多会导致内存溢出(不能支持写的量大于内存量)

shadow page 影子页

要修改页拷贝一份,更新在拷贝页中,读写在新的拷贝页中做,边改边刷新进入磁盘,在commit时,修改指针,再垃圾回收操作

image-20220306150831469.png

undo实现就是删掉影子页,对影子页和磁盘中的拷贝页都当垃圾回收掉

redo是不需要实现的,只要commit之后,数据就固化了

优点是:中间操作可以刷入磁盘

问题是:刷的更频繁了,冗余操作太多了,commit时操作太多了,容易造成数据碎片化

WAL write-ahead log 预写日志,窃取非强制的

在磁盘中单开一个data file(日志文件),保持txn对数据的修改,我们假设日志文件是存在理想文件夹中的,日志本身有足够的信息支持undo和redo操作

数据库在将操作内容写入磁盘之前将修改内容写入日志中,当用户commit时

事务开始时写一个begin,提交的时候写一个commit,写commit日志的时候保证要讲所有的日志都刷入盘中

WAL 格式

  • txn id
  • object id 修改的数据是什么东西
  • before value 修改之前是什么
  • after value 修改之后是什么

UNDO 用before value实现

REDO 用after value实现,从磁盘上的日志写入磁盘中的数据存储位置

WAL例子,先写日志,再写数据,日志落入磁盘中,用户就可以退出来,真正的数据在内存中,但是数据库中数据还没有更新,具体什么时候更新是数据库的事情

image-20220306161343751.png

用户commit之前必须全部刷入磁盘中

优化:group commit,要减少用户提交次数,因为磁盘存取是很慢的

让多个用户的数据搞到一起提交,大家都等一等,但是不能让等太长时间,就算页没满就刷入磁盘,也不要让用户等太久

内存中的数据什么时候刷盘?

要运行性能而不要恢复性能

image-20220306163325576.png

logging schemes 本身格式

physical logging 物理日志,记录每一个页到二进制级别的变化

logical logging 逻辑日志,记录操作本身,sql语句

物理日志的改进:physiological logging,记录物理页的变化,记录页的槽的变化,

image-20220306164904015.png

checkpoints 存档点

什么时候存档,什么时候删档

到了存档点,之后

  • 没有落盘的log先落盘
  • 脏页落盘
  • 日志中写一个checkpoint

宕机之后,因为T2提交了,要对T2redo,T3执行了一部分但没有commit,要对T3undo

image-20220306170125465.png




文章评论