redo mysql mvcc_学习笔记06:浅谈MySQL MVCC

一:在了解mvcc之前先熟悉下Mysql架构和数据库事务隔离级别

MYSQL 架构:

MySQL从概念上可以分为四层

第一层:接入层,即不同语言的客户端通过mysql的协议与mysql服务器进行连接通信,接入层进行权限验证、连接池管理、线程管理等

第二层:服务层,即包括sql解析器、sql优化器、数据缓冲、缓存等

第三层:存储引擎层,mysql中存储引擎是基于表的。

第四层:系统文件层,保存数据、索引、日志等。

事务隔离级别(ACID):

原子性: 原子性保证一个事务为一个最小的单元,内部不可分割。只存在已执行和未执行两种 状态,不存在只执行了部分指令的情况

一致性: 数据库总是从一个一致的状态转换到另一个一致状态。无论事务是完全成功或是在中途因某些环节失败而导致失败,但事务使系统处于一致的状态时,必须保持一致性

隔离性: 同时执行的事务之间相互隔离,不会互相影响。每个事务在自己的空间发生,和其他发生在系统中的事务隔离,而且事务的结果只在它完全被执行的时候才能看到,如果该事务未提交,则其他会话看不到执行的结果。

持久性: 事务成功提交后, 其写入的数据直到被覆盖永久有效。

二:MYSQL 事务日志

事务日志可以帮助提高事务的效率。使用事务日志,存储引擎在修改表的数据时只需要修改其内存拷贝,再把该修改行为记录到持久在硬盘上的事务日志中,而不用每次都将修改的数据本身持久到磁盘。事务日志采用的是追加的方式,因此写日志的操作是磁盘上一小块区域内的顺序I/O,而不像随机I/O需要在磁盘的多个地方移动磁头,所以采用事务日志的方式相对来说要快得多。事务日志持久以后,内存中被修改的数据在后台可以慢慢地刷回到磁盘。如果数据的修改已经记录到事务日志并持久化,但数据本身还没有写回磁盘,此时系统崩溃,存储引擎在重启时能够自动恢复这部分修改的数据。

MySQL中数据持久性、一致性有关的日志,主要有以下几种:

Redo Log: 记录了数据操作在物理层面的修改,mysql中使用了大量缓存,修改操作时会直接修改内存,而不是立刻修改磁盘,事务进行中时会不断的产生redo log,在事务提交时进行一次flush操作,保存到磁盘中。当数据库或主机失效重启时,会根据redo log进行数据的恢复,如果redo log中有事务提交,则进行事务提交修改数据。

Undo Log: 除了记录redo log外,当进行数据修改时还会记录undo log,undo log用于数据的撤回操作,通过undo log可以实现事务回滚,并且可以根据undo log回溯到某个特定的版本的数据。

三:mvcc

a. MVCC是一种多版本并发控制机制。

b.MVCC是为了解决什么问题?

大多数的MYSQL事务型存储引擎,都不使用一种简单的行锁机制.锁机制可以控制并发操作,但是其系统开销较大,而MVCC可以在大多数情况下代替行级锁,使用MVCC,能降低其系统开销.

MVCC最大的好处,相信也是耳熟能详:读不加锁,读写不冲突。

mvcc原理:

对于delete操作,innodb是通过先将要删除的那一行标记为删除,而不是马上清除这一行,因为innodb实现了MVCC,这些undo段用来实现MVCC多版本机制。

主键索引,每个行都有一个事务ID和一个undo ID,这个undo ID指向了这行的先前版本的位置。非主键索引,通过先找主键索引再找到undo段。而对于update操作,则是先标记删除,然后insert一个新的行,接下来如果有一致性读,那么查找old version的行的原理和delete操作是一样的。

innoDB的行记录格式中有6字节事务ID的和7字节的回滚指针,通过为每一行记录添加这两个额外的隐藏值来实现MVCC,这两个值一个记录这行数据何时被创建,另外一个记录这行数据何时过期(或者被删除)。但是InnoDB并不存储这些事件发生时的实际时间,相反它只存储这些事件发生时的系统版本号。这是一个随着事务的创建而不断增长的数字。每个事务在事务开始时会记录它自己的系统版本号。每个查询必须去检查每行数据的版本号与事务的版本号是否相同。

摘自博客:

SELECT:

当隔离级别是REPEATABLE READ时select操作,InnoDB必须每行数据来保证它符合两个条件:

1、InnoDB必须找到一个行的版本,它至少要和事务的版本一样老(也即它的版本号不大于事务的版本号)。这保证了不管是事务开始之前,或者事务创建时,或者修改了这行数据的时候,这行数据是存在的。

2、这行数据的删除版本必须是未定义的或者比事务版本要大。这可以保证在事务开始之前这行数据没有被删除。

符合这两个条件的行可能会被当作查询结果而返回。

* INSERT:
InnoDB为这个新行记录当前的系统版本号。

* DELETE:
InnoDB将当前的系统版本号设置为这一行的删除ID。

* UPDATE:
InnoDB会写一个这行数据的新拷贝,这个拷贝的版本为当前的系统版本号。它同时也会将这个版本号写到旧行的删除版本里。

这种额外的记录所带来的结果就是对于大多数查询来说根本就不需要获得一个锁。他们只是简单地以最快的速度来读取数据,确保只选择符合条件的行。这个方案的缺点在于存储引擎必须为每一行存储更多的数据,
做更多的检查工作,处理更多的善后操作。

MVCC只工作在REPEATABLE READ和READ COMMITED隔离级别下。READ UNCOMMITED不是MVCC兼容的,因为查询不能找到适合他们事务版本的行版本;它们每次都只能读到最新的版本。
SERIABLABLE也不与MVCC兼容,因为读操作会锁定他们返回的每一行数据。

理解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值