State Snapshot Transfer (SST) er en af de to måder, Galera bruger til at udføre indledende synkronisering, når en node slutter sig til en klynge, indtil noden er erklæret som synkroniseret og en del af den "primære komponent". Afhængigt af datasættets størrelse og arbejdsbelastning kan SST være lynhurtigt eller en dyr operation, som vil bringe din databasetjeneste ned på knæ.
SST kan udføres ved hjælp af 3 forskellige metoder:
- mysqldump
- rsync (eller rsync_wan)
- xtrabackup (eller xtrabackup-v2, mariabackup)
Det meste af tiden er xtrabackup-v2 og mariabackup de foretrukne muligheder. Vi ser sjældent folk, der kører på rsync eller mysqldump i produktionsklynger.
Problemet
Når SST startes, udløses der flere processer på joiner-noden, som udføres af "mysql"-brugeren:
$ ps -fu mysql
UID PID PPID C STIME TTY TIME CMD
mysql 117814 129515 0 13:06 ? 00:00:00 /bin/bash -ue /usr//bin/wsrep_sst_xtrabackup-v2 --role donor --address 192.168.55.173:4444/xtrabackup_sst//1 --socket /var/lib/mysql/mysql.sock --datadir
mysql 120036 117814 15 13:06 ? 00:00:06 innobackupex --no-version-check --tmpdir=/tmp/tmp.pMmzIlZJwa --user=backupuser --password=x xxxxxxxxxxxxxx --socket=/var/lib/mysql/mysql.sock --galera-inf
mysql 120037 117814 19 13:06 ? 00:00:07 socat -u stdio TCP:192.168.55.173:4444
mysql 129515 1 1 Oct27 ? 01:11:46 /usr/sbin/mysqld --wsrep_start_position=7ce0e31f-aa46-11e7-abda-56d6a5318485:4949331
Mens du er på donornoden:
mysql 43733 1 14 Oct16 ? 03:28:47 /usr/sbin/mysqld --wsrep-new-cluster --wsrep_start_position=7ce0e31f-aa46-11e7-abda-56d6a5318485:272891
mysql 87092 43733 0 14:53 ? 00:00:00 /bin/bash -ue /usr//bin/wsrep_sst_xtrabackup-v2 --role donor --address 192.168.55.172:4444/xtrabackup_sst//1 --socket /var/lib/mysql/mysql.sock --datadir /var/lib/mysql/ --gtid 7ce0e31f-aa46-11e7-abda-56d6a5318485:2883115 --gtid-domain-id 0
mysql 88826 87092 30 14:53 ? 00:00:05 innobackupex --no-version-check --tmpdir=/tmp/tmp.LDdWzbHkkW --user=backupuser --password=x xxxxxxxxxxxxxx --socket=/var/lib/mysql/mysql.sock --galera-info --stream=xbstream /tmp/tmp.oXDumYf392
mysql 88827 87092 30 14:53 ? 00:00:05 socat -u stdio TCP:192.168.55.172:4444
SST mod et stort datasæt (hundredevis af GBytes) er ikke sjovt. Afhængigt af hardware, netværk og arbejdsbyrde kan det tage timer at gennemføre. Serverressourcer kan være mættede under operationen. På trods af at throttling er understøttet i SST (kun for xtrabackup og mariabackup) ved hjælp af --rlimit og --use-memory muligheder, er vi stadig udsat for en forringet klynge, når du er ved at løbe tør for de fleste aktive noder. For eksempel hvis du er så uheldig at finde dig selv med kun én ud af tre noder kørende. Derfor anbefales det at udføre SST i rolige timer. Du kan dog undgå SST ved at tage nogle manuelle trin, som beskrevet i dette blogindlæg.
Stop en SST
Stop en SST skal ske på både donor- og joiner-knudepunkterne. Sammenføjningen udløser SST efter at have bestemt, hvor stort hullet er, når man sammenligner den lokale Galera-sekvens med klyngens sekvens. Den udfører wsrep_sst_{wsrep_sst_metoden} kommando. Dette vil blive valgt af den valgte donor, som vil begynde at streame data til joineren. En donornode har ingen muligheder for at nægte at sende snapshot-overførsel, når den først er valgt af Galera-gruppekommunikation, eller af værdien defineret i wsrep_sst_donor variabel. Når først synkroniseringen er startet, og du ønsker at fortryde beslutningen, er der ingen enkelt kommando til at stoppe handlingen.
Det grundlæggende princip ved at stoppe en SST er at:
- Få snedkeren til at se død ud fra et Galera-gruppekommunikationssynspunkt (nedlukning, hegn, blokering, nulstilling, tag kabel ud, sortliste osv.)
- Dræb SST-processerne på donoren
Man skulle tro, at det ville være nok at dræbe innobackupex-processen (kill -9 {innobackupex PID}) på donoren, men det er ikke tilfældet. Hvis du dræber SST-processerne på donor (eller joiner) uden at afskærme joineren, kan Galera stadig se joineren som aktiv og vil markere SST-processen som ufuldstændig, og dermed genoprette et nyt sæt processer for at fortsætte eller starte forfra. Du vil være tilbage til udgangspunktet. Dette er den forventede adfærd for /usr/bin/wsrep_sst_{method}-scriptet for at sikre SST-drift, som er sårbar over for timeouts (f.eks. hvis den er langvarig og ressourcekrævende).
Lad os se på et eksempel. Vi har en nedbrudt joiner-knude, som vi gerne vil slutte os til i klyngen. Vi ville starte med at køre følgende kommando på joineren:
$ systemctl start mysql # or service mysql start
Et minut senere fandt vi ud af, at operationen er for tung i det pågældende øjeblik, og besluttede at udskyde den senere i timer med lav trafik. Den mest ligetil måde at stoppe en xtrabackup-baseret SST-metode på er ved blot at lukke joiner-noden ned og dræbe de SST-relaterede processer på donor-knuden. Alternativt kan du også blokere de indgående porte på joineren ved at køre følgende iptables-kommando på joineren:
$ iptables -A INPUT -p tcp --dport 4444 -j DROP
$ iptables -A INPUT -p tcp --dport 4567:4568 -j DROP
Hent derefter PID'en for SST-processer på donoren (liste de processer, der ejes af "mysql"-brugeren):
$ ps -u mysql
PID TTY TIME CMD
117814 ? 00:00:00 wsrep_sst_xtrab
120036 ? 00:00:06 innobackupex
120037 ? 00:00:07 socat
129515 ? 01:11:47 mysqld
Til sidst, dræb dem alle undtagen mysqld-processen (du skal være ekstremt forsigtig med IKKE at dræbe mysqld-processen på donoren!):
$ kill -9 117814 120036 120037
Derefter, på donorens MySQL fejllog, bør du bemærke følgende linje, der vises efter ~100 sekunder:
2017-10-30 13:24:08 139722424837888 [Warning] WSREP: Could not find peer: 42b85e82-bd32-11e7-87ae-eff2b8dd2ea0
2017-10-30 13:24:08 139722424837888 [Warning] WSREP: 1.0 (192.168.55.172): State transfer to -1.-1 (left the group) failed: -32 (Broken pipe)
På dette tidspunkt skal donoren vende tilbage til "synkroniseret" tilstand som rapporteret af wsrep_local_state_comment og SST-processen er fuldstændig standset. Donoren er tilbage i sin operationelle tilstand og er i stand til at betjene klienter i fuld kapacitet.
Til oprydningsprocessen på snedkeren kan du blot skylle iptables-kæden:
$ iptables -F
Eller bare fjern reglerne med -D flag:
$ iptables -D INPUT -p tcp --dport 4444 -j DROP
$ iptables -D INPUT -p tcp --dport 4567:4568 -j DROP
Den lignende tilgang kan bruges med andre SST-metoder som rsync, mariabackup og mysqldump.
Throttling af en SST (kun xtrabackup-metode)
Afhængigt af hvor travlt donoren har, er det en god tilgang til at drosle SST-processen, så den ikke vil påvirke donoren væsentligt. Vi har set en række tilfælde, hvor brugere under katastrofale fejl var desperate efter at bringe en mislykket klynge tilbage som en enkelt bootstrapped node og lade resten af medlemmerne indhente det senere. Dette forsøg reducerer nedetiden fra applikationssiden, men det skaber en yderligere byrde på denne "one-node cluster", mens de resterende medlemmer stadig er nede eller er ved at komme sig.
Xtrabackup kan drosles med --throttle=
[sst]
rlimit=128k
inno-apply-opts="--use-memory=200M"
Flere detaljer på Percona Xtrabackup SST-dokumentationssiden.
Der er dog en fangst. Processen kan være så langsom, at den aldrig vil indhente transaktionsloggene, som InnoDB skriver, så SST bliver muligvis aldrig færdig. Generelt er denne situation meget ualmindelig, medmindre du virkelig har en meget skriveintensiv arbejdsbyrde, eller du allokerer meget begrænsede ressourcer til SST.
Konklusioner
SST er kritisk, men tungt og kan potentielt være en langvarig operation afhængigt af datasættets størrelse og netværksgennemstrømning mellem noderne. Uanset konsekvenserne er der stadig muligheder for at stoppe operationen, så vi kan få en bedre genopretningsplan på et bedre tidspunkt.