Estou com uma situação estranha, visto no log:
Process 37278 waits for ExclusiveLock on advisory lock [16421,999999,12864385,2]; blocked by process 53807.
Process 53807 waits for ExclusiveLock on advisory lock [16421,999999,12864395,2]; blocked by process 37278.
Process 37278: SELECT * FROM zel_api.insert_event ($1 ,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24)
Process 53807: SELECT * FROM zel_api.insert_event ($1 ,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24)",
"See server log for query details.",,,"SQL statement ""SELECT pg_advisory_xact_lock(999999, format('zel_event.%I', p_table_name)::regclass::oid::integer)""
Isso já é estranho por si só, pois parece que dois processos bloqueiam o mesmo bloqueio consultivo, mas nenhum deles pode agarrá-lo.
A função que tenta adquirir o bloqueio é a seguinte:
CREATE OR REPLACE FUNCTION zel_event.create_new_partition(
p_table_name text
)
RETURNS void AS
$BODY$
DECLARE
_schema text;
BEGIN
IF NOT EXISTS (table from catalog)
THEN
PERFORM pg_advisory_xact_lock(999999, format('zel_event.%I', p_table_name)::regclass::oid::integer);
IF NOT EXISTS (table from catalog)
THEN
EXECUTE format('
CREATE TABLE %1$I.%2$I (
LIKE zel_event.%2$I INCLUDING ALL
) INHERITS (zel_event.%2$I)', _schema, p_table_name);
END IF;
END IF;
RETURN;
END;
$BODY$
LANGUAGE plpgsql
SECURITY DEFINER;
A meu ver, nenhuma das causas de impasse 'clássico' está aqui, pois há apenas uma lógica ...
A ideia por trás disso é criar a nova tabela sob demanda onde a demanda pode vir em uma frequência muito alta de várias conexões. É chamado quando uma função de inserção faz o insert destinado à tabela pai, sendo desviado por uma trigger do despachante para a tabela filha apropriada.
É assim que a transação se parece:
INSERT INTO parent (zel_api.insert_event())
|
trigger
|
+----> child exists? ---no---> CREATE TABLE child
| |
yes |
| |
V V
INSERT INTO child (zel_event.create_new_partition())
A versão do PostgreSQL é 9.2
Seria muito interessante ter alguns insights de como isso pode acontecer (e mitigado, claro).
Não é o mesmo bloqueio consultivo. Seu log menciona um id de tabela diferente (desligado em 10) para o primeiro processo como o segundo. Isso parece uma situação clássica de impasse em que dois processos buscam os mesmos bloqueios apenas em uma ordem diferente. O terceiro número do primeiro é 12864385, enquanto o terceiro número do segundo é 12864395.
Portanto, minha suspeita é que ambos os processos estão tentando criar as mesmas partições, apenas em uma ordem diferente e, portanto, eles travam.
Uma coisa que achei útil em situações intrigantes como essa é analisar e comparar um dígito de cada vez em toda a série de números, porque com bloqueios consultivos é muito fácil perder um dígito sutilmente assim.