Прехвърлянето на моментна снимка на състоянието (SST) е един от двата начина, използвани от Galera за извършване на първоначално синхронизиране, когато възел се присъединява към клъстер, докато възелът не бъде деклариран като синхронизиран и част от „първичния компонент“. В зависимост от размера на набора от данни и работното натоварване, SST може да бъде светкавично бърз или скъпа операция, която ще постави услугата ви на база данни на колене.
SST може да се извърши с помощта на 3 различни метода:
- mysqldump
- rsync (или rsync_wan)
- xtrabackup (или xtrabackup-v2, mariabackup)
През повечето време, xtrabackup-v2 и mariabackup са предпочитаните опции. Рядко виждаме хора, работещи на rsync или mysqldump в производствени клъстери.
Проблемът
Когато SST се инициира, има няколко процеса, задействани на възела за свързване, които се изпълняват от потребителя "mysql":
$ 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
Докато сте на донорния възел:
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 срещу голям набор от данни (стотици GBytes) не е забавно. В зависимост от хардуера, мрежата и работното натоварване, завършването може да отнеме часове. Сървърните ресурси могат да бъдат наситени по време на операцията. Въпреки че дроселирането се поддържа в SST (само за xtrabackup и mariabackup) с помощта на опции --rlimit и --use-memory, ние все още сме изложени на влошен клъстер, когато изчерпвате по-голямата част от активните възли. Например, ако нямате късмета да се окажете с работещ само един от три възела. Ето защо се препоръчва да извършвате SST в тихи часове. Можете обаче да избегнете SST, като предприемете някои ръчни стъпки, както е описано в тази публикация в блога.
Спиране на SST
Спирането на SST трябва да се извърши както на донорния, така и на присъединителните възли. Съединителят задейства SST, след като определи колко голяма е разликата, когато сравнява локалния Galera seqno с seqno на клъстера. Той изпълнява wsrep_sst_{wsrep_sst_method} команда. Това ще бъде избрано от избрания донор, който ще започне да предава данни към дърводелеца. Донорният възел няма възможност да откаже да обслужва прехвърляне на моментна снимка, след като бъде избрана от груповата комуникация на Galera, или от стойността, дефинирана в wsrep_sst_donor променлива. След като синхронизирането започне и искате да отмените решението, няма една команда за спиране на операцията.
Основният принцип при спиране на SST е да:
- Направете дограмата да изглежда мъртва от гледна точка на комуникация на групата Galera (изключване, ограда, блокиране, нулиране, изваждане на кабела, черен списък и т.н.)
- Прекратете SST процесите на донора
Човек би си помислил, че убиването на процеса innobackupex (kill -9 {innobackupex PID}) на донора би било достатъчно, но това не е така. Ако унищожите SST процесите на донор (или съединител), без да преградите съединителя, Galera все още може да види съединителя като активен и ще маркира SST процеса като незавършен, като по този начин възобнови нов набор от процеси, които да продължи или да започне отново. Ще се върнете в изходна позиция. Това е очакваното поведение на /usr/bin/wsrep_sst_{method} скрипт за защита на SST операцията, която е уязвима към изчакване (например, ако е продължителна и ресурсоемка).
Нека да разгледаме един пример. Имаме сринат възел, към който бихме искали да се присъединим отново към клъстера. Ще започнем, като изпълним следната команда на съединителя:
$ systemctl start mysql # or service mysql start
Минута по-късно разбрахме, че операцията е твърде тежка в този конкретен момент и решихме да я отложим по-късно в часове с слаб трафик. Най-лесният начин да спрете базиран на xtrabackup SST метод е просто да изключите присъединителния възел и да убиете свързаните с SST процеси на донорния възел. Като алтернатива, можете също да блокирате входящите портове на съединителя, като изпълните следната команда iptables на съединителя:
$ iptables -A INPUT -p tcp --dport 4444 -j DROP
$ iptables -A INPUT -p tcp --dport 4567:4568 -j DROP
След това на донора извлечете PID на SST процеси (избройте процесите, притежавани от потребителя на "mysql"):
$ 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
Накрая ги убийте всички с изключение на процеса mysqld (трябва да сте изключително внимателни да НЕ убиете процеса mysqld на донора!):
$ kill -9 117814 120036 120037
След това, в дневника за грешки на MySQL на донора, трябва да забележите следния ред, който се появява след ~100 секунди:
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)
В този момент донорът трябва да се върне в „синхронизирано“ състояние, както се съобщава от wsrep_local_state_comment и SST процесът е напълно спрян. Донорът се върна в оперативното си състояние и е в състояние да обслужва клиенти с пълен капацитет.
За процеса на почистване на дограмата, можете просто да промиете веригата на iptables:
$ iptables -F
Или просто премахнете правилата с -D флаг:
$ iptables -D INPUT -p tcp --dport 4444 -j DROP
$ iptables -D INPUT -p tcp --dport 4567:4568 -j DROP
Подобен подход може да се използва с други SST методи като rsync, mariabackup и mysqldump.
Намаляване на SST (само метод за екстрабекъп)
В зависимост от това колко зает е донорът, това е добър подход за задушаване на SST процеса, така че той да не повлияе значително на донора. Виждали сме редица случаи, при които по време на катастрофални сривове потребителите отчаяно се опитваха да върнат неуспешен клъстер като единичен зареден възел и да оставят останалите членове да го настигнат по-късно. Този опит намалява времето на престой от страна на приложението, но създава допълнителна тежест за този „клъстер с един възел“, докато останалите членове все още не работят или се възстановяват.
Xtrabackup може да се дроселира с --throttle=
[sst]
rlimit=128k
inno-apply-opts="--use-memory=200M"
Повече подробности на страницата с документация на Percona Xtrabackup SST.
Има обаче уловка. Процесът може да бъде толкова бавен, че никога няма да настигне регистрационните файлове на транзакциите, които InnoDB пише, така че SST може никога да не завърши. Като цяло тази ситуация е много необичайна, освен ако наистина имате много интензивно натоварване на писане или не разпределите много ограничени ресурси за SST.
Заключения
SST е критичен, но тежък и потенциално може да бъде дългосрочна операция в зависимост от размера на набора от данни и пропускателната способност на мрежата между възлите. Независимо от последствията, все още има възможности за спиране на операцията, за да можем да имаме по-добър план за възстановяване в по-добър момент.