BDR 0.9.3 and Index on Expression
Giving BDR version 0.9.3 and patched-PostgreSQL 9.4.5 replication a shot. All runs smooth until I add an index expression to a replicated table then insert a record into. BDR crashes with error message:
LOG: worker process: bdr (6229655055721591121,1,16386,)->bdr (6229655055721591121,1, (PID 750) was terminated by signal 11: Segmentation fault
DETAIL: Failed process was running: bdr_apply: BEGIN origin(source, orig_lsn, timestamp): 0/9D50AD0, 2015-12-27 10:13:29.916096+07
Followed by series of:
FATAL: mismatch in worker state, got 0, expected 1
Dig into BDR C codes, I found out that the error is emitted from a point in bdr_apply.c:
function: process_remote_insert
simple_heap_insert(rel->rel, newslot->tts_tuple); --ok
UserTableUpdateOpenIndexes(estate, newslot); --failed
Go deeper into BDR-patched-PostgreSQL’s index.c, it is clear that BDR only crashes when updating index on expression (no problem with column index).
function: FormIndexDatum
iDatum = slot_getattr(slot, keycol, &isNull); --ok
but
iDatum = ExecEvalExprSwitchContext((ExprState *) lfirst(indexpr_item), GetPerTupleExprContext(estate),&isNull,NULL); --failed
Simple solution is removing the index expression and promote field (or new field) for regular column index instead.
It was an index on expression, a funktional index? And now a simple index? I think, this isn’t a solution. A column-index can’t replace a funktional index. Can you explain that in Detail?
From:
http://bdr-project.org/docs/stable/ddl-replication-statements.html#DDL-REPLICATION-PROHIBITED-COMMANDS
you’ll find at the end this:
CREATE INDEX
Generally CREATE INDEX is supported, but CREATE UNIQUE INDEX … WHERE, i.e. partial unique indexes are not allowed.
Martin, my index is not partial unique index
Same thing for non unique indexes (docs need fixing on that)
Can you post your CREATE INDEX statement?
akretschmer, I add new field to the table. Set it as index. Then -during insert or uodate- its value is updated using the same function formerly set as functional index. Anyway, in my next post (BDR … Part 2), I found out that the problematic expression index is when it is written in SQL language. Just modify it using PLPGSQL, BDR works fine.
Martin, this is my create index statement:
CREATE INDEX “mytable_idx: index”
ON mybdr.mytable
USING gin
(mybdr.funcidx(fa, fb, fc, fd) COLLATE pg_catalog.”default” gin_trgm_ops);
BDR crashes if mybdr.funcidx(fa, fb, fc, fd) is written in SQL. It works fine if written in PLPGSQL. Is it related with Memory Context Switches?
—–for more detail, I cut the code from execQual.c (BDR-patched Postgresql.9.4.5) where the error emitted:
Datum
ExecEvalExprSwitchContext(ExprState *expression,
ExprContext *econtext,
bool *isNull,
ExprDoneCond *isDone)
{
Datum retDatum;
MemoryContext oldContext;
oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
retDatum = ExecEvalExpr(expression, econtext, isNull, isDone);
//ExecEvalExpr never returned for failed expression index using SQL language
MemoryContextSwitchTo(oldContext);
return retDatum;
}