MySQL MGR : Analyse des deux indicateurs clés pour le monitoring

Ces deux indicateurs se trouvent dans la vue replication_group_member_status :

  • COUNT_TRANSACTIONS_IN_QUEUE : taille de la file d'attente en attente de validation de conflit, correspondant à la file de traitement pipeline (représentation interne m_transactions_waiting_certification). Unité : nombre de transactions.
  • COUNT_TRANSACTIONS_REMOTE_IN_APPLIER_QUEUE : taille de la file d'atttente en attente d'application (représentation interne m_transactions_waiting_apply). Unité : nombre de transactions.

Ces valeurs, en particulier la seconde, sont utilisées pour détecter le retard dans un mode monomaster. Cet article détaille leur signification et leur fonctionnement.

Origine des données et rôle du thread broadcast

Ces informations sont principalement destinées au contrôle de flux (flow control). Elles proviennent des données pipeline des nœuds locaux et distants. Comment un nœud distant reçoit-il ces données ? Un thread nommé Certifier_broadcast_thread::dispatcher transmet les informations pipeline du nœud local aux nœuds distants. Son fonctionnement est le suivant :

Toutes les 30 secondes

Le thread définit send_transaction_identifiers = true, ce qui conditionne l'inclusion des identifiants GTID dans le message de type Pipeline_stats_member_message. Ces GTID incluent committed_transactions et last_conflict_free_transaction, qui apparaissent également dans replication_group_member_status via les champs TRANSACTIONS_COMMITTED_ALL_MEMBERS et LAST_CONFLICT_FREE_TRANSACTION.

Transmission périodique des statistiques pipeline

Chaque seconde, le thread construit un message de type Pipeline_stats_member_message (type CT_PIPELINE_STATS_MEMBER_MESSAGE) et l'envoie aux nœuds distants. Ce message contient les deux indicateurs clés (m_transactions_waiting_certification et m_transactions_waiting_apply).

  • COUNT_TRANSACTIONS_IN_QUEUE (interne m_transactions_waiting_certification) : correspond à la taille de la file d'attente du pipeline de l'appler thread, obtenue via applier_module->get_message_queue_size(). Une fois le traitement terminé, la transaction est écrite dans le relay log et la file diminue. L'insertion dans cette file est effectuée par le thread xcom engine, tandis que le retrait (pop) a lieu après écriture dans le relay log. Même en mode monomaster, cette file existe, mais le traitement est plus rapide qu'en multimaster car chaque événement de transaction est soumis au pipeline (validation de conflit, génération GTID, écriture relay log, etc.).
  • COUNT_TRANSACTIONS_REMOTE_IN_APPLIER_QUEUE (interne m_transactions_waiting_apply) : provient de m_transactions_waiting_apply.load(). Cette valeur est incrémentée dans la fonction Applier_handler::handle_event après l'écriture dans le relay log. Elle est décrémentée dans le hook group_replication_trans_before_commit, qui vérifie d'abord si la transaction provient du canal applier. Pour une transaction locale (exécutée directement sur le nœud primaire), elle n'affecte pas cette valeur.

Exemple simplifié d'écriture dans le relay log et d'incrémentation de l'indicateur :

error = channel_interface.queue_packet((const char *)p->payload, p->len);
if (event->get_event_type() == binary_log::GTID_LOG_EVENT &&
    local_member_info->get_recovery_status() == Group_member_info::MEMBER_ONLINE) {
  applier_module->get_pipeline_stats_member_collector()
      ->increment_transactions_waiting_apply();
}

Ce message contient tous les indicateurs de replication_group_member_status :

  • m_transactions_certified.load() : mis à jour après certification, compte le nombre de transactions certifiées (via Certifier::certify). Présent même en monomaster.
  • m_transactions_applied.load() : transactions appliquées, incrémenté dans le hook group_replication_trans_before_commit pour les transactions du canal applier.
  • m_transactions_local.load() : transactions locales, incrémenté dans le même hook pour les sessions frontales.
  • get_negative_certified() : nombre de transactions ayant échoué à la certification.
  • get_certification_info_size() : taille de la base de certification des conflits.
  • send_transaction_identifiers : booléen activé toutes les 30 secondes, indique si les GTID locaux ont été envoyés.
  • committed_transactions : GTID des transactions globalement validées, envoyé toutes les 30 secondes via le message CT_CERTIFICATION_MESSAGE (intersection des GTID de tous les nœuds).
  • last_conflict_free_transaction : nombre de transactions sans conflit lors de la dernière certification.
  • m_transactions_local_rollback.load() : transactions locales annulées pour cause de conflit.
  • mode : indique si le contrôle de flux est activé.

Ces données sont ensuite utilisées par le contrôle de flux pour calculer les seuils de throttling. Si un ralentissement est nécessaire, les transactions subissent une attente dans le hook group_replication_trans_before_commit.

Toutes les 60 secondes

Le thread envoie le GTID_EXECUTED local aux nœuds distants via un message de type Gtid_Executed_Message (CT_CERTIFICATION_MESSAGE) via gcs_module->send_message(). Ce mécanisme sert au nettoyage de la base de certification et au calcul des GTID globalement validés. Par conséquent, les champs GTID dans replication_group_member_status peuvent être retardés de 60 à 120 secondes, tandis que les autres indicateurs sont plus réactifs (mais pas en temps réel).

Pipeline du canal applier

Quand le thread xcom engine transmet un message au thread applier, ce dernier exécute un pipeline :

event_cataloger → certification_handler → applier_handler

Ce pipeline gère la réception, la certification et l'application des transactions distantes. Pour une transaction locale, l'écriture dans le relay log n'est pas nécessaire, mais les autres étapes restent identiques.

Chargement des informations dans replication_group_member_status

La logique de chargement est la suivante :

ha_perfschema::rnd_next
 → table_replication_group_member_stats::rnd_next
   → table_replication_group_member_stats::make_row
 → PFS_engine_table::read_row
   → table_replication_group_member_stats::read_row_values

make_row lit les données, read_row_values les convertit en valeurs visibles par le DBA. Les deux indicateurs sont mappés comme suit :

case 3: /** transaction_in_queue */
  set_field_ulonglong(f, m_row.trx_in_queue);
  break;
case 9:
  set_field_ulonglong(f, m_row.trx_remote_applier_queue);

La distinction entre nœud local et nœud distant se fait dans get_group_member_stats :

  • Pour l'UUID local : applier_module->get_local_pipeline_stats()
  • Pour un UUID distant : applier_module->get_flow_control_module()->get_pipeline_stats(...)

Les statistiques des nœuds distants proviennnent des messages broadcast envoyés par chaque nœud.

Cas particulier du nœud primaire en mode monomaster

  • m_transactions_waiting_apply : normalement toujours 0, car les transactions locales ne passent pas par le relay log. Des exceptions sont possibles dans des cas spécifiques.
  • m_transactions_waiting_certification : peut être non nul sur chaque nœud, car la validation de conflit et la génération GTID sont inévitables.

La logique de séparation entre transaction locale et distante se trouve dans Certification_handler::handle_transaction_id.

Étiquettes: MySQL MGR Group Replication flow control pipeline

Publié le 15 juillet à 01h45