写在前面
上一篇中,我们对前5章的内容进行了梳理,重点就是第2章 InnoDB 引擎结构 和 5章 索引的内容。
下面我们对剩下的内容进行学习。重点是 6章的锁,7章的事务 以及8章中备份与恢复的部分内容。
第6章 锁
1. MyISAM引擎
MyISAM 引擎的锁是表锁设计,并发情况下读没有问题,但是写的性能较低。
2. InnoDB 引擎
InnoDB 主要支持的是行级锁
2.1 锁的类型
- 共享锁(S lock):允许事务读一行数据
- 排它锁(X lock):允许事务删除或者更新一条数据
2.2 一致性非锁定读
如果要读取的行,处于 update / delete 中,读操作不会等待其释放 X 锁,而是去读行的快照数据。
而针对不同的事务隔离级别,读取的快照版本是有差别的:
- 已提交隔离级别:读到最新的快照版本。可能会产生幻读
- 可重复读隔离级别:读到事务开始后第一次读取的快照。避免幻读
2.3 一致性锁定读
某些场景下需要对读操作加锁,来保证数据的严格一致性,可以显示指定。
- select *** for update(X 锁)
- select *** lock in share model(S 锁)
2.4 锁的算法
- record lock: 单个记录的锁
- gap lock:间隙锁,锁定一个范围,不包括记录本身
- next-key lock:前两者组合
默认隔离级别(可重复读)下,默认加的是next-key lock(为了解决幻读问题),当索引中含有唯一属性时,会降级为record lock。
在读已提交隔离级别下,加的是record lock。
第7章 事务 Transaction
7.1 什么是事务Transaction
- 事务是数据库系统区别于其他一切文件系统的重要特性之一
- 事务是一组具有原子性的 SQL 语句,或是一个独立的工作单元
如果不显示调用 start trasaction & commit ,那么每一句 SQL 就是一个事务
InnoDB 中的事务符合 ACID 特性:
- 原子性 Atomicity:要么全部做,要么都不做,不能再拆分
- 一致性 Consistency:事务在完成操作的前后,数据库数据状态要一致
比如说,事务操作前,有一个字段 name 是 unique的,但是操作使得 name 不 unique 了,那么就不满足一致性,这个事务操作就是无效的。
- 隔离性 Isolation:事务对于数据库中数据的修改,在未提交完成前对于其他事务是隔离的,不可见的
- 持久性 Durability:事务一旦提交,结果就是永久性的
7.2 事务的隔离级别
先要了解这几个概念。事务并发时候会产生下面这几个问题。
脏读:读取别人没有提交的数据
不可重复读:不可重复读的侧重点在于更新修改数据。在同一个事务中,同样的语句查询,同一个数据莫名改变了。
幻读:幻读的侧重点在于新增和删除。在同一个事务中,用同样的语句查询,第二次莫名有数据新增或者不见了。
事务的隔离级别有4种:
- 读未提交 read-uncomitted:即可以读取另外一个事务更新但是未提交数据,会出现幻读、脏读、不可重复读 等情况
- 读提交 read-comitted:只能读另一个事务更新且提交的数据。避免脏读;但是可能出现不可重复读、幻读
- 可重复读 repeatable-read:即可以重复读取数据。避免脏读和不可重复读,可能出现幻读。
InnoDB 默认的事务隔离等级
- 串行化 serializable:读、写都是串行的,读、写都会加上表锁,不会出现并发问题。
从上到下,事务的隔离级别越高,并发能力越弱。如下图
事务隔离对应的并发问题
7.3 事务的实现
事务实现的基础就是 redo log/ undo log/ lock / MVCC.
- 原子性A:通过 undo log 回滚日志实现
undo log 记录数据被修改前的信息。
用于错误发生时候数据回滚。保障,事务的原子性。
- 持久性D:通过 redo log 重做日志来实现的
redo log 记录成功提交事务的修改信息。
是用来恢复数据到最新位置, 用于保障,已提交事务的持久化特性
- 隔离性I:通过 读写锁+MVCC 实现
读锁(共享锁,shared lock)
写锁(排它锁,exclusive lock)
MVCC 多版本并发控制,是一种用于解决 “读写冲突”的无锁并发机制。对表中每一行给定一个版本号,每次更改操作会使得版本号递增。这样事务一开始,拿到所有数据的版本号都是<=当前版本号的,同一事务中的查询操作对该统一记录集进行操作,从而解决了读写冲突
- 一致性 C:通过前三个性质来实现的
第8章 备份与恢复
这一章不是重点,我们大概了解一下冷备热备等的概念和大概优缺点即可
8.1 备份分类
按照数据库运行状态,分为3类:
- 热备:在数据库运行的时候直接备份。对运行的数据库没有影响
- 冷备:在数据库停止运行的时候进行备份。最简单,只要复制数据库物理文件即可
- 温备:运行时候备份,对当前数据库操作有影响
热备优点
1.可在表空间或数据文件级备份,备份时间短。
2.备份时数据库依然可以使用。
3.可达到秒级恢复,能够恢复到某一个时间点上。
4.恢复的速度很快,在大多数情况下在数据库工作时就可恢复。
5.几乎所有的数据库实体都可以进行恢复。
热备份的缺点:
1.尽量不要出错,否则后果会很严重。
2.如果热备份不成功,所得结果不可用于时间点的数据恢复。
3.维护的工作比较困难。
冷备份的优点:
1.是非常快速的备份方法,因为只需要拷贝文件即可
2.容易归档,容易恢复到某个时间点上(只需将文件再拷贝回去即可)
3.能与归档方法相结合,作数据库(最新状态)的恢复。
4.容易维护,且比较安全。
冷备份的缺点:
1.单独使用时,只能提供到"某一时间点的上"的恢复。
2.再实施备份的全过程中,数据库必须是关闭状态。
3.不能按表或按用户恢复。
这里对于优缺点大概看一下就行,不用记住
MySQL的3个范式
定义
设计数据库的时候,需要满足一定的规范要求,这些不同的规范要求 被 称作 范式。
目前 关系型数据 库有6种范式。要求越来越严格,数据库的冗余越来越小。
MySQL的3个范式
1NF:字段不可再分
原子性
2NF:有主键,非主键字段依赖主键
唯一性
3NF:非主键字段不能相互依赖
每列都与主键有直接关系,不存在传递依赖
MySQL的 读写分离 和 主从复制
读写分离
在高并发场景下,一般来说,读是远远大于写的。
读写分离,其实就跟redis 集群是一个道理,我们采用主从模式,将写放在master,然后读全部放在 slave 上面。变相的提高了系统的吞吐量。
那么问题来了,如何保持 master 跟 slave 的数据同步呢,这里就要涉及到主从复制的概念了。
主从复制
简单来说,就是 slave 通过一个 IO 线程,将主库的 binlog cp 到自己本地的 relay log中,然后串行读取,并执行SQL操作。
之前在 redis 中的主从复制差不多也是这个道理,不过 redis 中的主从复制用的是快照。 MySQL中用的是 binlog。
主从复制的延时问题
按照上面这种,slave 的数据更新是会慢于 master 的,即会有延时问题。为了克服这个问题,有 半同步复制 和 并行复制的方案
半同步复制
指的就是主库写入 binlog 日志之后,就会将强制此时立即将数据同步到从库,从库将日志写入自己本地的 relay log 之后,接着会返回一个 ack 给主库,主库接收到至少一个从库的 ack 之后才会认为写操作完成了。
master 等 slave 返回 ack,才继续向下执行。
只要 slave 接受日志成功即可。
并行复制
如果 mater 产生 binlog 的速度远远超过 slave 消耗 binlog 的速度,就会出现延迟嘛
salve 开启多个线程,并行的读取SQL。
可以做到库级别 并发。就是说 DB1 DB2 DB3 可以并行的恢复。
网友评论