Maison >base de données >tutoriel mysql >La base de données MVCC la plus complète de tout le réseau, je suis responsable de toute explication incomplète.
Recommandations d'apprentissage associées : Tutoriel MySQL
Le nom complet est Multi-Version Concurrency Control, qui est 多版本并发控制
, principalement pour améliorer le 并发性能
de la base de données. Les articles suivants concernent uniquement le moteur InnoDB, car myIsam ne prend pas en charge les transactions.
Lorsqu'une demande de lecture ou d'écriture se produit pour la même ligne de données, elle 上锁阻塞
se fige. Mais mvcc utilise une meilleure façon de gérer les requêtes de lecture-écriture, de sorte que lorsqu'un conflit de requête de lecture-écriture se produit 不用加锁
.
Cette lecture fait référence à 快照读
, pas à 当前读
. La lecture actuelle est une opération de verrouillage, qui est 悲观锁
.
Alors comment lit-on et écrit 不用加锁
? Qu'est-ce que c'est que 快照读
et 当前读
Suivez votre 贴心老哥
et continuez à lire.
Que sont la lecture actuelle et la lecture d'instantané sous MySQL InnoDB ?
Les enregistrements de base de données qu'il lit sont tous 当前最新
de 版本
, et les données actuellement lues seront 加锁
éditées pour empêcher d'autres transactions de modifier les données. C'est une opération de 悲观锁
.
Les opérations suivantes sont des lectures actuelles :
sélectionner le verrouillage en mode partage (verrouillage partagé)
sélectionner pour la mise à jour ( verrouillage exclusif)
mettre à jour (verrouillage exclusif)
insérer (verrouillage exclusif)
supprimer (Verrouillage exclusif)
Niveau d'isolement des transactions sérialisées
La mise en œuvre de la lecture d'instantané est basée sur 多版本
Contrôle de concurrence, c'est-à-dire MVCC, puisqu'il est multi-version, les données lues par l'instantané ne sont pas forcément les dernières données, il peut s'agir des 历史版本
données précédentes.
Les opérations suivantes sont des lectures d'instantanés :
MVCCC
est un 抽象概念
qui "conserve plusieurs versions d'une donnée afin que les opérations de lecture et d'écriture soient sans conflit".
Ce concept nécessite la mise en œuvre de fonctions spécifiques, et cette implémentation spécifique est 快照读
. (La mise en œuvre spécifique est discutée ci-dessous)
Après avoir écouté l'explication de 贴心老哥
, c'était instantanément 茅厕顿开
.
读-读
: Il n'y a aucun problème et aucun contrôle de concurrence n'est requis
读-写
: Il existe des problèmes de sécurité des threads, qui peuvent entraîner des problèmes d'isolation des transactions et rencontrer des lectures sales, des lectures fantômes et des lectures non répétables
写-写
: Il existe des problèmes de sécurité des threads et il peut y avoir des problèmes de perte de mise à jour, tels que le premier type de perte de mise à jour, le deuxième type de perte de mise à jour
Le contrôle de concurrence sans verrouillage utilisé par mvcc pour résoudre les conflits de lecture-écriture consiste à allouer 单向增长
aux transactions. Enregistrez un 时间戳
, un horodatage de version et de transaction 版本
pour chaque modification de données. 相关联
de la transaction 只读取
. 开始前
数据库快照
并发读-写时
, 脏读
, etc., mais ne peut pas résoudre le problème 幻读
ci-dessus. 不可重复读
写-写 更新丢失
pour améliorer les performances de concurrence : 组合拳
MVCC + 悲观锁
MVCC + 乐观锁
, 版本链
undo日志
Read View
Chaîne de versions
. Ce sont respectivement 隐藏字段
, 天眼
et db_trx_id
. db_roll_pointer
db_row_id
6octets, dernière modification (modification/insertion)事务ID
: enregistrement 创建
cet enregistrement/最后一次修改
事务ID
de cet enregistrement.
db_roll_pointer (clé de chaîne de version)
7 octets, 回滚指针
, pointant vers 这条记录
de 上一个版本
(stocké dans le segment de restauration)
db_row_id
6 octets, implicite 自增ID
(clé primaire cachée), si la table de données est 没有主键
, InnoDB générera automatiquement un 聚簇索引
avec db_row_id.
a effectivement un 删除flag
champ caché. L'enregistrement étant 更新
ou 删除
ne signifie pas qu'il est réellement supprimé, mais que le 删除flag
a changé
est le db_row_id
généré par la base de données par défaut pour cette ligne d'enregistrements, et 唯一隐式主键
est l'opération actuelle de cet enregistrement db_trx_id
, et 事务ID
est un db_roll_pointer
utilisé pour faire correspondre 回滚指针
et pointer vers le undo日志
précédent. 旧版本
sera enregistré. Chaque journal d'annulation possède également un attribut undo日志
(le journal d'annulation correspondant à l'opération INSERT n'a pas cet attribut car l'enregistrement l'a). pas été mis à jour (version antérieure), vous pouvez ajouter ces roll_pointer
, undo日志都连起来
, donc la situation actuelle est comme l'image ci-dessous : 串成一个链表
par le <.> attribut.Nous mettons Cette liste chaînée est appelée roll_pointer
, et le nœud principal de la chaîne de versions est la dernière valeur de l'enregistrement actuel. De plus, chaque version contient également l'identifiant de transaction correspondant au moment où la version a été générée. Ces informations sont très importantes et seront utilisées pour juger de la visibilité de la version basée sur ReadView. 链表
版本链
Annuler le journal
Les données seront copiées dans 记录
avant que les informations de la table ne soient modifiées. 修改之前
undo log
Lorsque
peut être effectué 事务
via le journal d'annulation de connexion. 回滚时
数据还原
est en cours 事务
, lorsque la transaction est en cours rollback
Vous pouvez utiliser les données d'annulation du journal 原子性和一致性
. 回滚
恢复
de 快照读
, on peut se rendre compte que undo log
a. le sien 历史版本数据
. 不同事务版本号
独立的快照数据版本
représente le transaction dans Le journal d'annulation généré lors de l'insertion de nouveaux enregistrements n'est nécessaire que lorsque la transaction est annulée et peut être supprimé immédiatement après la validation de la transaction
Le journal d'annulation généré lorsqu'une transaction est mise à jour ou supprimée ; non seulement nécessaire lorsqu'une transaction est annulée, mais également lorsqu'un instantané est lu
afin qu'il ne puisse pas être supprimé par hasard, et ce journal ; n'est utilisé que lorsque la lecture rapide ou l'annulation de transaction ne l'implique pas, les journaux correspondants seront effacés uniformément par le fil de purge
( Read View), au moment où l'instantané de l'exécution de la transaction est lu, un 快照读
actuel du système de base de données sera généré. 读视图
快照
Enregistrer et maintenir le
actuellement dans le système qui ne devrait pas être vu par 活跃事务的ID
. 本事务
其他事务id列表
Read View est principalement utilisé pour
exécutons 可见性
, nous créons une Read View pour l'enregistrement et la comparons à une condition de jugement 某个事务
. peut voir les données de 快照读
, qui peuvent être les données du 当前事务
actuel ou les données de 哪个版本
dans le journal d'annulation enregistré dans cette ligne. 最新
某个版本
) dans le système actuel. trx_ids
未提交
+1" lors de la création de la vue de lecture actuelle. low_limit_id
up_limit_id
: "Le système est en transaction active 最小版本号
" lors de la création de la vue de lecture actuelle
creator_trx_id
: Création de la transaction de le numéro de version actuel de la vue en lecture ;
db_trx_id
< up_limit_id
|| db_trx_id
== creator_trx_id
(affichage)
Si l'ID de transaction de données est plus petit que le 最小活跃事务ID
dans la vue de lecture, vous pouvez être sûr que les données sont déjà dans 当前事务启之前
存在
Oui, donc ça va 显示
.
ou le 事务ID
des données est égal à creator_trx_id
, alors ces données sont la transaction en cours 自己生成的
Bien sûr, les données que vous générez peuvent être vues par vous-même, donc dans ce cas, ces données peuvent également être 显示
.
db_trx_id
>= low_limit_id
(non affiché)
Si l'ID de transaction de données est supérieur au 最大事务ID
du système actuel dans la lecture vue, cela signifie que les données sont créées 之后才产生
dans la vue de lecture actuelle, donc les données sont 不显示
. S'il est inférieur à, entrez le jugement suivant si
db_trx_id
est dans 活跃事务
(trx_ids)
不存在
: alors cela signifie lire La transaction est 已经commit
lorsque la vue est générée. Dans ce cas, les données peuvent être 显示
.
已存在
: Cela signifie que lorsque ma vue de lecture est générée, votre transaction est toujours active et n'a pas encore été validée. Les données que vous avez modifiées sont également invisibles pour ma transaction en cours.
Comme mentionné ci-dessusRead View
Utilisé pour prendre en charge RC
(Lecture validée, soumission de lecture) et RR
(Lecture répétable, lecture répétable) 隔离级别
pour 实现
.
RC
Sous le niveau d'isolement, chaque 快照读
sera 生成并获取最新
Read View
Sous le niveau d'isolement RR
, seul 同一个事务中
de 第一个快照读
créera Read View
, 之后的
les lectures d'instantanés obtiendront tous les 同一个Read View
, et les requêtes suivantes seront 不会重复生成
, donc les résultats de la requête d'une transaction sont 都是一样的
à chaque fois.
快照读
: Contrôlé via MVCC, aucun verrouillage requis. Effectuez des opérations telles que des ajouts, des suppressions, des modifications et des recherches selon la « grammaire » spécifiée dans MVCC pour éviter la lecture fantôme.
当前读
: résolvez le problème grâce au verrouillage de la touche suivante (verrouillage de rangée + verrouillage d'espace).
La première lecture d'un certain enregistrement par une certaine transaction au niveau RR La deuxième lecture d'instantané créera un instantané et une vue de lecture pour enregistrer d'autres transactions actives dans le système actuel. Après cela, lors de l'appel de la lecture d'instantané, la même vue de lecture sera toujours utilisée, tant que la transaction en cours est utilisée avant les autres. les transactions soumettent des mises à jour Lecture d'instantané, puis les lectures d'instantané suivantes utilisent la même vue de lecture, donc les modifications ultérieures ne sont pas visibles
C'est-à-dire, au niveau RR, lorsque la lecture d'instantané génère une lecture ; View, Read View enregistrera des instantanés de toutes les autres transactions actives à ce moment-là, et les modifications de ces transactions ne seront pas visibles pour la transaction en cours. Les modifications apportées par les transactions créées avant la Read View sont visibles
Au niveau RC, dans une transaction, chaque lecture d'instantané générera un nouvel instantané et une nouvelle Read View. peut voir les mises à jour soumises par d'autres transactions dans les transactions au niveau RC
Comme nous pouvons le voir dans la description ci-dessus, le soi-disant MVCC fait référence au processus d'utiliser les deux niveaux d'isolement de READ COMMITTD
et REPEATABLE READ
pour accéder aux SEELCT
enregistrés lors de l'exécution d'opérations 版本链
ordinaires. De cette façon, les 读-写
des différentes transactions sont accessibles, 写-读
opère , donc 并发执行
. 提升系统性能
Si vous souhaitez en savoir plus sur la programmation, faites attention à la rubriqueFormation php !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!