Java面试(7)之数据库mysql

mysql事务原理

一, 事务的隔离级别及解决的问题

隔离级别

含义说明

问题

时长

备注

其他

读未提交

1, 事务A修改了某个值但未提交事务

2, 事务B第一次读取这个值a

3, 然后事务A进行了撤销回滚

4, 事务B再次读取这个值不再是a

脏读

较短时间

事务B的操作在一个事务下进行

无锁

读已提交

1, 事务A第一次读取某条数据值为null

2, 事务B修改了该条数据值为b并提交了事务

3, 事务A再次读取该条数据值为b

4, 事务C修改了该条数据值为c并提交了事务

5, 事务A再次读取该条数据值为c


1, 事务A第一次根据某些条件查询了一批数据

2, 事务B插入了一批数据

3, 事务A再次根据同一条件查询数据多了几条

不可重复读

(单纯从业务上来说其实也没有问题,其实大部分的项目也用该隔离机制)


幻读

较短时间

事务A的操作在一个事务下进行

行锁+mvcc解决不可重复读、脏读

可重复读

(Innodb默认)

1, 事务A第一次根据某些条件查询了一批数据

2, 事务B插入了一批数据

3, 事务A再次根据同一条件查询数据一样

间隙锁+mvcc解决当前读幻读问题

较短时间

事务A的操作在一个事务下进行

间隙锁+mvcc解决幻读

串行化

所有的读写操作都会加锁

读写都加锁,性能极差

  

参照: 大白话讲解脏写、脏读、不可重复读和幻读 - 知乎

说明:

1, 一般的select 查询表示快照读,select * from xxx for update/share xxxx等表示当前读

2, oracle默认是读提交,如果存在数据库迁移切换,需要修改mysql的隔离级别

--------------------------------------------------------------------------------------------------

redo log、undo log、bing log

日志

位置

形式

记录方式

存在条件

文件大小

适用场景

Redo log

引擎层

物理日志(数据页)

循环写

Innodb引擎

固定大小,重新覆盖

崩溃恢复

Undo log

引擎层

相反sql(如 insert操作记录delete操作)

追加写

Innodb引擎

不限

事务恢复

MVCC(多版本并发控制)实现

Bing log

Server 层

逻辑日志(sql)

追加写

所有引擎都有

不限,可指定每个bing log大小

主从复制+崩溃恢复

Bing log日志格式:

日志格式

版本

复制方式

优点

缺点

STATMENT

5.7.7之前

sql复制

减少日志量,节约IO,提高了性能

某些情况下可能导致主从不一致.如 执行了sysdate()、slepp等

ROW

5.7.7之后

行复制

支持存储过程、function、trigger等复制

产生大量日志,尤其是alter table会让日志暴涨

MIXED

5.7.7之后

混合复制

可规避前面两个的问题

WAL(write ahead logging)技术:

一条插入/更新语句的执行过程是: mysql客户端-》buffer pool(引擎层) -〉log buffer(redo log buffer/undo log buffer)-> OS buffer-> log files(redo log/undo log/bing log)

简单来说,就是因为写入log buffer是顺序IO,而刷盘是需要寻址的,是随机IO,顺序IO的性能比随机IO高很多,所以提高了系统的性能,即采用了同步写缓存日志异步刷盘的方式来保证性能.

Redo log记录日志过程:

Redo log循环记录日志是根据write pos与check point来定位的,write pos表示redo log当前记录的LSN(逻辑序列号)位置,check point表示数据页更改记录刷盘后对应redo log所处的LSN(逻辑序列号)位置。当write pos要追上check Point时会触发刷盘(刷盘是异步定时刷的)

崩溃恢复只要redo log 或者 只要bing log可以吗?

不能;

如果只要redo log, 理论上是可以的,因为redo log记录了数据页的变化位置,数据恢复落盘会更容易. 但redo log 不具备归档的能力,循环写数据不完整,从历史发展来看,mysql 最开始的MYISAM存储引擎是没有redo log的,但都有bing log日志归档,方便做数据的全量崩溃恢复.

如果只要bing log, bing log是存储的sql 逻辑日志,主要还是无法找到数据的磁盘位置,故无法进行数据恢复;

如果把redo log功能做到bing log里面,redo log去掉行不行?

想法是好的,可惜的是mysql最开始没有计划redo log并入bing log,从发展历史来看已不支持

二阶段提交:

sql执行-》....-》redo log(prepare阶段)-》bing log(就绪阶段)-》commit

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱编程的Loren

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值