原文筆記

本課程筆記資料庫系統 · 30 篇
数据库补充习题 70+100 复习索引cs/db/100+70/00-复习索引Day 01 - 数据库100题:单项选择 1-20cs/db/100+70/Day01-数据库100题-选择01-20Day 02 - 数据库100题:单项选择 21-40cs/db/100+70/Day02-数据库100题-选择21-40Day 03 - 数据库100题:单选 41-50,填空 51-60cs/db/100+70/Day03-数据库100题-选择41-50填空51-60Day 04 - 数据库100题:填空 61-80cs/db/100+70/Day04-数据库100题-填空61-80Day 05 - 数据库100题:填空 81-100cs/db/100+70/Day05-数据库100题-填空81-100Day 06 - 数据库70题:试题 1-11cs/db/100+70/Day06-数据库70题-试题01-11Day 07 - 数据库70题:试题 12-25cs/db/100+70/Day07-数据库70题-试题12-25Day 08 - 数据库70题:综合题 1-8cs/db/100+70/Day08-数据库70题-综合01-08Day 09 - 数据库70题:综合题 22-33cs/db/100+70/Day09-数据库70题-综合22-33Day 10 - 数据库70题:综合题 37-47cs/db/100+70/Day10-数据库70题-综合37-47Day 11 - 数据库70题:综合题 48-61cs/db/100+70/Day11-数据库70题-综合48-61Day 12 - 数据库70题:综合题 62-71cs/db/100+70/Day12-数据库70题-综合62-71基础概念与题型全文cs/db/notes/01-基础概念与题型全文SQL语句与数据库操作全文cs/db/notes/02-SQL语句与数据库操作全文数据库编程全文cs/db/notes/03-数据库编程全文数据库设计与规范化全文cs/db/notes/04-数据库设计与规范化全文查询优化、恢复、并发控制全文cs/db/notes/05-查询优化恢复并发控制全文数据库规范化流程cs/db/notes/normalization2025-2026-2 计科数据库系统期末cs/db/pastpapers/25-26cs2024-2025-2 计科数据库系统期末cs/db/pastpapers/db-pastpaper-1数据库系统完整讲义总览与考试题型地图cs/db/tutorial/00-总览与考试题型地图01 数据库基础与关系模型cs/db/tutorial/01-数据库基础与关系模型02 SQL 与关系代数cs/db/tutorial/02-SQL与关系代数03 数据库编程专项:存储过程、触发器、游标、嵌入式 SQLcs/db/tutorial/03-数据库编程专项04 数据库设计、E-R 图与规范化cs/db/tutorial/04-数据库设计ER与规范化05 查询优化专项:关系代数、查询树、优化树cs/db/tutorial/05-查询优化专项06 事务、并发控制与数据库恢复cs/db/tutorial/06-事务并发控制与恢复07 填空选择速记清单cs/db/tutorial/07-填空选择速记清单08 大题答题模板cs/db/tutorial/08-大题答题模板

06 事务、并发控制与数据库恢复

这一章对应选择填空、简答、检查点恢复大题、封锁协议大题。

一、事务与 ACID

事务是用户定义的一个数据库操作序列,是 DBMS 的基本工作单位。事务要么全部成功,要么全部失败。

ACID:

  • 原子性 Atomicity:事务中所有操作要么都做,要么都不做。
  • 一致性 Consistency:事务使数据库从一个一致状态转变到另一个一致状态。
  • 隔离性 Isolation:并发事务之间相互隔离,不应互相干扰。
  • 持久性 Durability:事务一旦提交,对数据库的改变就是永久的。

实现子系统:

  • 原子性、持久性主要由恢复子系统保证。
  • 隔离性主要由并发控制子系统保证。
  • 一致性由完整性约束、并发控制和恢复共同保证。

二、并发操作异常

不加控制的并发可能产生:

  1. 丢失修改:两个事务都修改同一数据,后写覆盖前写。
  2. 读脏数据:一个事务读取了另一个事务未提交且后来回滚的数据。
  3. 不可重复读:同一事务两次读同一数据,中间被其他事务修改并提交,结果不同。
  4. 幻读:同一事务按条件两次查询,第二次出现了其他事务新插入的满足条件的行。

“脏数据”严格说是未提交后又被撤销的数据。

三、锁

基本封锁类型:

  • S 锁,共享锁,读锁。事务对数据加 S 锁后,可以读,不能写;其他事务可再加 S 锁,不能加 X 锁。
  • X 锁,排他锁,写锁。事务对数据加 X 锁后,可以读写;其他事务不能再加 S 锁或 X 锁。

兼容矩阵:

        已有 S   已有 X
请求 S   兼容    不兼容
请求 X   不兼容  不兼容

如果事务 T 获得数据项 Q 上的 X 锁,则 T 对 Q 既可读又可写;其他事务既不能读也不能写。

四、封锁协议

一级封锁协议:

  • 修改数据前必须加 X 锁,事务结束释放。
  • 可防止丢失修改。

二级封锁协议:

  • 在一级基础上,读数据前必须加 S 锁,读完即可释放。
  • 可防止读脏数据。

三级封锁协议:

  • 在一级基础上,读数据前必须加 S 锁,并保持到事务结束。
  • 可防止不可重复读。

两阶段封锁协议 2PL:

  • 加锁阶段:可以申请锁,不能释放锁。
  • 解锁阶段:一旦释放任何锁,就不能再申请新锁。

结论:

  • 遵守两阶段封锁协议可保证冲突可串行化。
  • 两阶段封锁协议不能保证不死锁,反而可能死锁。

五、两阶段封锁例题

题目:

T1:
read(A);
read(B);
if A = 0 then B := B + 1;
write(B);

T2:
read(B);
read(A);
if B = 0 then A := A + 1;
write(A);

一种满足 2PL 的写法:

T1:
SLock(A);
XLock(B);
read(A);
read(B);
if A = 0 then B := B + 1;
write(B);
Unlock(A);
Unlock(B);

T2:
SLock(B);
XLock(A);
read(B);
read(A);
if B = 0 then A := A + 1;
write(A);
Unlock(B);
Unlock(A);

是否可能死锁:可能。若 T1 持有 A 的 S 锁等待 B 的 X 锁,T2 持有 B 的 S 锁等待 A 的 X 锁,则互相等待。

避免死锁的常用方法:

  • 一次封锁法:事务开始前一次申请所有锁。
  • 顺序封锁法:所有事务按统一顺序申请锁。
  • 死锁检测与解除:构造等待图,发现环后撤销某事务。
  • 超时法:等待超过阈值就回滚。

避免活锁:先来先服务。

六、数据库故障类型

常见四类故障:

  1. 事务故障:事务内部错误、违反约束、死锁被撤销等。
  2. 系统故障:断电、操作系统崩溃,内存丢失,外存数据库未物理损坏。
  3. 介质故障:磁盘损坏,外存数据部分或全部丢失。
  4. 计算机病毒或人为破坏等。

突然停电通常归为系统故障,不是介质故障。

七、恢复的基本原理

恢复的核心是冗余。最常用冗余技术:

  • 数据转储:制作数据库后援副本。
  • 登记日志文件:记录事务对数据库的更新。

转储类型:

  • 静态转储:转储期间不允许事务运行。
  • 动态转储:转储期间允许事务运行,必须配合日志。
  • 海量转储:每次转储全部数据库。
  • 增量转储:只转储上次转储后变化的数据。

日志记录通常包括:

  • 事务开始记录。
  • 更新记录:事务标识、数据项、旧值、新值。
  • 提交记录。
  • 回滚记录。

日志原则:先写日志,再写数据库。即 WAL。

八、UNDO 与 REDO

UNDO:撤销未提交事务的影响,用旧值恢复。

REDO:重做已提交事务的影响,用新值重做。

判断规则:

  • 故障时未提交的事务:UNDO。
  • 故障前已经提交但其结果可能尚未写入数据库的事务:REDO。
  • 检查点前已提交且已写入稳定数据库的事务:通常不用 REDO。

系统故障恢复通常:

  1. UNDO 未完成事务。
  2. REDO 已提交但可能未落盘事务。

介质故障恢复:

  1. 装入最近的后援副本。
  2. 利用日志 REDO 自副本以来已提交事务。

九、检查点恢复

检查点的作用:减少恢复时需要扫描的日志范围。

检查点记录通常包含:

  • 检查点时刻正在执行的事务列表 ACTIVE-LIST。
  • 这些事务最近日志记录地址等信息。

基于检查点恢复的一般算法:

  1. 从最后一个检查点开始。
  2. 把检查点时正在运行的事务放入 UNDO-LIST 或活动集合。
  3. 向后扫描日志到故障点:
    • 遇到 START T:把 T 加入 UNDO-LIST。
    • 遇到 COMMIT T:把 T 从 UNDO-LIST 移出,加入 REDO-LIST。
  4. 扫描结束后:
    • UNDO-LIST 中的是故障时未提交事务,要 UNDO。
    • REDO-LIST 中的是故障前已提交事务,要 REDO。

考试图形判断:

时间轴:  检查点 CP ---------------- 故障 CRASH

T1: ----commit---- before CP             不处理
T2: ----start---- CP ----commit----      REDO
T3: ----start---- CP --------crash       UNDO
T4:             CP ----start--commit     REDO
T5:             CP ----start----crash    UNDO

一句话:

  • 故障时没结束:UNDO。
  • 故障前已提交且可能受检查点影响:REDO。
  • 检查点前已提交:一般不用管。

十、检查点题答题模板

1. 先找检查点时正在运行的事务,写 ACTIVE-LIST = {...}。
2. 从检查点向故障点扫描:
   遇到开始但未提交,加入 UNDO-LIST;
   遇到提交,移出 UNDO-LIST,加入 REDO-LIST。
3. 故障点处仍未提交的事务执行 UNDO。
4. 故障点前已经提交但在检查点之后相关的事务执行 REDO。

如果图上事务线看不清,也要把规则写清楚,再根据可辨认编号填集合。

十一、COMMIT 与 ROLLBACK

COMMIT:提交事务,使事务对数据库的更新永久生效。

ROLLBACK:回滚事务,撤销事务已经做过但未提交的更新。

SQL Server 事务模板:

BEGIN TRANSACTION;

UPDATE Account SET Balance = Balance - 300 WHERE Ano = 'A';
IF @@ERROR <> 0
BEGIN
    ROLLBACK TRANSACTION;
    RETURN;
END;

UPDATE Account SET Balance = Balance + 300 WHERE Ano = 'B';
IF @@ERROR <> 0
BEGIN
    ROLLBACK TRANSACTION;
    RETURN;
END;

COMMIT TRANSACTION;

十二、并发控制与恢复的关系

并发控制保证事务隔离执行,防止并发造成不一致;恢复保证故障后数据库回到一致状态。两者都服务于事务正确性。并发控制处理“同时运行”的冲突,恢复处理“失败之后”的修复。