Heim  >  Artikel  >  Datenbank  >  Mein Verständnis von MySQL Teil 4: Transaktionen, Isolationsstufen und MVCC

Mein Verständnis von MySQL Teil 4: Transaktionen, Isolationsstufen und MVCC

coldplay.xixi
coldplay.xixinach vorne
2020-10-27 17:03:222646Durchsuche

In der Spalte „MySQL-Tutorial“ werden MySQL-bezogene Transaktionen, Isolationsstufen und MVCC vorgestellt.

Der vierte Teil der MySQL-Reihe, der Hauptinhalt sind Transaktionen, einschließlich Transaktions-ACID-Eigenschaften, Isolationsstufen, Verständnis für schmutzige Lesevorgänge, nicht wiederholbare Lesevorgänge, Phantom-Lesevorgänge und Multi-Version-Parallelitätskontrolle (MVCC). ). Transaction kann garantieren, dass ein unteilbarer Satz atomarer Operationen entweder alle oder keine davon ausgeführt wird. Unter den in MySQL häufig verwendeten Speicher-Engines unterstützt InnoDB Transaktionen, die native MyISAM-Engine unterstützt jedoch keine Transaktionen. In diesem Artikel werden, sofern nicht anders angegeben, die folgenden Datentabellen und Daten verwendet:

CREATE TABLE `user`  (  `id` int(11) DEFAULT NULL,  `name` varchar(12) DEFAULT NULL) ENGINE = InnoDB;insert into user values(1, '刺猬');复制代码
1 Die vier Hauptmerkmale von ACID

Das erste, was Sie verstehen müssen, sind die vier Hauptmerkmale von Transaktions-ACID Atomizität (Atomizität), Konsistenz, Isolation und Haltbarkeit sind die vier Grundelemente einer Transaktion.

Mein Verständnis von MySQL Teil 4: Transaktionen, Isolationsstufen und MVCCUm die Eigenschaften von ACID im Detail zu erklären, stellen wir uns zunächst ein Szenario vor: Ich überweise Ihnen 100 Yuan.

Angenommen, dieser Vorgang kann in die folgenden Schritte unterteilt werden (vorausgesetzt, dass mein und Ihr Kontostand beide 100 Yuan betragen):

Meinen Kontostand prüfen

Mein Konto belastet 100 Yuan

100 Yuan startet die Überweisung

Überprüfen Ihr Kontostand

100 Yuan wurden Ihrem Konto gutgeschrieben

    1.1 Atomizität
  1. Die Atomizität einer Transaktion bedeutet: Eine Transaktion muss die kleinste Arbeitseinheit sein, die nicht neu aufgeteilt werden kann Erfolgreich oder beides schlägt fehl. Es ist unmöglich, nur einen Teil der Vorgänge in einer Transaktion auszuführen.
  2. Im obigen Überweisungsszenario erfordert die Atomizität, dass diese fünf Schritte entweder alle ausgeführt werden oder nicht. Es ist unmöglich, dass 100 Yuan von meinem Konto abgebucht werden, aber 100 Yuan werden Ihrem Konto nicht gutgeschrieben.
  3. 1.2 Konsistenz von Transaktionen bedeutet: Die Datenbank wechselt immer von einem Konsistenzzustand in einen anderen. Konsistenz konzentriert sich auf die Sichtbarkeit der Daten, und der Zwischenzustand der Daten ist für die Außenwelt nicht sichtbar.
  4. 同时,事务的一致性要求符合开发人员定义的约束,如金额大于0、身高大于0等。

    在上述的转账场景中,一致性能够保证最终执行完整个转账操作后,我账户的扣款金额与你账户到账金额是一致的,同时如果我和你的账户余额不满足金额的约束(如小于0),整个事务会回滚。

    1.3 隔离性(Isolation)

    事务的隔离性是指:在一次状态转换过程中不会受到其他状态转换的影响。

    假设我和你都有100元,我发起两次转账,转账金额都是50元,下面使用伪代码来表示的操作步骤:

    1. 查询我的账户余额 read my
    2. 我的账户扣款50元 my=my-50
    3. 50元开始转移
    4. 查询你的账户余额 read yours
    5. 你的账户到账50元 yours=yours+50

    如果未保证隔离性就可能发生下面的情况:

    时刻 第一次转账 第二次转账 我的账户余额 你的账户余额
    1 read my(100)
    my=100 yours=100
    2
    read my(100) my=100 yours=100
    3 my=my-50=100-50=50
    my=50 yours=100
    4 read yours(100) my=my-50=100-50=50 my=50 yours=100
    5 yours=yours+50=100+50=150
    my=50 yours=150
    6
    read yours(150) my=50 yours=150
    7
    yours=yours+50=150+50=200 my=50 yours=200
    7 end end my=50 yours=200

    两次转账后,最终的结果是我的账户余额为50元,你的账户余额为200元,这显然是不对的。

    而如果在保证事务隔离性的情况下,就不会发生上面的情况,损失的只是一定程度上的一致性。

    1.4 持久性(Durability)

    事务的持久性是指:事务在提交以后,它所做的修改就会被永久保存到数据库。

    在上述的转账场景中,持久性就保证了在转账成功之后,我的账户余额为0,你的账户余额为200。

    2. 自动提交与隐式提交

    2.1 自动提交

    在 MySQL 中,我们可以通过 begin 或 start transaction 来开启事务,通过 commit 来关闭事务,如果 SQL 语句中没有这两个命令,默认情况下每一条 SQL 都是一个独立的事务,在执行完成后自动提交

    比如:

    update user set name='重塑' where id=1;复制代码

    假设我只执行这一条更新语句,在我关闭 MySQL 客户端然后重新打开一个新的客户端后,可以看到 user 表中的 name 字段值全变成了「重塑」,这也印证了这条更新语句在执行后已被自动提交。

    自动提交是 MySQL 的一个默认属性,可以通过 SHOW VARIABLES LIKE 'autocommit' 语句来查看,当它的值为 ON 时,就代表开启事务的自动提交。

    mysql> SHOW VARIABLES LIKE 'autocommit';
    +---------------+-------+| Variable_name | Value |
    +---------------+-------+| autocommit    | ON    |
    +---------------+-------+1 row in set (0.00 sec)复制代码

    我们可以通过 SET autocommit = OFF 来关闭事务的自动提交。

    2.2 隐式提交

    然而,即便我们已经将 autocommit 变量的值改为 OFF 关闭事务自动提交了,在执行某些 SQL 语句的时候,MySQL 还是会将事务自动提交掉,这被称为隐式提交

    会触发隐式提交的 SQL 语句有:

    • DDL(Data definition language,数据定义语言),如 create, drop, alter, truncate
    • 修改 MySQL 自带表数据的语句,如 create/drop user, grant, set password
    • 在一个事务中,开启一个新的事务,会隐式提交上一个事务,如:
    时刻 事务A 事务B
    1 begin;
    2 update user set name='重塑' where id=1;
    3
    select name from user where id=1;(N1)
    4 begin;
    5
    select name from user where id=1;(N2)

    In Transaktion B gibt es zwei Abfrageanweisungen N1 und N2. Die Ausführungsergebnisse sind N1=Hedgehog und N2=Reshape, was bewiesen werden kann.

    • Es gibt einige andere Managementaussagen, daher werde ich nicht einzeln Beispiele nennen. Sie können sie selbst baiduieren.

    3. Isolationsstufe

    Die Isolationsstufe einer Transaktion gibt die Sichtbarkeit von Änderungen an, die in einer Transaktion innerhalb und zwischen Transaktionen vorgenommen werden. Niedrigere Isolationsstufen ermöglichen in der Regel eine höhere Parallelität und einen geringeren Systemaufwand.

    Im SQL-Standard sind vier Transaktionsisolationsstufen definiert: „Read Uncommitted“, „Read Committed“, „Repeatable Read“ und „Serializable“.

    Um diese vier Isolationsstufen und ihre jeweiligen Phänomene im Detail zu erklären, gehen wir davon aus, dass zwei Transaktionen ausgeführt werden sollen. Der Ausführungsinhalt lautet wie folgt:

    7commit;8Name vom Benutzer auswählen, wobei id=1;(N3) während der Ausführung von Transaktion A und Transaktion B , Es gibt drei Abfragen für N1, N2 und N3, deren Werte unterschiedlich sind und im Folgenden separat erläutert werden. . Wenn im obigen Szenario die Isolationsstufe der Datenbank nicht festgeschrieben gelesen wird, kann Transaktion A die geänderten Daten der nicht festgeschriebenen Transaktion B lesen, dh die Änderung von Transaktion B zum Zeitpunkt 3 ist für Transaktion A sichtbar, also N1 = Umformen, N2=umformen, N3=umformen. 3.2 Read Committed Unter der Isolationsstufe „Read Committed“ sind . 3.3 Wiederholbares LesenWiederholbares Lesen ist MySQLs Standard-Transaktionsisolationsstufe3.4 SerialisierbarUnter der serialisierbaren Isolationsstufe werden Wenn Transaktionen gleichzeitig ausgeführt werden, treten viele Probleme auf, z. B. Dirty Read (Dirty Read), nicht wiederholbares Lesen (Non-Repeatable Read) und Phantom Read usw. Im Folgenden werden diese Sachverhalte anhand verschiedener Beispiele näher erläutert. 4.1 Dirty Read
    Zeit Transaktion A Transaktion B
    1 set name='remodel' where id=1; 4 Wählen Sie den Namen des Benutzers aus, bei dem die ID = 1 ist. (N1)
    5


    3.1 Nicht festgeschrieben lesen Unter der Isolationsstufe „Nicht festgeschrieben lesen“ sind
    Änderungen in einer Transaktion für andere Transaktionen sichtbar, auch wenn sie nicht festgeschrieben sind
    Änderungen in einer Transaktion für andere Transaktionen erst sichtbar, nachdem sie festgeschrieben wurden
    Wenn im obigen Szenario die Isolationsstufe der Datenbank festgeschrieben ist, ist die Änderung von Transaktion B zum Zeitpunkt 3 für Transaktion A und die Abfrage nicht sichtbar, da Transaktion A die Daten erst lesen kann, nachdem Transaktion B übermittelt wurde Bei N2 ist es nach der Übermittlung von Transaktion B für Transaktion A sichtbar. Also N1=Igel, N2=Neuerfindung, N3=Neuerfindung.
    . Unter der Isolationsstufe „Wiederholbares Lesen“ sind die Ergebnisse immer konsistent, wenn Sie denselben Datensatz in einer Transaktion mehrmals abfragen. Wenn im obigen Szenario die Isolationsstufe der Datenbank wiederholbares Lesen ist, sind ihre Werte beide „Igel“, da sich die Abfragen N1 und N2 in einer Transaktion befinden und N3 eine Abfrage ist, die nach Transaktion A ausgeführt wird Die Änderungen an Transaktion B sind sichtbar, also N3 = Umgestaltung.
    Transaktionen seriell ausgeführt, und beim Schreiben wird eine Schreibsperre hinzugefügt. Daher treten keine Abweichungen auf. Wenn im obigen Szenario die Isolationsstufe der Datenbank serialisierbar ist, wird Transaktion A zuerst geöffnet und blockiert, wenn Transaktion B geöffnet wird. Transaktion B wird erst geöffnet, wenn Transaktion A übermittelt wird, also N1=Hedgehog, N2= Igel . Die Abfrage bei N3 wird ausgeführt, nachdem Transaktion B übermittelt wurde (Transaktion B wird zuerst blockiert und die Ausführungsreihenfolge liegt vor der N3-Abfrageanweisung), also ist N3 = Umformung. 4. Durch Isolationsstufen verursachte Probleme

    Dirty Read

    (Dirty Read) bedeutet, dass eine Transaktion Daten lesen kann, die durch eine andere nicht festgeschriebene Transaktion geändert wurden.

    Sehen Sie sich den folgenden Fall an, vorausgesetzt, dass die Isolationsstufe nicht festgeschrieben ist:

    Zeit

    Transaktion A

    Transaktion B

    1

    begin;

    2

    begin;

    3

    update Benutzer set name = 'reshape' wob 5 mit;

    Unter der nicht festgeschriebenen Lese-Isolationsstufe ist der Wert von N1 „Reshape“ und aufgrund des Rollbacks von Transaktion B ist der Wert von N2 „Igel“. Hier ist bei N1 ein Dirty Read aufgetreten. Offensichtlich handelt es sich bei dem Abfrageergebnis bei N1 um Dirty Data, was Auswirkungen auf das normale Geschäft haben wird.

    Dirty Reads treten in der Lese-Uncommitted-Isolationsstufe auf.

    4.2 Nicht wiederholbares Lesen

    Nicht wiederholbares Lesen bedeutet, dass die zweimalige Ausführung derselben Abfrage zu unterschiedlichen Ergebnissen führen kann.

    Verwenden Sie weiterhin den AB-Transaktionsfall, wenn Sie die Isolationsstufe einführen, und gehen Sie davon aus, dass die Isolationsstufe gelesen wird:

    Zeit Transaktion ATransaktion B1beginnen; ?? commit;Name vom Benutzer auswählen, wobei id=1;(N2)select name from user where id=1;(N3)Unter der Isolationsstufe „Read Committed“ können Transaktionen Daten lesen, die von anderen Transaktionen übermittelt wurden. Im obigen Fall sind die Ergebnisse N1=Igel, N2=Umformung, N3=Umformung. In Transaktion A gibt es zwei identische Abfragen N1 und N2, aber die Ergebnisse dieser beiden Abfragen sind nicht identisch. Dies ist nicht lesbar wiederholt. 4.3 Phantom ReadPhantom Read, wenn die vorherige Transaktion Datensätze in diesem Bereich liest Auch hier wird dieser neue Datensatz gelesen. Sehen Sie sich den folgenden Fall an, vorausgesetzt, dass die Isolationsstufe zu diesem Zeitpunkt wiederholbar ist: Transaktion ATransaktion. B
    4 Wählen Sie den Namen des Benutzers aus id= 1;(N1)
    5
    6
    7 commit ;
    8

    Nicht wiederholbare Lesevorgänge erfolgen in den Isolationsstufen „Read Uncommitted“ und „Read Committed“.
    (Phantom Read) bedeutet, dass, wenn eine Transaktion Datensätze in einem bestimmten Bereich liest, eine andere Transaktion einen neuen Datensatz in den Bereich einfügt
    Zeit

    1

    beginnen;

    2.Name vom Benutzer auswählen (2, '五条人') ;

    (N3)

    Transaktion A hat drei Abfragen zwischen N1 und N2, Transaktion B hat eine Einfügeanweisung ausgeführt und diese an N3 übermittelt for update.

    Das Ergebnis bei N1 ist offensichtlich nur ein „Igel“. Das Ergebnis bei N2 ist ebenfalls ein „Igel“, da Transaktion A vor Transaktion B geöffnet wird. Das Ergebnis bei N3 sollte theoretisch nur ein „Igel“ in der wiederholbaren Leseisolation sein Ebene „Igel“, aber tatsächlich ist das Ergebnis von N2 „Igel“ und „Fünf-Tiaoren“, und es kommt zu einer Phantomablesung.

    Das ist sehr seltsam. Bedeutet das nicht, dass die wiederholbare Leseisolationsstufe sicherstellen kann, dass derselbe Datensatz in einer Transaktion mehrmals abgefragt wird und die Ergebnisse immer konsistent sind? Dieses Ergebnis entspricht nicht der Definition eines wiederholbaren Lesevorgangs.

    Tatsächlich kann es unter der Isolationsstufe des wiederholbaren Lesens zu Phantom-Lesevorgängen kommen, wenn Sie „aktuelles Lesen“ verwenden.

    Aktuelles Lesen und Snapshot-Lesen werden später besprochen, wenn die Implementierungsprinzipien von Transaktionen und MVCC vorgestellt werden. Hier ist zunächst eine Schlussfolgerung.

    Phantom-Lesevorgänge werden in den Isolationsstufen „Lesen ohne Committed“, „Read Committed“ und „Repeatable Read“ durchgeführt.

    Was hier besondere Aufmerksamkeit erfordert: Phantom-Lesen und nicht wiederholbares Lesen bedeuten beide, dass die Ergebnisse derselben Abfrageanweisung in einer Transaktion unterschiedlich sind, Phantom-Lesen konzentriert sich jedoch mehr auf die Abfrage neu eingefügter Daten aus anderen Transaktionen (insert ) oder Daten, die durch andere Transaktionen gelöscht wurden (Löschen), während nicht wiederholbare Lesevorgänge einen größeren Umfang haben. Solange die Ergebnisse unterschiedlich sind, können sie als nicht wiederholbare Lesevorgänge betrachtet werden, aber im Allgemeinen sind wir der Meinung, dass nicht wiederholbare Lesevorgänge stärker im Fokus stehen zur Aktualisierung von Daten durch andere Transaktionen (Update). 4.4 Zusammenfassung

    Durch die obige Beschreibung kennen wir bereits die Konzepte der vier Isolationsstufen und die damit verbundenen Probleme. Je höher die Isolationsstufe einer Transaktion, desto stärker ist die Isolation und desto größer sind die auftretenden Probleme. Gleichzeitig gilt: Je höher die Isolationsstufe, desto schwächer ist die Parallelitätsfähigkeit.

    Die folgende Tabelle ist eine Zusammenfassung der Konzepte der Isolationsstufen und Probleme, die bei verschiedenen Isolationsstufen auftreten können:

    8 commit;
    Isolationsstufe Read commitedRead uncommittedSerialisierbar

    5. MVCC

    MVCC(Multi-Version Concurrency Control)即多版本并发控制,这是 MySQL 为了提高数据库并发性能而实现的。它可以在并发读写数据库时,保证不同事务的读-写操作并发执行,同时也能解决脏读、不可重复读、幻读等事务隔离问题。

    在前文讨论幻读的时候提到过当前读的概念,正是由于当前读,才会在可重复读的隔离级别下也会发生幻读的情况。

    在解释可重复读隔离级别下发生幻读的原因之前,首先介绍 MVCC 的实现原理。

    5.1 MVCC 的实现原理

    首先我们需要知道,InnoDB 的数据页中每一行的数据是有隐藏字段的:

    • DB_ROW_ID: 隐式主键,若表结构中未定义主键,InnoDB 会自动生成该字段作为表的主键
    • DB_TRX_ID: 事务ID,代表修改此行记录的最后一次事务ID
    • DB_ROLL_PTR: 回滚指针,指向此行记录的上一个版本(上一个事务ID对应的记录)

    每一条修改语句都会相应地记录一条回滚语句(undo log),如果把每一条回滚语句视为一条数据表中的记录,那么通过事务ID和回滚指针就可以将对同一行的修改记录看作一个链表,链表上的每一个节点就是一个快照版本,这就是 MVCC 中多版本的意思。

    举个例子,假设对 user 表中唯一的一行「刺猬」进行多次修改。

    update user set name='重塑' where id=1;update user set name='木马' where id=1;update user set name='达达' where id=1;复制代码

    那么这条记录的Mein Verständnis von MySQL Teil 4: Transaktionen, Isolationsstufen und MVCC就是:

    Mein Verständnis von MySQL Teil 4: Transaktionen, Isolationsstufen und MVCC

    在这个Mein Verständnis von MySQL Teil 4: Transaktionen, Isolationsstufen und MVCC中,头结点就是当前记录的最新版本。DB_TRX_ID 事务ID 字段是非常重要的属性,先 Mark 一下。

    除此之外,在读已提交(RC,Read Committed)和可重复读(RR,Repeatable Read)的隔离级别中,事务在启动的时候会创建一个读视图(Read View),用它来记录当前系统的活跃事务信息,通过读视图来进行本事务之间的可见性判断

    在读视图中有两个重要的属性:

    • 当前事务ID:表示生成读视图的事务的事务ID
    • 事务ID列表:表示在生成读视图时,当前系统中活跃着的事务ID列表
    • 最小事务ID:表示在生成读视图时,当前系统中活跃着的最小事务ID
    • 下一个事务ID:表示在生成读视图时,系统应该分配给下一个事务的事务ID

    需要注意下一个事务I的值,并不是事务ID列表中的最大值+1,而是当前系统中已存在过的事务的最大值+1。例如当前数据库中活跃的事务有(1,2),此时事务2提交,同时又开启了新事务,在生成的读视图中,下一个事务ID的值为3。

    我们通过将Mein Verständnis von MySQL Teil 4: Transaktionen, Isolationsstufen und MVCC与读视图两者结合起来,来进行并发事务间可见性的判断,判断规则如下(假设现在要判断事务A是否可以访问到事务B的修改记录):

    • 若事务B的当前事务ID小于事务A的最小事务ID的值,代表事务B是在事务A生成读视图之前就已经提交了的,所以事务B对于事务A来说是可见的。
    • 若事务B的当前事务ID大于或等于事务A下一个事务ID的值,代表事务B是在事务A生成读视图之后才开启,所以事务B对于事务A来说是不可见的。
    • 若事务B的当前事务ID在事务A的最小事务ID下一个事务ID之间(左闭右开,[最小事务ID, 下一个事务ID)),需要分两种情况讨论:
      • 若事务B的当前事务ID在事务A的事务ID列表中,代表创建事务A时事务B还是活跃的,未提交,所以事务B对于事务A来说是不可见的。
      • 若事务B的当前事务ID不在事务A的事务ID列表中,代表创建事务A时事务B已经提交,所以事务B对于事务A来说是可见的。

    如果事务B对于事务A来说是不可见的,就需要顺着修改记录的Mein Verständnis von MySQL Teil 4: Transaktionen, Isolationsstufen und MVCC,从回滚指针开始往前遍历,直到找到第一个对于事务A来说是可见的事务ID,或者遍历完Mein Verständnis von MySQL Teil 4: Transaktionen, Isolationsstufen und MVCC也未找到(表示这条记录对事务A不可见)。

    这就是 MVCC 的实现原理。

    5.2 Der Zeitpunkt der Erstellung der Leseansicht

    Hier muss der Zeitpunkt der Erstellung der Leseansicht beachtet werden. In der obigen Diskussion wissen wir bereits, dass eine Transaktion eine Leseansicht (Leseansicht) erstellt ) Wenn es startet und eine Transaktion startet, gibt es zwei Möglichkeiten, eine ist Transaktion starten/starten, die andere ist Transaktion mit konsistentem Snapshot starten Wenn Sie eine Transaktion starten, ist auch der Zeitpunkt für die Erstellung einer Leseansicht unterschiedlich:

    • Wenn die Transaktion mit begin/start Transaction gestartet wird, wird die Leseansicht erstellt beim Ausführen der ersten Snapshot-Leseanweisungbegin/start transaction,二是start transaction with consistent snapshot,通过这两种方式开启事务,创建读视图的时机也是不同的:
      • 如果是以 begin/start transaction 方式开启事务,读视图会在执行第一个快照读语句时创建
      • 如果以 start transaction with consistent snapshot 方式开启事务,同时便会创建读视图

      5.3 MVCC 的运行过程

      为了详细说明 MVCC 的运行过程,下面举个例子,假设当前存在有两个事务(事务隔离级别为 MySQL 默认的可重复读):

      这里需要注意的是事务的启动时机,在上面的论述中我们已经知道事务在启动时会创建一个读视图(Read View),而开启一个事务有两种方式,一是 begin/start transaction,二是start transaction with consistent snapshot,通过这两种方式开启事务,创建读视图的时机也是不同的:

      • 如果是以 begin/start transaction 方式开启事务,读视图会在执行第一个快照读语句时创建
      • 如果以 start transaction with consistent snapshot
      • Wenn mit >Transaktion mit konsistentem Snapshot starten die Methode zum Starten der Transaktion verwendet wird, wird gleichzeitig eine Leseansicht erstellt

      5.3 MVCC-Laufprozess

    Dirty Read Non-Repeatable Read Phantom Read Konzept
    Die Änderungen in der Transaktion sind für andere Transaktionen sichtbar, auch wenn sie nicht committet sind

    Transaktion Die Änderungen in werden erst nach der Übermittlung für andere Transaktionen sichtbar


    Transaktionen werden seriell ausgeführt, beim Lesen werden Lesesperren hinzugefügt und beim Schreiben werden Schreibsperren hinzugefügt
    Um den laufenden Prozess von MVCC im Detail zu erläutern, wird Folgendes angenommen: Angenommen, es gibt derzeit zwei Transaktionen (die Transaktionsisolationsstufe ist MySQLs standardmäßiger wiederholbarer Lesevorgang):
    Was hier beachtet werden muss, ist die Startzeit der TransaktionLeseansicht
  5. Wenn die Transaktion mit Transaktion mit konsistentem Snapshot starten gestartet wird, wird gleichzeitig die Leseansicht erstellt
  6. 12Transaktion mit konsistentem Snapshot starten; 3commit;
    In der obigen Diskussion wissen wir bereits, dass eine Transaktion eine erstellt, wenn sie beginnt, und es gibt zwei Möglichkeiten, eine Transaktion zu starten, eine ist Transaktion beginnen/starten, die andere ist Transaktion mit konsistentem Snapshot starten, durch diese beiden Möglichkeiten, eine Transaktion zu starten, wird der Zeitpunkt der Erstellung einer Auch die Leseansicht unterscheidet sich:
    • Wenn die Transaktion mit der Methode begin/start Transaction gestartet wird, wird die Leseansicht erstellt, wenn die erste Snapshot-Leseanweisung ausgeführt wird
    Transaktion A Transaktion B

    Transaktion mit konsistentem Snapshot starten;

    Benutzer aktualisieren set name='reshape' where id = 1; Benutzer mit ID =1;(N2)
    7

    Analysieren Sie dann den laufenden Prozess von MVCC basierend auf der oben beschriebenen Versionskette und der Leseansicht, wenn die beiden Transaktionen gestartet werden.

    Mein Verständnis von MySQL Teil 4: Transaktionen, Isolationsstufen und MVCC

    Das obige Bild ist die Leseansicht, wenn zwei Transaktionen gestartet werden. Wenn die Aktualisierungsanweisung von Transaktion B ausgeführt wird, lautet die Versionskette der Zeilen-ID = 1 wie folgt.

    mvcc2-Mein Verständnis von MySQL Teil 4: Transaktionen, Isolationsstufen und MVCC

    Sehen wir uns zunächst die Abfrageanweisung bei N1 an. Die aktuelle Transaktions-ID=2 von Transaktion B und ihr Wert ist gleich der nächsten Transaktions-ID von Transaktion A, also gemäß der oben diskutierten Sichtbarkeitsbeurteilung ist Transaktion B für Transaktion A unsichtbar und muss online entlang der Versionskette der aktuellen Zeile abgerufen werden. 事务ID=2,其值等于事务A的下一个事务ID,所以按照上文中所论述的可见性判断,事务B对于事务A来说是不可见的,需要循着当前行的Mein Verständnis von MySQL Teil 4: Transaktionen, Isolationsstufen und MVCC网上检索。

    于是循着Mein Verständnis von MySQL Teil 4: Transaktionen, Isolationsstufen und MVCC来到DB_TRX_ID=1事务ID=1的历史版本,恰巧等于事务A的事务ID值,也就是事务A开启时该行的版本,此版本对于事务A来说当然是可见的,所以读取到了id=1行的name='刺猬',即最终N1=刺猬。

    再来看N2处的查询语句,此时事务B已提交,Mein Verständnis von MySQL Teil 4: Transaktionen, Isolationsstufen und MVCC还是如上图所示,由于当前版本的事务ID等于事务A读视图中的下一个事务ID,所以当前版本的记录对于事务A来说是不可见的,所以同样N2=刺猬。

    这里需要注意的是,若例子中事务A的时刻4语句变更为对该行的更新语句,那么事务A便会等待事务B提交之后再执行更新语句,这是因为事务B未提交,即事务B对于id=1行的写锁未释放,而事务A也要更新该行,必须是更新当前的最新版本(当前读)才可以,所以事务A就被阻塞了,必须等待事务B对该行的写锁释放,才会继续执行更新语句。

    5.4 RC 与 RR 生成读视图的时机对比

    上面所讨论的 MVCC 运行过程都是针对可重复读(RR, Repeatable Read)隔离级别的,如果是读已提交(RC, Read Committed)级别呢?

    上文中已经讨论过读已提交隔离级别中关于不可重复读的情况了,这里就不再举例,直接给出结论就可以了。

    • 可重复读(RR, Repeatable Read)隔离级别下生成读视图(Read View)的时机是开启事务的时候
    • 读已提交(RC, Read Committed)隔离级别下生成读视图(Read View)的时机是每一条语句执行前

    对于上文中描述 MVCC 执行过程中的例子,如果隔离级别是读已提交(RC, Read Committed):

    • N1处的查询语句,由于事务B还未提交,事务A可见的版本依旧是事务ID=1的版本,所以N1=刺猬
    • N2处的查询语句,事务B已提交,N2处查询语句执行时也会生成读视图,其当前事务ID=3,而在该记录的Mein Verständnis von MySQL Teil 4: Transaktionen, Isolationsstufen und MVCC中,当前版本的事务ID DB_TRX_ID=2
    • Also folgten wir der Versionskette bis zur historischen Version von DB_TRX_ID=1 Transaktions-ID=1, die zufällig dem Transaktions-ID-Wert von Transaktion A entspricht, der die Version der Zeile ist, als Transaktion A wurde gestartet. Natürlich ist sie für Transaktion A sichtbar, daher wird der Name = 'Hedgehog' in Zeile id = 1 gelesen, dh der endgültige N1 = Hedgehog.

    Sehen Sie sich die Abfrageanweisung bei N2 an. Zu diesem Zeitpunkt wurde Transaktion B übermittelt und die Versionskette ist immer noch wie in der Abbildung oben dargestellt, da die Transaktions-ID der aktuellen Version mit der nächsten Transaktion übereinstimmt ID in der Leseansicht von Transaktion A, daher ist die aktuelle Version des Datensatzes für Transaktion A nicht sichtbar, also auch N2 = Hedgehog.

      Hier ist zu beachten, dass Transaktion A auf die Festschreibung von Transaktion B wartet, bevor die Aktualisierungsanweisung im Beispiel ausgeführt wird Da Transaktion B noch nicht festgeschrieben wurde, dh die Schreibsperre von Transaktion B für Zeilen-ID = 1 nicht freigegeben wurde, muss Transaktion A auch die Zeile aktualisieren, die auf die neueste Version (aktueller Lesevorgang) aktualisiert werden muss, also Transaktion A ist blockiert und muss warten, bis die Schreibsperre der Transaktion B für die Zeile freigegeben wird, bevor die Aktualisierungsanweisung weiter ausgeführt wird. 5.4 Vergleich des Timings der Generierung von Leseansichten zwischen RC und RR Isolationsstufe Ja, was ist, wenn es sich um die Stufe „Read Committed“ (RC, Read Committed) handelt?
    • Die Situation bezüglich nicht wiederholbarer Lesevorgänge in der Isolationsstufe „Read Committed“ wurde oben besprochen. Wir werden hier keine Beispiele nennen und nur die Schlussfolgerung direkt ziehen.
    • Die Zeit zum Generieren einer Leseansicht (Read View) unter der Isolationsstufe „Repeatable Read“ (RR, Repeatable Read) liegt beim Start einer Transaktion. Die Leseansicht (Read View) wird unter der Read Committed (RC, (Read Committed) Isolationsstufe Das Timing liegt vor der Ausführung jeder Anweisung

    Für das oben beschriebene Beispiel im MVCC-Ausführungsprozess, wenn die Isolationsstufe Read Committed (RC, Read Committed) ist:

    Die Abfrageanweisung bei N1, Da Transaktion B noch nicht übermittelt wurde, ist die sichtbare Version von Transaktion A immer noch die Version mit der Transaktions-ID = 1, also N1 = HedgehogDie Abfrageanweisung bei N2, Transaktion B, wurde übermittelt, und die Leseansicht wird ebenfalls generiert wenn die Abfrageanweisung bei N2 ausgeführt wird und ihre aktuelle Transaktions-ID = 3 ist. In der Versionskette des Datensatzes ist die Transaktions-ID der aktuellen Version DB_TRX_ID=2 vor der Transaktions-ID des Datensatzes sichtbar N2-Abfrageanweisung, also N2 = Umformen Datensatz wird nach bestimmten Regeln gelesen5.6 Phantom-Lesevorgänge treten bei wiederholbaren Lesevorgängen auf Grund Nachdem wir MVCC verstanden haben, schauen wir uns die Gründe an, warum Phantom-Lesevorgänge unter der Isolationsstufe für wiederholbare Lesevorgänge auftreten. Wie oben erwähnt, kommt es genau aufgrund des aktuellen Lesevorgangs zu Phantom-Lesevorgängen unter der Isolationsstufe wiederholbarer Lesevorgänge. Sehen wir uns zunächst das Beispiel an. ( 1) (N2)
    3
    begin;
    4
    in Benutzerwerte einfügen (2, '五条人');
    5
    verpflichten;

    Die Abfragen bei N1 und N2 müssen sehr deutlich gemacht haben, dass es sich bei allen um „Igel“ handelt. Die bei N3 verwendete Abfrageanweisung lautet for update. Wenn Sie sie zum Abfragen verwenden, wird dem Zieldatensatz eine „Zeilenebenensperre“ hinzugefügt Sie müssen nur wissen, dass for update den Zieldatensatz sperren kann. for update,使用它进行查询就会对目标记录添加一把「行级锁」,行级锁的意义以后再说,现在只需要知道for update能够锁住目标记录就可以了。

    加锁自然是防止别人修改,那么理所当然,锁住的当然也就是记录的最新版本了。所以,在使用for update进行查询的时候,会使用当前读

    Das Sperren dient natürlich dazu, zu verhindern, dass andere es ändern. Daher wird natürlich die neueste Version des Datensatzes gesperrt. Wenn daher for update zur Abfrage verwendet wird, wird current read verwendet, um die neueste Version des Zieldatensatzes zu lesen, sodass die Abfrageanweisung bei N3 Transaktion B-Datensätze einfügt für Transaktion A nicht sichtbar sind, werden ebenfalls abgefragt, und es kommt zu Phantomlesungen.

    Die aktuellen Leseanweisungen sind:
    • Auswählen ... für Aktualisierung
    • Auswählen ... Sperren im Freigabemodus (gemeinsame Lesesperre)
    • Aktualisieren ...
    • Einfügen ...
    • Löschen ... .

    6. Überprüfen Sie die Vergangenheit und lernen Sie das Neue kennen. Die vier wichtigsten ACID-Merkmale von Transaktionen Ebene der Transaktionen
    1. MVCC Das Implementierungsprinzip und der Prozess von
    2. RC- und RR-Zeitpunkt der Generierung von Leseansichten
    3. Weitere verwandte kostenlose Lernempfehlungen:
    4. MySQL-Tutorial
    (Video)

Das obige ist der detaillierte Inhalt vonMein Verständnis von MySQL Teil 4: Transaktionen, Isolationsstufen und MVCC. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.im. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen