Pull to refresh
12
0
Пётр Петров @ppetrov91

Инженер СУБД

Send message

Добрый день! Большое спасибо!

Про pg_auto_failover просто забыл упомянуть.

Добрый день!

Вопрос был не про то, что в PG сделали MERGE, о чём также написано в статьях.

А про то, что в Oracle могут быть ошибки ограничения целостности первичного ключа при работе нескольких MERGE одновременно.

Попросили привести ссылку, я привёл пример.

Кроме того, не все могут сразу обновиться на новую версию СУБД.

Добрый вечер!

СУБД не гонятся друг за другом.

Скорее при переходе на другую СУБД часто пытаются сделать всё под копирку без понимания особенностей СУБД-источника.

А между тем у каждой из них свои плюсы и минусы.

Нужно только уметь ими пользоваться и понимать, что развивать дальше.

Добрый вечер!

В комментарии ниже приведён пример такой ситуации в СУБД Oracle и PostgreSQL

Добрый вечер!

Пусть имеется следующая таблица в СУБД Oracle:

CREATE TABLE merge_test(
 id NUMBER NOT NULL,
 value VARCHAR2(10),
 CONSTRAINT PK_MERGE_TEST PRIMARY KEY (id)
);

Пусть к ней обращаются две сессии с autocommit = off следующим образом:

Первая сессия:

MERGE INTO merge_test d
USING (SELECT 1 id, 'A' value 
	     FROM dual
	    ) s
   ON (d.id = s.id)
 WHEN matched THEN
     UPDATE SET d.value = s.value
 WHEN not matched THEN
     INSERT (d.id, d.value) VALUES (s.id, s.value);

Вторая сессия выполняет запрос ниже, ждёт освобождения блокировки:

MERGE INTO merge_test d
USING (SELECT 1 id, 'B' value 
	     FROM dual
	    ) s
   ON (d.id = s.id)
 WHEN matched THEN
     UPDATE SET d.value = s.value
 WHEN not matched THEN
     INSERT (d.id, d.value) VALUES (s.id, s.value);

Первая сессия делает COMMIT, а во второй сессии запрос завершается с ошибкой:

Error report -
ORA-00001: нарушено ограничение уникальности (CISADM.PK_MERGE_TEST)

А теперь посмотрим на аналогичную ситуацию в СУБД PostgreSQL. Ниже приведена команда создания таблицы:

CREATE TABLE merge_test (
  id bigint NOT NULL,
  value VARCHAR(10),
  CONSTRAINT PK_MERGE_TEST PRIMARY KEY (id)
);

Первая сессия:

BEGIN;

INSERT INTO merge_test AS t
SELECT 1, 'A'
    ON CONFLICT (id)
    DO UPDATE
          SET value = EXCLUDED.value
        WHERE t.id = EXCLUDED.id;

INSERT 0 1

Вторая сессия ждёт снятия блокировки:

BEGIN;

INSERT INTO merge_test AS t
SELECT 1, 'B'
    ON CONFLICT (id)
    DO UPDATE
          SET value = EXCLUDED.value
        WHERE t.id = EXCLUDED.id;

Первая сессия выполняет COMMIT:

COMMIT;

Вторая сессия успешно завершается успешно:

INSERT 0 1

SELECT * FROM merge_test;
 id | value
----+-------
  1 | B

COMMIT;

Ниже приведено содержимое таблицы:

SELECT * FROM merge_test;

 id | value
----+-------
  1 | B

Добрый день! Спасибо.

Пока такой серии нет, но, наверное, сделать её можно

Пока не умеет.

Модуль pg_variables содержит функции для работы с переменными различных типов. Созданные переменные существуют в течение текущей пользовательской сессии.

https://postgrespro.ru/docs/postgrespro/14/pg-variables

Полагаю, что всё-таки наиболее правильным было бы использование сегмента общей памяти и примитивов его синхронизации. Об этом и был первоначальный вопрос.

В простом случае, да, immutable-функции помогают, но может быть случай, когда что-то вычисляется, помещается в переменную глобального контекста, а потом другой процесс из этой переменной достаёт значение и использует в своих расчётах

Добрый день!

А если требуется искать не по первичному ключу?

Добрый день!

В данном случае, возможно, придётся вносить изменения в pg_variables так, чтобы данные хранились в общей памяти, только так они будут видны всем сессиям.

Добрый день!

Да, придётся поддерживать глобальную таблицу, например, с помощью триггеров

Добрый вечер!

На часть вопросов ответ дан во 2-ой и 3-ей части цикла.

Oracle Advanced Queuing - секция "Использование механизма очередей", статья https://habr.com/ru/company/postgrespro/blog/683748/

В настоящий момент компрессия есть в СУБД Postgres Pro Enterprise, но там данные сжимаются целиком, если создать табличное пространство с опцией WITH (compression=true)

https://postgrespro.ru/docs/enterprise/14/cfs-usage

Объектные типы PL/SQL с методами - секция "Использование PL/SQL коллекций и объектов", статья https://habr.com/ru/company/postgrespro/blog/683748/

Глобальные контексты - секция "Расширение pg_variables", статья https://habr.com/ru/company/postgrespro/blog/679808/

Flashback, к сожалению, в PG отсутствует из-за того, что не хранится история об активных транзакциях в тот или иной момент времени в прошлом. Об этом подробно рассказывается, в частности, на курсе DBA-2 в лекции "Снимки данных"

https://edu.postgrespro.ru/dba2/dba2_03_mvcc_snapshots.pdf

Также об этом говорится в книге "PostgreSQL изнутри"

https://postgrespro.ru/education/books/internals

Добрый вечер!

Своё карьеру я начинал PL/SQL разработчиком. В моём случае, нужно было знать как можно больше про планы выполнения и про приёмы написания хорошего SQL-кода.

Мне также доводилось конвертировать запросы из exadata в СУБД PostgreSQL на одном из пилотных проектов. Там было над чем подумать, в том числе и над оптимальной схемой секционирования.

Правда, все запросы очень на OLAP были похожи хотя бы потому, что пришлось работать с сотнями миллионов строк.

Такие запросы можно сконвертировать в СУБД PostgreSQL, но запускать их стоит на асинхронной реплике с выключенным hot_standby_feedback и с max_standby_streaming_delay в -1.

Возможно, что в exadata есть свои продвинутые алгоритмы, но, к сожалению, это чёрный ящик, нельзя посмотреть, что там используется.

На самом деле, важно понимать, в каких случаях отчёты стоит выполнять на OLTP-базе, а в каких стоит использовать другие решения.

Если не секрет, какие особенности exadata использовались на проекте? И как сейчас живётся без них в PG?

Заранее спасибо.

Поэтому в тексте статьи написано, что в некоторых случаях INCLUDE-индекс может послужить заменой. Кроме того, надо понимать, что Index Only Scan это не совсем сканирование только по индексу. Даже если его планировщик выберет, то может быть ситуация, при которой придётся пойти в часть блоков из-за карты видимости.

Узкий уникальный индекс это отдельная история. В частности, если у Вас уникальный индекс состоит из одного столбца, то селективность считается немного по-другому. Более того, статистика по столбцу может быть проигнорирована, про это даже есть комментарий в коде СУБД.

Что касается bitmap index scan, то это зависит от того, сколько памяти выделяется в том числе и под карту. Потому что может быть ситуация, когда проверяются все строки блока, поскольку в карте сказано, что в нём находится интересующая нас строка. И это, конечно, вообще не быстро.

В предыдущем комментарии просто было сказано, что поскольку при CLUSTER строки будут упорядочены физически и по ключам индекса, то особо смысла нет делать Bitmap Heap Scan, будет просто Index Scan, что может позволить сэкономить на сортировках.

Корреляция это статистика. То, что Вы описали, это учёт корреляции по нескольким столбцам. Частично напоминает историю с разработкой расширенной статистики, когда всё хорошо считалось по одному столбцу, а по нескольким, мягко говоря, не очень.

Пока с корреляцией ничего такого не реализовали.

Добрый вечер!

Постараемся рассказать, варианты есть

Добрый день! Спасибо за уточнение!

Я поправлю это сейчас, а то, действительно, как-то не так это читается

Добрый день! Спасибо за комментарий!

Да, многоуровневое локальное секционирование поддерживается в СУБД PostgreSQL

А вот subpartition template нет. В статье приведён пример, показывающий что это такое.

Что касается DataGuard, наверное, стоило явно написать, что в СУБД PostgreSQL возможно использовать физическую репликацию, ведомый сервер выступает в качестве горячего резерва.

А далее в статье просто указываются технологии, позволяющие осуществить автоматическое переключение с ведущего на ведомый сервер.

1

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Works in
Date of birth
Registered
Activity

Specialization

Database Developer, Инженер баз данных
Senior
PostgreSQL
Java
Oracle
SQL
Linux
Bash