Стендап Сьогодні 📢 Канал в Telegram @stendap_sogodni
🤖🚫 AI-free content. This post is 100% written by a human, as is everything on my blog. Enjoy!21.02.2023
Виправляв помилки з матеріалізованими розрізами в Redshift
Сьогодні день видався виснажливий. З ранку до ночі шукав, чому мої розрізи, які так чудово працювали в локальному Postgres та в редакторі запитів Redshift, відмовились створюватись на CI. Встиг навіть створити та розвʼязати запитання на StackOverflow. Нарешті, знайшов — методом спроб та помилок. Це те, що мені найбільше не подобається в Redshift - деякі особливості ніде не пояснені, при цьому текст помилок веде на зовсім невірний хід думок. Мабуть, вже треба писати свій гайд.
Що трапилось. Спочатку була помилка, що у користувача не вистачає прав на якусь системну таблицю. Раніше я робив експерименти від суперкористувача, тому вирішив, що у CI користувача немає прав. Як дати права? Команда GRANT
працює тільки після факту. Є ALTER DEFAULT PRIVILEGES - не працює. Придумав створити процедуру, яка робить GRANT
: якщо у процедури буде атрибут SECURITY DEFINER
, то вона надасть CI користувача право на цю команду (щоб дати собі права.) Задоволений таким кмітливим рішенням, запустив тести на CI та… виявилось, що хоч створити розрізи вдалося, але тепер їх неможливо оновити. Чудово.
Виходить, що залежність розрізу від системної таблиці — це в принципі неправильно, та Redshift мав би так і сказати, а не водити за ніс. Тоді чого не вистачає моєму розрізу-основі, щоб цієї залежності не було? Щоб визначити це, зробив копію коду, що створює розрізи, та почав викидати з нього все підряд, запускаючи, щоб перевірити, чи не зникла проблема. Та нарешті виявилось, що треба не викидати, а додати — а саме, всі стовпчики з GROUP BY мали бути присутніми в SELECT. Напевно, інакше Redshift не може відстежувати зміни до розрізу, тому створює системну таблицю. Якби це був тільки один розріз, то я б й не помітив, а з залежностями маємо такі незрозумілі помилки.
Додам, що спочатку витратив багато часу, бо запускав кожне виправлення на CI та чекав 10 хвилин, поки дійде до місця помилки. Справа пішла спритніше, коли почав відтворювати запити з локального psql
. А потім, щоб перевірити на CI, скоротив сценарій до єдиної частини, що мене цікавила.