web-dev-qa-db-fra.com

L'esclave MySQL prend trop de temps sur "Master Master Event au journal du relais"

J'ai deux serveurs d'esclave MySQL mysql. La version DB est:

mysql> show variables like '%version%';
+-------------------------+-----------------------------------------------------+
| Variable_name           | Value                                               |
+-------------------------+-----------------------------------------------------+
| innodb_version          | 1.1.8-rel29.4                                       |
| protocol_version        | 10                                                  |
| slave_type_conversions  |                                                     |
| version                 | 5.5.29-29.4-log                                     |
| version_comment         | Percona Server (GPL), Release rel29.4, Revision 401 |
| version_compile_machine | x86_64                                              |
| version_compile_os      | Linux                                               |
+-------------------------+-----------------------------------------------------+
7 rows in set (0.00 sec)

Un développeur a dû reconstruire une grosse table sur maître, après quoi le statut de l'esclave est indiqué comme suit:

show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Queueing master event to the relay log
                  Master_Host: 10.140.10.31
                  Master_User: replicator
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000100
          Read_Master_Log_Pos: 246814935
               Relay_Log_File: relay-bin.000002
                Relay_Log_Pos: 163153081
        Relay_Master_Log_File: mysql-bin.000100
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: temp
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 244925740
              Relay_Log_Space: 165042426
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 10
1 row in set (0.01 sec)

Le Seconds_Behind_Master: 0 Valeur change de 0 un grand nombre pendant une courte période, puis revient à 0. J'ai vu que les changements sur le Master DB n'ont pas encore été écrits à des esclaves.

J'ai vérifié que l'activité de disque sur les esclaves et l'utilisation du disque est toujours très élevée, ce qui indique qu'il écrit aux journaux relais:

# iostat -dx 1
Linux 2.6.32-279.19.1.el6.centos.plus.x86_64 (hmg-slave-hoteldata2)     09/04/2014      _x86_64_        (4 CPU)

Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.01     8.99    0.49    9.65    23.04   213.78    23.34     0.05    4.45   2.28   2.31
dm-0              0.00     0.00    0.01    0.01     0.04     0.05     8.00     0.00   23.31   1.11   0.00
dm-1              0.00     0.00    0.50   18.64    23.00   213.74    12.36     0.18    9.33   1.21   2.31

Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.00   321.00    0.00  337.00     0.00  5264.00    15.62     0.87    2.59   2.59  87.20
dm-0              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
dm-1              0.00     0.00    0.00  658.00     0.00  5264.00     8.00     1.22    1.86   1.32  87.10

Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.00   315.00    0.00  345.00     0.00  5280.00    15.30     0.87    2.50   2.50  86.40
dm-0              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
dm-1              0.00     0.00    0.00  660.00     0.00  5280.00     8.00     1.27    1.92   1.31  86.40

Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.00   324.00    0.00  345.00     0.00  5352.00    15.51     0.86    2.50   2.50  86.10
dm-0              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
dm-1              0.00     0.00    0.00  669.00     0.00  5352.00     8.00     1.20    1.80   1.29  86.10

la requête qui a été couru pour reconstruire les tables était:

case 'TWN': 
        $query = "INSERT INTO Hotels.AllHotelImagesBAK (hmid, Caption, URL, Width, Height, PopOutURL, ThumbnailURL, `Default`, Source, ValidSize)
                    SELECT hmid, Caption, MainURL, Width, Height, PopOutURL, ThumbnailURL, DefaultImage, 'TWN', 'Y'
                        FROM FeedHotels.LondonTownImages 
                        INNER JOIN Hotels.HotelFeedLookup ON feedHotelID=HotelID AND feedID='TWN'
                        WHERE HotelID IN ('" . implode("','", $hotelIDs) . "')";
        break;
case 'EXP':
case 'XPP':  
        $query = "INSERT INTO Hotels.AllHotelImagesBAK (hmid, Caption, URL, Width, Height, PopOutURL, ThumbnailURL, `Default`, Source)
                    SELECT hmid, Caption, URL, Width, Height, URL, ThumbnailURL, `Default`, 'EXP' 
                        FROM FeedHotels.ExpediaImages
                        INNER JOIN Hotels.HotelFeedLookup ON feedHotelID=HotelID AND feedID='" . $feed->id . "'
                        WHERE feedHotelID IN ('" . implode("','", $hotelIDs) . "')";
        break;
case 'ORB': 
        $query = "INSERT INTO Hotels.AllHotelImagesBAK (hmid, URL, PopOutURL, ThumbnailURL, Source)
                    SELECT hmid, URL, URL, URL, 'ORB'
                        FROM FeedHotels.OrbitzImages 
                        INNER JOIN Hotels.HotelFeedLookup ON feedHotelID=HotelID AND feedID='ORB'
                        WHERE feedHotelID IN ('" . implode("','", $hotelIDs) . "')";
        break;
case 'HRS': 
        $query = "INSERT INTO Hotels.AllHotelImagesBAK (hmid, Caption, URL, Width, Height, PopOutURL, ThumbnailURL, `Default`, Source, ValidSize)
                    SELECT hmid, Location, URL, Width, Height, URL, URL, IF(`Default`='Y', 1, 0),'HRS','Y'
                        FROM FeedHotels.HRSImages 
                        INNER JOIN Hotels.HotelFeedLookup ON feedHotelID=HotelID AND feedID='HRS'
                        WHERE feedHotelID IN ('" . implode("','", $hotelIDs) . "')";
        break;
}

Je me demande ce qui cause cela et comment le résoudre. De l'aide?

3
mezi

Si la grande table était rechargée sur le maître en utilisant LOAD DATA INFILE, alors voici ce qui se passe:

  • Les journaux de relais sont utilisés pour transporter tout le fichier d'entrée.
  • Le fichier d'entrée doit être extrait à partir des journaux de relais dans un fichier Temp.
  • L'esclave doit exécuter LOAD DATA INFILE Contactez le fichier Temp extrait.

J'ai décrit ce processus dans le DBA Stackexchange avant

Vous devez laisser la réplication MySQL compléter ce processus.

Mise à jour 2014-09-07 15:40 EDT

J'ai une théorie de travail qui pourrait découvrir pourquoi le journal de relais augmente, ce qui entraîne beaucoup d'E/S écriture, et Secse_behind_master est toujours 0.

Si votre BINLOG_FORMAT est défini sur la ligne ou la mixte, ma sensation intestinale est que toutes les lignes de création de la sélection sont incorporées dans les journaux de relais de la même manière que j'ai décrit LOAD DATA INFILE, mais pas avec le même mécanisme. Pourquoi ?

LOAD DATA INFILE Incorde le fichier CSV dans les morceaux d'événement Binlog pour permettre l'extraction et la manifestation du fichier CSV dans l'esclave. Le INSERT ... SELECT devrait traiter le SELECT comme une seule transaction. Ensuite, importer toutes les modifications de la ligne dans le cadre du INSERT. Afin d'accomplir que, maître et esclave devraient utiliser Binlog_Format ROW ou MIXED. Si vous utilisiez Binlog_Format STATEMENT, la déclaration atterrirait instantanément dans les journaux de relais de l'esclave et que le Seconds_Behind_Master devrait commencer à grimper immédiatement.

C'est ma suspicion à cause de ( quelle dit la documentation MySQL sur le sujet de INSERT ... SELECT

En raison de ce problème, commençant par MySQL 5.6.4, insérer ... Sélectionnez sur la mise à jour de la touche Dupliquer et insérer Ignorer ... Sélectionner des instructions sont signalées comme dangereuses pour la réplication basée sur la relève. Avec ce changement, de telles instructions produisent un avertissement dans le journal lors de l'utilisation du mode basé sur l'instruction et sont enregistrés à l'aide du format à base de lignes lors de l'utilisation du mode mixte. (Bug # 11758262, Bug # 50439)

Cela prend une nouvelle perspective lorsque vous regardez ces rapports de bugs

Quand MySQL 5.5.18 a été publié , ce bogue était censé être corrigé

Bugs corrigés

  • Changement incompatible: Réplication: Les instructions de la liste suivante sont désormais marquées comme dangereuses pour la réplication basée sur la déclaration. Cela est dû au fait que chacune de ces déclarations dépend des résultats d'une instruction SELECT dont l'ordre ne peut pas toujours être déterminé. Lorsque vous utilisez le mode de journalisation de la déclaration, un avertissement est émis dans le journal binaire de l'une de ces déclarations; Lorsque vous utilisez le mode de journalisation mixte, l'instruction est enregistrée à l'aide du format à base de lignes.

    • Insérer ... Sélectionnez ... sur la mise à jour de la clé en double

    • Remplacer ... Sélectionnez

    • Créer une table ... Ignorer Sélectionner

    • Créer une table ... remplacer SELECT

    • Insérer Ignorer ... Sélectionnez

    • Mettre à jour Ignorer Lors de la mise à niveau, vous devez noter l'utilisation de ces instructions dans vos applications, en gardant à l'esprit qu'une instruction qui insère ou remplace les lignes obtenues à partir d'une sélection peut prendre plusieurs fois autant d'espace dans le journal binaire lorsqu'il est connecté à l'aide de la ligne format que lorsque seule la déclaration elle-même est enregistrée. En fonction du nombre et de la taille des lignes sélectionnées et insérées (ou remplacées) par de ces déclarations, la différence de taille du journal binaire après la mise en œuvre de ces instructions est commutée de la déclaration basée sur la ligne à base de lignes peut potentiellement être plusieurs commandes. de grandeur. Voir la section 15.1.2.1, "Avantages et inconvénients de la réplication basée sur la déclaration et à base de lignes." (Bug # 11758262, Bug # 50439)

Avez-vous vu cette partie qui dit

a statement that
inserts or replaces rows obtained from a SELECT can take up
many times as much space in the binary log when logged using
row-based format than when only the statement itself is
logged. Depending on the number and size of the rows selected
and inserted (or replaced) by any such statements, the
difference in size of the binary log after the logging of
these statements is switched from statement-based to row-based
can potentially be several orders of magnitude

Cela pourrait se produire car vous utilisez une version de MySQL avant 5.5.18 ou une version de MySQL qui manquait ce correctif.

Si vous passez à la relève Binlog_Format, ce phénomène de journaux de relais en croissance, d'E/S High Disk, et SECOND_BeHind_Master toujours en cours de disparition. Soit cela ou mettez à niveau votre mysql.

Mise à jour 2014-09-08 08:06 EDT

Laissez-moi faire une clarification. Personnellement, je n'aime pas Binlog_Format Rangée à cause de la façon dont les journaux bassins binaires et relais deviennent. Dans ce post, j'ai dit une déclaration d'utilisation. C'est juste ma préférence. Le plus correct pour moi de dire est: rendre le maître et ses esclaves ont exactement la même binlog_format . Il suffit de faire tout mélange. Vous devrez mordre la balle et resynchroniser l'esclave à partir de zéro.

3
RolandoMySQLDBA