
(ц) Яндекс.Картинки
Всі персонажі вигадані, торгові марки належать їхнім власникам, будь-які збіги випадкові і взагалі, це моя «суб'єктивна оцінна думка, будь ласка не ламайте двері…».
Ми маємо чималий досвід перекладу інформаційних систем з логікою в БД з однієї СУБД в іншу. У розрізі постанови уряду №1236 від 16.11.2016 часто це переклад з Oracle на Postgresql. Як організувати процес максимально ефективно і безболісно — ми можемо розповісти окремо, сьогодні ми розповімо про особливості використання кластера і з якими проблемами можна зіткнутися при побудові розподілених високонавантажених систем зі складною логікою в процедурах і функціях.
Спойлер - так кеп, RAC і pg multimaster це дуже різні рішення.
Припустимо, ви вже перенесли всю логіку з plsql на pgsql. А ваші регресійні тести цілком ОК, тепер ви звичайно думаєте про масштабування, т.к. навантажувальні тести не дуже вас радують, тим більше на тій залозі, яка була закладена в проект спочатку, під ту саму іншу СУБД. Допустимо, ви знайшли рішення від вітчизняного вендора «Postgres Professional» з опцією під назвою «multimaster», яка доступна тільки в «максимальній» версії «Postgres Pro Enterprise» і за описом – це дуже схоже на потрібне вам, і при першому поверхневому вивченні прийде на думку думка: «О! Замість RAC саме те! Та ще й з техсопроводом на Батьківщині!».
Але не поспішайте радіти, і далі ми опишемо, чому ці нюанси треба знати, т.к. їх складно передбачити, навіть добре почитавши документацію щодо продукту. Оцініть, чи готові ви часто оновлювати версії СУБД безпосередньо на промисловому майданчику, т.к. деякі дефекти не сумісні з промисловою експлуатацією та їх складно виявити на тестуванні.
Почніть із уважного прочитання розділу «multimaster» – «обмеження» на сайті виробника.
Перше, із чим можна зіткнутися, це особливості роботи транзакцій, у т.зв. «двох фазному» режимі, і іноді, окрім переписування всієї логіки вашої процедури, це ніяк не виправити. Ось простий приклад:
create table test1 (id integer, id1 integer);
insert into test1 values (1, 1),(1, 2);
ALTER TABLE test1 ADD CONSTRAINT test1_uk UNIQUE (id,id1) DEFERRABLE INITIALLY DEFERRED;
update test1
set id1 =
case id1
when 1
then 2
else id1 - sign(2 - 1)
end
where id1 between 1 and 2;Виникає помилка:
ОШИБКА: [MTM] Transaction MTM-1-2435-10-605783555137701 (10654) is aborted on node 3. Check its log to see error details.Далі можна довго боротися з 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, то перевірте, що при ось такому простенькому прикладі:
CREATE TABLE measurement (
city_id int not null,
logdate date not null,
peaktemp int,
unitsales int
) PARTITION BY RANGE (logdate);
CREATE TABLE measurement_y2019m06 PARTITION OF measurement FOR VALUES FROM ('2019-06-01') TO ('2019-07-01');
insert into measurement values (1, to_date('27.06.2019', 'dd.mm.yyyy'), 1, 1);
insert into measurement values (2, to_date('28.06.2019', 'dd.mm.yyyy'), 1, 1);
insert into measurement values (3, to_date('29.06.2019', 'dd.mm.yyyy'), 1, 1);
insert into measurement values (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
…
Transaction MTM-1-13604-7-612438856339841 (6919) is aborted on node 2. Check its log to see error details.
...
[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, яка зробить потрібні інкременти по кожному sequnce на всіх вузлах, але будьте готові, що функція не у всіх версіях працюватиме. Звичайно, її можна написати самим, взявши за основу код з github або поправивши самостійно прямо в СУБД. При цьому поля з типом serialbigserial працюватимуть коректніше, але для їх використання швидше за все вам потрібно переписувати код ваших процедур і функцій. Можливо, комусь буде корисна функція monotonic_sequences.
До версії 11.2 «Postgres Pro Enterprise» реплікація буде працювати лише за наявності унікальних первинних ключів, враховуйте це під час розробки.
Окремо хотілося б згадати про особливості роботи npgsql саме в кластерному рішенні, ці проблеми не виникають на single node, але в мультимайстрі цілком присутні.
У деяких версіях можна зіткнутися з помилкою:
Exception Details: Npgsql.PostgresException: 25001: команда SET TRANSACTION ISOLATION LEVEL
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Що можна зробити? Просто треба не використовувати деякі версії. Треба знати, т.к. помилка з'являється не в одній версії, і навіть після її першого виправлення ви можете зіткнутися з нею пізніше. До цього теж треба бути готовим і краще за всі виявлені дефекти СУБД, які виправляє виробник, покривати окремими регресійними тестами. Так би мовити, довіряй, але перевіряй.
Якщо програма використовує npgsql і перемикається між нодами думаючи, що вони прямі всі однакові, то у вас може виникати помилка:
EXCEPTION:Npgsql.PostgresException (0x80004005): XX000: cache lookup failed for type ...Така помилка буде через те, що виконується прив'язка
(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
