zoukankan      html  css  js  c++  java
  • mysql MVCC

                                                                                                                                                                                                                                                                                     

    InnoDB多版本(MVCC)实现简要分析

    MVCC实现-MySQL Innodb MVCC实现

     MVCC浅析

    mysql的mvcc(多版本并发控制)

    mysql innodb mvcc 读一致性(Repeatable Read)通俗笔记

    关于InnoDB中mvcc和覆盖索引查询的困惑

    • innodb可见性判断

    到这里我们也就不难看出实际实现就是这两个数据结构进行比较:

    InnoDB每个事务在开始的时候,会将当前系统中的活跃事务列表(trx_sys->trx_list)创建一个副本(read view)在read_vied_sees_trx_id方法里我们有如下比较:

    low_limit_id 是“高水位”即当时活跃事务的最大id,如果读到row的db_tx_id>=low_limit_id,说明这些id在此之前的数据都没有提交,如注释中的描述,这些数据都不可见。

    if (trx_id >= view->low_limit_id) {

    return(FALSE); 
    }

    up_limit_id 是“低水位”即当时活跃事务列表的最小事务id,如果row的db_tx_id<up_limit_id,说明这些数据在事务创建的id时都已经提交,如注释中的描述,这些数据均可见。

    if (trx_id < view->up_limit_id) {

    return(TRUE); 
    }

    在两个limit_id之间的我们需要从小到大逐个比较一下:

    n_ids = view->n_trx_ids;

    for (i = 0; i < n_ids; i++) { 
    trx_id_t        view_trx_id 
    = read_view_get_nth_trx_id(view, n_ids – i – 1);

    if (trx_id <= view_trx_id) { 
    return(trx_id != view_trx_id); 

    }

    这样我们在要在事务中获取100行数据,我们就能根据这100行的row db_tx_id即本事务的read_view来判断此版本的数据在事务中是否可见。

    如果数据不可见我们需要去哪里找上版本的数据呢?就是通过刚才提到过的7BIT的DATA_ROLL_PTR去undo信息中寻找,同时再判断下这个版本的数据是否可见,以此类推。

    • innodb更新

    更新这个大家一般都比较熟悉,我这里简单表述一下,如一个测试表:

    create table test (key int primary key,value varchar(10));

    insert

    InnoDB为每个新增行记录,如insert into test value(’1′,’aaa’), 会创建新的row,row db_tx_id即为当前系统版本号作为创建ID。

    update

    如update test set value=’bbb’  where key =’bbb’,InnoDB会复制了一行,这个新行的版本号使用了本次db_tx_id更新的版本号。它也把之前版本号作为了删除行的版本,即把原有row delete bit置为删除,不可见。

    delete

    InnoDB为每个删除行的记录当前系统版本号作为行的删除ID,也就是说把之前说的BIT位置成不可见的。

    我这里主要描述的是Innodb主键更新,二级索引的更新大多会映射或转换为多条的主键更新,之前提到 @何_登成 博客 http://hedengcheng.com/?p=148 中举了几个主键更新和二级索引更新的例子,大家可以参看下。

    后续也会针对Hbase,PostgreSQL,Oracle的MVCC进行对比和分析,来看下其他数据库的实现方式。

    三、深入MVCC实现机制

    1、到这里很多人就会发现,如果确实根据creat_num 即时事务DB_TRX_ID去比较获取事务的话,按道理在一个事务B(比A后,但A还没commit)select的话B. DB_TRX_ID>A.DB_TRX_ID则应该能返回A事务对数据的操作以及修改。那不是和前面矛盾?其实不然,只是前面没有讲到以下内容。

    InnoDB每个事务在开始的时候,会将当前系统中的活跃事务列表(trx_sys->trx_list)创建一个副本(read view),然后一致性读去比较记录的tx id的时候,并不是根据当前事务的tx id,而是根据read view最早一个事务的tx id(read view->up_limit_id)来做比较的,这样就能确保在事务B之前没有提交的所有事务的变更,B事务都是看不到的。当然,这里还有个小问题要处理一下,就是当前事务自身的变更还是需要看到的。

  • 相关阅读:
    c++ stack 适配器
    错误记录
    css3动画,制作跑步运动,画笔画圆,之类的连贯性动作的方法
    关于$.cookie
    JavaScript中常见易犯的小错误
    关于内存泄漏
    Javascript的异步编程方法
    JavaScript中this关键词的四种指向
    javascript之回调函数小知识
    移动端的兼容性
  • 原文地址:https://www.cnblogs.com/taek/p/4758122.html
Copyright © 2011-2022 走看看