Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Automatyczne przełączanie awaryjne replikacji asynchronicznej w MySQL 8.0.22

 

Oracle niedawno wydał MySQL 8.0.22, a ta nowa wersja została wyposażona w nowy mechanizm przełączania awaryjnego połączenia asynchronicznego. Umożliwia repliki automatyczne nawiązanie asynchronicznego połączenia replikacji z nowym źródłem w przypadku awarii istniejącego.

W tym blogu przyjrzymy się mechanizmowi przełączania awaryjnego połączenia.

Przegląd

Mechanizm asynchronicznego przełączania awaryjnego może być używany do utrzymywania synchronizacji repliki z grupą serwerów, które współdzielą dane (slave Multisource). Przeniesie połączenie replikacji do nowego źródła, gdy istniejące połączenie źródłowe nie powiedzie się.

Zasada działania

Gdy istniejące źródło połączenia ulegnie awarii, replika najpierw ponawia to samo połączenie liczbę razy określoną przez MASTER_RETRY_COUNT. Odstęp między próbami jest ustawiany przez opcję MASTER_CONNECT_RETRY. Gdy te próby zostaną wyczerpane, mechanizm przełączania awaryjnego połączenia asynchronicznego przejmuje proces przełączania awaryjnego.

Pamiętaj, że domyślna wartość MASTER_RETRY_COUNT to 86400 (1 dzień --> 24 godziny), a domyślna wartość MASTER_CONNECT_RETRY to 60.

Aby mieć pewność, że mechanizm przełączania awaryjnego połączenia asynchronicznego może zostać szybko aktywowany, ustaw MASTER_RETRY_COUNT na minimalną liczbę, która pozwala na kilka ponownych prób z tym samym źródłem, w przypadku gdy awaria połączenia jest spowodowana przez przejściową sieć awaria.

Jak aktywować asynchroniczne przełączanie awaryjne połączenia

  • Aby aktywować asynchroniczne przełączanie awaryjne połączenia dla kanału replikacji, ustaw SOURCE_CONNECTION_AUTO_FAILOVER=1 w instrukcji CHANGE MASTER TO dla kanału.
  • Mamy dwie nowe funkcje, które pomogą dodawać i usuwać wpisy serwera z listy źródeł.
    • asynchronous_connection_failover_add_source (dodaj wpisy serwera z listy źródeł)
    • asynchronous_connection_failover_delete_source (usuń wpisy serwera z listy źródeł)

Korzystając z tych funkcji, musisz określić argumenty takie jak ('kanał','host',port,'przestrzeń_nazw_sieci',waga).

Przykład

mysql> select asynchronous_connection_failover_add_source('testing', '192.168.33.12', 3306, '', 100);

+----------------------------------------------------------------------------------------+

| asynchronous_connection_failover_add_source('testing', '192.168.33.12', 3306, '', 100) |

+----------------------------------------------------------------------------------------+

| The UDF asynchronous_connection_failover_add_source() executed successfully.           |

+----------------------------------------------------------------------------------------+

1 row in set (0.00 sec)

Serwery źródłowe należy skonfigurować w tabeli „mysql.replication_asynchronous_connection_failover”. Możemy również użyć tabeli „performance_schema.replication_asynchronous_connection_failover”, aby wyświetlić dostępne serwery na liście źródeł.

Uwaga:jeśli nie używasz żadnej replikacji opartej na kanale, ten mechanizm przełączania awaryjnego będzie działał. Podczas uruchamiania instrukcji change master nie ma potrzeby podawania nazwy kanału. Ale upewnij się, że GTID jest włączony na wszystkich serwerach.

Przypadki użycia w produkcji

Załóżmy, że masz trzy węzły PXC-5.7 z danymi produkcyjnymi działające za ProxySQL. Teraz skonfigurujemy replikację asynchroniczną opartą na kanale w węźle 1 (192.168.33.12).

  • węzeł 1 – 192.168.33.12
  • węzeł 2 - 192.168.33.13
  • węzeł 3 – 192.168.33.14
  • Odczytaj replikę — 192.168.33.15
mysql> change master to master_user='repl',master_password='[email protected]',master_host='192.168.33.12',master_auto_position=1,source_connection_auto_failover=1,master_retry_count=3,master_connect_retry=6 for channel "prod_replica";

Query OK, 0 rows affected, 2 warnings (0.01 sec)



mysql> start replica for channel 'prod_replica';

Query OK, 0 rows affected (0.00 sec)

Schemat architektury

Przypadek testowy 1

Zamierzamy dodać ustawienia przełączania awaryjnego:

 mysql> select asynchronous_connection_failover_add_source('prod_replica', '192.168.33.12', 3306, '', 100);

+---------------------------------------------------------------------------------------------+

| asynchronous_connection_failover_add_source('prod_replica', '192.168.33.12', 3306, '', 100) |

+---------------------------------------------------------------------------------------------+

| The UDF asynchronous_connection_failover_add_source() executed successfully.            |

+---------------------------------------------------------------------------------------------+

1 row in set (0.00 sec)



mysql>  select asynchronous_connection_failover_add_source('prod_replica', '192.168.33.13', 3306, '', 80);

+--------------------------------------------------------------------------------------------+

| asynchronous_connection_failover_add_source('prod_replica', '192.168.33.13', 3306, '', 80) |

+--------------------------------------------------------------------------------------------+

| The UDF asynchronous_connection_failover_add_source() executed successfully.               |

+--------------------------------------------------------------------------------------------+

1 row in set (0.01 sec)



mysql>  select asynchronous_connection_failover_add_source('prod_replica', '192.168.33.14', 3306, '', 60);

+--------------------------------------------------------------------------------------------+

| asynchronous_connection_failover_add_source('prod_replica', '192.168.33.14', 3306, '', 60) |

+--------------------------------------------------------------------------------------------+

| The UDF asynchronous_connection_failover_add_source() executed successfully.            |

+--------------------------------------------------------------------------------------------+

1 row in set (0.00 sec)




mysql> select * from mysql.replication_asynchronous_connection_failover;

+-------------------+---------------+------+-------------------+--------+

| Channel_name | Host         | Port | Network_namespace | Weight |

+-------------------+---------------+------+-------------------+--------+

| prod_replica      | 192.168.33.12 | 3306 |                   |    100 |

| prod_replica      | 192.168.33.13 | 3306 |                   |     80 |

| prod_replica      | 192.168.33.14 | 3306 |                   |     60 |

+-------------------+---------------+------+-------------------+--------+

3 rows in set (0.00 sec)

Dobrze, mogę aktywować auto_failover. Zatrzymajmy węzeł 1 (192.168.33.12) MySQL. ProxySQL będzie promować następnego odpowiedniego mastera.

[[email protected] lib]# service mysqld stop

Redirecting to /bin/systemctl stop mysqld.service

Na serwerze replik

mysql> show replica status\G

*************************** 1. row ***************************

               Slave_IO_State: Reconnecting after a failed master event read

                  Master_Host: 192.168.33.12

                  Master_User: repl

                  Master_Port: 3306

                Connect_Retry: 6

              Master_Log_File: binlog.000004

          Read_Master_Log_Pos: 1143

               Relay_Log_File: relay-bin-testing.000006

                Relay_Log_Pos: 1352

        Relay_Master_Log_File: binlog.000004

             Slave_IO_Running: Connecting

            Slave_SQL_Running: Yes

              Replicate_Do_DB: 

Last_IO_Error: error reconnecting to master '[email protected]:3306' - retry-time: 10 retries: 2 message: Can't connect to MySQL server on '192.168.33.12' (111)

Wątek we/wy jest w stanie „łączenia”. Oznacza to, że próbuje nawiązać połączenie z istniejącego źródła (węzła 1) na podstawie ustawień master_retry_count i master_connect_retry.

Po kilku sekundach widać, że source_host został zmieniony na węzeł 2 (192.168.33.13). Teraz przełączanie awaryjne zostało zakończone.

mysql> show replica status\G

*************************** 1. row ***************************

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 192.168.33.13

                  Master_User: repl

                  Master_Port: 3306

                Connect_Retry: 6

              Master_Log_File: binlog.000004

          Read_Master_Log_Pos: 1162

               Relay_Log_File: relay-bin-testing.000007

                Relay_Log_Pos: 487

        Relay_Master_Log_File: binlog.000004

             Slave_IO_Running: Yes

            Slave_SQL_Running: Yes

             Last_IO_Error:

Z dziennika błędów

2020-10-29T22:22:05.679951Z 54 [ERROR] [MY-010584] [Repl] Slave I/O for channel 'prod_replica': error reconnecting to master '[email protected]:3306' - retry-time: 10 retries: 3 message: Can't connect to MySQL server on '192.168.33.12' (111), Error_code: MY-002003

2020-10-29T22:22:05.681121Z 58 [Warning] [MY-010897] [Repl] Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.

2020-10-29T22:22:05.682830Z 58 [System] [MY-010562] [Repl] Slave I/O thread for channel 'prod_replica': connected to master '[email protected]:3306',replication started in log 'FIRST' at position 2660

2020-10-29T22:22:05.685175Z 58 [Warning] [MY-010549] [Repl] The master's UUID has changed, although this should not happen unless you have changed it manually. The old UUID was 31b5b7d0-1a25-11eb-8076-080027090068.

(END)

Przypadek testowy 2 

Podczas uruchamiania instrukcji change master nie ma potrzeby podawania nazwy kanału, niezależnie od tego, czy korzystasz z replikacji opartej na kanale, czy nie.

Przykład

mysql> change master to master_user='repl',master_password='[email protected]',master_host='192.168.33.12',master_auto_position=1,source_connection_auto_failover=1,master_retry_count=3,master_connect_retry=10;

Query OK, 0 rows affected, 2 warnings (0.01 sec)



mysql> start replica;

Query OK, 0 rows affected (0.00 sec)

Następnie dodaj ustawienia przełączania awaryjnego, jak poniżej,

select asynchronous_connection_failover_add_source('', '192.168.33.12', 3306, '', 100);

select asynchronous_connection_failover_add_source('', '192.168.33.13', 3306, '', 80);

select asynchronous_connection_failover_add_source('', '192.168.33.14', 3306, '', 60);



 mysql> select * from mysql.replication_asynchronous_connection_failover;

+--------------+---------------+------+-------------------+--------+

| Channel_name | Host          | Port | Network_namespace | Weight |

+--------------+---------------+------+-------------------+--------+

|              | 192.168.33.12 | 3306 |                   |    100 |

|              | 192.168.33.13 | 3306 |                   |     80 |

|              | 192.168.33.14 | 3306 |                   |     60 |

+--------------+---------------+------+-------------------+--------+

3 rows in set (0.00 sec)

Teraz zatrzymam węzeł 1 (192.168.33.12).

Błąd replikacji

Last_IO_Error: error connecting to master '[email protected]:3306' - retry-time: 10 retries: 2 message: Can't connect to MySQL server on '192.168.33.12' (111)

Z dziennika błędów 

2020-10-30T00:38:03.471482Z 27 [ERROR] [MY-010584] [Repl] Slave I/O for channel '': error connecting to master '[email protected]:3306' - retry-time: 10 retries: 3 message: Can't connect to MySQL server on '192.168.33.12' (111), Error_code: MY-002003

2020-10-30T00:38:03.472002Z 29 [Warning] [MY-010897] [Repl] Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.

2020-10-30T00:38:03.473493Z 29 [System] [MY-010562] [Repl] Slave I/O thread for channel '': connected to master '[email protected]:3306',replication started in log 'FIRST' at position 234

2020-10-30T00:38:03.475471Z 29 [Warning] [MY-010549] [Repl] The master's UUID has changed, although this should not happen unless you have changed it manually. The old UUID was 1ff8a919-1a39-11eb-a27a-080027090068.

Korzystanie z ClusterControl

Teraz użyjemy ClusterControl, aby powtórzyć ten automatyczny proces przełączania awaryjnego. Mam trzy węzły pxc (5.7) wdrożone przez ClusterControl. Mam urządzenie podrzędne replikacji 8.0.22 pod moim węzłem PXC 2 i dodamy tę replikę do odczytu za pomocą ClusterControl.

Krok 1

Skonfiguruj logowanie SSH bez hasła z węzła ClusterControl, aby odczytać węzeł repliki.

$ ssh-copy-id -i ~/.ssh/id_rsa 192.168.33.15

Krok 2

Przejdź do ClusterControl i kliknij ikonę rozwijaną i wybierz opcję Dodaj urządzenie podrzędne replikacji.

Krok 3

Następnie wybierz opcję „Istniejące urządzenie podrzędne replikacji” i wprowadź odczytany adres IP repliki, a następnie kliknij „Dodaj urządzenie podrzędne replikacji”.

Krok 4

Zadanie zostanie uruchomione i możesz monitorować postęp w ClusterControl> Dzienniki> Zadania. Po zakończeniu procesu urządzenie podrzędne pojawi się na stronie Przegląd, jak pokazano na poniższym zrzucie ekranu.

Teraz możesz sprawdzić aktualną topologię w ClusterControl> Topologia

Proces automatycznego przełączania awaryjnego replik

Teraz zamierzam przeprowadzić testy przełączania awaryjnego i dodać poniższe ustawienia do tej funkcji (asynchronous_connection_failover_add_source) w mojej replice do odczytu.

 select asynchronous_connection_failover_add_source('prod_replica', '192.168.33.12', 3306, '', 100);

 select asynchronous_connection_failover_add_source('prod_replica', '192.168.33.13', 3306, '', 80);

 select asynchronous_connection_failover_add_source('prod_replica', '192.168.33.14', 3306, '', 60);



mysql> select * from mysql.replication_asynchronous_connection_failover;

+--------------+---------------+------+-------------------+--------+

| Channel_name | Host          | Port | Network_namespace | Weight |

+--------------+---------------+------+-------------------+--------+

| prod_replica | 192.168.33.12 | 3306 |                   |    100 |

| prod_replica | 192.168.33.13 | 3306 |                   |     80 |

| prod_replica | 192.168.33.14 | 3306 |                   |     60 |

+--------------+---------------+------+-------------------+--------+

3 rows in set (0.00 sec)



mysql> select CONNECTION_RETRY_INTERVAL,CONNECTION_RETRY_COUNT,SOURCE_CONNECTION_AUTO_FAILOVER from performance_schema.replication_connection_conf

iguration;

+---------------------------+------------------------+---------------------------------+

| CONNECTION_RETRY_INTERVAL | CONNECTION_RETRY_COUNT | SOURCE_CONNECTION_AUTO_FAILOVER |

+---------------------------+------------------------+---------------------------------+

|                         6 |                      3 | 1                               |

+---------------------------+------------------------+---------------------------------+

1 row in set (0.00 sec)

Zatrzymam węzeł 2 (192.168.33.13). W ClusterControl parametr (enable_cluster_autorecovery) jest włączony, więc będzie promować następny odpowiedni master.

Teraz mój obecny master nie działa, więc odczytana replika próbuje ponownie się połączyć mistrz.

Błąd replikacji z repliki odczytu

Last_IO_Error: error connecting to master '[email protected]:3306' - retry-time: 6 retries: 2 message: Can't connect to MySQL server on '192.168.33.13' (111)

Gdy ClusterControl wypromuje następnego odpowiedniego mastera, moja replika do odczytu połączy się z dowolnym z dostępnych węzłów klastra.

Automatyczny proces przełączania awaryjnego został zakończony, a moja replika do odczytu została ponownie połączona z węzłem 1 (192.168.33.13) serwer.

Wnioski

Jest to jedna ze wspaniałych funkcji MySQL, nie wymaga ręcznej interwencji. Ten automatyczny proces przełączania awaryjnego może zaoszczędzić trochę czasu. I zmniejsza awarię serwera replik. Warto zauważyć, że gdy mój stary master wrócił do rotacji, połączenie replikacji nie przełączy się z powrotem na starego mastera.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Przykłady LOCALTIME – MySQL

  2. Jak rozróżnianie wielkości liter w MySQL

  3. Najlepszy sposób na sprawdzenie, czy mysql_query zwrócił jakieś wyniki?

  4. Jak tworzyć i używać widoków MySQL

  5. JSON_ARRAY() – Utwórz tablicę JSON z listy wartości w MySQL