Настройването на репликация в MySQL е лесно, но управлението й в производството никога не е било лесна задача. Дори и с по-новото автоматично позициониране на GTID, пак може да се обърка, ако не знаете какво правите. След настройване на репликация всякакви неща могат да се объркат. Грешките могат лесно да бъдат направени и могат да имат катастрофален край за вашите данни.
Тази публикация ще подчертае някои от най-често срещаните грешки, допускани с MySQL репликация, и как можете да ги предотвратите.
Настройване на репликация
Когато настройвате MySQL репликация, трябва да заредите подчинените възли с набора от данни от главния. С решения като Galera cluster, това се обработва автоматично за вас с метода по ваш избор. За MySQL репликация трябва да направите това сами, така че естествено да вземете стандартния си инструмент за архивиране.
За MySQL има огромно разнообразие от инструменти за архивиране, но най-често използваният е mysqldump. Mysqldump извежда логическо архивиране на набора от данни на вашия главен. Това означава, че копието на данните няма да бъде двоично копие, а голям файл, съдържащ заявки за пресъздаване на вашия набор от данни. В повечето случаи това би трябвало да ви осигури (почти) идентично копие на вашите данни, но има случаи, в които няма да го направи - поради изхвърлянето на данни за всеки обект. Това означава, че дори преди да започнете да репликирате данни, вашият набор от данни не е същият като този на главния.
Има няколко настройки, които можете да направите, за да направите mysqldump по-надежден, като dump като единична транзакция, и също така не забравяйте да включите рутинни процедури и тригери:
mysqldump -uuser -ppass --single-transaction --routines --triggers --all-databases > dumpfile.sql
Добра практика е да проверите дали вашият подчинен възел е 100% същият, като използвате pt-table-checksum след настройката на репликацията:
pt-table-checksum --replicate=test.checksums --ignore-databases mysql h=localhost,u=user,p=pass
Този инструмент ще изчисли контролна сума за всяка таблица на главната, репликира командата на подчинения и след това подчинения възел ще извърши същата операция за контролна сума. Ако някоя от таблиците не е една и съща, това трябва да се вижда ясно в таблицата на контролната сума.
Използване на грешен метод на репликация
Методът за репликация по подразбиране на MySQL беше така наречената репликация, базирана на оператори. Този метод е точно това, което е:репликационен поток на всеки оператор, изпълняван на главния, който ще бъде възпроизведен на подчинения възел. Тъй като самият MySQL е многонишков, но неговата (традиционна) репликация не е, редът на изразите в репликационния поток може да не е 100% същият. Също така повторното възпроизвеждане на оператор може да даде различни резултати, когато не се изпълнява точно по едно и също време.
Това може да доведе до различни набори от данни между главен и подчинен, поради отклоняване на данните. Това не беше проблем в продължение на много години, тъй като не много са изпълнявали MySQL с много едновременни нишки, но при съвременните многопроцесорни архитектури това всъщност стана много вероятно при нормално ежедневно натоварване.
Отговорът от MySQL беше така наречената репликация, базирана на редове. Репликацията, базирана на ред, ще репликира данните, когато е възможно, но в някои изключителни случаи все още използва изрази. Добър пример би била промяната на DLL на таблица, където репликацията ще трябва да копира всеки ред в таблицата чрез репликация. Тъй като това е неефективно, подобно изявление ще бъде възпроизведено по традиционния начин. Когато базираната на ред репликация открие отклонение на данните, тя ще спре подчинената нишка, за да предотврати влошаване на нещата.
След това има метод между тези два:репликация в смесен режим. Този тип репликация винаги ще репликира изрази, освен когато заявката съдържа функцията UUID(), се използват тригери, съхранени процедури, UDF и няколко други изключения. Смесеният режим няма да реши проблема с отклонението на данните и, заедно с репликацията, базирана на изрази, трябва да се избягва.
Кръгова репликация
Изпълнението на MySQL репликация с мулти-главен често е необходимо, ако имате среда с множество центрове за данни. Тъй като приложението не може да изчака главният в другия център за данни да потвърди записа ви, се предпочита локален главен. Обикновено изместването на автоматично увеличение се използва за предотвратяване на сблъсъци на данни между главните. Общоприето решение е да се накарат двама главни да извършват запис помежду си по този начин.
Репликация на MySQL Master-MasterВъпреки това, ако трябва да пишете в множество центрове за данни в една и съща база данни, в крайна сметка ще получите множество господари, които трябва да запишат своите данни един към друг. Преди MySQL 5.7.6 нямаше метод за извършване на репликация от тип мрежа, така че алтернативата би била да се използва репликация с кръгов пръстен.
Топология на репликация на пръстен на MySQLРепликацията на пръстен в MySQL е проблематична поради следните причини:латентност, висока наличност и дрейф на данни. Записването на някои данни на сървър А ще са необходими три скока, за да се озоват на сървър D (чрез сървър B и C). Тъй като (традиционната) MySQL репликация е еднонишкова, всяка продължителна заявка в репликацията може да спре целия пръстен. Също така, ако някой от сървърите се повреди, пръстенът ще бъде счупен и в момента няма софтуер за отказ, който може да поправи структури на пръстена. Тогава може да възникне отклонение на данните, когато данните се записват на сървър A и се променят едновременно на сървър C или D.
Репликация на счупен пръстенПо принцип кръговата репликация не е подходяща за MySQL и трябва да се избягва на всяка цена. Galera би била добра алтернатива за писане в множество центрове за данни, тъй като е проектирана с това предвид.
Отлагане на вашата репликация с големи актуализации
Често различни пакетни задачи ще изпълняват различни задачи, вариращи от почистване на стари данни до изчисляване на средни стойности на „харесвания“, извлечени от друг източник. Това означава, че на определени интервали една работа ще създаде много активност на базата данни и най-вероятно ще запише много данни обратно в базата данни. Естествено това означава, че активността в репликационния поток ще се увеличи еднакво.
Репликацията, базирана на изрази, ще репликира точните заявки, използвани в пакетните задания, така че ако обработката на заявката отне половин час на главната, подчинената нишка ще бъде спряна за поне същото време. Това означава, че никакви други данни не могат да се репликират и подчинените възли ще започнат да изостават от главния. Ако това надхвърли прага на вашия инструмент за отказване или прокси сървър, той може да изхвърли тези подчинени възли от наличните възли в клъстера. Ако използвате репликация, базирана на изрази, можете да предотвратите това, като разбиете данните за заданието си на по-малки партиди.
Сега може да си мислите, че репликацията, базирана на редове, не е засегната от това, тъй като тя ще репликира информацията за реда вместо заявката. Това отчасти е вярно, тъй като за DDL промените, репликацията се връща обратно към формат, базиран на изрази. Също така голям брой CRUD операции ще повлияят на репликационния поток:в повечето случаи това все още е операция с една нишка и по този начин всяка транзакция ще чака предишната да бъде възпроизведена чрез репликация. Това означава, че ако имате висока степен на едновременност на главната, подчинената може да спре при претоварване на транзакции по време на репликация.
За да заобиколите това, MariaDB и MySQL предлагат паралелна репликация. Реализацията може да се различава в зависимост от доставчика и версията. MySQL 5.6 предлага паралелна репликация, стига заявките да са разделени от схема. MariaDB 10.0 и MySQL 5.7 могат да обработват паралелна репликация в схеми, но имат други граници. Изпълнението на заявки чрез паралелни подчинени нишки може да ускори вашия репликационен поток, ако пишете тежко. Ако обаче не сте, най-добре би било да се придържате към традиционната еднонишкова репликация.
Промени в схемата
Извършването на промени в схемата при работеща производствена настройка винаги е мъка. Това е свързано с факта, че промяната на DDL през повечето време ще заключи таблица и ще освободи това заключване само след като промяната на DDL бъде приложена. Дори се влошава, след като започнете да репликирате тези DDL промени чрез MySQL репликация, където освен това ще спре репликационния поток.
Често използвано решение е първо да се приложи промяната на схемата към подчинените възли. За репликация, базирана на изрази, това работи добре, но за репликация, базирана на ред, това може да работи до известна степен. Репликацията, базирана на редове, позволява да съществуват допълнителни колони в края на таблицата, така че стига да може да запише първите колони, ще бъде добре. Първо приложете промяната към всички подчинени устройства, след това преминете към един от подчинените и след това приложете промяната към главния и го прикачете като подчинен. Ако вашата промяна включва вмъкване на колона в средата или премахване на колона, това ще работи с репликация, базирана на редове.
Има инструменти, които могат да извършват промени в онлайн схемите по-надеждно. Промяната на Percona Online Schema (известна като pt-osc) ще създаде таблица в сянка с новата структура на таблицата, ще вмъкне нови данни чрез тригери и данни за запълване на заден план. След като приключи създаването на новата таблица, тя просто ще замени старата с новата таблица в транзакция. Това не работи във всички случаи, особено ако съществуващата ви таблица вече има тригери.
Алтернатива е новият инструмент Gh-ost от Github. Този онлайн инструмент за промяна на схема първо ще направи копие на съществуващото оформление на таблицата, ще промени таблицата с новото оформление и след това ще свърже процеса като MySQL реплика. Той ще използва репликационния поток, за да намери нови редове, които са били вмъкнати в оригиналната таблица и в същото време запълва таблицата. След като приключи запълването, оригиналната и новата таблици ще се сменят. Естествено всички операции към новата таблица ще завършат и в потока за репликация, така че на всяка реплика миграцията се случва едновременно.
Таблици с памет и репликация
Докато сме по темата за DDL, често срещан проблем е създаването на таблици с памет. Таблиците с памет са непостоянни таблици, структурата им остава, но те губят данните си след рестарт на MySQL. Когато създавате нова таблица с памет както на главен, така и на подчинен, и двете ще имат празна таблица и това ще работи перфектно. След като някоя от тях бъде рестартирана, таблицата ще бъде изпразнена и ще възникнат грешки при репликация.
Репликацията, базирана на ред, ще се прекъсне, след като данните в подчинения възел върне различни резултати, а репликацията, базирана на изрази, ще прекъсне, след като се опита да вмъкне данни, които вече съществуват. За таблици с памет това е често прекъсване на репликацията. Поправката е лесна:просто направете ново копие на данните, променете двигателя на InnoDB и вече трябва да е безопасен за репликация.
Задаване на променливата само за четене на True
Както описахме по-рано, липсата на същите данни в подчинените възли може да наруши репликацията. Често това е било причинено от нещо (или някой), променящ данните на подчинения възел, но не и на главния възел. След като данните на главния възел се променят, това ще бъде репликирано на подчинения, където не може да приложи промяната и това причинява прекъсване на репликацията.
Има лесна превенция за това:задаване на променливата read_only на true. Това ще забрани на никого да прави промени в данните, с изключение на потребителите на репликация и root. Повечето мениджъри за отказване задават този флаг автоматично, за да попречат на потребителите да пишат на използвания главен код по време на отказ. Някои от тях дори запазват това след отказ.
Това все още оставя root потребителя да изпълни грешна CRUD заявка на подчинения възел. За да предотвратите това да се случи, от MySQL 5.7.8 има променлива super_read_only, която дори блокира root потребителя от актуализиране на данни.
Активиране на GTID
При репликацията на MySQL е от съществено значение да стартирате подчинения от правилната позиция в двоичните регистрационни файлове. Получаването на тази позиция може да стане, когато правите резервно копие (xtrabackup и mysqldump поддържат това) или когато сте спрели да работите на възел, на който правите копие. Стартирането на репликация с командата CHANGE MASTER TO би изглеждало така:
mysql> CHANGE MASTER TO MASTER_HOST='x.x.x.x',MASTER_USER='replication_user', MASTER_PASSWORD='password', MASTER_LOG_FILE='master-bin.0001', MASTER_LOG_POS= 04;
Стартирането на репликация на грешното място може да има катастрофални последици:данните може да бъдат записани двойно или да не се актуализират. Това причинява отклонение на данните между главния и подчинения възел.
Също така, когато прехвърлянето на главен към подчинен включва намиране на правилната позиция и смяна на главния към подходящия хост. MySQL не запазва двоичните регистрационни файлове и позиции от своя господар, а по-скоро създава свои собствени двоични регистрационни файлове и позиции. За повторното подравняване на подчинен възел към новия главен възел това може да се превърне в сериозен проблем:точната позиция на главния възел при отказ трябва да бъде намерена на новия главен обект и след това всички подчинени устройства могат да бъдат повторно подравнени.
За да се реши този проблем, глобалният идентификатор на транзакция (GTID) е внедрен както от Oracle, така и от MariaDB. GTID позволяват автоматично подравняване на подчинените и както в MySQL, така и в MariaDB сървърът сам определя коя е правилната позиция. И двете обаче са приложили GTID по различен начин и следователно са несъвместими. Ако трябва да настроите репликация от един към друг, репликацията трябва да бъде настроена с традиционно позициониране на двоичен журнал. Също така вашият софтуер за преодоляване на срив трябва да бъде наясно да не използва GTID.
Заключение
Надяваме се, че сме ви дали достатъчно съвети, за да избегнете проблеми. Това са общи практики от експертите в MySQL. Те трябваше да го научат по трудния начин и с тези съвети гарантираме, че няма да се налага.
Имаме някои допълнителни бели книги, които може да са полезни, ако искате да прочетете повече за MySQL репликацията.
Свързани бели документи BySQL Replication Blueprint Бялата книга за MySQL Replication Blueprint включва всички аспекти на топологията за репликация с тънкостите на внедряването, настройката на репликация, наблюдението, надстройките, извършването на архивиране и управлението на висока наличност с помощта на прокси сървъри. Изтеглете информацията за висока репликация на MySQL относно MySQL репликацията, с информация за най-новите функции, въведени в 5.6 и 5.7. Има и по-практически, практически раздел за това как бързо да разгръщате и управлявате настройка за репликация с помощта на ClusterControl.Download