sql >> Database >  >> RDS >> Mysql

MySQL InnoDB Cluster 8.0 - Een complete operatie walk-through:deel twee

In het eerste deel van deze blog hebben we een implementatieoverzicht van MySQL InnoDB Cluster besproken met een voorbeeld van hoe de applicaties verbinding kunnen maken met het cluster via een speciale lees-/schrijfpoort.

In deze operatie-walkthrough gaan we voorbeelden laten zien van het bewaken, beheren en schalen van de InnoDB-cluster als onderdeel van de lopende clusteronderhoudsoperaties. We gebruiken hetzelfde cluster dat we in het eerste deel van de blog hebben geïmplementeerd. Het volgende diagram toont onze architectuur:

We hebben een MySQL-groepsreplicatie met drie knooppunten en één toepassingsserver met MySQL-router. Alle servers draaien op Ubuntu 18.04 Bionic.

MySQL InnoDB-clusteropdrachtopties

Voordat we verder gaan met enkele voorbeelden en uitleg, is het goed om te weten dat u een uitleg van elke functie in MySQL-cluster voor clustercomponent kunt krijgen door de help()-functie te gebruiken, zoals hieronder weergegeven:

$ mysqlsh
MySQL|localhost:3306 ssl|JS> shell.connect("[email protected]:3306");
MySQL|db1:3306 ssl|JS> cluster = dba.getCluster();
<Cluster:my_innodb_cluster>
MySQL|db1:3306 ssl|JS> cluster.help()

De volgende lijst toont de beschikbare functies op MySQL Shell 8.0.18, voor MySQL Community Server 8.0.18:

  • addInstance(instance[, options])- Voegt een instance toe aan het cluster.
  • checkInstanceState(instance)- verifieert de gtid-status van de instantie in relatie tot het cluster.
  • describe()- Beschrijf de structuur van het cluster.
  • disconnect()- Verbreekt de verbinding met alle interne sessies die door het clusterobject worden gebruikt.
  • dissolve([options])- Deactiveert replicatie en de registratie van de ReplicaSets uit het cluster.
  • forceQuorumUsingPartitionOf(instance[, password])- Herstelt het cluster van quorumverlies.
  • getName()- Haalt de naam van het cluster op.
  • help([member])- Biedt hulp over deze klas en zijn leden
  • options([options])- Geeft de clusterconfiguratie-opties weer.
  • rejoinInstance(instance[, options])- Voegt een instance opnieuw toe aan het cluster.
  • removeInstance(instance[, options])- Verwijdert een instance uit het cluster.
  • rescan([options])- Scant het cluster opnieuw.
  • resetRecoveryAccountsPassword(options)- Reset het wachtwoord van de herstelaccounts van het cluster.
  • setInstanceOption(instance, option, value)- Wijzigt de waarde van een configuratie-optie in een clusterlid.
  • setOption(option, value)- Wijzigt de waarde van een configuratieoptie voor het hele cluster.
  • setPrimaryInstance(instance)- Kiest een specifiek clusterlid als de nieuwe primaire.
  • status([options])- Beschrijf de status van het cluster.
  • switchToMultiPrimaryMode()- Schakelt het cluster naar de multi-primaire modus.
  • switchToSinglePrimaryMode([instance])- Schakelt het cluster naar de single-primary-modus.

We gaan kijken naar de meeste functies die beschikbaar zijn om ons te helpen bij het bewaken, beheren en schalen van het cluster.

MySQL InnoDB-clusterbewerkingen bewaken

Clusterstatus

Om de clusterstatus te controleren, gebruikt u eerst de MySQL-shell-opdrachtregel en maakt u vervolgens verbinding als [email protected]{one-of-the-db-nodes}:

$ mysqlsh
MySQL|localhost:3306 ssl|JS> shell.connect("[email protected]:3306");

Maak vervolgens een object met de naam "cluster" en declareer het als "dba" globaal object dat toegang biedt tot InnoDB-clusterbeheerfuncties met behulp van de AdminAPI (bekijk de MySQL Shell API-documenten):

MySQL|db1:3306 ssl|JS> cluster = dba.getCluster();
<Cluster:my_innodb_cluster>

Vervolgens kunnen we de objectnaam gebruiken om de API-functies voor het "dba"-object aan te roepen:

MySQL|db1:3306 ssl|JS> cluster.status()
{
    "clusterName": "my_innodb_cluster",
    "defaultReplicaSet": {
        "name": "default",
        "primary": "db1:3306",
        "ssl": "REQUIRED",
        "status": "OK",
        "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
        "topology": {
            "db1:3306": {
                "address": "db1:3306",
                "mode": "R/W",
                "readReplicas": {},
                "replicationLag": null,
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.18"
            },
            "db2:3306": {
                "address": "db2:3306",
                "mode": "R/O",
                "readReplicas": {},
                "replicationLag": "00:00:09.061918",
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.18"
            },
            "db3:3306": {
                "address": "db3:3306",
                "mode": "R/O",
                "readReplicas": {},
                "replicationLag": "00:00:09.447804",
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.18"
            }
        },
        "topologyMode": "Single-Primary"
    },
    "groupInformationSourceMember": "db1:3306"
}

De uitvoer is behoorlijk lang, maar we kunnen deze eruit filteren door de kaartstructuur te gebruiken. Als we bijvoorbeeld alleen de replicatievertraging voor db3 willen zien, kunnen we het volgende doen:

MySQL|db1:3306 ssl|JS> cluster.status().defaultReplicaSet.topology["db3:3306"].replicationLag
00:00:09.447804

Houd er rekening mee dat replicatievertraging iets is dat optreedt bij groepsreplicatie, afhankelijk van de schrijfintensiteit van het primaire lid in de replicaset en de group_replication_flow_control_*-variabelen. We gaan hier niet uitgebreid op dit onderwerp in. Bekijk deze blogpost om meer te weten te komen over de prestaties van groepsreplicatie en flow control.

Een andere soortgelijke functie is de functie description(), maar deze is iets eenvoudiger. Het beschrijft de structuur van het cluster inclusief alle informatie, ReplicaSets en Instances:

MySQL|db1:3306 ssl|JS> cluster.describe()
{
    "clusterName": "my_innodb_cluster",
    "defaultReplicaSet": {
        "name": "default",
        "topology": [
            {
                "address": "db1:3306",
                "label": "db1:3306",
                "role": "HA"
            },
            {
                "address": "db2:3306",
                "label": "db2:3306",
                "role": "HA"
            },
            {
                "address": "db3:3306",
                "label": "db3:3306",
                "role": "HA"
            }
        ],
        "topologyMode": "Single-Primary"
    }
}

Op dezelfde manier kunnen we de JSON-uitvoer filteren met behulp van de kaartstructuur:

MySQL|db1:3306 ssl|JS> cluster.describe().defaultReplicaSet.topologyMode
Single-Primary

Toen het primaire knooppunt uitviel (in dit geval is dit db1), retourneerde de uitvoer het volgende:

MySQL|db1:3306 ssl|JS> cluster.status()
{
    "clusterName": "my_innodb_cluster",
    "defaultReplicaSet": {
        "name": "default",
        "primary": "db2:3306",
        "ssl": "REQUIRED",
        "status": "OK_NO_TOLERANCE",
        "statusText": "Cluster is NOT tolerant to any failures. 1 member is not active",
        "topology": {
            "db1:3306": {
                "address": "db1:3306",
                "mode": "n/a",
                "readReplicas": {},
                "role": "HA",
                "shellConnectError": "MySQL Error 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 104",
                "status": "(MISSING)"
            },
            "db2:3306": {
                "address": "db2:3306",
                "mode": "R/W",
                "readReplicas": {},
                "replicationLag": null,
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.18"
            },
            "db3:3306": {
                "address": "db3:3306",
                "mode": "R/O",
                "readReplicas": {},
                "replicationLag": null,
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.18"
            }
        },
        "topologyMode": "Single-Primary"
    },
    "groupInformationSourceMember": "db2:3306"
}

Let op de status OK_NO_TOLERANCE, waar het cluster nog steeds actief is, maar geen storing meer kan tolereren nadat één over drie knooppunten niet beschikbaar is. De primaire rol is automatisch overgenomen door db2 en de databaseverbindingen van de toepassing worden omgeleid naar het juiste knooppunt als ze verbinding maken via MySQL Router. Zodra db1 weer online komt, zouden we de volgende status moeten zien:

MySQL|db1:3306 ssl|JS> cluster.status()
{
    "clusterName": "my_innodb_cluster",
    "defaultReplicaSet": {
        "name": "default",
        "primary": "db2:3306",
        "ssl": "REQUIRED",
        "status": "OK",
        "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
        "topology": {
            "db1:3306": {
                "address": "db1:3306",
                "mode": "R/O",
                "readReplicas": {},
                "replicationLag": null,
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.18"
            },
            "db2:3306": {
                "address": "db2:3306",
                "mode": "R/W",
                "readReplicas": {},
                "replicationLag": null,
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.18"
            },
            "db3:3306": {
                "address": "db3:3306",
                "mode": "R/O",
                "readReplicas": {},
                "replicationLag": null,
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.18"
            }
        },
        "topologyMode": "Single-Primary"
    },
    "groupInformationSourceMember": "db2:3306"
}

Het laat zien dat db1 nu beschikbaar is, maar als secundair diende met alleen-lezen ingeschakeld. De primaire rol wordt nog steeds toegewezen aan db2 totdat er iets misgaat met het knooppunt, waar het automatisch wordt overgedragen naar het volgende beschikbare knooppunt.

Controleer instantiestatus

We kunnen de status van een MySQL-knooppunt controleren voordat we het aan het cluster toevoegen door de functie checkInstanceState() te gebruiken. Het analyseert de door de instantie uitgevoerde GTID's met de uitgevoerde/opgeschoonde GTID's op het cluster om te bepalen of de instantie geldig is voor het cluster.

Het volgende toont de instantiestatus van db3 wanneer het zich in de zelfstandige modus bevond, vóór een deel van het cluster:

MySQL|db1:3306 ssl|JS> cluster.checkInstanceState("db3:3306")
Cluster.checkInstanceState: The instance 'db3:3306' is a standalone instance but is part of a different InnoDB Cluster (metadata exists, instance does not belong to that metadata, and Group Replication is not active).

Als het knooppunt al deel uitmaakt van het cluster, zou u het volgende moeten krijgen:

MySQL|db1:3306 ssl|JS> cluster.checkInstanceState("db3:3306")
Cluster.checkInstanceState: The instance 'db3:3306' already belongs to the ReplicaSet: 'default'.

Bewaak elke "opvraagbare" status

Met MySQL Shell kunnen we nu de ingebouwde commando's \show en \watch gebruiken om elke administratieve query in realtime te volgen. We kunnen bijvoorbeeld de realtime waarde van verbonden threads krijgen door:

MySQL|db1:3306 ssl|JS> \show query SHOW STATUS LIKE '%thread%';

Of haal de huidige MySQL-proceslijst op:

MySQL|db1:3306 ssl|JS> \show query SHOW FULL PROCESSLIST

We kunnen dan het \watch commando gebruiken om een ​​rapport uit te voeren op dezelfde manier als het \show commando, maar het ververst de resultaten met regelmatige tussenpozen totdat je het commando annuleert met Ctrl + C. Zoals getoond in de volgende voorbeelden:

MySQL|db1:3306 ssl|JS> \watch query SHOW STATUS LIKE '%thread%';
MySQL|db1:3306 ssl|JS> \watch query --interval=1 SHOW FULL PROCESSLIST

Het standaard verversingsinterval is 2 seconden. U kunt de waarde wijzigen door de vlag --interval te gebruiken en een waarde van 0,1 tot 86400 op te geven.

MySQL InnoDB-clusterbeheerbewerkingen

Primaire omschakeling

Primaire instantie is het knooppunt dat kan worden beschouwd als de leider in een replicatiegroep, dat lees- en schrijfbewerkingen kan uitvoeren. Er is slechts één primaire instantie per cluster toegestaan ​​in de modus voor één primaire topologie. Deze topologie wordt ook wel replicaset genoemd en is de aanbevolen topologiemodus voor groepsreplicatie met bescherming tegen vergrendelingsconflicten.

Om de omschakeling van de primaire instantie uit te voeren, logt u in op een van de databaseknooppunten als de clusteradmin-gebruiker en geeft u het databaseknooppunt op dat u wilt promoten met behulp van de functie setPrimaryInstance():

MySQL|db1:3306 ssl|JS> shell.connect("[email protected]:3306");
MySQL|db1:3306 ssl|JS> cluster.setPrimaryInstance("db1:3306");
Setting instance 'db1:3306' as the primary instance of cluster 'my_innodb_cluster'...

Instance 'db2:3306' was switched from PRIMARY to SECONDARY.
Instance 'db3:3306' remains SECONDARY.
Instance 'db1:3306' was switched from SECONDARY to PRIMARY.

WARNING: The cluster internal session is not the primary member anymore. For cluster management operations please obtain a fresh cluster handle using <Dba>.getCluster().

The instance 'db1:3306' was successfully elected as primary.

We hebben zojuist db1 gepromoot als het nieuwe primaire onderdeel, ter vervanging van db2 terwijl db3 als het secundaire knooppunt blijft.

De cluster afsluiten

De beste manier om het cluster netjes af te sluiten door eerst de MySQL Router-service te stoppen (als deze actief is) op de applicatieserver:

$ myrouter/stop.sh

De bovenstaande stap biedt clusterbeveiliging tegen onbedoeld schrijven door de toepassingen. Sluit vervolgens één databaseknooppunt per keer af met behulp van de standaard MySQL stop-opdracht, of sluit het systeem af zoals u wilt:

$ systemctl stop mysql

Het cluster starten na een afsluiting

Als uw cluster last heeft van een volledige storing of als u het cluster wilt starten na een schone afsluiting, kunt u ervoor zorgen dat het correct opnieuw wordt geconfigureerd met de functie dba.rebootClusterFromCompleteOutage(). Het brengt gewoon een cluster terug ONLINE wanneer alle leden OFFLINE zijn. In het geval dat een cluster volledig is gestopt, moeten de instances worden gestart en pas dan kan de cluster worden gestart.

Zorg er dus voor dat alle MySQL-servers gestart en actief zijn. Kijk op elk databaseknooppunt of het mysqld-proces wordt uitgevoerd:

$ ps -ef | grep -i mysql

Kies vervolgens een databaseserver als het primaire knooppunt en maak er verbinding mee via MySQL-shell:

MySQL|JS> shell.connect("[email protected]:3306");

Voer de volgende opdracht uit vanaf die host om ze op te starten:

MySQL|db1:3306 ssl|JS> cluster = dba.rebootClusterFromCompleteOutage()

U krijgt de volgende vragen te zien:

Nadat het bovenstaande is voltooid, kunt u de clusterstatus controleren:

MySQL|db1:3306 ssl|JS> cluster.status()

Op dit punt is db1 het primaire knooppunt en de schrijver. De rest zijn de secundaire leden. Als u het cluster wilt starten met db2 of db3 als het primaire knooppunt, kunt u de functie shell.connect() gebruiken om verbinding te maken met het bijbehorende knooppunt en de rebootClusterFromCompleteOutage() vanaf dat specifieke knooppunt uit te voeren.

U kunt dan de MySQL Router-service starten (als deze niet is gestart) en de toepassing opnieuw verbinding laten maken met het cluster.

Lid- en clusteropties instellen

Om de clusterbrede opties te krijgen, voert u eenvoudig het volgende uit:

MySQL|db1:3306 ssl|JS> cluster.options()

Het bovenstaande geeft een overzicht van de algemene opties voor de replicaset en ook de individuele opties per lid in het cluster. Deze functie wijzigt een InnoDB Cluster-configuratieoptie in alle leden van het cluster. De ondersteunde opties zijn:

  • clusterName:tekenreekswaarde om de clusternaam te definiëren.
  • exitStateAction:tekenreekswaarde die de exit-statusactie van de groepsreplicatie aangeeft.
  • memberWeight:geheel getal met een gewichtspercentage voor automatische primaire verkiezing bij failover.
  • failoverConsistency:tekenreekswaarde die de consistentiegaranties aangeeft die het cluster biedt.
  • consistentie: tekenreekswaarde die de consistentiegaranties aangeeft die het cluster biedt.
  • expelTimeout:geheel getal om de tijdsperiode in seconden te definiëren waarin clusterleden moeten wachten op een niet-reagerend lid voordat deze uit het cluster wordt verwijderd.
  • autoRejoinTries:geheel getal om het aantal keren te definiëren dat een instantie probeert opnieuw deel te nemen aan het cluster nadat het is verwijderd.
  • disableClone:​​booleaanse waarde die wordt gebruikt om het kloongebruik op het cluster uit te schakelen.

Net als bij andere functies kan de uitvoer worden gefilterd in de kaartstructuur. De volgende opdracht geeft alleen de opties voor db2 weer:

MySQL|db1:3306 ssl|JS> cluster.options().defaultReplicaSet.topology["db2:3306"]

U kunt de bovenstaande lijst ook verkrijgen door de help()-functie te gebruiken:

MySQL|db1:3306 ssl|JS> cluster.help("setOption")

De volgende opdracht toont een voorbeeld om een ​​optie met de naam memberWeight in te stellen op 60 (van 50) voor alle leden:

MySQL|db1:3306 ssl|JS> cluster.setOption("memberWeight", 60)
Setting the value of 'memberWeight' to '60' in all ReplicaSet members ...

Successfully set the value of 'memberWeight' to '60' in the 'default' ReplicaSet.

We kunnen ook automatisch configuratiebeheer uitvoeren via MySQL Shell door de functie setInstanceOption() te gebruiken en de databasehost, de optienaam en waarde dienovereenkomstig door te geven:

MySQL|db1:3306 ssl|JS> cluster = dba.getCluster()
MySQL|db1:3306 ssl|JS> cluster.setInstanceOption("db1:3306", "memberWeight", 90)

De ondersteunde opties zijn:

  • exitStateAction: tekenreekswaarde die de exit-statusactie van de groepsreplicatie aangeeft.
  • memberWeight:geheel getal met een gewichtspercentage voor automatische primaire verkiezing bij failover.
  • autoRejoinTries:geheel getal om het aantal keren te definiëren dat een instantie probeert opnieuw deel te nemen aan het cluster nadat het is verwijderd.
  • label een tekenreeks-ID van de instantie.

Overschakelen naar Multi-Primary/Single-Primary Mode

Standaard is InnoDB Cluster geconfigureerd met single-primary, slechts één lid dat lees- en schrijfbewerkingen tegelijk kan uitvoeren. Dit is de veiligste en aanbevolen manier om het cluster uit te voeren en geschikt voor de meeste workloads.

Als de toepassingslogica echter gedistribueerde schrijfbewerkingen aankan, is het waarschijnlijk een goed idee om over te schakelen naar de multi-primaire modus, waarbij alle leden in het cluster lees- en schrijfbewerkingen tegelijkertijd kunnen verwerken. Gebruik de functie switchToMultiPrimaryMode() om over te schakelen van de enkel-primaire naar de multi-primaire modus:

MySQL|db1:3306 ssl|JS> cluster.switchToMultiPrimaryMode()
Switching cluster 'my_innodb_cluster' to Multi-Primary mode...

Instance 'db2:3306' was switched from SECONDARY to PRIMARY.
Instance 'db3:3306' was switched from SECONDARY to PRIMARY.
Instance 'db1:3306' remains PRIMARY.

The cluster successfully switched to Multi-Primary mode.

Verifieer met:

MySQL|db1:3306 ssl|JS> cluster.status()
{
    "clusterName": "my_innodb_cluster",
    "defaultReplicaSet": {
        "name": "default",
        "ssl": "REQUIRED",
        "status": "OK",
        "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
        "topology": {
            "db1:3306": {
                "address": "db1:3306",
                "mode": "R/W",
                "readReplicas": {},
                "replicationLag": null,
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.18"
            },
            "db2:3306": {
                "address": "db2:3306",
                "mode": "R/W",
                "readReplicas": {},
                "replicationLag": null,
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.18"
            },
            "db3:3306": {
                "address": "db3:3306",
                "mode": "R/W",
                "readReplicas": {},
                "replicationLag": null,
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.18"
            }
        },
        "topologyMode": "Multi-Primary"
    },
    "groupInformationSourceMember": "db1:3306"
}

In de multi-primaire modus zijn alle knooppunten primair en kunnen ze lees- en schrijfbewerkingen verwerken. Bij het verzenden van een nieuwe verbinding via MySQL Router op poort met één schrijver (6446), wordt de verbinding naar slechts één knooppunt verzonden, zoals in dit voorbeeld db1:

(app-server)$ for i in {1..3}; do mysql -usbtest -p -h192.168.10.40 -P6446 -e 'select @@hostname, @@read_only, @@super_read_only'; done

+------------+-------------+-------------------+
| @@hostname | @@read_only | @@super_read_only |
+------------+-------------+-------------------+
| db1        | 0           | 0                 |
+------------+-------------+-------------------+

+------------+-------------+-------------------+
| @@hostname | @@read_only | @@super_read_only |
+------------+-------------+-------------------+
| db1        | 0           | 0                 |
+------------+-------------+-------------------+

+------------+-------------+-------------------+
| @@hostname | @@read_only | @@super_read_only |
+------------+-------------+-------------------+
| db1        | 0           | 0                 |
+------------+-------------+-------------------+

Als de applicatie verbinding maakt met de multi-writer-poort (6447), wordt de verbinding via een round-robin-algoritme voor alle leden in evenwicht gebracht:

(app-server)$ for i in {1..3}; do mysql -usbtest -ppassword -h192.168.10.40 -P6447 -e 'select @@hostname, @@read_only, @@super_read_only'; done

+------------+-------------+-------------------+
| @@hostname | @@read_only | @@super_read_only |
+------------+-------------+-------------------+
| db2        | 0           | 0                 |
+------------+-------------+-------------------+

+------------+-------------+-------------------+
| @@hostname | @@read_only | @@super_read_only |
+------------+-------------+-------------------+
| db3        | 0           | 0                 |
+------------+-------------+-------------------+

+------------+-------------+-------------------+
| @@hostname | @@read_only | @@super_read_only |
+------------+-------------+-------------------+
| db1        | 0           | 0                 |
+------------+-------------+-------------------+

Zoals je kunt zien aan de bovenstaande uitvoer, kunnen alle knooppunten lees- en schrijfbewerkingen verwerken met alleen-lezen =UIT. U kunt veilige schrijfbewerkingen naar alle leden distribueren door verbinding te maken met de multi-writer-poort (6447) en de conflicterende of zware schrijfbewerkingen naar de single-writer-poort (6446) te sturen.

Om terug te schakelen naar de enkelvoudige primaire modus, gebruikt u de functie switchToSinglePrimaryMode() en geeft u één lid op als het primaire knooppunt. In dit voorbeeld hebben we db1 gekozen:

MySQL|db1:3306 ssl|JS> cluster.switchToSinglePrimaryMode("db1:3306");

Switching cluster 'my_innodb_cluster' to Single-Primary mode...

Instance 'db2:3306' was switched from PRIMARY to SECONDARY.
Instance 'db3:3306' was switched from PRIMARY to SECONDARY.
Instance 'db1:3306' remains PRIMARY.

WARNING: Existing connections that expected a R/W connection must be disconnected, i.e. instances that became SECONDARY.

The cluster successfully switched to Single-Primary mode.

Op dit moment is db1 nu het primaire knooppunt geconfigureerd met alleen-lezen uitgeschakeld en de rest wordt geconfigureerd als secundair met alleen-lezen ingeschakeld.

MySQL InnoDB-clusterschaalbewerkingen

Opschalen (een nieuw DB-knooppunt toevoegen)

Bij het toevoegen van een nieuw exemplaar moet een knoop punt eerst worden ingericht voordat het mag deelnemen aan de replicatiegroep. Het inrichtingsproces wordt automatisch afgehandeld door MySQL. U kunt ook eerst de instantiestatus controleren of het knooppunt geldig is om lid te worden van het cluster door de functie checkInstanceState() te gebruiken, zoals eerder uitgelegd.

Om een ​​nieuw DB-knooppunt toe te voegen, gebruikt u de functie addInstances() en geeft u de host op:

MySQL|db1:3306 ssl|JS> cluster.addInstance("db3:3306")

Het volgende is wat u krijgt als u een nieuwe instantie toevoegt:

Controleer de nieuwe clustergrootte met:

MySQL|db1:3306 ssl|JS> cluster.status() //or cluster.describe()

MySQL Router zal automatisch het toegevoegde knooppunt, db3, opnemen in de taakverdelingsset.

Verkleinen (een knooppunt verwijderen)

Om een ​​knooppunt te verwijderen, maakt u verbinding met een van de DB-knooppunten behalve degene die we gaan verwijderen en gebruikt u de functie removeInstance() met de naam van de database-instantie:

MySQL|db1:3306 ssl|JS> shell.connect("[email protected]:3306");
MySQL|db1:3306 ssl|JS> cluster = dba.getCluster()
MySQL|db1:3306 ssl|JS> cluster.removeInstance("db3:3306")

Het volgende is wat u krijgt als u een instantie verwijdert:

Controleer de nieuwe clustergrootte met:

MySQL|db1:3306 ssl|JS> cluster.status() //or cluster.describe()

MySQL Router zal het verwijderde knooppunt, db3, automatisch uitsluiten van de taakverdelingsset.

Een nieuwe replicatieslave toevoegen

We kunnen het InnoDB-cluster uitschalen met asynchrone replicatie-slave-replicaties vanaf elk van de clusterknooppunten. Een slave is losjes aan het cluster gekoppeld en kan een zware belasting aan zonder de prestaties van het cluster te beïnvloeden. De slave kan ook een live-kopie van de database zijn voor noodherstel. In de multi-primaire modus kunt u de slave gebruiken als de speciale MySQL alleen-lezen processor om de leeswerklast uit te schalen, analysebewerkingen uit te voeren of als een speciale back-upserver.

Download op de slave-server het nieuwste APT-configuratiepakket, installeer het (kies MySQL 8.0 in de configuratiewizard), installeer de APT-sleutel, update repolist en installeer MySQL-server.

$ wget https://repo.mysql.com/apt/ubuntu/pool/mysql-apt-config/m/mysql-apt-config/mysql-apt-config_0.8.14-1_all.deb
$ dpkg -i mysql-apt-config_0.8.14-1_all.deb
$ apt-key adv --recv-keys --keyserver ha.pool.sks-keyservers.net 5072E1F5
$ apt-get update
$ apt-get -y install mysql-server mysql-shell

Wijzig het MySQL-configuratiebestand om de server voor te bereiden op de replicatieslave. Open het configuratiebestand via de teksteditor:

$ vim /etc/mysql/mysql.conf.d/mysqld.cnf

En voeg de volgende regels toe:

server-id = 1044 # must be unique across all nodes
gtid-mode = ON
enforce-gtid-consistency = ON
log-slave-updates = OFF
read-only = ON
super-read-only = ON
expire-logs-days = 7

Herstart de MySQL-server op de slave om de wijzigingen toe te passen:

$ systemctl restart mysql

Maak op een van de InnoDB Cluster-servers (we kozen voor db3) een replicatieslave-gebruiker en gevolgd door een volledige MySQL-dump:

$ mysql -uroot -p
mysql> CREATE USER 'repl_user'@'192.168.0.44' IDENTIFIED BY 'password';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'192.168.0.44';
mysql> exit
$ mysqldump -uroot -p --single-transaction --master-data=1 --all-databases --triggers --routines --events > dump.sql

Verplaats het dumpbestand van db3 naar de slave:

$ scp dump.sql [email protected]:~

En voer het herstel uit op de slaaf:

$ mysql -uroot -p < dump.sql

Met master-data=1 zal ons MySQL-dumpbestand automatisch de door GTID uitgevoerde en verwijderde waarde configureren. We kunnen het verifiëren met de volgende verklaring op de slave-server na het herstel:

$ mysql -uroot -p
mysql> show global variables like '%gtid_%';
+----------------------------------+----------------------------------------------+
| Variable_name                    | Value                                        |
+----------------------------------+----------------------------------------------+
| binlog_gtid_simple_recovery      | ON                                           |
| enforce_gtid_consistency         | ON                                           |
| gtid_executed                    | d4790339-0694-11ea-8fd5-02f67042125d:1-45886 |
| gtid_executed_compression_period | 1000                                         |
| gtid_mode                        | ON                                           |
| gtid_owned                       |                                              |
| gtid_purged                      | d4790339-0694-11ea-8fd5-02f67042125d:1-45886 |
+----------------------------------+----------------------------------------------+

Ziet er goed uit. We kunnen dan de replicatielink configureren en de replicatiethreads op de slave starten:

mysql> CHANGE MASTER TO MASTER_HOST = '192.168.10.43', MASTER_USER = 'repl_user', MASTER_PASSWORD = 'password', MASTER_AUTO_POSITION = 1;
mysql> START SLAVE;

Controleer de replicatiestatus en zorg ervoor dat de volgende status 'Ja' retourneert:

mysql> show slave status\G
...
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
...

Op dit moment ziet onze architectuur er nu als volgt uit:

Veelvoorkomende problemen met MySQL InnoDB-clusters

Geheugenuitputting

Bij het gebruik van MySQL Shell met MySQL 8.0 kregen we constant de volgende foutmelding wanneer de instances waren geconfigureerd met 1 GB RAM:

Can't create a new thread (errno 11); if you are not out of available memory, you can consult the manual for a possible OS-dependent bug (MySQL Error 1135)

Het upgraden van het RAM-geheugen van elke host naar 2 GB RAM loste het probleem op. Blijkbaar hebben MySQL 8.0-componenten meer RAM nodig om efficiënt te kunnen werken.

Lost Connection to MySQL Server

In case the primary node goes down, you would probably see the "lost connection to MySQL server error" when trying to query something on the current session:

MySQL|db1:3306 ssl|JS> cluster.status()
Cluster.status: Lost connection to MySQL server during query (MySQL Error 2013)

MySQL|db1:3306 ssl|JS> cluster.status()
Cluster.status: MySQL server has gone away (MySQL Error 2006)

The solution is to re-declare the object once more:

MySQL|db1:3306 ssl|JS> cluster = dba.getCluster()
<Cluster:my_innodb_cluster>
MySQL|db1:3306 ssl|JS> cluster.status()

At this point, it will connect to the newly promoted primary node to retrieve the cluster status.

Node Eviction and Expelled

In an event where communication between nodes is interrupted, the problematic node will be evicted from the cluster without any delay, which is not good if you are running on a non-stable network. This is what it looks like on db2 (the problematic node):

2019-11-14T07:07:59.344888Z 0 [ERROR] [MY-011505] [Repl] Plugin group_replication reported: 'Member was expelled from the group due to network failures, changing member status to ERROR.'
2019-11-14T07:07:59.371966Z 0 [ERROR] [MY-011712] [Repl] Plugin group_replication reported: 'The server was automatically set into read only mode after an error was detected.'

Meanwhile from db1, it saw db2 was offline:

2019-11-14T07:07:44.086021Z 0 [Warning] [MY-011493] [Repl] Plugin group_replication reported: 'Member with address db2:3306 has become unreachable.'
2019-11-14T07:07:46.087216Z 0 [Warning] [MY-011499] [Repl] Plugin group_replication reported: 'Members removed from the group: db2:3306'

To tolerate a bit of delay on node eviction, we can set a higher timeout value before a node is being expelled from the group. The default value is 0, which means expel immediately. Use the setOption() function to set the expelTimeout value:

Thanks to Frédéric Descamps from Oracle who pointed this out:

Instead of relying on expelTimeout, it's recommended to set the autoRejoinTries option instead. The value represents the number of times an instance will attempt to rejoin the cluster after being expelled. A good number to start is 3, which means, the expelled member will try to rejoin the cluster for 3 times, which after an unsuccessful auto-rejoin attempt, the member waits 5 minutes before the next try.

To set this value cluster-wide, we can use the setOption() function:

MySQL|db1:3306 ssl|JS> cluster.setOption("autoRejoinTries", 3)
WARNING: Each cluster member will only proceed according to its exitStateAction if auto-rejoin fails (i.e. all retry attempts are exhausted).

Setting the value of 'autoRejoinTries' to '3' in all ReplicaSet members ...

Successfully set the value of 'autoRejoinTries' to '3' in the 'default' ReplicaSet.

Conclusie

For MySQL InnoDB Cluster, most of the management and monitoring operations can be performed directly via MySQL Shell (only available from MySQL 5.7.21 and later).


  1. ClassNotFoundException met PostgreSQL en JDBC

  2. Microsoft SQL Server Management Studio verkrijgen en installeren

  3. Veelgebruikte database-infrastructuurpatronen vergelijken

  4. Een varchar vol met komma's gescheiden waarden doorgeven aan een SQL Server IN-functie