数据库同步工具
sqlserver,Mysql数据同步软件

【mysql 事务实现原理】

在线QQ客服:1922638

专业的SQL Server、MySQL数据库同步软件

我相信每个人都使用事务并了解他的特性,例如原子性,一致性,隔离性和耐用性。今天,我想与您一起研究如何执行交易。在解释之前,我想提出一个问题:
交易想要达到什么效果?

根据我的理解,它不过是可靠性并发处理。

可靠性:数据库必须确保在插入或更新操作期间引发异常,或者在数据库崩溃之前和之后数据必须保持一致。为此,我需要知道修改前后的状态,因此会有撤消日志和重做日志。

并发处理:换句话说,当多个并发请求到来,而其中一个请求影响数据修改操作时,为了避免读取脏数据,有必要将事务之间的读写隔离开隔离的程度取决于业务系统的场景,要实现这一点,必须使用MySQL的隔离级别。

下面,我将首先讨论实现事务功能的三种技术,即日志文件(重做日志和撤消日志),锁定技术和MVCC,然后讨论事务实现的原理,包括如何实现原子性,隔离它是如何实现的,等等。最后,我正在做一个总结,希望每个人都可以耐心地阅读它

  • 重做日志和撤消日志介绍

  • mysql锁定技术和MVCC基础

  • 交易实现原理

  • 摘要

1.重做日志

什么是重做日志?

重做日志称为重做日志,用于实现事务持久性。日志文件由两部分组成:重做日志缓冲区(重做日志缓冲区)和重做日志文件(重做日志),前者在内存中,后者在磁盘中。提交交易后,所有修改的信息将存储在日志中。假设有一个名为tb1(id,用户名)的表,现在我们要插入数据(3,ceshi)

重做日志有什么作用?

mysql不会将每个修改实时同步到磁盘以提高性能,但是会先存储在Boffer池(缓冲池)中,并将其用作缓存。然后使用后台线程在缓冲池和磁盘之间进行同步

然后问题来了,如果在同步到来之前出现停机或断电,我该怎么办?我没有时间执行上图中的红色操作。这将导致丢失已提交事务的部分已修改信息!

因此,引入了重做日志以记录成功提交的事务的修改信息,并且重做日志将保留在磁盘上。系统重新启动后,将读取重做日志以还原最新数据。

摘要:

重做日志用于恢复数据以保证已提交事务的持久性

2.undo log

什么是撤消日志?

撤消日志称为回滚日志,用于记录修改前数据的信息。他与之前提到的重做日志完全相反,重做日志数据被修改后的信息。撤消日志主要记录数据的逻辑变化。为了在发生错误时回滚以前的操作,需要记录以前的操作,然后可以在发生错误时回滚。

还要使用上面的两个表

每次写入数据或修改数据之前,修改前的信息都会记录在撤消日志中。

撤消日志有什么作用?

撤消日志记录事务修改之前版本的数据信息,因此,如果由于系统错误或回滚操作而回滚系统,则可以使用撤消日志信息回滚到修改前的状态。 。

摘要:

undo log用于回滚数据,以确保未提交事务的原子性

1.mysql锁定技术

当有多个读取表中数据的请求时,无法采取任何措施,但是,如果多个请求中有读取请求和修改请求,则必须采取并发控制措施。否则,很可能导致不一致。
读写锁

解决上述问题非常简单,只需使用两个锁的组合来控制读写请求,这两个锁称为:

共享锁(shared lock),也称为”读取锁”

可以共享读取锁,或者多个读取请求可以共享一个锁以读取数据而不会阻塞。

排他锁,也称为”写锁”

写锁将拒绝所有其他获取该锁的请求并阻塞,直到写操作完成并释放该锁为止。

摘要:

通过读写锁,可以实现读写可以并行,但不可以读写,可以并行读写

事务隔离基于读写锁! ! !稍后再说。

2.MVCC基础

MVCC(多版本并发控制)称为多版本并发控制。

InnoDB的MVCC是通过在每行记录的后面存储两行隐藏列来实现的。这两列,一列节省了该行的创建时间,一列节省了该行的到期时间。当然,实际时间值为不是存储,而是系统版本号。

上面的摘录摘自《高性能MySQL》一书中MVCC的定义。他的主要实现思想是通过多个版本的数据实现读写分离。为了实现免读并行读写。

mysql中MVCC的实现取决于撤消日志和读取视图

  • 撤消日志:撤消日志记录一行数据的多个数据版本。

  • 读取视图:用于判断当前版本数据的可见性


前面提到的重做日志,回滚日志和锁定技术是事务的基础。

  • 事务的原子性通过撤消日志来实现

  • 通过重做日志实现事务的持久性

  • 通过(读写锁+ MVCC)实现事务隔离

  • 交易的最终老板? 一致性是通过原子性,耐用性和隔离性实现的! ! !

半天的原子性,持久性,隔离性和折腾的目的还在于确保数据一致性!

简而言之,ACID只是一个概念,事务的最终目标是确保数据的可靠性和一致性。

1.原子性的实现

什么是原子性:

必须将交易视为不可分割的最小工作单元。事务中的所有操作必须成功提交或失败并回滚。事务不可能仅执行某些操作。这是一笔交易。原子性。

上段摘自《 High Performance MySQL》一书中原子性的定义。原子性可以概括为实现所有失败或所有成功。

相信上述概念是大公司可以理解的,那么如何实现数据库?通过回滚操作。所谓的回滚操作是在发生错误异常或明确执行回滚语句时将数据还原到原始外观,因此这一次您需要使用撤消日志进行回滚。接下来,看一下实现事务原子的撤消日志

1.1?撤消日志生成

假设有两个表bank和finance,该表中的原始数据如图所示,而插入,删除和更新操作时生成的撤消日志如下图所示:

从上图可以看到,数据更改伴随着回滚日志:

(1)生成修改前数据的回滚日志(zhangsan,1000)

(2)生成修改前的数据(zhangsan,0)的回滚日志

根据上述过程,可以得出以下结论:
1.每个数据更改(插入/更新/删除)操作都伴随着撤消日志和回滚日志的生成。必须在数据持久化之前到磁盘
2.所谓的回滚是基于回滚日志执行反向操作,例如,删除的反向操作是insert,插入的反向操作是删除,更新的反向是更新等待。

思考:为什么先写日志,然后写数据库?—稍后解释

1.2?基于撤消日志的回滚

为了同时实现成功或失败,当系统中发生错误或执行回滚操作时,需要根据撤消日志回滚

回滚操作将恢复到原始状态。撤消日志记录修改数据之前的信息以及新添加和删除的数据信息。根据撤消日志,将生成一个回滚语句,例如:

(1)如果回滚日志中有新的数据记录,则会生成一条删除文章的语句

(2)如果回滚日志中有已删除的数据记录,则会生成生成文章的语句

(3)如果回滚日志中有修改数据记录,则会生成一条修改原始数据的语句

2.持久性的实现

提交事务后,其所做的更改将永久保存在数据库中。此时,即使系统崩溃,修改后的数据也不会丢失。

首先了解MySQL数据存储机制。 MySQL表数据存储在磁盘上,因此,当您要访问磁盘时,必须遍历磁盘IO,但是即使使用SSD磁盘IO也非常昂贵。为此,InnoDB提供了一个缓冲池(Buffer Pool),其中包含磁盘数据页的映射,可以用作缓存:
读取数据:缓冲池,如果它不在缓冲池中,请从磁盘读取并将其放入缓冲池;
写入数据:将首先写入缓冲池,并且缓冲池中的数据会定期同步到磁盘;

尽管这种缓冲池度量带来了性能上的质的飞跃,但它也带来了新的问题。当MySQL系统关闭并断电时,数据可能会丢失! ! !

因为我们的数据已经提交,但是此时它在缓冲池中,所以还没有时间将其保留在磁盘上,因此我们急需一种机制,该机制需要为磁盘保存提交的事务的数据。恢复数据的目的。

这样,重做日志就派上用场了。让我们看看何时生成重做日志

由于还需要存储重做日志,为什么它涉及磁盘IO?

(1)重做日志存储是顺序存储,而高速缓存同步是随机操作。

(2)缓存同步基于数据页面,并且每次传输的数据大小大于重做日志。


3.隔离实现

隔离是事务的ACID特性中最复杂的一项。 SQL标准中定义了四个隔离级别,每个级别指定了事务中的修改,这些修改在事务之间是可见的,而是不可见的。

隔离级别越低,并发性越高,但是复杂性和开销也越大。

Mysql隔离级别具有以下四个级别(从低到高):

  • 读未读? (未提交阅读)

  • 读取已提交? (提交阅读)

  • 可重复读取? (可重复阅读)

  • 可序列化? (可重复阅读)

只要对隔离级别及其实现原理有透彻的了解,就相当于了解ACID中的隔离类型。如前所述,原子性,隔离性和持久性的目的是实现一致性,但是隔离类型不同于其他两种。原子性和持久性是为了保证数据可用性,例如在停机后实现恢复,并在发生错误后回滚。

那么隔离需要做什么? ? 隔离用于管理多个并发读写请求的访问顺序。 ?此序列包括串行并行

为了清楚起见,写请求不仅涉及插入操作,而且涉及更新操作。

简而言之,从隔离的实现中,我们可以看到这是数据的可靠性和性能之间的权衡。

  • 高可靠性,低并发性能(例如可序列化)

  • 低可靠性和高并发性能(例如未提交读)

读未提交

在READ UNCOMMITTED隔离级别下,事务中的更改对于其他事务可见,即使尚未提交也是如此。事务可以读取未提交的数据,从而导致脏读。

因为读取不会添加任何锁定,所以写入操作将在读取过程中修改数据,因此将导致读取不干净。优点是可以提高并发处理的性能,并可以实现并行读写

换句话说,读取操作不能排除写入请求。

优点:并行读写,高性能

缺点:导致阅读不清

读取已提交

事务在提交之前的所有修改对于其他事务都是不可见的。其他事务可以读取提交的更改。在许多情况下,此逻辑是可以接受的。

InnoDB在READ COMMITTED中使用排他锁。读取的数据未锁定,但使用了MVCC机制。换句话说,他采用了读写分离机制

但是,此级别将导致无法读取幻像阅读问题。

什么是不可重复的?

事务中多次读取的结果不同。

为什么会有不可重复的读取?

这与READ COMMITTED级别下的MVCC机制有关。在此隔离级别中,每次做出选择时都会生成一个新的生成版本号,因此,每次读取一个选择时,它都不是副本。是另一份副本。

每个选择之间还有其他事务更新我们读取和提交的数据,然后存在不可重复的读取

可重复读取(MySQL默认隔离级别)

事务中多次读取的结果是相同的。在此级别上,可以避免查询问题,例如脏读和不可重复读。 mysql有两个实现这种隔离级别的机制,即使用读写锁和MVCC。

使用读写锁:

为什么要重复?只要不解除读取锁定,就可以在第二次读取期间读取第一笔读取数据。

优点:易于实现

缺点:无法实现并行读写

使用MVCC :

为什么要重复?因为只有一个版本可生成多次读数,所以自然会读取相同的数据。

优点:并行读写?

缺点:高实现复杂度

但是,在此隔离级别中仍然存在幻像读取问题。我计划介绍另一篇有关幻影阅读解决方案的文章。

可序列化

隔离级别是最简单的理解和最简单的实现。在隔离级别上,除了不会导致数据不一致之外,没有其他优势。

-来自”高性能MySQL”

4.实施一致性

数据库始终从一种一致状态转换为另一种一致状态。

这是一个示例:张三从银行卡向财富管理帐户转帐400

1.如果执行异常,则不能无辜减少银行卡中的钱,而是将其还原到原始状态。

2.或者,在提交事务之后,如果缓冲池尚未同步到磁盘,则缓冲池将关闭,这也是不可接受的。重新启动后,应将其还原并保留。

3.如果存在并发的事务请求,则还应进行事务之间的可见性,以避免脏读,不可重复读和幻像读。当涉及到并发时,性能和一致性通常是平衡的,并且需要进行权衡,因此隔离也违反了一致性。


本文的起点是讨论Mysql事务的实现原理。

采用了哪些技术和思想来实现交易?

  • 原子性:使用撤消日志来实现回滚

  • 耐久性:使用重做日志从故障中恢复

  • 隔离:使用锁和MVCC,所使用的优化思想是读写分离,读写并行,读写并行

  • 一致性:一致性是通过并发环境中的回滚,恢复和隔离来实现的。

未经允许不得转载:数据库同步软件|Mysql数据同步软件|sqlserver数据库同步工具|异构同步 » 【mysql 事务实现原理】

分享到:更多 ()

syncnavigator 8.6.2 企业版

联系我们联系我们