zoukankan      html  css  js  c++  java
  • 十七、事务

    事务

    事务的ACID特性
    Atomic(原子性)
    所有语句作为一个单元全部成功执行或全部取消。不能出现中间状态。

    Consistent(一致性)
    如果数据库在事务开始时处于一致状态,则在执行该事务期间将保留一致状态。

    Isolated(隔离性)
    事务之间不相互影响。

    Durable(持久性)
    事务成功完成后,所做的所有更改都会准确地记录在数据库中。所做的更改不会丢失。

    事务的生命周期(标准的事务控制语句)

    如何开启事务
    begin ;

    标准的事务语句
    一条DML语句就是一个事务
    insert
    update
    delete

    案例

    #使用回滚修改不生效
    mysql> use world;
    mysql> begin;
    mysql> update city set countrycode='CHN' where id=1;
    mysql> update city set countrycode='CHN' where id=2;
    mysql> update city set countrycode='CHN' where id=3;
    mysql> rollback;
    

    事务的结束
    提交:
    commit;

    回滚:
    rollback;

    自动提交机制(autocommit)

    只要执行DML语句,则自动提交事务,不需要手动commit;

    #默认开启自动提交
    mysql> select @@autocommit;
    +--------------+
    | @@autocommit |
    +--------------+
    |            1 |
    +--------------+
    1 row in set (0.01 sec)
    
    #在当前会话关闭自动提交
    mysql> set autocommit=0;
    
    #全局级别关闭自动提交,需要断开重连生效
    mysql> set global autocommit=0;  
    
    #修改配置文件,重启数据库,永久生效
    $ vim /etc/my.cnf
    [mysqld]
    autocommit=0
    

    隐式提交机制
    begin;为写提交再写begin,之前begin的语句会自动提交

    mysql> begin;
    mysql> update city set countrycode='CHN' where id=1;
    mysql> update city set countrycode='CHN' where id=2;
    mysql> begin;
    

    导致自动提交的非事务语句
    DDL语句
    ALTER、CREATE、DROP

    DCL语句
    GRANT、REVOKE、SET PASSWORD

    锁定语句
    LOCK TABLES 和 UNLOCK TABLES

    导致隐式提交的语句示例:
    TRUNCATE TABLE
    LOAD DATA INFILE
    SELECT FOR UPDATE

    保证事务的ACID的相关概念

    redo log
    重做日志文件ib_logfile0~1
    位于mysql默认/data/目录下
    默认50M,轮询使用

    redo log buffer
    负责redo重做日志的读写内存区域
    保存着数据页的变化信息+数据页的LSN号

    ibd
    存储数据行和索引文件

    data buffer pool
    数据缓冲区池,负责ibd数据和索引读写的内存缓冲区域

    LSN
    日志序列号
    ibd ,redolog ,data buffer pool, redo buffer文件都有LSN号
    MySQL每次启动数据库,都会比较ibd和redolog的LSN,必须要求两者LSN一致数据库才能正常启动

    WAL
    全称叫write ahead log
    日志优先写入硬盘的方式实现持久化,持久化即把内存的数据写入到硬盘
    日志是优先于数据写入磁盘的

    脏页
    例如内存脏页,内存中发生了修改,没写入到磁盘之前,我们把内存页称之为脏页
    通过对比LSN号来实现

    CKPT
    全称叫Checkpoint
    检查点,就是将脏页刷写到磁盘的动作

    TXID
    事务id号,InnoDB会为每一个事务生成一个事务号,伴随着整个事务
    在事务开始时,begin;命令执行后就会产生一个事务ID号

    redo

    也叫重做日志或前滚日志,主要保证持久性,也就是ACID中的D
    1、记录了内存数据页的变化
    2、提供快速的事务提交
    3、提供CSR前滚功能

    案例

    1、开启事务,如将A列的值从1改为2,该数据假设在100号数据页上,一个数据页为16KB,mysql会将100号数据页加载到内存data buffer pool中。假如此时的数据页的LSN为101
    2、updata语句执行,A从1变为2,该数据页LSN从101变为102,此时redo buffer内存中记录了data buffer pool内存中数据页的变化,此条日志大小为几个字节,并记录更改后的LSN号为102(先将redo写入磁盘是因为数据小,写入快)
    3、comint;提交事务会将redo buffer中的日志信息(日志信息记录着A从1变为2的变化)写入硬盘,此时的LSN号为102
    4、此时突然断电。内存数据消失。重启数据库后MySQL会检查所有数据页的LSN是否跟redo log中记录的LSN一致。
    5、此时会将redo log加载到内存redo buffer中,重做整个过程,然后出发CKPT校验点,然后将重做的data buffer pool数据写入硬盘,从而使ibd数据页中的LSN变为102跟redo log日志中的LSN一致,从而mysql正常启动完成。
    以上过程称为CSR前滚操作。

    redo的刷写策略
    commit;命令执行时会将当前事务的redo buffer写入到磁盘
    还会顺便将一部分redo buffer中没有提交的事务日志也写入到磁盘
    MySQL在启动时,必须保证redo日志文件和数据文件LSN必须一致, 如果不一致就会触发CSR,发生如上第5点,最终使LSN保证一致,MySQL才会启动成功。
    当事务没有执行commit就断电时就要用到undo

    undo

    undo也叫回滚日志
    主要保证原子性,也就是ACID中的A,要么全部成功,要么执行不成功。

    主要功能

    1. 记录了数据修改之前的状态,如果遇到断电,方便回滚到之前的状态。
    2. rollback 将内存的数据修改恢复到修改之前
    3. 在CSR中实现未提交数据的回滚操作
    4. 实现一致性快照,配合隔离级别保证MVCC(多版本并发控制),读和写的操作不会互相阻塞。

    参考资料: 什么是隔离级别

    详见: 09.day06 事务AACID特性-redo+undo配合工作完成CSR过程 从10min开始到最后

    学习来自:郭老师博客,老男孩深标DBA课程 第五章

    今天的学习是为了以后的工作更加的轻松!
  • 相关阅读:
    git命令log与reflog的比较
    git基础仓库提交到新仓库,保存老仓库历史,并同步老仓库跟新到新仓库中
    classpath*与classpath
    fastjson将对象和json互转,@JSONField的使用及不生效
    feign接口自动生成工具
    IIS .Net Core 413错误和Request body too large解决办法
    thinphp 上传文件到七牛
    php 整合微信、支付宝扫码付款
    Jenkins:整合SonarQube8
    Jenkins:流水线打包运行boot项目
  • 原文地址:https://www.cnblogs.com/tz90/p/14485208.html
Copyright © 2011-2022 走看看