lol网站建设,网站建设仟首先金手指12,北京建网站公司怎么样,深圳大型网站建设MySQL知识点总结#xff08;三#xff09;——事务 事务事务的四大特性ACID原子性一致性隔离性持久性 脏读、幻读、不可重复读脏读不可重复读幻读 隔离级别读未提交读已提交可重复读串行化 事务的原理InnoDB如何实现事务的ACID事务的两阶段提交redo log与binlog的区别事务两阶… MySQL知识点总结三——事务 事务事务的四大特性ACID原子性一致性隔离性持久性 脏读、幻读、不可重复读脏读不可重复读幻读 隔离级别读未提交读已提交可重复读串行化 事务的原理InnoDB如何实现事务的ACID事务的两阶段提交redo log与binlog的区别事务两阶段提交流程为什么要两阶段提交一阶段不行吗 redo log、undo log、binlogredo logbinlogundo log 事务
事务是保证一批SQL同时成功或同时失败的一种机制是保证一致性的一种手段。
事务的四大特性ACID
A原子性C一致性I隔离性D持久性 原子性
事务的原子性是指事务是一个原子性的操作必须保证同一个事务里面的这一批SQL同时成功或同时失败不可以某些成功某些失败。
一致性
这个要表达清楚还真不容易往往需要举例。事务的一致性是指事务在提交之前和提交之后事务涉及到的所有修改的表记录它们的状态的变化是保持一致。比如银行转账。。。。还是不说了这例子都被举烂掉了 隔离性
事务的隔离性是指两个事务之间互不影响互不干扰。
持久性
事务的持久性是指事务一旦提交涉及的修改是持久生效的。
脏读、幻读、不可重复读
这是事务可能会发生的三大问题。 脏读
当前事务读取到了另一个事务还没有提交的修改如果另一个事务把这个修改回滚了那么就相当于是读到了脏数据。
不可重复读
当前事务对同一行数据的读取前后两次读到了不同的结果。出现这种情况一般是隔离级别设的不够高其他事务对该行数据做了修改后提交了当前事务再次读取就是修改后的值因此出现了前后两次读到的值不一致。
幻读
当前事务前后两次读取读到的记录数不一致比如前面读到了9条后面再次读取读到了10条多出了一条这就好像出现了幻觉。出现这种情况一般是其他事务在当前事务第一次读取后在读取范围内新增了数据导致当前事务第二次读取时读到了其他事务新增的数据。
隔离级别
读未提交读已提交可重复读串行化
读未提交
当前事务可以读到其他事务还没有提交的修改。这种隔离级别是最低的无法防止脏读、不可重复读和幻读。
读已提交
当前事务只能读取到其他事务已经提交的修改其他事务没有提交的修改则不能被当前事务读取到。这是大多数数据库默认的隔离级别但是MySQL并没有把它作为默认的隔离级别。这种隔离级别下可以防止脏读但是无法防止不可重复读和幻读。
可重复读
比读已提交更严格的隔离级别是MySQL默认的隔离级别。在这种隔离级别下可以保证一个事务内对同一条记录的读取总是能读到相同的结果。可以防止脏读和不可重复读但是还是有可能出现幻读。
串行化
最严格的隔离级别一般很少会使用隔离性最高但是性能最低。在这种隔离级别下可以认为事务是一个个串行执行的读读可以并行事务的读取会加读锁修改会加写锁。这种隔离级别可以防止脏读、幻读、不可重复读。 事务的原理
InnoDB如何实现事务的ACID
事务的原子性通过undo log实现undo log可以理解为数据库表行记录的历史版本每次事务对库表的行记录进行修改时都会先记录它的历史版本到undo log中如果该事务回滚了那么就从undo log中读取行记录的历史版本把它还原回去。
事务的隔离性通过锁和MVCC多版本并发控制保证。如果一个事务对一行或多行加了锁其他事务自然是无法对它们进行修改也就达到了隔离效果只是加锁这种隔离手段代价太高了会阻塞其他事务的执行。于是就有了MVCCMVCC是多版本并发控制简单理解就是一个行记录可以同时存在多个版本那么不同事务间读写同一个行记录的不同的版本自然可以互不影响。
事务的持久性是通过redo log实现的redo log是一种WAL预写日志机制一个事务提交了对库表行记录的修改InnoDB并不会马上持久化到磁盘的索引页中因为磁盘中的索引页读写是随机读写性能是极低的InnoDB会通过redo log记录“某索引页某个位置要修改成某某值”之类的日志把它持久化到磁盘假设MySQL宕机了重启之后也可以利用redo log恢复这样就不会发生更新丢失这就是redo log的作用而redo log在磁盘中是顺序写的性能是极高的这样就满足了持久性的同时又保证了性能。
而一致性是最终目的满足了原子性、隔离性和持久性才能满足一致性。 事务的两阶段提交
redo log与binlog的区别
除了redo log、undo log以外MySQL还有一个binlog。binlog与redo log的功能看似很相似实际上并不一样。
redo log是InnoDB存储引擎独有的binlog是属于MySQL服务端的是所有存储引擎共享的。
redo log记录的是索引页的修改是用于崩溃恢复的比如有一个事务提交了修改记录到redo log中但是没有持久化到磁盘索引页此时MySQL宕机了当我们重启MySQL后InnoDB就会自动使用redo log去恢复索引页把更新持久化到索引页中。而binlog日志记录的是事务提交的SQL本身是用于备份和主从同步到当然遇到删库跑路的场景也可以用它来恢复到某个时间点。
因此当一个事务提交时需要保证redo log和binlog的一致性。
事务两阶段提交流程
当一个事务要提交时首先InnoDB会记录redo log日志并持久化到磁盘并修改日志的状态位prepare状态然后响应MySQL服务端。当服务端收到响应时会记录binlog并持久化。然后服务端再调InnoDB存储引擎执行真正的事务提交此时InnoDB把redo log的状态改为commit状态。 为什么要两阶段提交一阶段不行吗
我们看一下当MySQL宕机重启后两阶段提交的各种可能情况。
当MySQL宕机重启时检查发现事务提交后记录了redo log处于prepare状态而binlog并没有记录那么会把记录的redo log日志回滚掉这相当于是事务提交失败了但是redo log和binlog是保持一致的。
如果事务提交时记录了redo log处于prepare状态并且MySQL服务端也记录了binlog此时才宕机的那么MySQL重启后会把redo log提交这样事务就算是提交成功了redo log和binlog也是一致的。
如果是redo log和binlog都没有记录或者redo log记录了并处于commit状态并且MySQL服务端也记录了binlog这两种情况本身就是一致的。 嗯~~~怎么看都是没有问题横竖都是一致的。
那假如改成了一阶段提交呢
比如先提交redo log再记录binlog此时就有可能出现这种情况提交完redo log后MySQL宕机了没来得及记录binlog此时MySQL重启后发现redo log是有的于是当前库表的修改是生效的但是如果我们配了主从同步由于binlog上是没有修改记录的因此同步到从库时从库就少了一次修改。 那改成先记录binlog再提交redo log呢那又有可能出现另一个问题MySQL服务端记录了binlog此时MySQL宕机了InnoDB没来得及提交redo log。当MySQL重启时发现没有redo log那么当前数据库的库表是不存在此次事务的修改的但是binlog却记录事务的修改同步到从库时从库就比主库多了一次更新于是又出现了主从不一致。 redo log、undo log、binlog
redo log
redo log是“重做日志”它的作用就是可以使得InnoDB每次执行SQL的增删改操作修改了数据行记录之后无需马上把修改持久化到磁盘而是记一条redo log日志redo log是顺序写入的写入速度非常快大大提高了写入更新的性能。而数据索引页的修改InnoDB会异步的以随机写入的方式写入到磁盘如果没来得及写入就宕机了InnoDB可以利用redo log去恢复数据的更新不会丢失。
redo log记录的是索引页的修改类似于“某个索引页某某位置修改为xxx”是物理日志物理层面的修改。
redo log是固定大小的我们可以配置它的固定大小以及分成几个文件。redo log 有一个 write pos指针指向当前写入到的位置当redo log写满之后就会回到开头此时会覆盖掉最开始写入的日志。redo log还有一个check point指针当数据更新被持久化到磁盘数据索引页后check point会往前推进write pos到check point之间的区域都是可以覆盖的。当write pos追上check point后InnoDB只能停止redo log的写入先把一部分数据更新到磁盘把check point往前推一段距离让write pos有空间可以写入。 binlog
binlog是二进制日志与redo log不同的是binlog是属于MySQL服务端日志是所有存储引擎共享的而redo log是InnoDB存储引擎专有的日志只有使用了InnoDB存储引擎才有redo log日志。
binlog是二进制归档日志记录的是SQL语句的逻辑比如“给某某表的某某id的行记录的某某字段的值改为xxx”因此执行binlog是需要经过解析的不像redo log那样拿到之后可以直接重放。
binlog是不固定大小的写满了一个文件再新开一个。
binlog是不具备崩溃自动恢复的能力的它不像redo logbinlog的作用主要用于归档也就是用来做备份当有人删库跑路时我们可以拿它来人工手动恢复出一个某时间点的库不至于删完就GG同时也可以用于主从同步。 undo log
undo log是回滚日志顾名思义它是在事务回滚时使用的所以它的一大作用是事务事务回滚。
undo log记录的是行记录的历史版本当事务发生回滚时就从undo log中拿到该行记录的历史版本恢复回去。