MySQL阶段三——MySQL事务

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

Mysql事务

MySQL事务

    什么是事务

    事务的四大特性

    MySQL的事务

事务隔离级别

    并发常见问题

    四大隔离级别

编码中的事务

事务的分类

事务的实现

    redo

    undo

    purge

    group commit

事务的控制语句

mysql事务

什么是事务

 事务(transaction)是数据库区别于文件系统的重要特性之一。

    银行转账!张三转10000块到李四的账户,这其实需要两条SQL语句:

    给张三的账户减去10000元;

    给李四的账户加上10000元。

    如果在第一条SQL语句执行成功后,在执行第二条SQL语句之前,程序被中断了(可能是抛出了某个异常,也可能是其他什么原因),那么李四的账户没有加上10000元,而张三却减去了10000元。这肯定是不行的!

    你现在可能已经知道什么是事务了吧!事务中的多个操作,要么完全成功,要么完全失败!不可能存在成功一半的情况!也就是说给张三的账户减去10000元如果成功了,那么给李四的账户加上10000元的操作也必须是成功的;否则给张三减去10000元,以及给李四加上10000元都是失败的!

     

    事务的四大特性(ACID

    事务的四大特性是:

    原子性(Atomicity):事务中所有操作是不可再分割的原子单位。事务中所有操作要么全部执行成功,要么全部执行失败。

    一致性(Consistency):事务执行后,数据库状态与其它业务规则保持一致。如转账业务,无论事务执行成功与否,参与转账的两个账号余额之和应该是不变的。

    隔离性(Isolation):隔离性是指在并发操作中,不同事务之间应该隔离开来,使每个并发中的事务不会相互干扰。

    持久性(Durability):一旦事务提交成功,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证通过某种机制恢复数据。

     

    MySQL中的事务

    在默认情况下,MySQL每执行一条SQL语句,都是一个单独的事务。如果需要在一个事务中包含多条SQL语句,那么需要开启事务和结束事务。

    开启事务:start transaction

    结束事务:commitrollback

    在执行SQL语句之前,先执行strat transaction,这就开启了一个事务(事务的起点),然后可以去执行多条SQL语句,最后要结束事务,commit表示提交,即事务中的多条SQL语句所做出的影响会持久化到数据库中。或者rollback,表示回滚,即回滚到事务的起点,之前做的所有操作都被撤消了!

事务隔离级别

并发事务问题

因为并发事务导致的问题大致有5类,其中两类是更新问题,三类是读问题。

脏读(dirty read):读到另一个事务的未提交更新数据,即读取到了脏数据;

不可重复读(unrepeatable read):对同一记录的两次读取不一致,因为另一事务对该记录做了修改;

幻读(虚读)(phantom read):对同一张表的两次查询不一致,因为另一事务插入了一条记录;

不可重复读和幻读的区别:

不可重复读是读取到了另一事务的更新;

幻读是读取到了另一事务的插入(MySQL中无法测试到幻读);

四大隔离级别

4个等级的事务隔离级别,在相同数据环境下,使用相同的输入,执行相同的工作,根据不同的隔离级别,可以导致不同的结果。不同事务隔离级别能够解决的数据并发问题的能力是不同的。

1SERIALIZABLE(串行化)

不会出现任何并发问题,因为它是对同一数据的访问是串行的,非并发访问的;

性能最差;

2REPEATABLE READ(可重复读)(MySQL

防止脏读和不可重复读,不能处理幻读问题;

性能比SERIALIZABLE

3READ COMMITTED(读已提交数据)(Oracle

防止脏读,没有处理不可重复读,也没有处理幻读;

性能比REPEATABLE READ

4READ UNCOMMITTED(读未提交数据)

可能出现任何事务并发问题

性能最好

MySQL隔离级别

MySQL的默认隔离级别为Repeatable read,可以通过下面语句查看:

select @@tx_isolation


也可以通过下面语句来设置当前连接的隔离级别:

set transaction isolationlevel [41]


编码中的事务

    重点: 事务的理解

    在代码开发中,业务逻辑类中的每一个public方法,都可以看成是一个事务 !

    业务逻辑层中的每一个public方法,都是一个交易

    强调: 事务操作中的多个步骤,这些必须要使用同一个connection对象,否则无法进行事务控制


事务的分类

本地事务(local transaction) :  事务管理器控制本地资源(数据库资源,消息中间件资源)

XA事务 (二段提交) :又叫JTA, 可以管理两个系统的资源 ,两段提交,两个资源不一定在本地

    可以是两个数据库系统,也可以是一个数据库+消息中间件。

    TUXEDO(BEA公司) -->> WebLogic ,  EJB

声明式事务:spring

分布式事务:  BASE, MOM(异步通讯)


image.png


事务的实现

redo log称为重做日志,用来保证事务的原子性和持久性。undo log用来保证事务的一致性。

一、redo

基本概念

    其由两部分组成:一是内存中的重做日志缓冲,其是易丢失的;而是重做日志文件、其是持久的。

    每个InnoDB 存储引擎至少有1 个重做日志文件组(group),每个文件组下至少有2 个重做日志文件,如默认的ib_logfile0 和ib_logfile1。为了得到更高的可靠性,用户可以设置多个的镜像日志组(mirrored log groups),将不同的文件组放在不同的磁盘上,以此提高重做日志的高可用性。在日志组中每个重做日志文件的大小一致,并以循环写入的方式运行。InnoDB 存储引擎先写重做日志文件1,当达到文件的最后时,会切换至重做日志文件2,再当重做日志文件2 也被写满时,会再切换到重做日志文件1 中。

    下列参数影响着重做日志文件的属性:

  • innodb_log_file_size

  • innodb_log_files_in_group

  • innodb_mirrored_log_groups

  • innodb_log_group_home_dir

参数innodb_log_file_size 指定每个重做日志文件的大小。在InnoDB1.2.x 版本之前,重做日志文件总的大小不得大于等于4GB,而1.2.x 版本将该限制扩大为了512GB。

参数innodb_log_files_in_group 指定了日志文件组中重做日志文件的数量,默认为2。

参数innodb_mirrored_log_groups 指定了日志镜像文件组的数量,默认为1,表示只有一个日志文件组,没有镜像。


    重做日志文件的大小设置对于InnoDB 存储引擎的性能有着非常大的影响。一方面重做日志文件不能设置得太大,如果设置得很大,在恢复时可能需要很长的时间;另一方面又不能设置得太小了,否则可能导致一个事务的日志需要多次切换重做日志文件。此外,重做日志文件太小会导致频繁地发生async checkpoint,导致性能的抖动。


也许有人会问,既然同样是记录事务日志,和之前介绍的二进制日志有什么区别?

    首先,二进制日志会记录所有与MySQL 数据库有关的日志记录,包括InnoDB、MyISAM、Heap 等其他存储引擎的日志。而InnoDB 存储引擎的重做日志只记录有关该存储引擎本身的事务日志。

    其次,记录的内容不同,无论用户将二进制日志文件记录的格式设为STATEMENT还是ROW,又或者是MIXED,其记录的都是关于一个事务的具体操作内容,即该日志是逻辑日志。而InnoDB 存储引擎的重做日志文件记录的是关于每个页(Page)的更改的物理情况。

    此外,写入的时间也不同,二进制日志文件仅在事务提交前进行提交,即只写磁盘一次,不论这时该事务多大。而在事务进行的过程中,却不断有重做日志条目(redoentry)被写入到重做日志文件中。


在InnoDB 存储引擎中,对于各种不同的操作有着不同的重做日志格式。到InnoDB1.2.x 版本为止,总共定义了51 种重做日志类型。虽然各种重做日志的类型不同,但是它们有着基本的格式:

image.png


写入重做日志文件的操作不是直接写,而是先写入一个重做日志缓冲(redo log buffer)中,然后按照一定的条件顺序地写入日志文件。

image.png

从重做日志缓冲往磁盘写入时,是按512 个字节,也就是一个扇区的大小进行写入。因为扇区是写入的最小单位,因此可以保证写入必定是成功的。因此在重做日志的写入过程中不需要有doublewrite。


    主线程(master thread),知道在主线程中每秒会将重做日志缓冲写入磁盘的重做日志文件中,不论事务是否已经提交。另一个触发写磁盘的过程是由参数innodb_flush_log_at_trx_commit 控制,表示在提交(commit)操作时,处理重做日志的方式。

    参数innodb_flush_log_at_trx_commit 的有效值有0、1、2。0 代表当提交事务时,并不将事务的重做日志写入磁盘上的日志文件,而是等待主线程每秒的刷新。1 和2 不同的地方在于:1 表示在执行commit 时将重做日志缓冲同步写到磁盘,即伴有fsync 的调用。2 表示将重做日志异步写到磁盘,即写到文件系统的缓存中。因此不能完全保证在执行commit 时肯定会写入重做日志文件,只是有这个动作发生。

    因此为了保证事务的ACID 中的持久性,必须将innodb_flush_log_at_trx_commit 设置为1,也就是每当有事务提交时,就必须确保事务都已经写入重做日志文件。那么当数据库因为意外发生宕机时,可以通过重做日志文件恢复,并保证可以恢复已经提交的事务。而将重做日志文件设置为0 或2,都有可能发生恢复时部分事务的丢失。不同之处在于,设置为2 时,当MySQL 数据库发生宕机而操作系统及服务器并没有发生宕机时,由于此时未写入磁盘的事务日志保存在文件系统缓存中,当恢复时同样能保证数据不丢失。


二、undo

Undolog:在操作任何数据之前,首先将数据备份到一个地方(undolog),然后再修改;这样就算更改到一半的时候,出现意外更改没有完成,则还可以恢复原来数据。

image.png

image.png


undo log格式:insert undo log、update undo log;


三、purge

image.png

四、group commit



image.png



本文转自 叫我北北 51CTO博客,原文链接:http://blog.51cto.com/qinbin/1931089

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
22天前
|
SQL 关系型数据库 MySQL
轻松入门MySQL:保障数据完整性,MySQL事务在进销存管理系统中的应用(12)
轻松入门MySQL:保障数据完整性,MySQL事务在进销存管理系统中的应用(12)
|
1月前
|
关系型数据库 MySQL 数据库
深入探讨MySQL并发事务的问题及解决方案
深入探讨MySQL并发事务的问题及解决方案
74 0
|
1天前
|
存储 SQL 关系型数据库
MySQL 事务
MySQL 事务
|
15天前
|
存储 SQL 关系型数据库
【MySQL实战笔记】03.事务隔离:为什么你改了我还看不见?-02
【4月更文挑战第7天】数据库通过视图实现事务隔离,不同隔离级别如读未提交、读已提交、可重复读和串行化采用不同策略。以可重复读为例,MySQL使用多版本并发控制(MVCC),每个事务有其独立的视图。回滚日志在无更早视图时被删除。长事务可能导致大量存储占用,应避免。事务启动可显式用`begin`或设置`autocommit=0`,但后者可能意外开启长事务。建议使用`autocommit=1`并显式管理事务,若需减少交互,可使用`commit work and chain`。
30 5
|
27天前
|
关系型数据库 MySQL 测试技术
面试-MySQL的四种事务隔离级别
面试-MySQL的四种事务隔离级别
18 0
|
28天前
|
存储 缓存 关系型数据库
MySQL事务的四大特性是如何保证的
在MySQL数据库中还有一种二进制日志,其用来基于时间点的还原及主从复制。从表面上来看其和重做日志非常相似,都是记录了对于数据库操作的日志。但是,从本质上来看有着非常大的不同。
14 1
|
1月前
|
存储 SQL 关系型数据库
[MySQL]事务原理之redo log,undo log
[MySQL]事务原理之redo log,undo log
|
SQL 关系型数据库 MySQL
【mysql】—— 事务
【mysql】—— 事务
|
1月前
|
SQL 关系型数据库 MySQL
深入理解MySQL事务特性:保证数据完整性与一致性
深入理解MySQL事务特性:保证数据完整性与一致性
95 1
|
1月前
|
SQL 缓存 关系型数据库
MySQL的万字总结(缓存,索引,Explain,事务,redo日志等)
MySQL的万字总结(缓存,索引,Explain,事务,redo日志等)
66 0