• MySQL MVCC


    简介

    • Multi Version Concurrency Control (MVCC), 即多版本并发控制, 是基于锁的并发控制。(Lock-Based Concurrency Control)
    • MVCC在Oracle, MySQL, PostgreSQL等主流RDBMS中都有应用, 在此仅解释MySQL中的MVCC。
    • 特征优势: 读不加锁, 读写不冲突, 有利于提升读多写少的OLTP应用中系统的并发性能。
    • 在理解MVCC前需要复习一下MySQL架构, 事务隔离级别 以及锁机制。

    MySQL架构

    • 架构图

      “MYSQL 架构”的图片搜索结果

    • Connector

      • 连接器, 不同语言的客户端通过mysql的协议与mysql服务器进行连接通信。
    • Connection Pool

      • 连接池, 进行权限验证, 连接池管理, 线程管理等。
    • SQL Interface

      • SQL接口, 生成 Data Manipulation Language(DML), Data Defination Language(DDL), 存储过程, 视图, 触发器等。
    • Parser

      • 解析器
        • 内部将文本格式转换为二进制结构
        • 目的是为了让优化器更好的处理指令,以便以最优的路径,最少的耗时返回我们想要的结果。
    • Optimizer

      • 查询优化器

        • 对语法分析树的形态进行修改,把语法分析树变为查询树。

        • 逻辑优化

          • 逻辑优化阶段主要解决的问题是: 如何找出SQL语句等价的变换形式,使得SQL执行更高效。
        • 物理优化

          • 查询优化器在物理优化阶段,主要解决的问题:
            • 从可选的单表扫描方式中,挑选什么样的单表扫描方式是最优的?
            • 对于两个表连接时,如何选择是最优的?
            • 对多个表连接,连接顺序有多种组合,是否要对每种组合都探索?如果不全部探索,怎么找到最优的一种组合?
          • 目前数据库的查询优化器通常融合这两种方式。
    • Cache Buffer

      • 缓存区
        • 将sql 文本及缓存结果,用KV形式保存再服务器内存中,如果运行相同的sql,服务器直接从缓存中去获取结果,不需要在再去解析、优化、执行sql。
        • 具体的命中条件, 工作流程, 缓存失败, 缓存内存管理, 缓存的使用时机, 缓存参数, 减少内存碎片策略等暂不展开。
    • Pluggable Storage Engines

      • 可植入的存储引擎
        • 是MySql中具体的与文件打交道的子系统。
        • 随着MyISAM在mysql5.5后被废弃, 日常开发常用的也就是InnoDB了。
    • File System

      • 文件系统
        • NTFS(New Technology File System):
        • NFS(Network File System):
          • 网络文件系统, 允许网络中的计算机之间通过TCP/IP 网络共享资源。
        • SAN(Storage Area Network):
          • 存储区域网络, 建立专用于存储的区域网络,以达到存储和主机的物理分离。
          • 主要面向企业级存储。
        • NAS(Network Attached Storage):
          • 网络附加存储, 可以简单理解为便捷的局域网存储装置, 在linux系统中可以通过NFS协议挂载NAS存储。
          • NAS相对于SAN拥有自己的操作系统, 可以与各个系统更好的兼容, 且更加灵活。
    • Files & Logs

      • 文件及日志
        • InnoDB中与数据持久性, 一致性相关的日志:
          • Bin Log
            • 是mysql服务层产生的日志,常用来进行数据恢复、数据库复制,常见的mysql主从架构,就是采用slave同步master的binlog实现的
          • Redo Log
            • 记录了数据操作在物理层面的修改
            • mysql中使用了大量缓存,修改操作时会直接修改内存,而不是立刻修改磁盘
            • 事务进行中时会不断的产生redo log,在事务提交时进行一次flush操作,保存到磁盘中。
            • 当数据库或主机失效重启时,会根据redo log进行数据的恢复,如果redo log中有事务提交,则进行事务提交修改数据。
          • Undo Log
            • 进行数据修改时会记录undo log, 用于数据的撤回操作。
            • 比如,插入对应删除,修改对应修改为原来的数据,通过undo log可以实现事务回滚,并且可以根据undo log回溯到某个特定的版本的数据,实现MVCC。

    事务隔离级别

    • ACID就不说了, 老生常谈。

    • Read Uncommitted

      • 读未提交, 可以读取尚未提交的数据。
      • 缺点: 会产生脏读, 幻读, 不可重复读。
    • Read Committed

      • 读已提交(大多数数据库默认事务隔离级别, MySQL不是)
      • 优点: 避免了脏读
      • 缺点: 可能会造成不可重复读
    • Repeatable Read

      • 可重复读(MySQL 默认事务隔离级别)
      • 优点: 避免了不可重复读
      • 缺点: 可能出现幻读
    • Serializable

      • 序列化, 最高的事务隔离级别

      • 优点: 避免了脏读, 幻读, 不可重复读

      • 缺点: 代价高, 性能很低

      • 很少使用

    锁机制

    • 读锁
      • 也称共享锁, 若事务I对数据对象A加上读锁, 则事务T可以读A但不能修改A。
      • 其他事务只能再对A加读锁, 而不能加写锁, 直到I释放A上的读锁。
      • 它保证了其他事务可以读A, 但是在I释放A上的S锁之前不能对A做任何修改。
    • 写锁
      • 又称排他锁, 若事务I对数据对象加上写锁, 事务I可以读A也可以修改A。
      • 其他事务不能再对A加任何锁, 直到I释放A上的锁。
      • 这保证了其他事务在I释放A上的锁之前不能再读取和修改A
    • 表锁
      • 操作对象是数据表。
      • MySQL大多数锁策略都支持表锁,是系统开销最低但并发性最低的一个锁策略。
    • 行级锁
      • 操作对象是数据表中的一行。
      • MVCC较多使用该锁。
      • 对系统开销较大, 但处理高并发较好。

    重要字段

    • data_trx_id
      • 用来标识最近一次对本行记录做修改(insert|update)的事务的标识符, 即最后一次修改(insert|update)本行记录的事务id。
      • DB_TRX_ID记录了行的创建的时间,删除的时间在每个事件发生的时候,每行存储版本号,而不是存储事件实际发生的时间
      • 每次事务的开始此版本号都会增加。
      • 自记录时间开始,每个事物都会保存记录的系统版本号。
      • 依照事物的版本来检查每行的版本号。
    • data_poll_ptr
      • 指写入回滚段(rollback segment)的 undo log record (撤销日志记录记录)。如果一行记录被更新, 则 undo log record 包含 '重建该行记录被更新之前内容' 所必须的信息。

    “DB_TRX_ID”的图片搜索结果

    MVCC实现

    • 基本原理
      • MVCC通过在每行纪录后面保存两个隐藏的列来实现的。
        • 一个保存了行的创建时间[实际存储的是版本号]
        • 一个报存了行的过期时间(或删除时间)[实际存储的是版本号]
      • 每开始一个新的事务, 系统版本号都会自动递增
      • 事务开始时刻的系统版本号会作为事务的版本号, 用来与查询到的每行记录的版本号进行比较。
    • 在RR(Repeatable Read) 隔离级别下, MVCC具体操作如下:
      • select
        • InnoDB会根据以下两个条件检查每行记录:
          • InnoDB只查找版本早于当前事务版本的数据行。这样可以确保事务读取的行,要么是在事务开始前已经存在的,要么是事务自身插入或者修改过的。
          • 行的删除版本,要么未定义,要么大于当前事务版本号。这样可以确保事务读取到的行,在事务开始之前未被删除
      • insert
        • InnoDB为插入的每一行保存当前系统版本号作为行版本号。
      • delete
        • InnoDB为删除的每一行保存当前系统版本号作为行删除标识。
      • update
        • InnoDB为插入一行新纪录,保存当前系统版本号作为行版本号。
        • 同时,保存当前系统版本号到原来的行作为行删除标识。
    • 优点
      • 保存这两个额外系统版本号,使大多数读操作都可以不用加锁
      • 这样设计使得读数据操作很简单,性能很好
    • 缺点
      • 每行纪录都需要额外的存储空间,需要做更多的行检查工作,以及一些额外的维护工作
  • 相关阅读:
    java中eclipse控制台接受输入的方法
    java中Timer类的详细介绍(详解)
    java中Timer类的详细介绍(详解)
    java中Timer类的详细介绍(详解)
    java中Timer类的详细介绍(详解)
    java中ReentrantLock类的详细介绍(详解)
    java中ReentrantLock类的详细介绍(详解)
    java中ReentrantLock类的详细介绍(详解)
    java中ReentrantLock类的详细介绍(详解)
    Spring中WebApplicationInitializer的理解
  • 原文地址:https://www.cnblogs.com/ronnieyuan/p/12203052.html
Copyright © 2020-2023  润新知