安全性保护
数据库的安全性保护是为了防止非法用户和用户非法操作数据库,包括恶意破坏和越权存储数据。
从数据库用户的角度来说,DBMS提供的数据库安全性保护措施有以下几个:
- 用户鉴别
- 存储权限控制
- 视图机制
- 跟踪审查
-
完整性保护
数据库的完整性是防止合法用户使用数据库时向数据库中加入不合语义的数据。
静态约束
静态列级约束:对数据类型、数据格式、取值范围/集合、空值的约束。
- 静态元组约束:涉及到多列的约束。
静态关系约束:涉及到多个关系的约束,包括实体完整性、参照完整性、函数依赖和统计约束。
动态约束(属性名/值、修改时应满足的条件)
动态列级约束
- 动态元组约束
- 动态关系约束
并发控制
事务及其特性
- 什么是事务
事务是用户定义的一组操作序列的集合,是数据恢复和并发控制的基本单位。数据库系统在执行事务时,要么执行事务中的所有操作,要么不执行任何操作。
- 定义事务的语句有以下三条:
- BEGIN TRENSACTION:定义一个事务的开始。
- COMMIT:提交一个事务。
- ROLLBACK:当事务执行失败时,回滚(撤回)该事务所执行的所有更新操作。
- 事务的ACID特性
- 原子性(Atomicity):事务是不可分割的最小工作单元。
- 一致性(Consistency):事务的执行只允许两种情况出现,成功执行和失败回滚,即要么什么操作都没有执行,要么完整地执行了该事务,这就是从一个一致性状态变到另一个一致性状态。
- 隔离性(Isolation):一个事务的执行不能被其他事务干扰。
- 持续性(Durability):也称永久性,指事务一旦提交,其对数据的改变应该是永久性存在的。
- 事务处理技术(基于事务的ACID特性)
- 并发控制
- 故障恢复
并发控制可能出现的问题
- 并发的目的
- 改善系统资源利用率
- 改善短事务响应时间
- 并发引起的问题
- 丢失修改:A和B读取同一数据并进行修改,提交时将引起写-写冲突。
- 脏读:A读取B尚未提交的数据所引起的,而后B撤回修改,导致读-写冲突。
- 不能重读:A读取数据后,B读取并修改该数据,A再次读取校验时二者不一致。
基于封锁的并发控制方法
以上问题的出现主要是由于并发操作不当,违背了ACID特性,为了解决这些问题,就有了封锁技术。
- 封锁技术
- 排它锁(X锁):若事务A对某数据建立了X锁,则该事务科对该数据进行增删查改操作,而其他事务不行。
- 共享锁(S锁):若事务A对某数据建立了S锁,则该事务科对该数据进行查询操作,而其他事务只能对该数据加S锁而不能加X锁。
- 封锁粒度
指被封锁数据对象的大小。在关系数据库中,封锁粒度有以下几种:属性值、属性值集、元组、索引项、整个索引或整个数据库,还可以是一些物理单元。 封锁粒度越大,系统中能被封锁的对象越少,并发度也就越小,但系统开销也越小; 封锁粒度越小,系统中能被封锁的对象越多,并发度也就越大,但系统开销也越大。 一个系统中如果能同时存在不同大小的封锁粒度是比较理想的,在选择封锁粒度时也应该同时考虑封锁开销和并发度,以达到最佳效果。
- 封锁协议
包括事务何时该申请哪种锁、封锁时间、何时释放锁等。
- 一级封锁协议:事务要修改某一数据对象前,必须对其加X锁,直到事务结束释放,解决了丢失修改问题。
- 二级封锁协议:事务要读取某一数据对象前,必须对其加S锁,读完后才可释放,解决了脏读问题。
- 三级封锁协议:一级封锁协议基础上,事务要读取某一数据对象前,必须对其加S锁,事务结束后才可释放,解决了不可重读问题。
- 死锁和活锁
- 活锁:事务A封锁了数据对象R后,事务B也请求封锁R,于是B等待,接下来C也请求。而当A释放锁之后,系统首先批准了C,接着D请求,C释放锁后系统又批准了D,B可能永远等待下去。避免活锁的策略是先来先服务。
- 死锁:事务A封锁了数据对象X,事务B封锁了数据对象Y;事务A申请封锁数据对象Y,事务B申请封锁对象X。导致了A等待B结束而B等待A结束的局面,这就是死锁。
- 解决死锁的方法
- 预防法
- 一次封锁法:每个事务必须一次性将所要访问的数据对象全部加锁,在操作结束后一次性释放所有锁。但这些数据对象难以确定,为此系统会扩大封锁范围,导致系统的并发度降低。
- 顺序封锁法:预先对数据对象排序,所有事务按该顺序实施封锁。但维护封锁顺序十分困难且成本太高。
- 诊断解除法
系统允许产生死锁,由死锁诊断程序检测死锁的发生,交给解锁程序去解除死锁。
并发调度
- 调度的概念
多个事务按照顺序执行,被称为串行调度;通过分时方法同时处理多个事务,被称为并发调度
- 调度的可串行性
多个事务的并发执行是正确的调度,当且仅当其结果与串行执行的结果相同,称这种调度是可串行化的调度。
- 两段封锁协议
一级、二级和三级封锁协议可以预防事务并发执行的三类错误,但并不一定能保证并发调度的正确性,于是就有了两段封锁协议。
- 特性:读写数据前要获得锁,每个事务中所有封锁请求先于任何一个解锁请求。
- 两阶段:加锁段,解锁段。加锁段中不能有解锁操作,解锁段中不能有加锁操作。
- 总结:遵守两段封锁协议的调度可以保证可串行化,但可串行化的调度不一定满足两段封锁协议。但遵守两段封锁协议的调度可能导致更多的死锁发生,因为每个调度都不能及时解除被它封锁的数据对象。
数据库恢复
故障种类
- 静态转储:事务全部结束后才能进行。
- 动态转储:可随时进行,实现较难。
- 海量转储:将全部数据进行转储。
- 增量转储:只转储更新过的物理块。
- 推荐策略:小周期增量 + 大周期海量
- 日志文件
- 严格按照并行事务执行的事件次序登记。
- 必须先写日志文件,再写数据库。
- 恢复策略
- 事务故障的恢复
- 反向扫描日志
- 对事务更新执行逆操作
- 系统故障的恢复
- 正向扫描日志
- 撤销、重做事务
- 介质故障的恢复
- 写入数据库副本
- 加载日志,重做事务
- 检查点机制