@pgsql

Страница 348 из 1062
Denis
30.05.2017
12:36:47
Да без разницы, у вас select не должен возвращать значения внутри plpgsql функции, если это не return. Если внутри вы вызываете функцию, то пишите perform

Sergey
30.05.2017
12:36:54
Ага, через perform работает

А в полной версии таки

Google
Sergey
30.05.2017
12:38:34
postgres=# select check_fdw_serialization(); ERROR: error executing query: OCIStmtExecute failed to execute remote query DETAIL: ORA-08177: can't serialize access for this transaction CONTEXT: SQL statement "update ts_table set ts = (select sync_date from sync.state where sync_id = 'rr')" PL/pgSQL function check_fdw_serialization() line 6 at SQL statement Time: 1726464.124 ms postgres=#

Вероятно действительно пересекается с чем-то другим.

Anatoliy
30.05.2017
12:39:29
check_fdw_serialization() line 6

судя по всему, на pg_sleep и ругается

body у вас от $$

Denis
30.05.2017
12:41:52
Где-то закрался уровень изоляции serializable, не в pg_sleep() ли?

Guardian
30.05.2017
12:45:21
Попробуй все же, как я тебе сказал, SET TRANSACTION ISOLATION LEVEL to READ COMMITTED

Sergey
30.05.2017
12:45:58
В FDW либо repeatable read либо serializable

Guardian
30.05.2017
12:46:27
ну оно проапгрейдится до repeatable read.

Явно указать IL

А то фиг знает, что там в конфиге по умолчанию.

а какая, кстати, версия pg и oracle_fdw?

Если вдруг oracle_fdw транзакции открывает только в IL serializable, то тебе придется изменить логику хранения этого твоего ts так, чтобы не переписывать один и тот же row. Например, можно делать не update, а insert :)

Google
Guardian
30.05.2017
12:56:53
Ну и быть готовым повторять транзакцию при возникновении этой ошибки. Как всегда, когда ты имеешь дело с serializable. Имхо так.

Вот:

oracle_fdw uses transaction isolation level "serializable" on the Oracle side, which corresponds to PostgreSQL's repeatable read. This is necessary because a single PostgreSQL statement can lead to multiple Oracle queries (e.g. during a nested loop join) and the results need to be consistent.

И вот:

Since oracle_fdw uses serialized transactions, it is possible that data modifying statements lead to a serialization failure: ORA-08177: can't serialize access for this transaction This can happen if concurrent transactions modify the table and gets more likely in long running transactions. Such errors can be identified by their SQLSTATE (40001). An application using oracle_fdw should retry transactions that fail with this error.

Sergey
30.05.2017
13:05:54
Postgres 9.6.2, oracle_fdw совсем свежий

Guardian
30.05.2017
13:06:48
Ну вот смотри выше — oracle_fdw использует serializable IL, поэтому ты получаешь все, что к этому IL причитается.

Ты должен либо повторять транзакции, либо, если у тебя при повторении процент ошибок неприемлемо высок — менять логику, избегая проблем с сериализацией.

Sergey
30.05.2017
13:08:35
Вот только если раздробить одну большую долгую функцию на несколько функций с ровно одним DML через oracle_fdw внутри

Собственно что странно - одна pl/pgsql функция на стороне postgres'а выглядит как одна транзакция или меньше. Почему со стороны oracle получается serialization conflict?

Там несколько транзакций? Пока postgres локально считает свой pl/pgsql oracle_fdw успевает сделать recoonect?

Guardian
30.05.2017
13:12:16
Ничего не понял.

Можно сформулировать почище?

oracle_fdw, судя по его описанию, может превращать один statement pg в несколько statement-ов oracle

disconnect сессии fdw должен приводить к rollback транзакции в pg

Sergey
30.05.2017
13:16:30
OK Есть задача сверить таблицы PG vs Oracle

Guardian
30.05.2017
13:16:48
Насколько я понимаю твой код из обрывочных листингов, у тебя активно конкуррентно меняется один row в таблице

Sergey
30.05.2017
13:17:18
С одной и с другой стороны (через oracle_fdw) выполняем select hash_aggregate_function(*) from table1;

Затем сравниваем и переходим к следующей таблице.

Чтобы зафиксироваться на момент времени из postgres'а в ts_table в oracle прописываем текущий таймстамп и oracle select идёт as of timestamp

Google
Sergey
30.05.2017
13:19:57
Собственно вторая попытка прописать таймстамп в ts_table в рамках одной pl/pgsql функции отваливается с ORA-08177: can't serialize access for this transaction

Guardian
30.05.2017
13:20:46
У тебя это происходит, когда только ОДНА транзакция активна? Руками? Без конкуренциИ?

Или когда эти транзакции выполняются конкурентно?

Sergey
30.05.2017
13:21:56
Думаю да. Сессия в oracle со стороны postgres точно одна.

Guardian
30.05.2017
13:23:05
oracle конкурентно модифицирует ts_table со своей стороны?

Sergey
30.05.2017
13:23:39
Вряд ли.

Guardian
30.05.2017
13:24:45
А зачем, кстати, ты два раза внутри одной транзакции меняешь поле в ts_table?

Ты же не используешь его значение внутри блока /* some work */?

Sergey
30.05.2017
13:26:52
Использую

Guardian
30.05.2017
13:28:00
Тогда, насколько я понимаю, чтобы разбираться дальше, нужно видеть, как ты его используешь.

Но в целом — попробуй перестать менять одну и ту же запись, а вместо этого — дописывать записи insert-ом.

Последнюю всегда можешь найти и получить значение.

Sergey
30.05.2017
13:31:52
Да я уже нашел обход. Мне интересно чем это вызвано и где взорвется в следующий раз.

Guardian
30.05.2017
13:33:31
oracle какой?

Я невеликий специалист по ораклу, но я бы попытался включить там какой-нибудь лог-дебаг, и посмотреть, что происходит, и нет ли каких-нибудь ошибок/падений.

Гуглятся всякие баги оракла на эту тему.

Bug 2728408 can cause ORA-8177 cannot serialize access for this transaction even if no modification of remote data is attempted. It can occur with Oracle server 8.1.7.4 (install one-off patch 2728408) or Oracle server 9.2 (install Patch Set 9.2.0.4 or better).

Если это повторяется руками путем последовательного выполнения statement-ов в транзакции, я бы еще посмотрел EXPLAIN на update, который выдает эту ошибку, чтобы понять, какие конкретно запросы уходят в oracle

Sergey
30.05.2017
13:43:16
Интересный способ. Попробую.

Dmitry
30.05.2017
14:34:15
#cluster_name = '' # added to process titles if nonempty # (change requires restart) а сообщать в sql pg не научился?

Google
Peter
30.05.2017
14:35:46
подскажите, а в официальном docker images, который на debian jessie умышленно оторван create main cluster?

Peter
30.05.2017
14:39:32
вот в этом месте зачем sed'ом меняется на false? RUN apt-get update \ && apt-get install -y postgresql-common \ && sed -ri 's/#(create_main_cluster) .*$/\1 = false/' /etc/postgresql-common/createcluster.conf \ && apt-get install -y \ postgresql-$PG_MAJOR=$PG_VERSION \ postgresql-contrib-$PG_MAJOR=$PG_VERSION \

Dmitry
30.05.2017
14:39:38
SELECT setting FROM pg_settings WHERE name = 'data_directory';
ну тоже тема, только эта настройка не реплицируется

Guardian
30.05.2017
14:40:33
дык реплика не обязана иметь тот же cluster name

Dmitry
30.05.2017
14:41:03
дык реплика не обязана иметь тот же cluster name
просто приставка для процесса :(

Dmitry
30.05.2017
14:42:31
https://github.com/petere/postgresql-common/blob/homebrew/pg_ctlcluster#L276

поделка debian-team. пользуйте ванильный pg_ctl и проч

Admin
ERROR: S client not available

Peter
30.05.2017
14:43:28
вот как

Guardian
30.05.2017
14:43:34
ну это только если уже попробовали все остальное, а постгрес все равно висит

Dmitry
30.05.2017
14:44:00
"висит" :D

Guardian
30.05.2017
14:44:40
да, но предыдущие команды-то ждут возврата же.

Dmitry
30.05.2017
14:45:24
ну а для чего kill -9? почему самому вернуть не нулевой код?

остановка не удалась

зачем kill -9?

Guardian
30.05.2017
14:45:53
а что ты сделал бы руками в такой ситуации?

Google
Dmitry
30.05.2017
14:46:06
РУКАМИ попробовал разобраться в проблеме

Guardian
30.05.2017
14:46:16
если ты ему immediate, а он ноль эмоций.

Dmitry
30.05.2017
14:46:20
для этого ЧЕЛОВЕК нужен

решить что делать дальше с данными

Guardian
30.05.2017
14:47:00
Твоя точка зрения ясна. Но что именно можно сделать? Кроме как ждать вечно?

Guardian
30.05.2017
14:48:03
тут, на мой взгляд, некая подмена понятий.

этот скрипт предназначен для работы в ситуации, когда остановку нужно обеспечить

например, для остановки сервиса при перезагрузке

если ты не сделаешь kill -9, это сделает init

и т. п.

Dmitry
30.05.2017
14:48:51
мне не важна ситуация, мне важны данные

Guardian
30.05.2017
14:49:06
в этой ситуации ты совершенно прав — этот скрипт не подходит.

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

Dmitry
30.05.2017
14:50:12
проанализировать ситуацию

куда залипло

мож синхронная реплика в tcp залипла?

зачем kill -9?

Guardian
30.05.2017
14:52:03
затем, что скрипт предназначен для работы в кейсе, когда остановка неизбежна. Серьезными базами ценных данных так не управляют, конечно. Вопрос сферы применимости.

Viktor
30.05.2017
14:55:46
Подскажите с сортировкой, не могу решение придумать Есть таблица One Two 1 1 1 2 1 2 2 2 3 2 3 1 4 1 Нужно получить One Two 1 1 1 2 1 2 3 1 3 2 4 1 2 2 Как то так...

Andrey
30.05.2017
14:56:24
ORDER BY One, Two

Viktor
30.05.2017
14:57:18
Типа приоритет

Страница 348 из 1062