Dieser Artikel bietet Ihnen eine detaillierte Einführung (Bilder und Texte) über die Transaktionsisolation und MVCC der MySQL-Datenbank. Ich hoffe, dass er für Sie hilfreich ist.
Vorwort: Eine Transaktion ist eine Abfolge von Vorgängen zum Zugriff auf die Datenbank. Das Datenbankanwendungssystem vervollständigt den Zugriff auf die Datenbank über Transaktionssätze.
1. Was ist eine Transaktion?
Transaktion muss den von ISO/IEC festgelegten ACID-Grundsätzen entsprechen. ACID ist die Abkürzung für Atomizität, Konsistenz, Isolation und Haltbarkeit. Die Bedeutung dieser vier Zustände ist:
1 Atomarität
Atomarität bedeutet, dass alle in einer Transaktion enthaltenen Vorgänge entweder erfolgreich sind oder fehlschlagen und zurückgesetzt werden. Dies ist das gleiche Konzept wie die in den beiden vorherigen Blogs vorgestellte Funktion. Wenn die Transaktion erfolgreich ist, muss sie vollständig auf die Datenbank angewendet werden. Wenn die Operation fehlschlägt, kann dies keine Auswirkungen auf die Datenbank haben .
2. Konsistenz
Konsistenz bedeutet, dass eine Transaktion die Datenbank von einem Konsistenzzustand in einen anderen umwandeln muss. Isolation
Wenn die Transaktion korrekt ist, werden die Daten geändert dürfen keiner anderen Transaktion zur Verfügung gestellt werden, das heißt, ihre möglichen Ergebnisse sollten nicht anderen Transaktionen angezeigt werden, bevor die Transaktion korrekt festgeschrieben wurde
4 Wird festgeschrieben, sind die Änderungen an den Daten in der Datenbank dauerhaft und der Festschreibungsvorgang der Transaktion geht nicht verloren, selbst wenn im Datenbanksystem ein Fehler auftritt.
2. Die Rolle von Transaktionen
Wenn mehrere Threads Transaktionen starten, um Daten in der Datenbank zu verarbeiten, muss das Datenbanksystem in der Lage sein, Isolationsvorgänge durchzuführen, um die Genauigkeit der von jedem Thread erhaltenen Daten sicherzustellen .
3. Es sind Probleme mit der Parallelität aufgetreten
1. Die erste Art der verlorenen Aktualisierung: Wenn Transaktion A widerrufen wird, werden die aktualisierten Daten der übermittelten Transaktion B überschrieben.
2 . Die zweite Klassenverlustaktualisierung: Transaktion A überschreibt die von Transaktion B übermittelten Daten, wodurch der Vorgang von Transaktion B verloren geht.3. Dirty Read: Transaktion A liest nicht festgeschriebene Daten in Transaktion B.
4 -Wiederholbarer Lesevorgang: Der von Transaktion A mehrmals gelesene Wert ist unterschiedlich, da der Wert von Transaktion B geändert und festgeschrieben wurde.
5. Phantom-Lesevorgang: Zwischen den beiden Lesevorgängen von Transaktion A hat Transaktion B Daten eingefügt.
4. Wie kann das oben genannte Problem gelöst werden?
Um das oben genannte Problem zu lösen, haben Entwickler die folgenden vier Transaktionsisolationsstufen für die MySQL-Datenbank entwickelt:
1. : erlaubt Dirty Reading bedeutet, dass Daten, die durch nicht festgeschriebene Transaktionen in anderen Sitzungen geändert wurden, gelesen werden dürfen
2. Festgeschrieben lesen: Nur festgeschriebene Daten können gelesen werden. Die meisten Datenbanken wie Oracle verwenden standardmäßig diese Ebene (keine wiederholten Lesevorgänge).
3. Abfragen innerhalb derselben Transaktion sind zu Beginn der Transaktion konsistent, InnoDB-Standardebene. Im SQL-Standard eliminiert diese Isolationsstufe nicht wiederholbare Lesevorgänge, es gibt jedoch weiterhin Phantom-Lesevorgänge, aber innoDB löst Phantom-Lesevorgänge.
4. Serialisierbar (serieller Lesevorgang): Vollständig serialisierter Lesevorgang, jeder Lesevorgang muss abgerufen werden eine gemeinsame Sperre auf Tabellenebene, und Lesen und Schreiben blockieren sich gegenseitig.
1. Sehen Sie sich die globale oder Sitzungstransaktionsisolationsstufe an
Ändern Sie die globale oder SitzungstransaktionsisolationsstufeSELECT @@global.tx_isolation, @@tx_isolation;
Gemeinsame Sperre (Lesesperre)
Sperre auf Zeilenebene
8.1 Pessimistisches Sperren
Sperren Sie die gelesenen Datensätze, um zu verhindern, dass andere Transaktionen diese Datensätze lesen und aktualisieren. Andere Transaktionen werden blockiert, bis diese Transaktion endet.
implementiert werden kann. Optimistisches Sperren ist für Multi-Read-Anwendungstypen geeignet, was den Durchsatz verbessern kann. 2. Erläuterung: Optimistisches Sperren ist eine Idee, die nichts sperrt, das heißt, es basiert nicht auf dem Transaktionsmechanismus der Datenbank . Die optimistische Sperre erfolgt vollständig auf der Ebene des Anwendungssystems. Wenn optimistisches Sperren verwendet wird, muss die Datenbank ein Versionsfeld hinzufügen, andernfalls können alle Felder nur verglichen werden. Da Gleitkommatypen jedoch nicht verglichen werden können, ist dies ohne ein Versionsfeld tatsächlich nicht möglich > 8.3 Versionsnummernmechanismus Im Allgemeinen wird der Datentabelle ein Datenversionsnummernfeld hinzugefügt, um anzugeben, wie oft die Daten geändert wurden um eins erhöht. Wenn Thread A den Datenwert aktualisieren möchte, liest er beim Einlesen der Daten auch den Versionswert. Aktualisieren Sie ihn beim Senden des Updates nur, wenn der gerade gelesene Versionswert mit dem Versionswert in der aktuellen Datenbank übereinstimmt. Versuchen Sie es andernfalls erneut . Update-Vorgang, bis das Update erfolgreich ist.
8.4 CAS-Algorithmus
Wie bereits erwähnt, implementiert MySQL standardmäßig die Isolationsstufe für wiederholbare Lesetransaktionen, kann das Problem der Phantom-Lesevorgänge jedoch nicht lösen auftreten. MySQL verwendet MVCC (Multi-version Concurrency) Control.
1.MVCC:是multiversion concurrency control的简称,也就是多版本并发控制,是个很基本的概念。MVCC的作用是让事务在并行发生时,在一定隔离级别前提下,可以保证在某个事务中能实现一致性读,也就是该事务启动时根据某个条件读取到的数据,直到事务结束时,再次执行相同条件,还是读到同一份数据,不会发生变化(不会看到被其他并行事务修改的数据)。
2.read view:InnoDB MVCC使用的内部快照的意思。在不同的隔离级别下,事务启动时(有些情况下,可能是SQL语句开始时)看到的数据快照版本可能也不同。在上面介绍的几个隔离级别下会用到 read view。
3.快照读: 就是所谓的根据read view去获取信息和数据,不会加任何的锁。
4.当前读:前读会获取得到所有已经提交数据,按照逻辑上来讲的话,在一个事务中第一次当前读和第二次当前读的中间有新的事务进行DML操作,这个时候俩次当前读的结果应该是不一致的,但是实际的情况却是在当前读的这个事务还没提交之前,所有针对当前读的数据修改和插入都会被阻塞,主要是因为next-key lock解决了当前读可能会发生幻读的情况。
next-key lock当使用主键索引进行当前读的时候,会降级为record lock(行锁)
InnoDB支持MVCC多版本控制,其中READ COMMITTED和REPEATABLE READ隔离级别是利用consistent read view(一致读视图)方式支持的。所谓的consistent read view就是在某一时刻给事务系统trx_sys打snapshot(快照),把当时的trx_sys状态(包括活跃读写事务数组)记下来,之后的所有读操作根据其事务ID(即trx_id)与snapshot中trx_sys的状态做比较,以此判断read view对事务的可见性。
REPEATABLE READ隔离级别(除了GAP锁之外)和READ COMMITTED隔离级别的差别是创建snapshot时机不同。REPEATABLE READ隔离级别是在事务开始时刻,确切的说是第一个读操作创建read view的时候,READ COMMITTED隔离级别是在语句开始时刻创建read view的。这就意味着REPEATABLE READ隔离级别下面一个事务的SELECT操作只会获取一个read view,但是READ COMMITTED隔离级别下一个事务是可以获取多个read view的。
创建/关闭read view需要持有trx_sys->mutex,会降低系统性能,5.7版本对此进行优化,在事务提交时session会cache只读事务的read view。
在InnoDB中,创建一个新事务的时候,InnoDB会将当前系统中的活跃事务列表(trx_sys->trx_list)创建一个副本(read view),副本中保存的是系统当前不应该被本事务看到的其他事务id列表。当用户在这个事务中要读取该行记录的时候,InnoDB会将该行当前的版本号与该read view进行比较。
具体的算法如下:
设该行的当前事务id为trx_id,read view中最早的事务id为trx_id_min, 最迟的事务id为trx_id_max。
如果trx_id如果trx_id>trx_id_max的话,那么表明该行记录所在的事务在本次新事务创建之后才开启,所以该行记录的当前值不可见。
如果trx_id_min
从该行记录的DB_ROLL_PTR指针所指向的回滚段中取出最新的undo-log的版本号的数据,将该可见行的值返回。
需要注意的是,新建事务(当前事务)与正在内存中commit 的事务不在活跃事务链表中。
在具体多版本控制中我们先来看下源码:
函数:read_view_sees_trx_id。 read_view中保存了当前全局的事务的范围: 【low_limit_id, up_limit_id】 1.当行记录的事务ID小于当前系统的最小活动id,就是可见的。 if (trx_id up_limit_id) { return(TRUE); } 2.当行记录的事务ID大于当前系统的最大活动id(也就是尚未分配的下一个事务的id),就是不可见的。 if (trx_id >= view->low_limit_id) { return(FALSE); } 3.当行记录的事务ID在活动范围之中时,判断是否在活动链表中,如果在就不可见,如果不在就是可见的。 for (i = 0; i <p><strong>Read view 图解</strong>:<br></p><p><img src="https://img.php.cn/upload/image/428/162/665/1553653110536794.jpg" title="1553653110536794.jpg" alt="Detaillierte Einführung in die Transaktionsisolation und MVCC der MySQL-Datenbank (Bild und Text)"></p><p style="max-width:90%">结语:笔者水平有限,文中如有不妥,请大家多多指教,MySQL数据库事务机制还有很多需要深入研究的,我们仍需不断钻研。</p><p>本篇文章到这里就已经全部结束了,更多其他精彩内容可以关注PHP中文网的<a href="//m.sbmmt.com/course/list/51.html" target="_blank">MySQL视频教程</a>栏目!</p><p></p>
Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in die Transaktionsisolation und MVCC der MySQL-Datenbank (Bild und Text). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!