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.