#ifdef BUILDING_BDR
#include "access/committs.h"
+#include "access/seqam.h"
#endif
#include "access/heapam.h"
#include "access/xact.h"
Oid BdrLocksRelid;
Oid BdrLocksByOwnerRelid;
Oid BdrReplicationSetConfigRelid;
+Oid BdrSeqamOid;
/* GUC storage */
static bool bdr_synchronous_commit;
bdr_lookup_relid("bdr_global_locks", schema_oid);
BdrLocksByOwnerRelid =
bdr_lookup_relid("bdr_global_locks_byowner", schema_oid);
+ BdrSeqamOid = get_seqam_oid("bdr", false);
#endif
bdr_conflict_handlers_init();
extern Oid BdrSequenceValuesRelid;
extern Oid BdrSequenceElectionsRelid;
extern Oid BdrVotesRelid;
+extern Oid BdrSeqamOid;
#endif
/* Structure representing bdr_nodes record */
/* sequence support */
extern void bdr_sequencer_shmem_init(int sequencers);
extern void bdr_sequencer_init(int seq_slot, Size nnodes);
+extern void bdr_sequencer_lock(void);
extern bool bdr_sequencer_vote(void);
extern void bdr_sequencer_tally(void);
extern bool bdr_sequencer_start_elections(void);
relid = RangeVarGetRelidExtended(rv, mode, false, false, NULL, NULL);
+#ifdef BUILDING_BDR
+ /*
+ * Acquire sequencer lock if any of the sequencer relations are
+ * modified. We used to rely on relation locks, but that had problems with
+ * deadlocks and interrupting auto-analyze/vacuum.
+ */
+ if (relid == BdrSequenceValuesRelid ||
+ relid == BdrSequenceElectionsRelid ||
+ relid == BdrVotesRelid)
+ bdr_sequencer_lock();
+#endif
+
return bdr_heap_open(relid, NoLock);
}
slot->nnodes = nnodes;
}
-static void
-bdr_sequencer_lock_rel(char *relname, Oid relid)
-{
- SetCurrentStatementStartTimestamp();
- pgstat_report_activity(STATE_RUNNING, relname);
- LockRelationOid(relid, ExclusiveLock);
-}
-
-static void
+/*
+ * Acquire sequencer lock.
+ *
+ * We lock on on our seqam instead of the underlying relations. That's
+ * advantageous because we only want to prevent modifications by the sequencer
+ * or apply processes, it's perfectly fine for auto-analyze/vacuum to process
+ * the relation.
+ */
+void
bdr_sequencer_lock(void)
{
- bdr_sequencer_lock_rel("bdr_votes", BdrVotesRelid);
- bdr_sequencer_lock_rel("bdr_sequence_elections", BdrSequenceElectionsRelid);
- bdr_sequencer_lock_rel("bdr_sequence_values", BdrSequenceValuesRelid);
+ SetCurrentStatementStartTimestamp();
+ pgstat_report_activity(STATE_RUNNING, "acquiring sequencer lock");
+ LockDatabaseObject(SeqAccessMethodRelationId, BdrSeqamOid, InvalidOid,
+ ExclusiveLock);
}
bool
PopActiveSnapshot();
SPI_finish();
CommitTransactionCommand();
+ pgstat_report_stat(false);
elog(DEBUG1, "started %d votes", processed);
PopActiveSnapshot();
SPI_finish();
CommitTransactionCommand();
+ pgstat_report_stat(false);
return processed > 0;
}
PopActiveSnapshot();
SPI_finish();
CommitTransactionCommand();
+ pgstat_report_stat(false);
}
PopActiveSnapshot();
SPI_finish();
CommitTransactionCommand();
+ pgstat_report_stat(false);
elog(DEBUG1, "checked %d sequences for filling", total);
}