
(ц) Яндекс.Картинки
Всички персонажи са измислени, търговските марки принадлежат на техните собственици, всякакви съвпадения са случайни и всъщност, това е моето „субективно оценъчно мнение, моля не счупвайте вратата…“.
Имаме значителен опит в превода на информационни системи с логика в БД от една СУБД в друга. В контекста на постановление на правителството №1236 от 16.11.2016, често става въпрос за превод от Oracle на Postgresql. Как да организирате процеса максимално ефективно и безболезнено — можем да разкажем отделно, днес ще споделим особеностите на използването на клъстер и с какви проблеми може да се сблъскате при изграждането на високо натоварени разпределени системи със сложна логика в процедурите и функциите.
Спойлер – да, капе, RAC и pg multimaster са много различни решения.
Да предположим, че вече сте пренесли цялата логика от plsql на pgsql. Вашите регресивни тестове са напълно ОК, сега разбира се мислите за мащабиране, тъй като натоварените тестове не ви радват особено, особено на онова оборудване, което беше заложено в проекта първоначално, под онази друга СУБД. Предположим, че сте намерили решение от местния доставчик „Postgres Professional“ с опция на име „multimaster“, която е налична само в „максималната“ версия „Postgres Pro Enterprise“ и по описание – това звучат много като нужното ви, и при първоначално повърхностно проучване ще ви дойде наум мисълта: „О! Вместо RAC, най-доброто! Да още и с техническа поддръжка на родна земя!“.
Но не бързайте да се радвате, и по-нататък ще опишем защо тези нюанси трябва да се знаят, тъй като е трудно да се предвидят, дори и добре да прочетете документацията на продукта. Оценете дали ще бъдете готови често да обновявате версиите на СУБД директно на производствената площадка, тъй като някои дефекти не са съвместими с промишлената експлоатация и е трудно да се открият по време на тестовете.
Започнете с внимателно прочитане на раздела „multimaster“ — „ограничения“ на сайта на производителя.
Първото, с което можете да се сблъскате, са особеностите на работата с транзакции в така наречения „двуфазов“ режим, и понякога, освен ако не пренапишете изцяло логиката на вашата процедура, няма как да го поправите. Ето един прост пример:
създайте таблица test1 (id integer, id1 integer);
въведете в test1 стойности (1, 1),(1, 2);
ALTER TABLE test1 ADD CONSTRAINT test1_uk UNIQUE (id,id1) DEFERRABLE INITIALLY DEFERRED;
актуализирайте test1
set id1 =
case id1
when 1
then 2
else id1 - sign(2 - 1)
end
where id1 between 1 and 2;Появява се грешка:
ГРЕШКА: [MTM] Транзакция MTM-1-2435-10-605783555137701 (10654) е прекратена на възел 3. Проверете логовете, за да видите подробности за грешката.Може да се борите дълго с dead lock в версии 10.5, 10.6, и единственото известно решение, което убива цялата същност на кластера – е да се извадят "проблемните" таблици от кластера, т.е. да се направи make_table_local, но поне това ще позволи да работите, а не да спрете всичко заради заседнали очаквания за фиксация на транзакции. Или да обновите до версия 11.2, която трябва да помогне, а може и да не помогне, не забравяйте да проверите.
В някои версии можете да получите още по-загадъчна блокировка:
username= mtm и backend_type = background workerИ в тази ситуация единственото, което ще ви помогне, е обновлението на версията на СУБД до 11.2 и по-висока, а може и да не помогне.
Някои операции с индекси могат да доведат до грешки, където изрично е посочено, че проблемът е именно в Bi-Directional Replication, в логовете MTM ще видите точно BDR. Наистина ли 2ndQuadrant? Не… ние сме купили multimaster, това е просто съвпадение, това е името на технологията.
[MTM] bdr doesn't support index rechecks
[MTM] 12124: REMOTE begin abort transaction 4083
[MTM] 12124: send ABORT notification for transaction (5467) local xid=4083 to coordinator 3
[MTM] Receive ABORT_PREPARED logical message for transaction MTM-3-25030-83-605694076627780 from node 3
[MTM] Abort prepared transaction MTM-3-25030-83-605694076627780 status InProgress from node 3 originId=3
[MTM] MtmLogAbortLogicalMessage node=3 transaction=MTM-3-25030-83-605694076627780 lsn=9fff448 Ако използвате временни таблици, въпреки уверенията: "Разширението multimaster осъществява репликация на данните напълно автоматично. Можете едновременно да извършвате писмени транзакции и да работите с временни таблици на който и да е възел на кластера."
То в действителност ще получите, че репликацията не работи за всички таблици, използвани в процедурата, ако в кода съществува създаване на временна таблица, и дори използването на multimaster.remote_functions няма да помогне, ще трябва да се обновите или да пренапишете логиката си в процедурата. Ако трябва да използвате едновременно две разширения multimaster и pg_pathman в рамките на "Postgres Pro Enterprise" v 10.5, проверете, че при този прост пример:
СЪЗДАДИ ТАБЛИЦА measurement (
city_id int not null,
logdate date not null,
peaktemp int,
unitsales int
) PARTITION BY RANGE (logdate);
СЪЗДАДИ ТАБЛИЦА measurement_y2019m06 PARTITION OF measurement ЗА ТВЪРДЕНИЯ ОТ ('2019-06-01') ДО ('2019-07-01');
вмъкни в measurement стойности (1, to_date('27.06.2019', 'dd.mm.yyyy'), 1, 1);
вмъкни в measurement стойности (2, to_date('28.06.2019', 'dd.mm.yyyy'), 1, 1);
вмъкни в measurement стойности (3, to_date('29.06.2019', 'dd.mm.yyyy'), 1, 1);
вмъкни в measurement стойности (4, to_date('30.06.2019', 'dd.mm.yyyy'), 1, 1);В логовете на възлите на СУБД започват да се появяват подобни грешки:
…
PATHMAN_CONFIG doesn't contain relation 23245
> find_in_dynamic_libpath: trying "/opt/.../ent-10/lib/pg_pathman"
> find_in_dynamic_libpath: trying "/opt/.../ent-10/lib/pg_pathman.so"
> ОТЛАДКА: find_in_dynamic_libpath: trying "/opt/.../ent-10/lib/pg_pathman"
> find_in_dynamic_libpath: trying "/opt/.../ent-10/lib/pg_pathman.so"
> PrepareTransaction(1) name: unnamed; blockState: PREPARE; state: INPROGR, xid/subid/cid: 6919/1/40
> StartTransaction(1) name: unnamed; blockState: DEFAULT; state: INPROGR, xid/subid/cid: 0/1/0
> switched to timeline 1 valid until 0/0
…
Транзакция MTM-1-13604-7-612438856339841 (6919) е отменена на възел 2. Проверете логовете му, за да видите детайлите на грешката.
...
[MTM] 28295: REMOTE begin abort transaction 7017
…
[MTM] 28295: send ABORT notification for transaction (6919) local xid=7017 to coordinator 1
Какво означават тези грешки, ще можете да разберете в техническата поддръжка, не случайно я купихте.
Какво да правим? Правилно! Да се обнови до "Postgres Pro Enterprise" до v 11.2
Важно е да знаете, че sequence, като обект на реплицираната БД, не притежава глобална стойност за целия клъстер. Всеки sequence е локален за всеки възел и ако имате полета с уникални ограничения и използвате sequence, можете само да направите инкремент, еквивалентен на номера на възела в клъстера, тъй като броят на възлите в клъстера влияе върху скоростта, с която ще нараства и sequence, и int може да приключи по-бързо от очакваното. За опростяване на работата с sequence в продукта ще намерите дори функцията alter_sequences, която ще направи нужните инкременти за всеки sequence на всички възли, но бъдете готови, че функцията не работи във всички версии. Разбира се, може да я напишете сами, като използвате код от github или модифицирате сами директно в СУБД. В полетата с тип serialbigserial ще работят по-коректно, но за тяхното използване вероятно ще трябва да пренапишете кода на вашите процедури и функции. Може би на някого ще му е полезна функцията monotonic_sequences.
До версия 11.2 "Postgres Pro Enterprise" репликацията ще работи само при наличие на уникални първични ключове, имайте предвид това при разработката.
Отделно бих искал да спомена особенностите на работата на npgsql именно в кластерното решение, тези проблеми не възникват на единичен възел, но в многомастера са напълно налични.
В някои версии може да се сблъскате с грешка:
Exception Details: Npgsql.PostgresException: 25001: команда SET TRANSACTION ISOLATION LEVEL
Description: Възникна необработено изключение по време на изпълнението на текущото уеб искане. Моля, прегледайте стека за повече информация за грешката и откъде е произлязла в кода. Какво можете да направите? Просто не трябва да използвате някои версии. Трябва да ги знаете, тъй като грешката не се появява в една версия, и дори след първоначалното й поправяне, можете да се сблъскате с нея по-късно. Трябва да сте подготвени и е по-добре да покривате всички открити дефекти на СУБД, които производителят поправя, с отделни регресионни тестове. Както се казва, доверявайте се, но проверявайте.
Ако приложението използва npgsql и превключва между възлите, мислейки, че те са всичките еднакви, може да възникне грешка:
EXCEPTION:Npgsql.PostgresException (0x80004005): XX000: кеширане на тип неуспешно ...Тази грешка ще се появи, защото се извършва свързване
(NpgsqlConnection.GlobalTypeMapper.MapComposite<SomeType>("some_composite_type");) на композитни типове при стартиране на приложението за всички връзки. В резултат получаваме идентификатор от един възел, а при заявка на другия възел той не съвпада, поради което се връща грешка, т.е. прозрачното работа с композитни типове в кластер за някои приложения ще бъде невъзможно без допълнителни пренаписвания отстрани на приложението (ако успеете да го направите).
Както всички знаем, общата оценка на състоянието на клъстера е много важна за диагностика и оперативни мерки по време на работа, а в продукта ще можете да намерите някои функции, които трябва да улеснят живота ви, но понякога те могат да дават съвсем различно от това, което вие и дори самият производител очакват от тях.
Например:
select mtm.collect_cluster_info();
на всеки възел дава идентичен резултат:
(1,Online,0,0,0,2,3,0,0,0,1,0,0,1,1,3,7,0,0,0,"2018-10-31 05:33:06")
(2,Online,0,0,0,2,3,0,0,0,1,0,0,1,1,3,7,0,0,0,"2018-10-31 05:33:06")
(3,Online,0,0,0,2,3,0,0,0,1,0,0,1,1,3,7,0,0,0,"2018-10-31 05:33:09")Но защо в полето LiveNodes навсякъде стои числото 2, въпреки че по описание на работата на многомастера трябва да съответства на числото AllNodes=3? Отговор: трябва да актуализирате версията на СУБД.
И бъдете готови да събирате логове от всички възли, тъй като обикновено ще виждате „грешката е в логовете на друг възел“. Техническата поддръжка ще приеме всички открити от вас дефекти и ще съобщи за готовността на следващата версия, която ще трябва да инсталирате понякога с спиране на услугата, а понякога и за дълго (в зависимост от обема на вашата СУБД). Не разчитайте, че проблемите с експлоатацията ще притесняват много вендора, и ъпдейтът поради откритите дефекти ще бъде извършен с участието на представители на вендора, точник дори не е необходимо да привличате представители на вендора, тъй като в крайна сметка можете да получите на продуктивна среда разбит клъстер без бекъп.
Всъщност, в лицензията за търговския продукт производителят честно предупреждава: „Този софтуер се предоставя на принципа „както е“ и дружеството с ограничена отговорност „Постгрес Професионален“ не е задължено да предоставя поддръжка, услуги, ъпдейти, разширения или промени.“
Ако все още не сте разбрали за кой продукт става въпрос, то целият този опит е получен в резултат на годишна експлоатация на базата Postgres Pro Enterprise. Изводите можете да направите сами, толкова е суров, че гъбите израстват.
Но това щеше да е само половината беда, ако проблемите се решаваха своевременно и оперативно.
Но именно това не се случва. Явно ресурсите на производителя не са достатъчни, за да се решават идентифицираните бъгове бързо.
Само регистрирани потребители могат да участват в анкетата. , моля.
Имате ли опит в преминаването от чужда/проприетарна СУБД на свободна/родна?
21,3%Да, положителен 10
10,6%Да, отрицателен 5
21,3%Не, не сме сменяли СУБД 10
4,3%Сменяли сме СУБД, но нищо не се промени 2
42,6%Прегледайте резултатите 20
Гласували са 47 потребители. Въздържали се 12 потребители.
Източник: habr.com
