目录
1.MySQL的事务的特性(ACID)
原子性:
在一个事务内,要么同时成功,要么都失败叫原子性
如何保证的呢?
原子性的保证是有undolog(回滚日志)来保证的,它记录了需要回滚的信息,事务回滚会撤销掉已经执行的sql。
一致性:
在一个事务中,比如转账,一个转出500,必有一个到账500
如何保证的呢?
一致性的保证是有其它三个特性来保证的。
隔离性:
一个事务不可被另一个事务干扰
如何保证的呢?
隔离性的保证是通过,读已提交,读未提交,可重复度,串行化,MVCC多版本并发控制来保证的。
持久性
持久性体现在事务提交后,要把数据持久化(可以说是落盘操作)
如何保证的呢?
持久化的保证是通过redolog(记录的是数据页的物理变化)
mysql在插入数据时会有一个bufferpool(缓冲区),在缓冲区进行同步数据的时候宕机会导致数据的丢失,这时候就需要redolog+内存来保证数据不丢失,在宕机的时候用redolog来恢复数据,由于Buffer Pool刷新磁盘是随机io,性能消耗大,redolog file(日志文件)是追加形式,是顺序io,性能好
2.MySQL的事务会出现哪些问题?
脏读
一个事务修改数据,还没有提交,第二个事务就读到了没有提交的数据,也称为脏数据。
不可重复读
第一个事务读取一个数据,假如这个数据是1,这时候这个事务还没结束,
第二个事务来对这个数据进行修改,此时数据为2,
最后第一个事务有来读取一边数据与第一次读取的不一样,成为不可重复度
幻读
一次事务中两次读取数据的数量不一样
第一个事务读取了三条数据,此时事务二来对数据进行修改,并提交,
第一个事务来读取时会发现多了一些不存在的记录,就像产生幻觉一样。
3.MySQL的事务隔离级别?
读未提交
可以读取未提交的数据,会导致脏读,幻读,不可重复度。
读已提交
只能读已提交的事务,解决了脏读,没解决幻读,不可重复度
可重复度(MySQL默认的隔离级别)
解决了脏读,不可重复度,没完全解决幻读
串行化
它可以解决刚才提出来的所有问题,但是由于让是事务串行执行的,性能比较低。
4.当前读和快照读
当前读:当执行select...lock in share mode ,select...for update,update,delete,insert时是当前读,会读取最新数据
快照读:普通的seletc操作,利用MVCC机制进行读取,不会对记录进行加锁,读取的是历史数据
5.MVCC多版本并发控制
MVCC多版本并发控制,由三部分组成,第一个是隐藏字段,第二个是undo log日志,第三个是readView读视图
1.隐藏字段
在mysql中给每个表都设置了隐藏字段,有一个是trx_id(事务id),记录每一次操作的事务id,是自增的;另一个字段是roll_pointer(回滚指针),指向上一个版本的事务版本记录地址 ,还有个是隐藏主键
2.undolog日志
记录的是回滚日志,存储老版本数据,内部会生成版本链,通过roll_pointer来连接
3.readview
决定事务的版本,字段有当前活跃的事务id集合,最小事务id,最大事务id+1,readview创建时事务的id,在内部定义了一些匹配规则和当前的一些事务id判断该访问那个版本的数据,不同的隔离级别快照读是不一样的,最终的访问的结果不一样。如果是rc隔离级别,每一次执行快照读时生成ReadView,如果是rr隔离级别仅在事务中第一次执行快照读时生成ReadView,后续复用