MariaDB
 sql >> база данни >  >> RDS >> MariaDB

Как да направите възстановяване по време на MySQL и MariaDB данни с помощта на ClusterControl

Архивирането е от решаващо значение, когато става въпрос за безопасност на данните. Те са най-доброто решение за възстановяване при бедствия – нямате достъпни възли на база данни и вашият център за данни може буквално да е изгорял, но стига да имате резервно копие на данните си, все още можете да се възстановите от такава ситуация.

Обикновено ще използвате резервни копия за възстановяване от различни видове случаи:

  • случайно DROP TABLE или DELETE без клауза WHERE или с клауза WHERE, която не е достатъчно конкретна.
  • надстройка на базата данни, която се проваля и поврежда данните
  • срив/повреда на носителя за съхранение

Възстановяването от архивиране не е достатъчно? Какво трябва да бъде в момента? Трябва да имаме предвид, че архивирането е моментна снимка на данни, направени в даден момент от време. Ако направите резервно копие в 1:00 часа сутринта и таблица е била премахната случайно в 11:00 часа сутринта, можете да възстановите данните си до 1:00 часа сутринта, но какво да кажем за промените, които са се случили между 1:00 и 11:00 часа сутринта? Тези промени ще бъдат загубени, освен ако не можете да възпроизведете промените, които са се случили между тях. За щастие MySQL има такъв механизъм за съхранение на промените - двоични регистрационни файлове. Може да знаете, че тези регистрационни файлове се използват за репликация - MySQL ги използва за съхраняване на всички промени, които са се случили на главния, а подчинен ги използва, за да възпроизведе тези промени и да ги приложи към своя набор от данни. Тъй като binlogs съхраняват всички промени, можете да ги използвате и за възпроизвеждане на трафик. В тази публикация в блога ще разгледаме как ClusterControl може да ви помогне да извършите възстановяване по време (PITR).

Създаване на резервно копие, съвместимо с възстановяване в момента

Първо, нека поговорим за предпоставките. Хост, от който правите резервни копия, трябва да има активирани двоични регистрационни файлове. Без тях PITR не е възможен. Второ изискване - хост, от който правите архиви, трябва да има всички двоични регистрационни файлове, необходими за възстановяване до даден момент от време. Ако използвате твърде агресивна ротация на двоичен журнал, това може да се превърне в проблем.

И така, нека видим как да използваме тази функция в ClusterControl. На първо място, трябва да направите резервно копие, което е съвместимо с PITR. Такова архивиране трябва да бъде пълно, пълно и последователно. За xtrabackup, стига да съдържа пълен набор от данни (не сте включили само подмножество от схеми), той ще бъде PITR-съвместим.

За mysqldump има опция да го направите PITR-съвместим. Когато активирате тази опция, всички необходими опции ще бъдат конфигурирани (например, няма да можете да избирате отделни схеми, които да включите в дъмпа) и архивирането ще бъде маркирано като налично за възстановяване в момента.

Възстановяване в момента от резервно копие

Първо, трябва да изберете резервно копие за възстановяване.

Ако архивът е съвместим с PITR, ще бъде представена опция за извършване на възстановяване в момента. Ще имате две опции за това - „Въз основа на времето“ и „Въз основа на позицията“. Нека обсъдим разликата между тези две опции.

„Време базиран“ PITR

С тази опция можете да подадете дата и час, до които архивът трябва да бъде възстановен. Може да се дефинира в рамките на една секунда резолюция. Това не гарантира, че всички данни ще бъдат възстановени, защото, дори ако сте много точни при дефинирането на времето, по време на една секунда множество събития могат да бъдат записани в двоичния дневник. Да кажем, че знаете, че загубата на данни се е случила на 18 април, в 10:00:01. Подавате следната дата и час във формата:„2018-04-18 10:00:00“. Моля, имайте предвид, че трябва да използвате време, което се основава на настройките на часовата зона на сървъра на базата данни, на който е създадено резервното копие.

Все още може да се случи загубата на данни дори да не е първата, която се е случила в 10:00:01, така че някои от събитията ще бъдат загубени в процеса. Нека да видим какво означава това.

По време на една секунда, множество събития могат да бъдат регистрирани в binlogs. Нека разгледаме такъв случай:
10:00:00 - събития A,B,C,D,E,F
10:00:01 - събития V,W,X,Y,Z
където X е събитието за загуба на данни. С детайлност от секунда можете или да възстановите до всичко, което се е случило в 10:00:00 (така че до F) или до 10:00:01 (до Z). По-късният случай не е от полза, тъй като X ще бъде повторно изпълнен. В първия случай пропускаме V и W.

Ето защо възстановяването въз основа на позиция е по-прецизно. Можете да кажете „Искам да възстановя до W“.

Възстановяването въз основа на времето е най-прецизното, което можете да получите, без да се налага да отивате в двоичните регистрационни файлове и да дефинирате точната позиция до мястото, където искате да възстановите. Това ни води до втория метод за извършване на PITR.

PITR „базиран на позиция“

Тук се изисква известен опит с инструменти на командния ред за MySQL, а именно помощната програма mysqlbinlog. От друга страна, вие ще имате най-добрия контрол върху начина, по който ще се извърши възстановяването.

Нека преминем през прост пример. Както можете да видите на екранната снимка по-горе, ще трябва да подадете име на двоичен регистрационен файл и позиция на двоичен дневник, до която точка трябва да бъде възстановено архивирането. През повечето време това трябва да е последната позиция преди събитието за загуба на данни.

Някой изпълни SQL команда, която доведе до сериозна загуба на данни:

mysql> DROP TABLE sbtest1;
Query OK, 0 rows affected (0.02 sec)

Нашето приложение веднага започна да се оплаква:

sysbench 1.1.0-ecf1191 (using bundled LuaJIT 2.1.0-beta3)

Running the test with following options:
Number of threads: 2
Report intermediate results every 1 second(s)
Initializing random number generator from current time


Initializing worker threads...

Threads started!

FATAL: mysql_drv_query() returned error 1146 (Table 'sbtest.sbtest1' doesn't exist) for query 'DELETE FROM sbtest1 WHERE id=5038'
FATAL: `thread_run' function failed: /usr/local/share/sysbench/oltp_common.lua:490: SQL error, errno = 1146, state = '42S02': Table 'sbtest.sbtest1' doesn't exist

Имаме резервно копие, но искаме да възстановим всички данни до този фатален момент. На първо място, приемаме, че приложението не работи, така че можем да отхвърлим всички записи, случили се след DROP TABLE като неважни. Ако приложението ви работи до известна степен, ще трябва да обедините останалите промени по-късно. Добре, нека да разгледаме двоичните регистрационни файлове, за да намерим позицията на оператора DROP TABLE. Тъй като искаме да избегнем синтактичния анализ на всички двоични регистрационни файлове, нека да открием каква е позицията, която покриваше последното ни резервно копие. Можете да проверите това, като прегледате регистрационните файлове за най-новия набор за архивиране и потърсите ред, подобен на този:

И така, говорим за име на файл 'binlog.000008' и позиция '16184120'. Нека използваме това като наша отправна точка. Нека проверим какви двоични регистрационни файлове имаме:

[email protected]:~# ls -alh /var/lib/mysql/binlog.*
-rw-r----- 1 mysql mysql  58M Apr 17 08:31 /var/lib/mysql/binlog.000001
-rw-r----- 1 mysql mysql 116M Apr 17 08:59 /var/lib/mysql/binlog.000002
-rw-r----- 1 mysql mysql 379M Apr 17 09:30 /var/lib/mysql/binlog.000003
-rw-r----- 1 mysql mysql 344M Apr 17 10:54 /var/lib/mysql/binlog.000004
-rw-r----- 1 mysql mysql 892K Apr 17 10:56 /var/lib/mysql/binlog.000005
-rw-r----- 1 mysql mysql  74M Apr 17 11:03 /var/lib/mysql/binlog.000006
-rw-r----- 1 mysql mysql 5.2M Apr 17 11:06 /var/lib/mysql/binlog.000007
-rw-r----- 1 mysql mysql  21M Apr 18 11:35 /var/lib/mysql/binlog.000008
-rw-r----- 1 mysql mysql  59K Apr 18 11:35 /var/lib/mysql/binlog.000009
-rw-r----- 1 mysql mysql  144 Apr 18 11:35 /var/lib/mysql/binlog.index

Така че, в допълнение към 'binlog.000008' имаме и 'binlog.000009' за проверка. Нека изпълним командата, която ще преобразува двоични регистрационни файлове в SQL формат, започвайки от позицията, която открихме в архивния дневник:

[email protected]:~# mysqlbinlog --start-position='16184120' --verbose /var/lib/mysql/binlog.000008 /var/lib/mysql/binlog.000009 > binlog.out

Моля, възелът „--verbose“ е необходим за декодиране на събития, базирани на редове. Това не е задължително за търсената от нас DROP TABLE, но за други видове събития може да е необходимо.

Нека потърсим нашия изход за заявката DROP TABLE:

[email protected]:~# grep -B 7 -A 1 "DROP TABLE" binlog.out
# at 20885489
#180418 11:24:32 server id 1  end_log_pos 20885554 CRC32 0xb89f2e66     GTID    last_committed=38168    sequence_number=38170    rbr_only=no
SET @@SESSION.GTID_NEXT= '7fe29cb7-422f-11e8-b48d-0800274b240e:38170'/*!*/;
# at 20885554
#180418 11:24:32 server id 1  end_log_pos 20885678 CRC32 0xb38a427b     Query    thread_id=54    exec_time=0    error_code=0
use `sbtest`/*!*/;
SET TIMESTAMP=1524050672/*!*/;
DROP TABLE `sbtest1` /* generated by server */
/*!*/;

В тази извадка можем да видим две събития. Първо, на позиция 20885489 задава променлива GTID_NEXT.

# at 20885489
#180418 11:24:32 server id 1  end_log_pos 20885554 CRC32 0xb89f2e66     GTID    last_committed=38168    sequence_number=38170    rbr_only=no
SET @@SESSION.GTID_NEXT= '7fe29cb7-422f-11e8-b48d-0800274b240e:38170'/*!*/;

Второ, на позиция 20885554 е нашето събитие DROP TABLE. Това води до заключението, че трябва да изпълним PITR до позиция 20885489. Единственият въпрос, на който трябва да се отговори, е за кой двоичен лог става дума. Можем да проверим това, като потърсим записи за ротация на binlog:

[email protected]:~# grep  "Rotate to binlog" binlog.out
#180418 11:35:46 server id 1  end_log_pos 21013114 CRC32 0x2772cc18     Rotate to binlog.000009  pos: 4

Както може ясно да се види чрез сравняване на дати, ротацията към binlog.000009 се случи по-късно, затова искаме да предадем binlog.000008 като binlog файл във формуляра.

След това трябва да решим дали ще възстановим архива на клъстера или искаме да използваме външен сървър, за да го възстановим. Тази втора опция може да бъде полезна, ако искате да възстановите само подмножество от данни. Можете да възстановите пълно физическо архивиране на отделен хост и след това да използвате mysqldump, за да изхвърлите липсващите данни и да ги заредите на производствения сървър.

Имайте предвид, че когато възстановите архива на вашия клъстер, ще трябва да възстановите възли, различни от този, който сте възстановили. В сценария главен - подчинен обикновено ще искате да възстановите архива на главния и след това да изградите отново подчинени от него.

Като последна стъпка ще видите обобщение на действията, които ClusterControl ще предприеме.

Накрая, след като бекъпът е възстановен, ще тестваме дали липсващата таблица е била възстановена или не:

mysql> show tables from sbtest like 'sbtest1'\G
*************************** 1. row ***************************
Tables_in_sbtest (sbtest1): sbtest1
1 row in set (0.00 sec)

Всичко изглежда наред, успяхме да възстановим липсващите данни.

Последната стъпка, която трябва да направим, е да възстановим нашия роб. Моля, имайте предвид, че има опция за използване на резервно копие на PITR. В примера тук това не е възможно, тъй като ведомото устройство би репликирало събитието DROP TABLE и в крайна сметка то не би било в съответствие с главната.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Извадете месец от дата в MariaDB

  2. Как да сравните производителността на MySQL и MariaDB с помощта на SysBench

  3. Избор на система за съхранение:Aria

  4. Мониторинг на производителността на MariaDB в хибриден облак

  5. MariaDB JSON_TABLE() Обяснено