事务与锁

事务:一个或一组SQL语句组成的一个执行单元,这个单元要么全执行,要么全不执行。是相互依赖的,其中某行语句发生失败或者错误,整个单元将会回滚

事务ACID

原子性  :不可分割,要么全部成功,全部失败

快照

mvcc 多版本并发过程

一致性:事务的执行结果必须使数据库从一个一致性状态到另一个一致性状态。

比如:转账前后 两个账户的总金额保持不变

数据库本身的约束 一致性读 一致性写

一致性是事务最终的根本追求,通过原子性,隔离性,持久性 保证一致性的实现

隔离性:并发执行的事务不会相互影响 ,其对数据库的影响和它们串行执行时一样

共享锁 拍他所 独占锁 临键锁 间隙锁 自增锁 意向锁

读未提交 读已提交 可重复度 串行化

 

持久性 事务一旦提交,其对数据库的更新是持久的。任何事务或系统故障都不会导致数据丢失。数据持久化

wal日志 write ahead log 预写日志

 

原子性实现原理

日志 undo、redo   归属于innodb引擎    bin log 归属mysql sever  

myisam 不支持事务,没有undo、 redo日志

undo log 事务回滚

逻辑日志 当delete一条记录时,undolog会记录一条insert 记录,当insert delete 当update 记录相反的update sql语句

逻辑日志 对当前sql记录,不改当前物理页的内容

物理日志

mvcc  multipart version conccurry controll  undolog 记录了当前数据之前的历史版本

 

持久性实现原理

redo log  记录的是新数据的备份

在事务提交前,只要将redo log 持久化即可,不需要将数据持久化

user space 当前进程内存空间    innodeb engine> log buffer  >redo log buffer undo log buffeg

kernel space 系统内存空间   os buffer

fsync ->  磁盘 redo log file ib_logfilen \undo log file  零拷贝

所以mysql是否持久化的关键要看redo log的持久化策略,mysql提供了三种redo log持久化策略

  • 0:只写redo log,每秒落地一次,性能最高,数据一致性最差,如果mysql奔溃可能丢失一秒的数据
  • 1:写redolog buffer同时落地,性能最差,一致性最高
  • 2:写redo log buffer同时写入到os buffer,性能好,安全性也高,只要os不宕机就能保证数据一致性

  • 事务与锁

 

数据更新流程

先查询数据 再更新

获取数据

数据页是否在内存中  否从磁盘加载数据  是 返回数据

更改数据

写入新的数据

新数据更新到内存

写入redo,始于prepare 阶段

写binlog

提交事务,处于commit阶段

 

mysql 隔离级别   隔离级别越高,越安全,性能越低

读未提交 脏读 幻读 不可重复读

读已提交    orecal 默认隔离级别  幻读 不可重复读

rc读的最新的快照

可重复读    mysql默认隔离级别  幻读    

RR 读的是历史

串行化

 

脏读:

不可重复读:同一个事务,相同的sql语句,不同的结果

幻读:

 

间隙锁:

行锁

临键锁

 innodb 只有通过索引条件检索数据,innodb才使用行级锁,否则,innodb将使用表锁

共享锁

lock in share mode

排他锁

for update

独占锁

自增锁  

意向锁