#include "pgstat.h"
#include "access/committs.h"
+#include "access/heapam.h"
#include "access/xact.h"
+#include "catalog/pg_extension.h"
#include "catalog/pg_index.h"
+#include "commands/extension.h"
#include "lib/stringinfo.h"
#include "replication/replication_identifier.h"
#include "utils/builtins.h"
#include "utils/guc.h"
#include "utils/memutils.h"
+#include "utils/snapmgr.h"
#include "utils/timestamp.h"
/* sequencer */
void _PG_init(void);
+static void bdr_maintain_schema(void);
+
/*
* Converts an int64 to network byte order.
*/
/* Connect to our database */
BackgroundWorkerInitializeConnection(bdr_apply_con->dbname, NULL);
+ /* make sure BDR extension exists */
+ bdr_maintain_schema();
+
/* always work in our own schema */
SetConfigOption("search_path", "bdr, pg_catalog",
PGC_BACKEND, PGC_S_OVERRIDE);
/* Connect to our database */
BackgroundWorkerInitializeConnection(bdr_sequencer_con->dbname, NULL);
+ /* make sure BDR extension exists */
+ bdr_maintain_schema();
+
/* always work in our own schema */
SetConfigOption("search_path", "bdr, pg_catalog",
PGC_BACKEND, PGC_S_OVERRIDE);
elog(WARNING, "starting sequencer on db \"%s\"", bdr_sequencer_con->dbname);
- /* make sure BDR extension exists */
+ /* initialize sequencer */
bdr_sequencer_init();
while (!got_sigterm)
MemoryContextSwitchTo(old_context);
}
+
+/*
+ * Make sure all required extensions are installed in the correct version for
+ * the current database.
+ *
+ * Concurrent executions will block, but not fail.
+ */
+static void
+bdr_maintain_schema(void)
+{
+ Relation extrel;
+ Oid extoid;
+
+ StartTransactionCommand();
+ PushActiveSnapshot(GetTransactionSnapshot());
+
+ /* make sure we're operating without other bdr workers interfering */
+ extrel = heap_open(ExtensionRelationId, ShareUpdateExclusiveLock);
+
+ extoid = get_extension_oid("bdr", true);
+
+ /* create required extension if they don't exists yet */
+ if (extoid == InvalidOid)
+ {
+ CreateExtensionStmt create_stmt;
+
+ create_stmt.if_not_exists = false;
+ create_stmt.options = NIL;
+ create_stmt.extname = (char *)"btree_gist";
+
+ CreateExtension(&create_stmt);
+
+ create_stmt.extname = (char *)"bdr";
+ CreateExtension(&create_stmt);
+ }
+ else
+ {
+ AlterExtensionStmt alter_stmt;
+
+ alter_stmt.options = NIL;
+ alter_stmt.extname = (char *)"btree_gist";
+ ExecAlterExtensionStmt(&alter_stmt);
+
+ alter_stmt.extname = (char *)"bdr";
+ ExecAlterExtensionStmt(&alter_stmt);
+ }
+
+ heap_close(extrel, ShareUpdateExclusiveLock);
+
+ PopActiveSnapshot();
+ CommitTransactionCommand();
+}
#include "access/xact.h"
#include "catalog/pg_type.h"
#include "catalog/namespace.h"
-#include "commands/extension.h"
#include "commands/sequence.h"
#include "executor/spi.h"
#include "utils/builtins.h"
void
bdr_sequencer_init(void)
{
- CreateExtensionStmt create_stmt;
- AlterExtensionStmt alter_stmt;
BdrSequencerSlot *slot;
Assert(bdr_sequencer_con != NULL);
slot = &BdrSequencerCtl->slots[bdr_sequencer_con->slot];
slot->database_oid = MyDatabaseId;
slot->proclatch = &MyProc->procLatch;
-
- create_stmt.if_not_exists = true;
- create_stmt.options = NIL;
-
- alter_stmt.options = NIL;
-
- StartTransactionCommand();
- PushActiveSnapshot(GetTransactionSnapshot());
-
- create_stmt.extname = (char *)"btree_gist";
- alter_stmt.extname = (char *)"btree_gist";
-
- /* create extension if not exists */
- CreateExtension(&create_stmt);
- /* update extension otherwise */
- ExecAlterExtensionStmt(&alter_stmt);
-
- create_stmt.extname = (char *)"bdr";
- alter_stmt.extname = (char *)"bdr";
- /* create extension if not exists */
- CreateExtension(&create_stmt);
- /* update extension otherwise */
- ExecAlterExtensionStmt(&alter_stmt);
-
- PopActiveSnapshot();
- CommitTransactionCommand();
}
static void