Тъй като все повече и повече публикации в PostgreSQL 11 се появяват в мрежата, толкова по-стари може да се почувствате, когато използвате Postgres 9. Въпреки че пускането на версията на PostgreSQL 10 се случи само преди месеци, хората вече говорят за следващата версия. Нещата се движат, така че не искате да бъдете изоставени. В този блог ще обсъдим какво трябва да знаете, за да надстроите до най-новата версия, Postgres 10.
Опции за надстройка
Първото нещо, което трябва да знаете, преди да започнете, е, че има няколко начина за извършване на надстройката:
- Традиционен pg_dumpall(pg_dump) / pg_restore(psql)
- Традиционен pg_upgrade
- Репликация, базирана на задействане (Slony, самостоятелно написана)
- Използване на pglogical репликация
Защо има такова разнообразие? Тъй като всеки има различна история, изисква различни усилия за настройка и предлага различни услуги. Нека разгледаме по-отблизо всеки от тях.
Традиционно изхвърляне/възстановяване
pg_dump t > /tmp/f
psql -p 5433 -f /tmp/f
Традиционното изхвърляне/възстановяване отнема най-дълго време за завършване и въпреки това често е популярен избор за тези, които могат да си позволят престоя. Първо, това е толкова лесно, колкото да направите логически архив и да го възстановите до нова, по-висока версия на базата данни. Може да се каже, че всъщност не е надстройка, тъй като "импортирате" данните си в "нова структура". В резултат ще получите две настройки - една стара (по-ниска версия) и ново обновена. Ако процесът на възстановяване завърши без грешка, значи сте почти там. Ако не, трябва да модифицирате съществуващия стар клъстер, за да премахнете всички грешки и да започнете процеса отново.
Ако използвате psql за импортиране, може също да се наложи сами да създадете някои скриптове за предварително зареждане, които да изпълните при новата настройка преди миграцията. Например, бихте искали да pg_dumpall -g, за да получите списък с нужните роли за подготовка в новата настройка, или обратното да стартирате pg_dump -x, за да пропуснете разрешенията от старата. Този процес е доста прост за малки бази данни, сложността нараства с размера и сложността на вашата db структура и зависи от това какви функции сте настроили. По принцип, за да бъде този метод успешен, трябва да продължите да опитвате и да коригирате, докато надстройката е успешна.
Предимствата на използването на този метод включват...
- Въпреки че може да прекарате дълго време с едно архивно копие, което сте направили – натоварването на стария сървър е толкова малко, колкото да направите едно резервно копие.
- Този метод е най-вече просто последователност за архивиране-възстановяване (потенциално с някои заклинания, песни и барабани)
- Използването на този метод е най-старият начин за надстройка и е проверен от МНОГО хора
Когато най-накрая завършите надстройката, трябва или да изключите стария сървър, или да приемете някаква загуба на данни (или алтернативно да възпроизведете DML, който се е случил на стария сървър, докато възстановявате резервно копие на новия сървър). И времето, прекарано в това, е в зависимост от размера на вашата база данни.
Можете, разбира се, да започнете да „използвате“ нова база данни, преди възстановяването да е приключило (особено преди да бъдат изградени всички индекси – често най-много време е необходимо за индекси). Но въпреки това такъв престой често е неприемлив.
Традиционна pg_upgrade
MacBook-Air:~ vao$ /usr/local/Cellar/postgresql/10.2/bin/initdb -D tl0 >/tmp/suppressing_to_save_screen_space_read_it
WARNING: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.
MacBook-Air:~ vao$ /usr/local/Cellar/postgresql/10.2/bin/pg_upgrade -b /usr/local/Cellar/postgresql/9.5.3/bin -B /usr/local/Cellar/postgresql/10.2/bin -d t -D tl0 | tail
Creating script to delete old cluster ok
Upgrade Complete
----------------
Optimizer statistics are not transferred by pg_upgrade so,
once you start the new server, consider running:
./analyze_new_cluster.sh
Running this script will delete the old cluster’s data files:
./delete_old_cluster.sh
Традиционният pg_upgrade е създаден, за да съкрати времето, необходимо за надграждане до основна версия. В зависимост от количеството връзки, които имате, това може да бъде толкова бързо, колкото минути (секунди в нелепи случаи, като една таблица с база данни и часове в „обратните случаи“), особено с аргумент --link.
Последователността на подготовка малко се различава от метода за първо надграждане. За да моделирате надстройката и по този начин да проверите дали е възможно, трябва да изградите поточно репликация или да възстановите резервен сървър от WAL. Защо това е толкова сложно? Искате да сте сигурни, че сте тествали надстройката на база данни с възможно най-близко състояние, както сте правили първоначално. Тук ще ни помогне "двоично" репликация или PITR. След като завършите възстановяването и recovery_target_action =promote (PITR) или популяризирате новоизградения подчинен (pg_ctl популяризиране или поставяне на файл за задействане) (поточно репликация), можете да опитате да стартирате pg_upgrade. Проверката на pg_upgrade_internal.log ще ви даде представа дали процесът е бил успешен или не. Освен това имате същия подход за изпробване и коригиране като предишния метод. Записвате действията, предприети срещу тестовата база данни в скрипт, докато не я надградите успешно pg_upgrade. Освен това можете да унищожите вече ненужния тест надстроена база данни, стартирайте след това запазен скрипт, за да подготвите оригиналната база данни за извършване на надстройката.
Предимствата на използването на този метод включват...
- По-кратко време на престой от логическото архивиране/възстановяване
- Един процес – pg_upgrade надгражда оригиналната база данни със съществуващи данни и структура
- Използван е много в миналото и все още е предпочитание за повечето DBA, работещи версия под 9.4 (което позволява използването на pglogical)
Недостатъците на използването на този метод включват...
- Изисква престой
Репликация, базирана на задействане
Ако приемем, че версия 10 е на порт 5433 и има подготвена същата таблица:
db=# create server upgrade_to_10 foreign data wrapper postgres_fdw options (port '5433', dbname 'dbl0');
CREATE SERVER
Time: 9.135 ms
db=# create user mapping for vao SERVER upgrade_to_10 options (user 'vao');
CREATE USER MAPPING
Time: 8.741 ms
db=# create foreign table rl0 (pk int, t text) server upgrade_to_10 options (table_name 'r');
CREATE FOREIGN TABLE
Time: 9.358 ms
Това е изключително опростен fn() и тригер за много основна логическа репликация. Такъв подход е толкова примитивен, че няма да работи с външни ключове, но кодът е кратък:
db=# create or replace function tf() returns trigger as $$
begin
if TG_0P = 'INSERT' then
insert into r10 select NEW.*;
elseif TG_0P = 'UPDATE' then
delete from rl0 where pk = NEW.pk;
insert into rl0 select NEW.*;
elseif TG_0P = 'DELETE' then
delete from rl0 where pk = OLD.pk;
end if;
return case when TG_0P in ('INSERT','UPDATE') then NEW else OLD end;
end;
SS language plpgsql;
CREATE FUNCTION
Time: 8.531 ms
db=# create trigger t before insert or update or delete on r for each row execute procedure tf(); CREATE TRIGGER
Time: 8.813 ms
Пример:
db=# insert into r(t) select chr(g) from generate_series(70,75) g;
INSERT 0 6
Time: 12.621 ms
db=# update r set t = 'updated' where pk=2;
UPDATE 1
Time: 10.398 ms
db=# delete from r where pk=1;
DELETE 1
Time: 9.634 ms
db=# select * from r;
pk | t
----+---------
3 | H
4 | I
5 | J
6 | K
2 | updated
(5 rows)
Time: 9.026 ms
db=# select * from rl0;
pk | t
----+---------
3 | H
4 | I
5 | J
6 | K
2 | updated
(5 rows)
Time: 1.201 ms
И накрая, проверяваме дали репликираме в друга база данни:
db=# select *,current_setting('port') from dblink('upgrade.to.lO','select setting from pg_settings where name=$$port$$') as t(setting_10 text);
setting_10 | currerrt.setting
------------+------------------
5433 | 5432
(l row)
Time: 23.633 ms
Бих нарекла този метод най-екзотичния. Както поради факта, че при стрийминг репликация и по-късно с pglogical, използването на репликация, базирана на тригери, става по-малко популярна. Той има по-голямо натоварване на главния, повишена сложност по време на настройката и липса на добре структурирана документация. Тук няма подготовка (като такава) на процеса, тъй като просто искате да настроите Slony на различни основни версии.
Предимствата на използването на този метод включват...
- Не е необходимо да се правят резервни копия и не се изисква престой (особено вие сте зад някакъв pgbouncer или haproxy).
Недостатъците на използването на този метод включват...
- Висока сложност на настройката
- Липса на структурирана документация
- Не е много популярно – по-малко потребителски случаи за изучаване (и споделяне)
По същия начин, самонаписаната репликация на тригера е друг възможен начин за надграждане. Въпреки че идеята е същата (завъртате нова база данни с по-висока версия и настройвате тригери на по-ниска версия, за да изпратите модифицирани данни към нея), самонаписаната настройка ще ви бъде ясна. Няма да имате нужда от поддръжка и по този начин потенциално ще използвате по-малко ресурси, когато го изпълнявате. Разбира се, поради същата причина вероятно ще се окажете, че някои функции липсват или не работят според очакванията. Ако имате няколко таблици за преминаване към нови версии, такава опция вероятно ще ви отнеме по-малко време и, ако се направи добре, може да изисква по-малко ресурси. Като бонус можете да комбинирате някои ETL трансформации с надстройката, като преминете към нова версия без прекъсване.
Изтеглете Бялата книга днес Управление и автоматизация на PostgreSQL с ClusterControl Научете какво трябва да знаете, за да внедрите, наблюдавате, управлявате и мащабирате PostgreSQLD Изтеглете Бялата книгаЛогическа репликация с pglogical
Това е много обещаващ нов начин за надграждане на Postgres. Идеята е да се настрои логическа репликация между различни основни версии и буквално да има паралелна, по-висока (или по-ниска) база данни с едни и същи данни. Когато сте готови, просто превключвате връзките с приложението си от старо към ново.
Предимствата на използването на този метод включват...
- По принцип няма престой
- Изключително обещаваща функция, много по-малко усилия от репликация, базирана на задействане
Недостатъците на използването на този метод включват...
- Все още е много сложно за настройка (особено за по-стари версии)
- Липса на структурирана документация
- Не е много популярно – по-малко потребителски случаи за изучаване (и споделяне)
Миграциите на основната версия, базирана на тригери и pglogical, могат да се използват за понижаване на версията (до някаква разумна стойност, разбира се, например pglogical е достъпна само от 9.4 и репликацията на тригера става все по-трудна и по-трудна за настройка като версията, която искате за понижаване до остарява).
Действия, които трябва да се предприемат преди надстройката
- Направете резервно копие
- Уверете се, че има достатъчно дисково пространство
- Проверете разширенията си (важно е всички външни модули да са и двоично съвместими, въпреки че това не може да се провери от pg_upgrade)
- Уверете се, че използвате един и същ datcollate и datctype и така нататък (проверете pg_database) в новата база данни
- Проверете (DDL + Drop) изгледи, функции, разширения, типове, които биха могли да нарушат надстройката
- Използвайте --check преди наистина pg_upgrade
Действия, които трябва да бъдат предприети след надстройката
- Консултирайте се с pg_upgrade_server.log (ако сте използвали pg_upgrade)
- Изпълнете анализ на надстроени бази данни (по избор, тъй като това би било направено чрез автоматично вакуумиране, но можете да изберете кои отношения да бъдат анализирани първо, ако го направите сами)
- Предварително затопляне на популярни страници (по избор, но може да повиши производителността в началото)
Заключение
Ето някои общи бележки, които е добре да знаете, преди да решите да отидете на PostgreSQL версия 10...
- въведени бяха pg_sequences, променяйки поведението на по-рано популярното SELECT * FROM име_на последователност - сега само последна_стойност | log_cnt | is_called се връщат, скривайки от вас "първоначални свойства" (коригирайте всеки код, който разчита на променено поведение)
- pg_basebackup предава потоци WAL по подразбиране. След надстройката може да се наложи да модифицирате скриптовете си (опцията -x е премахната)
- Всички действия pg_ctl чакат завършване. Преди трябваше да добавите -w, за да избегнете опитите да се свържете с базата данни веднага след стартиране на pg_ctl. По този начин, ако все пак искате да използвате "асинхронно" стартиране или спиране, трябва изрично да го маркирате с -W. Може да се наложи да коригирате скриптовете си, така че да се държат по предназначение.
- Всички скриптове за архивиране на WAL или наблюдение/контрол на репликацията на поточно предаване или PITR трябва да бъдат прегледани, за да ги коригирате към променените имена на xlog. напр. select * от pg_is_xlog_replay_paused() вече няма да ви показва състоянието на възпроизвеждане на подчинени WAL - вместо това трябва да използвате select * от pg_is_wal_replay_paused(). Също така cp /blah/pg_xlog/* трябва да се промени на /blah/pg_wal/* и така нататък основно за всички случаи на pg_xlog. Причината за такава масивна промяна, която не е обратно съвместима, е да се обърне внимание на случая, когато newby премахва регистрационни файлове с предварителна запис, за да „почисти малко пространство“ чрез премахване на регистрационни файлове и губи базата данни.
- Коригирайте скриптове с помощта на pg_stat_replication за нови имена (местоположението е променено на lsn)
- Коригирайте заявките със зададени функции за връщане, ако е необходимо
- Ако сте използвали pglogical като разширение преди версия 10, може да се наложи да коригирате pg_hba.conf, променяща стойността между "колони"
- Коригирайте скриптове за ново име на pg_log, което е log, така че нещо като find /pg_data/pg_log/postgresql-* -mmin +$((60*48)) -type f -exec bash /blah/moveto.s3 .sh {} \; бих работил. Разбира се, вместо това можете да създадете символична връзка, но ще трябва да се предприемат действия, за да се намерят регистрационните файлове в местоположението по подразбиране. Друга малка промяна в настройките по подразбиране е log_line_prefix – ако вашият регулярен израз зависи от определен формат, трябва да го коригирате.
- Ако все още сте използвали нешифровани пароли в базите си на Postgres, тази версия го премахва. Така че е време да подредим нещата за тези, които разчитаха на --unencrypted...
- Останалите несъвместими промени с предишни издания са или твърде свежи, за да бъдат споменати в много код (min_parallel_relation_size), или твърде древни (external tsearch2), или са твърде екзотични (премахване на поддръжка на времеви печати с плаваща запетая в изграждането), така че ще ги пропуснем. Разбира се, те са изброени на страницата за издаване.
- Както беше с 9.5 до 9.6, може да се наложи да коригирате скриптовете си за заявка pg_stat_activity (една нова колона и нови възможни стойности)
- Ако запазвате/анализирате вакуумен подробен изход, може да се наложи да коригирате кода си
- Също така може да искате да разгледате новата реализация на разделяне - може да искате да преработите съществуващия си "комплект", за да отговарят на новите "стандарти"
- проверете времевата линия (ще бъде нулирана за новата база данни, ако pg_upgrade)
Освен тези стъпки, които трябва да знаете, за да надстроите до 10, има много неща, които правят тази версия дългоочаквана. Моля, прочетете раздела за промените в бележките за версията или в блога на depesz.