Trois principaux journaux MySQL: redo log, undo log, binlog

Le journal mysql est divisé en plusieurs catégories: journal des erreurs, journal des requêtes, journal des requêtes lentes, journal des transactions (journalisation et annulation), journal binaire (binlog).

binlog

En ce qui concerne le journal de la base de données, pour un exemple simple, après le chargement du disque dur dans la mémoire, nous effectuons une série d'opérations sur les données. Avant d'actualiser sur le disque dur, nous devons l'enregistrer à la position XXX, puis effectuer ajouts, suppressions et modifications normaux Vérifiez le fonctionnement, puis flashez sur le disque dur. Si le disque dur n'est pas flashé, après le redémarrage, chargez d'abord l'enregistrement précédent, puis les données reviendront.

Il est utilisé pour enregistrer l' opération d'écriture (sans compter la requête) effectuée par la base de données , et il est stocké sur le disque sous forme binaire. Binlog est le journal logique de mysql (cela peut être compris comme un enregistrement de l'instruction sql ), et il est enregistré par la couche Serveur. La base de données mysql utilisant n'importe quel moteur de stockage enregistrera le journal binlog.

utilisation:

  • Réplication maître-esclave: MySQL Replication ouvre binlog du côté maître, et le maître transmet son journal binaire aux esclaves et le rejoue pour atteindre l'objectif de cohérence des données maître-esclave
  • Récupération de données: récupérer des données via l'outil mysqlbinlog
  • Sauvegarde incrémentielle

Vue:

    1.   mysqlbinlog  mysql-bin.000007

    2. 命令 行 解析 SHOW BINLOG EVENTS [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count]

mysql> show binlog events in 'mysql-bin.000007' from 1190 limit 2\G

Format: STATMENT, ROW et MIXED

  • Réplication basée sur des instructions SQL (réplication basée sur des instructions, SBR), chaque instruction SQL qui modifiera les données sera enregistrée dans le journal des opérations.
  • La réplication basée sur les lignes (RBR) n'enregistre pas les informations de contexte de chaque instruction SQL, mais enregistre les données qui ont été modifiées.
  • Sur la base de la réplication mixte (MBR) des deux modes ci-dessus, la réplication générale utilise le mode précédent pour enregistrer le binlog, et les opérations qui ne peuvent pas être répliquées utilisent le mode ROW pour enregistrer le binlog. Règle de sélection: Si INSERT, UPDATE, DELETE sont utilisés pour manipuler directement la table, le format du journal sera enregistré selon le paramètre de binlog_format; si cela est fait avec des instructions de gestion telles que GRANT, REVOKE, SET PASSWORD, etc., alors L'instruction est utilisée de toute façon Enregistrement de modèle

binlog_format = contenu du journal au format de la déclaration : affiche les événements du journal binlog dans'master.000001 ';

Consigner le contenu au format binlog_format = ligne :

Cette image est toujours affichée via la commande show, mais vous ne pouvez pas encore vraiment voir les détails du journal, vous devez utiliser la commande:

mysqlbinlog -vv data / master.000001 --start-position = 8900

Pourquoi y a-t-il une scène où le format de binlog mixte existe?

  • Certains binlogs au format d'instruction peuvent entraîner des incohérences entre le maître et l'esclave, utilisez donc le format de ligne.
  • L'inconvénient du format de ligne est qu'il prend de l'espace. Par exemple, si vous utilisez une instruction delete pour supprimer 100 000 lignes de données, si vous utilisez une instruction, une instruction SQL est enregistrée dans le binlog, occupant des dizaines d'octets d'espace. Mais si vous utilisez un binlog au format ligne, vous devez écrire tous ces 100 000 enregistrements dans le binlog. Cela prendra non seulement plus d'espace, mais consommera également des ressources d'E / S pour écrire le binlog et affectera la vitesse d'exécution.
  • MySQL a pris une solution de compromis, qui est d'avoir binlog au format mixte. Le format mixte signifie que MySQL jugera lui-même si cette instruction SQL peut entraîner une incohérence entre le maître et l'esclave. Si possible, utilisez le format de ligne, sinon utilisez le format d'instruction.

Pourquoi de plus en plus de scénarios exigent-ils maintenant que le format du journal binlog MySQL soit défini sur ligne?

  • delete, le binlog au format ligne enregistrera la ligne entière de la ligne supprimée. Si vous constatez que vous avez supprimé les mauvaises données, vous pouvez directement convertir l'instruction de suppression enregistrée dans le binlog pour l'insérer et réinsérer les données supprimées pour les restaurer.
  • Si vous exécutez la mauvaise instruction d'insertion, toutes les informations de champ seront enregistrées dans le binlog de l'instruction d'insertion, qui peut être utilisée pour localiser la ligne qui vient d'être insérée. À ce stade, vous pouvez directement convertir l'instruction d'insertion en instruction de suppression et supprimer la ligne de données insérée par erreur.
  • Si l'instruction de mise à jour est exécutée, la ligne entière de données avant modification et la ligne entière de données après modification seront enregistrées dans binlog. Par conséquent, si vous exécutez l'instruction de mise à jour par erreur, il vous suffit de permuter les deux lignes d'informations avant et après l'événement, puis de l'exécuter dans la base de données.

La méthode standard d'utilisation de binlog pour restaurer des données consiste à les analyser avec l'outil mysqlbinlog, puis à envoyer le résultat complet de l'analyse à MySQL pour exécution. Similaire à la commande suivante:

将 master.000001 文件里面从第 2738 字节到第 2973 字节中间这段内容解析出来,放到 MySQL 去执行。
mysqlbinlog master.000001  --start-position=2738 --stop-position=2973 | mysql -h127.0.0.1 -P13000 -u$user -p$pwd;

Mécanisme d'écriture Binlog:

  • La logique d'écriture de binlog est relativement simple: lors de l'exécution de la transaction, le journal est d'abord écrit dans le cache binlog (écriture) , et lorsque la transaction est soumise, le cache binlog est écrit dans le fichier binlog (fsync) .
  • Le binlog d'une transaction ne peut pas être désassemblé, donc quelle que soit la taille de la transaction, il doit être écrit une fois.
  • Le système alloue un morceau de mémoire au cache binlog, un pour chaque thread. Le paramètre binlog_cache_size est utilisé pour contrôler la taille de la mémoire occupée par le cache binlog dans un seul thread. S'il dépasse la taille spécifiée par ce paramètre, il sera temporairement enregistré sur le disque.

Remarque: Le journal est écrit dans le cache de pages du système de fichiers et les données ne sont pas conservées sur le disque, de sorte que la vitesse est plus rapide. En général, nous pensons que fsync ne tient compte que des IOPS du disque.

Le moment du rinçage est contrôlé par le paramètre sync_binlog:

  • Lorsque sync_binlog = 0, cela signifie uniquement écrire à chaque fois qu'une transaction est soumise, pas fsync;
  • Lorsque sync_binlog = 1, cela signifie que fsync sera exécuté à chaque fois qu'une transaction est soumise;
  • Lorsque sync_binlog = N (N> 1), cela signifie que la transaction est écrite à chaque fois que la transaction est soumise, mais que fsync est effectuée après le cumul de N transactions.

Dans les scénarios où des goulots d'étranglement d'E / S se produisent, la définition de sync_binlog sur une valeur plus élevée peut améliorer les performances. Dans les scénarios commerciaux réels, compte tenu de la contrôlabilité de la quantité de journaux perdus, il n'est généralement pas recommandé de définir ce paramètre sur 0. Il est plus courant de le définir sur une valeur comprise entre 100 et 1000. La valeur par défaut pour les versions MySQL après 5.7.7 est 1.

refaire le journal

produire:

L'une des quatre principales caractéristiques des transactions est la persistance. Plus précisément, tant que la transaction est soumise avec succès, les modifications apportées à la base de données sont enregistrées en permanence et il est impossible de revenir à l'état d'origine pour quelque raison que ce soit. À ce stade, comment mysql assure-t-il la cohérence?

Le moyen le plus simple consiste à vider toutes les pages de données impliquées dans la transaction sur le disque chaque fois qu'une transaction est validée. Mais cela entraînera de graves problèmes de performances, qui se reflètent principalement sous deux aspects:

  • Innodb interagit avec les disques en unités de pages , et une transaction ne peut modifier que quelques octets dans une page de données. Pour le moment, vider la page de données complète sur le disque est un gaspillage de ressources!
  • Une transaction peut impliquer la modification de plusieurs pages de données, et ces pages de données ne sont pas physiquement continues, et les performances de l'utilisation de l'écriture IO aléatoire sont trop faibles!

Si MySQL est en panne et que les données du pool de tampons ne sont pas complètement vidées sur le disque, les données seront perdues et la durabilité ne pourra être garantie. Par conséquent, mysql a conçu le fichier de journalisation, en particulier, il n'enregistre que les modifications apportées à la page de données par la transaction . Relativement parlant, le fichier est plus petit et est séquentiel IO .

concept de base:

Le journal de rétablissement se compose de deux parties: l'une est le tampon de journal en mémoire ( tampon de journalisation ) et l'autre est le fichier journal sur le disque ( fichier de journalisation ). Chaque fois que mysql exécute une instruction DML, il écrit d'abord l'enregistrement dans le tampon de journalisation, puis écrit plusieurs enregistrements d'opération dans le fichier de journalisation à la fois. Cette technique d'écriture des journaux d'abord, puis d'écriture sur le disque est la technique WAL (Write-Ahead Logging) souvent mentionnée dans MySQL .

Processus d'écriture de nouveau journal:  A. tampon de journalisation -> tampon B. os -> C. fichier de journalisation

Il est temps de se rafraîchir:

Il y a trois moments pour écrire le tampon de journalisation dans le fichier de journalisation, qui peuvent être configurés via le paramètre innodb_flush_log_at_trx_commit.

0: écriture différée, actualisant les données écrites sur le disque environ toutes les secondes. En cas de panne du système, 1 seconde de données peut être perdue, entre AB dans le processus.

1: écriture en temps réel, flash en temps réel, écriture sur le disque à chaque fois que vous soumettez, mauvaises performances d'E / S.

2: Écriture en temps réel, brossage retardé, c'est-à-dire brossage toutes les secondes, entre BC dans le processus.

Le journal de rétablissement d'une transaction non validée sera également écrit sur le disque. Il y a trois horaires:

  • InnoDB a un thread d'arrière-plan qui écrira le journal dans le tampon de journalisation dans le cache de page du système de fichiers en appelant write toutes les 1 seconde, puis appelez fsync pour le conserver sur le disque. Parmi eux, le redo log au milieu de l'exécution de la transaction est également directement écrit dans le tampon de redo log.
  • Lorsque l'espace occupé par le tampon de journalisation est sur le point d'atteindre la moitié de innodb_log_buffer_size, le thread d'arrière-plan écrira activement sur le disque. Notez que puisque cette transaction n'a pas été validée, l'action d'écriture sur disque consiste simplement à écrire sans appeler fsync, c'est-à-dire qu'elle n'est laissée que dans le cache de page du système de fichiers.
  • En passant, lorsqu'une transaction parallèle est validée, le tampon de journalisation de cette transaction est conservé sur le disque.

Habituellement, nous disons que la configuration "double 1" de MySQL signifie que sync_binlog et innodb_flush_log_at_trx_commit sont mis à 1. En d'autres termes, avant qu'une transaction ne soit complètement validée, vous devez attendre deux vidages, un pour le redo log (phase de préparation) et un pour le binlog.

Formulaire d'enregistrement:

Le journal de restauration enregistre en fait les modifications de la page de données, et cet enregistrement de modification n'est pas nécessaire pour tout enregistrer, de sorte que l'implémentation de la journalisation adopte une taille fixe et une méthode d'écriture circulaire. Lorsque l'écriture atteint la fin, elle revient au début pour écrire le journal de manière circulaire.

Le LSN (Logical Sequence Number) augmente de façon monotone et est utilisé pour correspondre aux points d'écriture du journal de rétablissement. Chaque fois qu'un journal de rétablissement avec une longueur de longueur est écrit, la longueur est ajoutée à la valeur de LSN. Le LSN sera également écrit sur la page de données InnoDB En tête de chaque page, la valeur FIL_PAGE_LSNenregistre le LSN de la page , indiquant la taille du LSN lors du dernier rafraîchissement de la page . Pour s'assurer que la page de données ne sera pas exécutée plusieurs fichiers de journalisation.

La position d'écriture est la position LSN de l'enregistrement en cours du journal de rétablissement et le point de contrôle est la position LSN du journal de rétablissement correspondant une fois que l'enregistrement de modification de page de données est vidé. Il recule également et effectue une boucle. L'enregistrement doit être mis à jour vers le fichier de données avant d'effacer l'enregistrement. La partie entre write pos et check point est la partie vide du redo log, utilisée pour enregistrer de nouveaux enregistrements; entre check point et write pos est l'enregistrement de changement de page de données du redo log à placer sur le disque, lorsque write pos rattrape point de contrôle À ce moment-là , le point de contrôle sera poussé vers l'avant en premier et le poste sera libéré avant l'enregistrement d'un nouveau journal.

anti-crash

Lors du démarrage d'innodb, qu'il ait été arrêté normalement ou anormalement la dernière fois, il effectuera toujours une opération de récupération. Étant donné que le journal de rétablissement enregistre les modifications physiques des pages de données, la vitesse de récupération est beaucoup plus rapide que les journaux logiques (tels que binlog). Lors du redémarrage d'innodb, le LSN de la page de données dans le disque sera vérifié en premier. Si le LSN de la page de données est inférieur au LSN dans le journal, la récupération commencera à partir du point de contrôle.

Il existe également une situation dans laquelle le processus de vidage des points de contrôle était en cours avant le temps d'arrêt et la progression du vidage de la page de données a dépassé la progression du vidage de la page de journal. À ce stade, le LSN enregistré dans la page de données est supérieur au LSN. La partie qui dépasse la progression du journal ne sera pas refaite, car elle-même signifie que quelque chose a déjà été fait et n'a pas besoin d'être refait.

Engagement en deux phases        

 Regardez le processus d'exécution de la mise à jour dans la figure ci-dessous:

               

L'écriture du redo log est divisée en deux étapes: préparer et valider . Il s'agit d'une «validation en deux phases», qui consiste à rendre cohérente la logique entre les deux logs.  

Engagement de groupe:

Supposons qu'il existe un scénario dans lequel plusieurs transactions simultanées sont en phase de préparation. La transaction écrite en premier sera sélectionnée comme chef de file de ce groupe. Lors de l'écriture de disques, il y a déjà trois transactions dans ce groupe et le LSN devient également le groupe. Le LSN de la dernière transaction, trois transactions sont écrites sur le disque en même temps.

Dans le scénario de mise à jour simultanée, une fois que la première transaction a terminé l'écriture du tampon de journalisation, plus cette fsync est appelée tard, plus il y a de membres du groupe et meilleur est l'effet de l'enregistrement des IOPS. Ici, MySQL dispose d'un mécanisme d'optimisation:

Comme mentionné précédemment, binlog est divisé en deux étapes, write et fsync. Afin d'améliorer l'effet de soumission de groupe, MySQL a retardé le redo log en tant que fsync après l'écriture de binlog.

Ainsi, le commit en deux phases devient:

                                                             

De cette manière, binlog peut également être soumis en tant que groupe. Lorsque le binlog est synchronisé sur le disque à l'étape 4 de la figure d'exécution, si les binlogs de plusieurs transactions ont été écrits, ils sont également conservés ensemble, ce qui peut également réduire la consommation d'IOPS. Cependant, l'étape 3 est généralement exécutée très rapidement, de sorte que l'intervalle entre l'écriture et la fsync de binlog est court, ce qui entraîne moins de binlogs pouvant être assemblés pour la persistance, de sorte que l'effet de la soumission du groupe binlog n'est généralement pas aussi bon que l'effet de refaire le journal si gentil.

Si vous souhaitez améliorer l'effet de la soumission du groupe binlog, vous pouvez le faire en définissant binlog_group_commit_sync_delay et binlog_group_commit_sync_no_delay_count.

  • Le paramètre binlog_group_commit_sync_delay indique le nombre de microsecondes à retarder avant d'appeler fsync;
  • Le paramètre binlog_group_commit_sync_no_delay_count indique combien de fois fsync est appelé après l'accumulation.

Ces deux conditions sont dans une relation OR, ce qui signifie que tant que l'une des conditions est remplie, fsync sera appelée. Par conséquent, lorsque binlog_group_commit_sync_delay est défini sur 0, binlog_group_commit_sync_no_delay_count est également invalide.

À ce stade, certaines personnes se demanderont, le mécanisme WAL est de réduire les écritures sur disque, mais le journal de rétablissement et le journal du bac sont écrits chaque fois qu'une transaction est soumise, et le nombre de lectures et d'écritures de disque n'a pas diminué? Vous comprenez maintenant que le mécanisme WAL bénéficie principalement de deux aspects:

  • Le redo log et le binlog sont écrits séquentiellement, et l'écriture séquentielle sur le disque est plus rapide que l'écriture aléatoire;
  • Le mécanisme de soumission de groupe peut réduire considérablement la consommation d'IOPS du disque.

Alors, quelle est l'utilité de garder la logique cohérente entre les deux journaux? En termes simples, lorsque vous utilisez la base de données à mauvais escient ou que vous augmentez la capacité de lecture pour l'expansion de la base de données, cette performance cohérente garantit que les données de la base de données sont restaurées avant le mauvais fonctionnement ou peuvent atteindre l'objectif de cohérence maître-esclave.

binlog enregistrera toutes les opérations logiques, et se présente sous la forme d'une "écriture supplémentaire". Si votre administrateur de base de données promet que les données dans un délai d'un demi-mois peuvent être restaurées, tous les binlogs du dernier semestre seront enregistrés dans le système de sauvegarde et le système sauvegardera régulièrement la base de données entière. Le «régulier» dépend ici de l'importance du système, il peut être préparé une fois par jour ou une fois par semaine.

Lorsque vous devez restaurer à une seconde spécifiée, par exemple, à deux heures de l'après-midi un jour, une table a été supprimée par erreur à 12 heures et vous devez récupérer les données, vous pouvez le faire:

Tout d'abord, recherchez la sauvegarde complète la plus récente.Si vous avez de la chance, il peut s'agir d'une sauvegarde de la nuit dernière et d'une restauration à partir de cette sauvegarde vers la bibliothèque temporaire;

Ensuite, à partir du moment de la sauvegarde, retirez les binlogs sauvegardés à tour de rôle, et rejouez-les à l'heure précédant la suppression accidentelle de la table à midi.

Vous pouvez vous référer à ces deux étapes: https://zhuanlan.zhihu.com/p/33504555

Comment l'engagement en deux phases garantit-il la cohérence? Ou s'il n'y a pas de soumission en deux étapes, peut-on garantir la cohérence des données?

En utilisant à nouveau l'exemple de l'organigramme ci-dessus, supposons que la ligne ID actuelle = 2, la valeur du champ c est 0, puis supposons qu'après l'écriture du premier journal pendant l'exécution de l'instruction de mise à jour, le deuxième journal n'a pas encore Crash, que va-t-il se passer?

1. Écrivez d'abord le journal de rétablissement, puis binlog. Une fois le journal de rétablissement écrit, même si le système tombe en panne, les données peuvent toujours être récupérées, de sorte que la valeur de c dans cette ligne après la récupération est 1. Mais comme le binlog s'est écrasé avant la fin de l'écriture, cette instruction n'a pas été enregistrée dans le binlog à ce moment. Par conséquent, lorsque le journal est sauvegardé ultérieurement, il n'y aura aucune instruction de ce type dans le journal des opérations enregistré. Ensuite, vous constaterez que si vous devez utiliser ce binlog pour restaurer la bibliothèque temporaire, parce que le binlog de cette instruction est perdu, la bibliothèque temporaire sera manquante cette fois. La valeur de la ligne restaurée c est 0, qui est la même comme valeur de la bibliothèque d'origine.

2. Écrivez d'abord le binlog, puis le journal de rétablissement. S'il se bloque après l'écriture de binlog, puisque le journal de rétablissement n'a pas encore été écrit, la transaction est invalide après la restauration du plantage, donc la valeur de c dans cette ligne est 0. Mais le journal "changement c de 0 à 1" a été enregistré dans binlog. Par conséquent, lorsque le binlog est utilisé pour une restauration ultérieure, il existe une transaction supplémentaire. La valeur de c dans la ligne restaurée est 1, ce qui est différent de la valeur de la base de données d'origine.

Maintenant, vous pouvez voir ce qui se passe lorsque MySQL redémarre anormalement à différents moments de la validation en deux phases?

Si un plantage se produit après l'écriture du journal de rétablissement dans la phase de préparation et avant d'écrire le journal du bin, étant donné que le binlog n'a pas encore été écrit et que le journal de rétablissement n'a pas encore été validé, la transaction sera annulée lorsque le plantage est restauré. Pour le moment, binlog n'a pas encore été écrit, il ne sera donc pas transmis à la base de données de secours

Si binlog est écrit et que le journal de restauration plante avant la validation, que fera MySQL une fois le crash restauré? Si la transaction dans le journal de rétablissement a seulement une préparation complète, alors déterminez si le journal des transactions correspondant existe et est complet, et si c'est le cas, la transaction est validée.

Posez quelques questions:

1. Sans introduire deux journaux, il n'y a pas besoin de validation en deux phases. N'utilisez binlog que pour prendre en charge la récupération après incident, mais aussi pour prendre en charge l'archivage, n'est-ce pas suffisant?

Pour des raisons historiques, InnoDB n'est pas le moteur de stockage natif de MySQL. Le moteur natif de MySQL est MyISAM, et il ne prenait pas en charge la récupération après incident au début de sa conception. Avant qu'InnoDB ne rejoigne la famille de moteurs MySQL en tant que plug-in MySQL, c'était déjà un moteur qui fournissait une reprise après incident et une prise en charge des transactions.

La raison de l'implémentation est que binlog n'a pas de capacité anti-crash.

2. D'un autre côté, ne peut-il que refaire le journal?

La première est que le journal de rétablissement n'a pas la capacité d'archiver, et il écrit en boucle. La première est que le système mysql repose sur binlog, et la base de la haute disponibilité du système MySQL est la réplication binlog.

3. Dans l'instance en cours d'exécution normale, une fois les données écrites sur le disque final, sont-elles mises à jour à partir du journal de rétablissement ou du pool de mémoire tampon?

En fait, le journal de rétablissement n'enregistre pas les données complètes de la page de données, il n'a donc pas la possibilité de mettre à jour la page de données du disque par lui-même, et il n'y a aucune situation où "les données sont finalement placées sur le disque et mises à jour par le journal de rétablissement ".

4. Pourquoi le cache binlog est-il maintenu par chaque thread lui-même, alors que le tampon de redo log est partagé globalement?

La raison principale pour laquelle MySQL est conçu de cette façon est que binlog ne peut pas être "interrompu". Le journal des opérations d'une transaction doit être écrit en continu, donc une fois la transaction terminée, il est écrit ensemble dans le fichier.

Le journal de rétablissement n'a pas cette exigence. Les journaux générés au milieu peuvent être écrits dans le tampon de journalisation. Le contenu de la mémoire tampon de journalisation peut également être «gratuit», et d'autres transactions peuvent être écrites ensemble sur le disque lorsqu'elles sont validées.

5. Lors de l'exécution de la transaction, la phase de validation n'a pas encore été atteinte. En cas de plantage, le journal de rétablissement doit être perdu. Cela entraînera-t-il une incohérence entre le maître et l'esclave?

Ne fera pas. Étant donné que binlog est toujours dans le cache binlog à ce moment, il n'est pas envoyé à la base de données de secours. Après le plantage, le journal de rétablissement et le journal de stockage ont disparu. D'un point de vue commercial, la transaction n'est pas validée, les données sont donc cohérentes.

6. Si une panne survient après l'écriture du binlog, il redémarrera sans donner de réponse au client. Attendez que le client se reconnecte et constate que la transaction a été soumise avec succès. S'agit-il d'un bogue?

Ce n'est pas. Vous pouvez imaginer une situation plus extrême, la transaction entière est soumise avec succès, la validation du redo log est terminée et la base de données de secours reçoit également le binlog et l'exécute. Toutefois, la bibliothèque principale et le réseau du client sont déconnectés et les paquets qui aboutissent à des transactions réussies ne peuvent pas être renvoyés. À ce stade, le client recevra également une exception «réseau déconnecté». Cela ne peut être considéré que comme une transaction réussie, pas comme un bogue.

En fait, la garantie de sécurité de la base de données est:

Si le client reçoit un message indiquant que la transaction a réussi, la transaction doit être persistante;

Si le client reçoit un échec de transaction (tel qu'un conflit de clé primaire, une restauration, etc.), la transaction doit avoir échoué;

Si le client reçoit un message "d'exception d'exécution", l'application doit se reconnecter et poursuivre la logique suivante en interrogeant l'état actuel. À ce stade, la base de données doit uniquement assurer la cohérence interne (entre les données et le journal, entre la base de données principale et la base de données de secours).

annuler le journal

L'une des quatre caractéristiques des transactions de base de données est l'atomicité. Plus précisément, l'atomicité fait référence à une série d'opérations sur la base de données, toutes réussissent ou échouent toutes, et un succès partiel est impossible.

En fait, l'atomicité sous-jacente est obtenue grâce à un journal d'annulation. Le journal des annulations enregistre principalement les modifications logiques des données, comme une instruction INSERT, correspondant à un journal d'annulation DELETE, pour chaque instruction UPDATE, correspondant à un journal d'annulation UPDATE opposé, de sorte que lorsqu'une erreur se produit, elle peut être annulée. à avant la transaction État des données. Dans le même temps, l'annulation du journal est également la clé de la réalisation du MVCC (contrôle d'accès concurrentiel multi-version).

  • insert Undo Log est le journal des annulations généré par l'opération INSERT. Comme il s'agit du premier enregistrement des données, il est invisible pour les autres transactions. Le journal des annulations peut être supprimé directement après la validation de la transaction.
  • Le journal d'annulation de mise à jour enregistre le journal d'annulation généré par les opérations DELETE et UPDATE. En raison du mécanisme MVCC, il ne peut pas être supprimé lorsque la transaction est validée, mais il est placé dans la liste liée du journal d'annulation, en attendant que le thread de purge exécute le suppression définitive.

 emplacement de stockage:

Le moteur de stockage innodb utilise une méthode de segment pour la gestion des annulations. Le segment d'annulation est appelé le segment d'annulation et il y a 1024 segments de journal d'annulation dans chaque segment d'annulation. Dans la version précédente, un seul segment d'annulation était pris en charge, de sorte que seuls 1 024 segments du journal d'annulation pouvaient être enregistrés. Plus tard, MySQL5.5 peut prendre en charge 128 segments d'annulation, soit 128 * 1024 opérations d'annulation. Vous pouvez également personnaliser le nombre de segments d'annulation via la variable innodb_undo_logs (cette variable était innodb_rollback_segments avant la version 5.6). La valeur par défaut est 128.

Le segment de restauration est stocké dans l'espace table partagé par défaut, c'est-à-dire dans le fichier ibdata, ou un espace table UNDO indépendant peut être défini. Lorsque la pression d'écriture de la base de données est élevée, des espaces de table UNDO indépendants peuvent être définis et le nombre d'espaces de table indépendants doit être spécifié lorsque l'instance de base de données est initialisée. Séparez ensuite le journal UNDO du fichier ibdata et spécifiez le répertoire innodb_undo_directory pour le stocker, qui peut être défini sur un disque haute vitesse pour accélérer les performances de lecture et d'écriture de UNDO LOG.

Comment annuler et rétablir les transactions d'enregistrement

En supposant qu'il existe deux données A et B, les valeurs sont 1 et une transaction est lancée. Le contenu de l'opération de la transaction est le suivant: modifiez 1 à 3 et 2 à 4, puis l'enregistrement réel est le suivant (simplifié) :

  A. Début de la transaction.
  B. Enregistrer A = 1 pour annuler le journal.
  C. Modifier A = 3.
  D. Enregistrer A = 3 pour rétablir le journal.
  E. Enregistrer B = 2 pour annuler le journal.
  F. Modifier B = 4.
  G Enregistrez B = 4 pour rétablir le journal
  H. Ecrire le journal de restauration sur le disque.

  I. Engagement de transaction

 La principale considération dans la conception de Undo + Redo est d'améliorer les performances d'E / S et d'augmenter le débit de la base de données. On peut voir que BDEGH sont toutes de nouvelles opérations, mais BDEG est mis en mémoire tampon dans la zone tampon, et seul G ajoute des opérations d'E / S. Afin de garantir que Redo Log peut avoir de meilleures performances d'E / S, le Redo Log d'InnoDB est conçu comme suit Caractéristiques:

  1. Essayez de conserver le journal de rétablissement stocké dans un espace continu. Lorsque le système est démarré pour la première fois, l'espace du fichier journal sera entièrement alloué et le journal de rétablissement sera enregistré en mode d'ajout séquentiel, et les performances seront améliorées. via des E / S séquentielles.
  2. Écrivez les journaux par lots. Le journal n'est pas écrit directement dans le fichier, mais il est d'abord écrit dans le tampon de journalisation. Lorsque le journal doit être vidé sur le disque (comme la validation de transaction), de nombreux journaux sont écrits ensemble sur le disque.
  3. Les transactions simultanées partagent l'espace de stockage de Redo Log, et leurs Redo Logs sont enregistrés ensemble en alternance selon l'ordre d'exécution des instructions pour réduire l'espace occupé par le journal. Cela entraînera l'écriture sur le disque des journaux d'autres transactions non validées.
  4. Le Redo Log n'effectue que des opérations d'ajout séquentielles. Lorsqu'une transaction doit être annulée, ses enregistrements Redo Log ne sont pas supprimés du Redo Log.

Comment récupérer?

Comme mentionné ci-dessus, les transactions non validées et les transactions annulées seront également enregistrées dans le journal de rétablissement. Par conséquent, ces transactions doivent être traitées spécialement lors de la récupération.

En raison des caractéristiques de la journalisation elle-même, il est impossible de ne refaire que les transactions validées. Mais cela peut être fait, refaire toutes les transactions, y compris les transactions non validées et les transactions annulées. Ensuite, annulez ces transactions non validées via Annuler le journal.

Le mécanisme de récupération du moteur de stockage InnoDB présente plusieurs caractéristiques:

Lors de la refonte du Redo Log, je ne me souciais pas de la transaction. Lors de la récupération, il n'y a pas de comportement BEGIN, aucun COMMIT, ROLLBACK. Ne vous souciez pas de la transaction de chaque journal. Bien que les contenus liés à la transaction tels que l'identifiant de transaction soient enregistrés dans le journal de rétablissement, ces contenus ne sont considérés que comme faisant partie des données à exploiter.

Pour rendre le journal d'annulation persistant, le journal d'annulation correspondant doit être écrit sur le disque avant d'écrire le journal de rétablissement. L'association entre Undo et Redo Log rend la persistance plus compliquée. Afin de réduire la complexité, InnoDB traite le journal d'annulation comme des données, de sorte que l'opération d'enregistrement du journal d'annulation sera également enregistrée dans le journal de rétablissement. De cette manière, le journal des annulations peut être mis en cache comme des données au lieu d'être écrit sur le disque avant le journal de rétablissement.

Comme Redo n'est pas transactionnel, il réexécutera la transaction qui a été annulée. En même temps, Innodb enregistrera également l'opération lorsque la transaction sera restaurée dans le journal de rétablissement. L'opération de restauration consiste essentiellement à modifier les données, de sorte que les opérations sur les données pendant la restauration seront également enregistrées dans le journal de restauration. L'opération d'une transaction annulée pendant la récupération consiste à recommencer d'abord, puis à annuler, afin que la cohérence des données ne soit pas détruite.

Référence source: https://zhuanlan.zhihu.com/p/190886874 , https://www.cnblogs.com/wyy123/p/7880077.html , https://www.cnblogs.com/drizzle-xu/p /9713513.html

Et Lin Xiaobin "45 conférences sur le combat réel MySQL"

Je suppose que tu aimes

Origine blog.csdn.net/qq_24436765/article/details/110493416
conseillé
Classement