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

Докато изпълнявате PITR, възможно ли е да се постави на пауза/възобновяване в PostgreSQL?

Да, наистина е възможно и се обработва интелигентно от PostgreSQL. За да демонстрирам това, първо трябва да се възползвам от стандартната техника на Point in Time Recovery в PostgreSQL. Различни книги/статии/блогове, демонстрирани изключително добре от изключителни автори, следователно не се впускам в подробности как да го направя, но се насочвам директно към темата, т.е. как да направите пауза, докато се възстановявате със същата техника. Може да се каже, че изложих математически израз от PITR като „PITR =(Последно архивиране на файловата система (LFB) + WAL архиви, генерирани след LFB + неархивирани WAL в текущите $PGDATA/pg_xlogs)“. За по-добро разбиране поставих това в графика, в светлината на факта, че изяснява мисълта повече:(Съжаляваме, този блог е малко дълъг, несъзнателно се случи, докато се впускаше в подробности за концепцията)

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

Стъпка 1. Възстановете най-новото архивиране на ниво файлова система (FSB) на всяко място, където се планира да се извърши възстановяване.
Стъпка 2. Ако FSB е tar, тогава го разархивирайте и почистете директорията pg_xlog, оставяйки archive_status. Ако архивирането е изключило тази директория, създайте празната директория pg_xlog в FSB.
Стъпка 3. Копирайте неархивирани WAL от разбития клъстер $PGDATA/pg_xlog в $FSB/pg_xlog (Стъпка 2)
Стъпка 4. Изтрийте postmaster.pid от директорията на FSB.
Стъпка 5. Създайте файл recovery.conf в директория FSB.
Стъпка 6. Стартирайте клъстера (FSB).

Трябва да зададем въпрос, когато се изисква пауза на възстановяването?. Може би, за да предотвратите многократни базови възстановявания или възстановяване с превъртане напред, но проверете между или отменете дадени данни от таблици или интерес, за да видите докъде са се възстановили :). Не забравяйте, че пауза във възстановяването означава, че позволява да се свържете по време на възстановяване. За да очертая това, възпроиздох в диаграмата ситуация на подобрение на конкретен ред в таблицата до злополука.

От горната диаграма се вижда, че редовете на DEMO таблицата са 10 00 000, когато е направено архивиране на ниво файлова система ($PGDATA) и 40 00 000 реда преди срива. В моята местна виртуална машина направих ситуацията на основата на TIME вместо дата.

Предварително условие:
1. Архивиране на ниво файлова система, когато DEMO таблици имат 10 00 000 реда.
2. От този момент нататък WAL архивира преди срив, където DEMO таблица има 40 00 000 реда.
3. Местоположение на архивите на WAL:/opt/PostgreSQL/9.3/archives.
4. Директория с данни:/opt/PostgreSQL/9.3/data (PGDATA)
5. Местоположение за архивиране:/opt/PostgreSQL/9.3/backups

Имайте предвид, че работата с възстановяване на пауза се нуждае от задължителни промени в главния клъстер ($PGDATA) „wal_level“ е зададен на „hot_standby“ и в клъстера за възстановяване (архив на ниво файлова система) „hot_standby“ е зададен на „ON“. Направих тези промени в основния клъстер, рестартирах клъстера, за да влезе в сила, и започнах архивирането. Ако нямате нищо против, направете бележка, това е просто демонстрация, така че моите WAL архиви може да не са гигантски брой, тъй като са в малко числа. Тук съм посочил и WAL архиви, които са генерирани от момента на архивиране до срив.

-bash-4.1$ psql -c "изберете брой(*), сега() от демонстрация;"
брой | сега
-------+------------------------------
1000000 | 2014-04-04 15:06:04.036928-07
(1 ред)

-bash-4.1$ pg_basebackup -D /opt/PostgreSQL/9.3/backup/data_pitr -- Имам моят комплект $PGDATA, $PGUSER, $PGPORT, така че това е права команда в моя случай
ЗАБЕЛЕЖКА:pg_stop_backup завършен, всички необходими WAL сегменти са архивирани

Текущо състояние на WAL архивите и $PGDATA/pg_xlog

-bash-4.1$ ls -lrth /opt/PostgreSQL/9.3/archives
-rw------- 1 postgres postgres 16M 4 април 16:01 00000001000000000000001C-- />-rw ----- 1 postgres postgres 16M 4 април 16:01 0000000100000000000001D
-rw------- 1 postgres postgres 289 април 4 16:06 000000010000000000 ----- 1 postgres postgres 16M 4 април 16:06 00000001000000000000001E

-bash-4.1$ ls -lrth /opt/PostgreSQL/9.3/data/pg_xlog | tail -4
-rw------- 1 postgres postgres 289 4 април 16:06 00000001000000000000001E.000000C8.backup
-rw------- 1 postgres postgres 16M 4 април 16 г. :06 00000001000000000000001E
-rw------- 1 postgres postgres 16M 4 апр 16:06 00000001000000000000001F
drwx-------- 1 Apr.4 postgres 16. />

Добре, сега имаме резервно копие, позволява да ВМЕСНЕТЕ няколко записа в три части, като отбелязвате часа, така че ще помогне да се постави на пауза възстановяването и допълнително да се види WAL, произведен от времето на FSB.

-bash-4.1$ psql -c "вмъкнете в демонстрационни стойности (generate_series(1,1000000));"
INSERT 0 1000000
-bash-4.1$ psql -c "изберете брой (* ),now() от демонстрация;"
count | сега
-------+------------------------------
2000000 | 2014-04-04 16:06:34.941615-07
(1 ред)
-bash-4.1$ psql -c "вмъкнете в демонстрационни стойности (generate_series(1,1000000));"
INSERT 0 1000000
-bash-4.1$ psql -c "изберете count(*),now() от демонстрация;"
count | сега
-------+------------------------------
3000000 | 2014-04-04 16:10:31.136725-07
(1 ред)
-bash-4.1$ psql -c "вмъкнете в демонстрационни стойности (generate_series(1,1000000));"
INSERT 0 1000000
-bash-4.1$ psql -c "изберете count(*),now() от демонстрация;"
count | сега
-------+------------------------------
4000000 | 2014-04-04 16:13:00.136725-07
(1 ред)

Проверете броя на WAL, произведени по време на INSERT.

-bash-4.1$ ls -lrth /opt/PostgreSQL/9.3/archives
-rw------- 1 postgres postgres 289 4 април 16:06 00000001000000000000001E.0000001E.000000 -rw------- 1 postgres postgres 16M 4 април 16:06 00000001000000000000001E
-rw------- 1 postgres postgres 16M 4 април 16:06 00000001000000000000000000-10 ----- 1 postgres postgres 16M 4 април 16:06 000000010000000000000020
-rw------- 1 postgres postgres 16M 4 април 16:06 00000001000000------0 - 1 postgres postgres 16M 4 април 16:06 000000010000000000000022
-rw------- 1 postgres postgres 16M 4 април 16:06 00000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 16M 4 април 16:06 000000010000000000000024
-rw------- 1 postgres postgres 16M 4 апр 16:06 0000000100000000000000025
-rw------- 1 postgres postgres 16M 4 апр 16:06 0000000100000000000000025
Postgres 16:06 :06 000000010000000000000026
-rw------- 1 postgres postgres 16M 4 апр 16:10 000000010000000000000027
-rw------- 1 postgres postgres 0016 00 01 апр 0016 00028
-rw------- 1 postgres postgres 16M 4 април 16:10 00000001000000000000029
-rw------- 1 postgres postgres 16M 4 април 16:10 0000000000000000000000000000000>-rw------- 1 postgres postgres 16M 4 април 16:13 00000001000000000000002B

Да приемем, че в този момент се е случило злополука и трябва да извършите възстановяване с помощта на FSB + WAL архиви + неархивирани WAL (ако има такива). По време на възстановяването искам да направя пауза три пъти, за да видя всяко възстановяване на 20,00,000, 30,00,000 и 40,00,000 реда на ДЕМО таблица, като се свържа с базата данни в режим САМО ЧЕТЕНЕ. За всяко възобновяване на възстановяване се нуждаете от рестартиране на клъстера за възстановяване, като се насочите към нова времева линия в recovery.conf/recovery_target_time. Също така в $FSB/postgresql.conf трябва да зададем hot_standby=on. Ето моя файл recovery.conf:

-bash-4.1$ more recovery.conf
pause_at_recovery_target =true
#recovery_target_time ='2014-04-04 16:06:34' # За 2 лакх записа
#recovery_target_time ='2014-04-04 16:10:31' # За 3 лакх записа
#recovery_target_time ='2014-04-04 16:13:00' # За 4 лакх записа
restore_command ='cp / opt/PostgreSQL/9.3/archives/%f %p'

Нека започнем възстановяването на 20 00 000 записа:

-bash-4.1$ /opt/PostgreSQL/9.3/bin/pg_ctl -D /opt/PostgreSQL/9.3/data_pitr/ start
Сървърът стартира

Сега в регистрационните файлове:

-bash-4.1$ още postgresql-2014-04-04_162524.log
2014-04-04 16:25:24 PDT-24187---[] LOG:начална точка в- време за възстановяване до 2014-02-06 18:48:56-08
2014-04-04 16:25:24 PDT-24187---[] LOG:възстановен регистрационен файл "000000010000000000000001E" от>2014-04-04 16:25:24 PDT-24187---[] LOG:повторението започва от 0/1E0000C8
2014-04-04 16:25:24 PDT-24187---[] LOG :последователно състояние на възстановяване, достигнато при 0/1E000190
2014-04-04 16:25:24 PDT-24185---[] LOG:системата на базата данни е готова да приема връзки само за четене
2014-04- 04 16:25:24 PDT-24187---[] LOG:възстановен регистрационен файл "00000001000000000000001F" от архив
2014-04-04 16:25:24 PDT-24187-:възстановен дневник[LOG] Файл "00000001000000000000000020" от архив
2014-04-04 16:25:25 PDT-24187 --- [] LOG:Възстановен лог файл "0000000100000000000021" от архив
2014-04-04 16:25:25 PDT-24187---[] LOG:възстановен регистрационен файл "000000010000000000000022" от архив
2014-04-04 16:25:25 PDT-24187---[] LOG преди възстановяване:възстановяване на транзакция 1833, час 2014-04-04 16:06:23.893487-07
2014-04-04 16:25:25 PDT-24187---[] LOG:възстановяването е на пауза
2014-04 -04 16:25:25 PDT-24187---[] СЪВЕТ:Изпълнете pg_xlog_replay_resume(), за да продължите

Страхотно, вижте в регистрационните файлове, че е спрял на пауза и интелигентен СЪВЕТ с молба за възобновяване. Тук, ако възстановяването е било задоволително, можете да го възобновите, като извикате „select pg_xlog_replay_resume();“ (Можете да го проверите). Нека не възобновяваме сега, но проверете броя на възстановените редове, като се свържете със сървъра.

-bash-4.1$ psql -c "изберете count(*),pg_is_in_recovery() от демонстрация;"
count | pg_is_in_recovery
--------+-------------------
2000000 | t
(1 ред)

Добре, стигна се до точката и спря, където поисках. Нека се придвижим още една стъпка напред за възстановяване на 30 00 000 реда. Сега задайте следващата времева линия в recovery.conf/recovery_target_time и рестартирайте клъстера.

2014-04-04 16:28:40 PDT-24409---[] LOG:възстановен регистрационен файл "0000000100000000000002A" от архив
2014-04-04 16:28-24:40 PDT- -[] Дневник:възстановяването спира преди извършване на транзакция 1836, време 2014-04-04 16:10:40.141175-07
2014-04-04 16:28:40 PDT-24409---[] ДВИГАТЕЛ:възстановяването е на пауза
2014-04-04 16:28:40 PDT-24409---[] СЪВЕТ:Изпълнете pg_xlog_replay_resume(), за да продължите.

-bash-4.1$ psql -c "изберете count(*),pg_is_in_recovery() от демонстрация;"
count | pg_is_in_recovery
--------+-------------------
3000000 | t
(1 ред)

Хубаво..., нека направим последния опит за пауза при 40 00 000 реда.

2014-04-04 20:09:07 PDT-4723---[] LOG:възстановен регистрационен файл "0000000100000000000002B" от архив
cp:не може да stat `/opt/PostgreSQL/00000000000000000000000000000000000000000000000000 ':Няма такъв файл или директория
2014-04-04 20:09:07 PDT-4723---[] LOG:повторете извършено в 0/2B0059A0
2014-04-04 20:09:07 PDT-4723---[] ЛОГ:последната завършена транзакция беше в регистрационния час 2014-04-04 16:11:12.264512-07
2014-04-04 20:09:07 PDT-4723--- [] LOG:възстановен регистрационен файл "00000001000000000000002B" от архив
2014-04-04 20:09:07 PDT-4723---[] LOG:възстановен регистрационен файл "00000002.archive
от архива 2014-04-04 20:09:07 PDT-4723---[] LOG:възстановен регистрационен файл "00000003.history" от архив
2014-04-04 20:09:07 PDT-4723--- [] LOG:възстановен регистрационен файл "00000004.history" от архив
cp:не може да stat `/opt/PostgreSQL/9.3/archives/00000005.history':Няма такъв файл или директория
2014-04- 04 20:09:07 PDT-4723---[] LOG:избран нов идентификационен номер на времевата линия:5
cp:не може да stat `/opt/PostgreSQL/9.3/archive s/00000001.history':Няма такъв файл или директория
2014-04-04 20:09:07 PDT-4723---[] LOG:възстановяването на архива е завършено
2014-04-04 20:09:08 PDT-4721---[] LOG:системата за база данни е готова за приемане на връзки
2014-04-04 20:09:08 PDT-4764---[] LOG:стартиран автоматичен стартер

-bash-4.1$ psql -c "изберете count(*),pg_is_in_recovery() от демонстрация;"
count | pg_is_in_recovery
--------+-------------------
4000000 | f
(1 ред)

Опа, какво се случи, защо не е на пауза и какво се оплаква?. Имайте предвид, че ако няма WAL архиви в момента на recovery_target_time, тогава той няма да спре и да очаква, тъй като е стигнал до последната точка и ще отвори базата данни за ЧЕТЕНЕ/ЗАПИСВАНЕ. В регистрационните файлове, без много разтягане, той търсеше файл „00000001000000000000002C“, който не е наличен, тъй като по това време клъстерът се е сринал. Някои може да не признават това поведение, но това е факт и има смисъл, когато няма WAL архиви, тогава няма причина за спиране на възстановяването. Ако изобщо се наложи да направите пауза дори след липса на WAL архиви, използвайте standby_mode=’on’ (HOT_STANDBY), при този метод няма да излезе от възстановяване, а да изчака WAL архиви.

Надявам се да е било полезно.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Нормализиране на Unicode в PostgreSQL 13

  2. Postgresql заявка между периоди от време

  3. LEAST() Функция в PostgreSQL

  4. Избиране на редове, подредени по една колона и различни от друга

  5. Конкатениране на множество редове в масив с SQL на PostgreSQL