【原创】想了解Mysql事务,知道这些就够了
阅读原文时间:2023年07月09日阅读:3

Mysql事务:
1. 事务进行一次数据库操作时将数据会存到BufferPoll缓存池中
2. 数据存入缓存池后,Mysql会新建一个线程将数据存入到RedoLogBuffer中
3. 事务提交时RedoLogBuffer中的数据落盘到RedoLogFile中
4. 当服务器崩溃时没有Commit成功的数据都在RedoLogFile中了,未Commit成功的则直接返回给客户端失败信息,
服务器重启后从RedoLogFile中读取出已提交的数据恢复到数据库中
5. 缓存池中的数据根据CheckPoint则是刷新脏页到数据库,又称脏页落盘

事务特性(ACID)

原子性:一个事务中的所有操作要么全部成功,要么全部失败
一致性:事务的开始和结束,数据库的完整性不会被破环
持久性:事务提交后,对数据的修改是永久性的。
隔离性:不同事务之间互不影响,(多版本并发控制机制实现和锁机制)
事务并发出现的问题
①.更新丢失 两个事务同时对一条数据进行操作,eg.a事务将某字段从1000改为1100这是还未提交,
b事务将某字段从1000改为900且提交,这时a事务进行了提交操作。这时该字段的值为1100,b事务的更新丢失。(行锁机制可)
②.脏读 一个事务读取到另一事务还未提交的数据,eg.a事务查询账户余额为2000元,取出1000元,这时b事务开始:读取结果为1000
这是a事务又发生了回滚数据库数据又变成了2000;b事务却只读到1000。(锁机制可实现避免,a写操作b不可读(读写冲突))
③.不可重复读 同一个事务前后两个读取同一条数据的结果不同,读取过程中有其他事务修改了数据,读取到其它事务update/delete的数据
④.幻读 同一个事务前后两次读取同一个表的数据条数不同,读取到其他事务insert的数据
隔离级别分为 ①.读未提交(read-uncommitted) 无法保证任何情况的发生
②.读已提交(RC: read-commit) 可保证避免脏读,但还如果其他事务修改同一条数据后且提交会导致同一条数据在一个事务中前后两次读取到的结果不同
③.可重复读(RR: repeatable-read) 可避免不可重复读
④.可串行化 可避免所有状况的发生
级别越高对消耗的性能越大,一般的数据库默认隔离级别为RC:ReadCommit, MySql的默认隔离级别为RR: Repeatable-Read
MCVV:是为数据库提供并发访问控制的并发控制技术,MVCC读不加锁,写加锁(加排他写锁),读写不冲突。
MVCC是多版本的并发控制技术,其核心理念就是数据快照,不同的事务访问不同版本的快照,这样就使事务间相互隔离,innodb中实现是根据updolog和readview来实现的MVCC。
undolog:数据库数据修改时就会产生一个undolog,这样的话当事务回滚时可根据undolog将数据恢复到之前的状态。
事务链表:RR隔离级别下:当一个事务开启时,innodb会将当前系统中所有的活跃事务ID存入一个链表中,事务被commit时从链表中移除
RC隔离级别下:每一个语句开始时,innodb就会将当前系统中所有的活跃事务ID存入一个链表中,事务被commit时从链表中移除。
readview:MVCC对同一数据会有多个不同版本的UndoLog, 那么如果当前系统中有活跃的事务,那么这时一个新的事务要查询该数据,这时应该需要查询哪个版本呢
就需要使用readview来控制
该事务的事务链表及ReadView结构如下
事务链表:ct-trx --> trx11 --> trx9 --> trx6 --> trx5 --> trx3; trx11等均为当前活跃事务的ID
readview:
read_view->creator_trx_id = ct-trx; 当前事务ID
read_view->up_limit_id = trx3; 低水位
read_view->low_limit_id = trx11; 高水位
read_view->trx_ids = [trx11, trx9, trx6, trx5, trx3];
如果读取到的行数据的事务ID 大于 low_limit_id 高水位,说明这个数据的事务是在当前事务后面后面完成的,则不可见
如果读取到的行数据的事务ID 小于 up_limit_id 低水位,则说明这个数据的事务在本事务开启之前已经不再活跃,即已提交过的,则该数据可见
如果读取到的行数据的事务ID 在低水位和高水位之间,则看当前事务的read_view的事务链表中是否存在该事务ID,
如存在则说明,当前事务开启时,这个数据的事务正在活跃还未提交所以不可见,如果不存在则可见