Backport bdr.permit_ddl_locking to 0.9 stable branch
authorCraig Ringer <craig@2ndquadrant.com>
Tue, 21 Apr 2015 13:10:28 +0000 (21:10 +0800)
committerCraig Ringer <craig@2ndquadrant.com>
Fri, 24 Apr 2015 04:51:34 +0000 (12:51 +0800)
See 330dd989d94b53cd8cf70d6a31d0f93b87599812 for the
original commit with full details.

This incorporates the subsequent docs <para> fix and
the change of the default from false to true.

37 files changed:
Makefile.in
bdr.c
bdr.h
bdr_locks.c
doc/manual-ddl-replication.sgml
doc/manual-settings.sgml
expected/ddl/disable_ddl.out [new file with mode: 0644]
expected/ddl/enable_ddl.out [new file with mode: 0644]
expected/ddl/view.out
expected/dml/basic.out
expected/dml/contrib.out
expected/dml/delete_pk.out
expected/dml/extended.out
expected/dml/missing_pk.out
expected/dml/toasted.out
expected/init_bdr.out
expected/isolation/alter_table.out
expected/isolation/basic_triple_node.out
expected/isolation/ddlconflict.out
specs/isolation/alter_table.spec
specs/isolation/basic_triple_node.spec
specs/isolation/ddlconflict.spec
specs/isolation/dmlconflict_dd.spec
specs/isolation/dmlconflict_ii.spec
specs/isolation/dmlconflict_ud.spec
specs/isolation/dmlconflict_uu.spec
specs/isolation/update_pk_change_conflict.spec
sql/ddl/disable_ddl.sql [new file with mode: 0644]
sql/ddl/enable_ddl.sql [new file with mode: 0644]
sql/ddl/view.sql
sql/dml/basic.sql
sql/dml/contrib.sql
sql/dml/delete_pk.sql
sql/dml/extended.sql
sql/dml/missing_pk.sql
sql/dml/toasted.sql
sql/init_bdr.sql

index 72105eeafa1777d06bf0369aa472154b48a627be..2a74e89194b543bb280f4df492acfa1aba3cdc4c 100644 (file)
@@ -211,9 +211,9 @@ installcheck: ;
 
 ifeq "@BUILDING_BDR@" "1"
 check: regresscheck isolationcheck
-DDLREGRESSCHECKS=ddl/create ddl/alter_table ddl/extension ddl/function \
+DDLREGRESSCHECKS=ddl/enable_ddl ddl/create ddl/alter_table ddl/extension ddl/function \
                 ddl/grant ddl/mixed ddl/namespace ddl/replication_set \
-                ddl/sequence ddl/view
+                ddl/sequence ddl/view ddl/disable_ddl
 REGRESSINIT=init_bdr
 else
 check: regresscheck
diff --git a/bdr.c b/bdr.c
index c366b513da9e58e7103f324d434ad0166d4da3d5..58e7fd595ff6c307112616d1397e45403cdea14b 100644 (file)
--- a/bdr.c
+++ b/bdr.c
@@ -702,6 +702,15 @@ _PG_init(void)
                             NULL, NULL, NULL);
 #endif
 
+   DefineCustomBoolVariable("bdr.permit_ddl_locking",
+                            "Allow commands that can acquire the global "
+                            "DDL lock",
+                            NULL,
+                            &bdr_permit_ddl_locking,
+                            true, PGC_USERSET,
+                            0,
+                            NULL, NULL, NULL);
+
    DefineCustomBoolVariable("bdr.permit_unsafe_ddl_commands",
                             "Allow commands that might cause data or " \
                             "replication problems under BDR to run",
diff --git a/bdr.h b/bdr.h
index 13d68c9bcc1f4d330b26430c63e311215db8e2cf..9ad31151b8aa7868f151c329c01931f67094facc 100644 (file)
--- a/bdr.h
+++ b/bdr.h
@@ -270,6 +270,7 @@ extern int bdr_max_databases;
 extern char *bdr_temp_dump_directory;
 extern bool bdr_log_conflicts_to_table;
 extern bool bdr_conflict_logging_include_tuples;
+extern bool bdr_permit_ddl_locking;
 extern bool bdr_permit_unsafe_commands;
 extern bool bdr_skip_ddl_locking;
 #ifdef BUILDING_UDR
index a6fa042d47401c6e3d3887025e3ee62e6c2cb866..14f966479d210c0e7ea80694374777e3b8c7fa3c 100644 (file)
@@ -152,6 +152,9 @@ static BdrLocksDBState *bdr_my_locks_database = NULL;
 
 static bool this_xact_acquired_lock = false;
 
+/* GUCs */
+bool bdr_permit_ddl_locking = false;
+
 static size_t
 bdr_locks_shmem_size(void)
 {
@@ -532,6 +535,17 @@ bdr_acquire_ddl_lock(void)
    if (this_xact_acquired_lock)
        return;
 
+   if (!bdr_permit_ddl_locking)
+   {
+       ereport(ERROR,
+               (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+                errmsg("Global DDL locking attempt rejected by configuration"),
+                errdetail("bdr.permit_ddl_locking is false and the attempted command "
+                          "would require the global DDL lock to be acquired. "
+                          "Command rejected."),
+                errhint("See the 'DDL replication' chapter of the documentation.")));
+   }
+
    initStringInfo(&s);
 
    bdr_locks_find_my_database(false);
index b09782a4fef3aaa0b9fb9c52d47c5ec70d0916db..020cc3761faf53ee92a947803c4ce541949f110f 100644 (file)
    is modifying.</emphasis>
   </para>
 
+  <para>
+   Because DDL is disruptive in &bdr;, transactions can't do DDL
+   that requires a heavy global lock by default. This is controlled
+   by the <xref linkend="guc-bdr-permit-ddl-locking"> setting. If
+   set to <literal>false</literal> (the default), any command that would
+   acquire the global DDL lock is rejected with an
+   <literal>ERROR</literal> instead. This helps prevent unintended global
+   DDL lock acquisitions.
+  </para>
+
   <para>
    To minimise the impact of DDL, transactions performing DDL should be short,
    should not be combined with lots of row changes, and should avoid long
index 48b14e7e9a02441f7d835defb7298105053d8d23..6b33ab75a3cfc155e9a46cb5f8c3477c5b0e1992 100644 (file)
       </listitem>
      </varlistentry>
 
+     <varlistentry id="guc-bdr-permit-ddl-locking" xreflabel="bdr.permit_ddl_locking">
+      <term><varname>bdr.permit_ddl_locking</varname> (<type>boolean</type>)
+       <indexterm>
+        <primary><varname>bdr.permit_ddl_locking</varname> configuration parameter</primary>
+       </indexterm>
+      </term>
+      <listitem>
+       <para>
+        Allow sessions to run DDL commands that acquire the global DDL lock. See
+        <xref linkend="ddl-replication"> for details on the DDL lock. Setting this
+        to off by default means that unintended DDL that can be disruptive to
+        production is prevented.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry id="guc-bdr-permit-unsafe-ddl-commands" xreflabel="bdr.permit_unsafe_ddl_commands">
       <term><varname>bdr.permit_unsafe_ddl_commands</varname> (<type>boolean</type>)
        <indexterm>
diff --git a/expected/ddl/disable_ddl.out b/expected/ddl/disable_ddl.out
new file mode 100644 (file)
index 0000000..cd270dc
--- /dev/null
@@ -0,0 +1,2 @@
+ALTER DATABASE regression RESET bdr.permit_ddl_locking;
+ALTER DATABASE postgres RESET bdr.permit_ddl_locking;
diff --git a/expected/ddl/enable_ddl.out b/expected/ddl/enable_ddl.out
new file mode 100644 (file)
index 0000000..aac1606
--- /dev/null
@@ -0,0 +1,18 @@
+SET bdr.permit_ddl_locking = false;
+CREATE TABLE should_fail ( id integer );
+ERROR:  Global DDL locking attempt rejected by configuration
+DETAIL:  bdr.permit_ddl_locking is false and the attempted command would require the global DDL lock to be acquired. Command rejected.
+HINT:  See the 'DDL replication' chapter of the documentation.
+SET bdr.permit_ddl_locking = true;
+CREATE TABLE create_ok (id integer);
+SET bdr.permit_ddl_locking = false;
+ALTER TABLE create_ok ADD COLUMN alter_should_fail text;
+ERROR:  Global DDL locking attempt rejected by configuration
+DETAIL:  bdr.permit_ddl_locking is false and the attempted command would require the global DDL lock to be acquired. Command rejected.
+HINT:  See the 'DDL replication' chapter of the documentation.
+SET bdr.permit_ddl_locking = true;
+DROP TABLE create_ok;
+-- Now for the rest of the DDL tests, presume they're allowed,
+-- otherwise they'll get pointlessly verbose.
+ALTER DATABASE regression SET bdr.permit_ddl_locking = true;
+ALTER DATABASE postgres SET bdr.permit_ddl_locking = true;
index 65f32e5da3bab846e46e7a05ad0450e0bae0baed..0551c76bb72030534da6a4ec0df09cbf1072fbca 100644 (file)
@@ -147,12 +147,26 @@ SELECT * FROM renamed_test_view;
 (4 rows)
 
 DROP VIEW renamed_test_view;
+SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), pid) FROM pg_stat_replication;
+ pg_xlog_wait_remote_apply 
+---------------------------
+(2 rows)
+
 \d renamed_test_view
 \c regression
 \d renamed_test_view
 CREATE VIEW test_view AS SELECT * FROM test_src_tbl;
 DROP TABLE test_src_tbl CASCADE;
 NOTICE:  drop cascades to view test_view
+SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), pid) FROM pg_stat_replication;
+ pg_xlog_wait_remote_apply 
+---------------------------
+(2 rows)
+
 \d test_view
 \c postgres
 \d test_view
index d198e1513bbceb43a9b26894f34cc35f51ca1017..0ebdfc697eb7d690958dad217cd95a382bf18a05 100644 (file)
@@ -2,6 +2,8 @@
 SELECT * FROM public.bdr_regress_variables()
 \gset
 \c :writedb1
+BEGIN;
+SET LOCAL bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($$
    CREATE TABLE public.basic_dml (
        id serial primary key,
@@ -15,6 +17,7 @@ $$);
  
 (1 row)
 
+COMMIT;
 -- check basic insert replication
 INSERT INTO basic_dml(other, data, something)
 VALUES (5, 'foo', '1 minute'::interval),
@@ -170,9 +173,12 @@ SELECT id, other, data, something FROM basic_dml ORDER BY id;
 (4 rows)
 
 \c :writedb1
+BEGIN;
+SET LOCAL bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($$DROP TABLE public.basic_dml;$$);
  bdr_replicate_ddl_command 
 ---------------------------
  
 (1 row)
 
+COMMIT;
index a6170f5fdb10026a208a49d6694ae08de047b8ca..81296efb34cbbaf30849a853b221138f9d2cf3e3 100644 (file)
@@ -2,6 +2,8 @@
 SELECT * FROM public.bdr_regress_variables()
 \gset
 \c :writedb1
+BEGIN;
+SET LOCAL bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($$
    CREATE EXTENSION IF NOT EXISTS cube SCHEMA public;
    CREATE EXTENSION IF NOT EXISTS hstore SCHEMA public;
@@ -17,6 +19,7 @@ $$);
  
 (1 row)
 
+COMMIT;
 -- check basic insert replication
 INSERT INTO contrib_dml(fixed, variable)
 VALUES ('(1,2)', 'a=>1,b=>2'),
@@ -145,9 +148,12 @@ SELECT id, fixed, variable FROM contrib_dml ORDER BY id;
 (0 rows)
 
 \c :writedb1
+BEGIN;
+SET LOCAL bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($$DROP TABLE public.contrib_dml;$$);
  bdr_replicate_ddl_command 
 ---------------------------
  
 (1 row)
 
+COMMIT;
index 3f8deab91ec23fea56cf65ffa28ab7d06ca1467e..cf5517e8807d9f85b7da79701cba811e930ad626 100644 (file)
@@ -2,6 +2,8 @@
 SELECT * FROM public.bdr_regress_variables()
 \gset
 \c :writedb1
+BEGIN;
+SET LOCAL bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($$
    CREATE TABLE public.test (
        id TEXT,
@@ -14,6 +16,7 @@ $$);
  
 (1 row)
 
+COMMIT;
 SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), 0);
  pg_xlog_wait_remote_apply 
 ---------------------------
@@ -79,9 +82,12 @@ SELECT id FROM test ORDER BY ts;
 (0 rows)
 
 \c :writedb1
+BEGIN;
+SET LOCAL bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($$DROP TABLE public.test;$$);
  bdr_replicate_ddl_command 
 ---------------------------
  
 (1 row)
 
+COMMIT;
index 344337321311a126550e8f56d9d492f5793db301..7ab9ebdf938112a87f7732076703694d2dcbc449 100644 (file)
@@ -2,6 +2,8 @@
 SELECT * FROM public.bdr_regress_variables()
 \gset
 \c :writedb1
+BEGIN;
+SET LOCAL bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($$
    CREATE TABLE public.tst_one_array (
        a INTEGER PRIMARY KEY,
@@ -77,6 +79,7 @@ $$);
  
 (1 row)
 
+COMMIT;
 SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), 0);
  pg_xlog_wait_remote_apply 
 ---------------------------
@@ -1376,6 +1379,8 @@ SELECT a, b, c FROM tst_range_array ORDER BY a;
 (1 row)
 
 \c :writedb1
+BEGIN;
+SET LOCAL bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($$
    DROP TABLE public.tst_one_array;
    DROP TABLE public.tst_arrays;
@@ -1402,3 +1407,4 @@ $$);
  
 (1 row)
 
+COMMIT;
index 174a6ed5c4adb83a47e91a8c5263ff77d52a2422..2d7d563886a26248a692b3f5e52c6389d3eda954 100644 (file)
@@ -2,6 +2,8 @@
 SELECT * FROM public.bdr_regress_variables()
 \gset
 \c :writedb1
+BEGIN;
+SET LOCAL bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($$
    CREATE TABLE public.bdr_missing_pk_parent(a serial PRIMARY KEY);
    CREATE TABLE public.bdr_missing_pk(a serial) INHERITS (public.bdr_missing_pk_parent);
@@ -18,6 +20,7 @@ CONTEXT:  during DDL replay of ddl statement:
  
 (1 row)
 
+COMMIT;
 INSERT INTO bdr_missing_pk SELECT generate_series(1, 10);
 SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), 0);
  pg_xlog_wait_remote_apply 
@@ -106,6 +109,8 @@ SELECT * FROM bdr_missing_pk;
 (0 rows)
 
 \c :writedb1
+BEGIN;
+SET LOCAL bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($$DROP TABLE public.bdr_missing_pk CASCADE;$$);
 NOTICE:  drop cascades to view public.bdr_missing_pk_view
 CONTEXT:  during DDL replay of ddl statement: DROP TABLE public.bdr_missing_pk CASCADE;
@@ -114,3 +119,4 @@ CONTEXT:  during DDL replay of ddl statement: DROP TABLE public.bdr_missing_pk C
  
 (1 row)
 
+COMMIT;
index b50d364f972533c9f88bf790bf21550da576ef69..6d6b5b0f65fc9137926c48ae38dc2f9ab65a735b 100644 (file)
@@ -2,6 +2,8 @@
 SELECT * FROM public.bdr_regress_variables()
 \gset
 \c :writedb1
+BEGIN;
+SET LOCAL bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($$
    CREATE TABLE public.toasted (
        id serial primary key,
@@ -22,6 +24,7 @@ $$);
  
 (1 row)
 
+COMMIT;
 -- check replication of toast values
 INSERT INTO toasted(other, data) VALUES('foo', repeat('1234567890', 300));
 -- check that unchanged toast values work correctly
@@ -62,9 +65,12 @@ SELECT * FROM toasted ORDER BY id;
 (6 rows)
 
 \c :writedb1
+BEGIN;
+SET LOCAL bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($$DROP TABLE public.toasted;$$);
  bdr_replicate_ddl_command 
 ---------------------------
  
 (1 row)
 
+COMMIT;
index b482b328b70439a86ac2f918db211942ce75cc7e..3f7b1e034314362daf144c18191d76ca83456e69 100644 (file)
@@ -78,6 +78,7 @@ SELECT node_status, node_local_dsn, node_init_from_dsn FROM bdr.bdr_nodes ORDER
  r           | dbname=regression | dbname=postgres
 (2 rows)
 
+SET bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($DDL$
 CREATE OR REPLACE FUNCTION public.bdr_regress_variables(
     OUT readdb1 text,
index ebed678b59f5cf201b1652c12f8d3bef29b82cc3..9af4e9d13c5560134b40eb657efb615569c5c028 100644 (file)
@@ -1,6 +1,8 @@
 Parsed test spec with 2 sessions
 
-starting permutation: n1s1 n1sync n2read n1s2 n1sync n2read n1s3 n1s4 n1sync n2read n1s5 n1s6 n1sync n2read n1s7 n1sync n2read n1s8 n1s9 n1s10 n2s1 n2sync n1s11 n1sync n2sync n2read n1read n2s2 n2sync n1read
+starting permutation: n1setup n2setup n1s1 n1sync n2read n1s2 n1sync n2read n1s3 n1s4 n1sync n2read n1s5 n1s6 n1sync n2read n1s7 n1sync n2read n1s8 n1s9 n1s10 n2s1 n2sync n1s11 n1sync n2sync n2read n1read n2s2 n2sync n1read
+step n1setup: SET bdr.permit_ddl_locking = true;
+step n2setup: SET bdr.permit_ddl_locking = true;
 step n1s1: INSERT INTO tst (a, b) VALUES (4, 'four');
 step n1sync: SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), pid) FROM pg_stat_replication;
 pg_xlog_wait_remote_apply
index 2c8d77ddece1faaadf0b4b88fe2fdaf2f4ca9b3d..04ba88426d3a7c1eff3542b9dcf64ebcfc8a4340 100644 (file)
@@ -1,6 +1,8 @@
 Parsed test spec with 3 sessions
 
-starting permutation: n1s1 n1sync n2reada n2readb n2readc n2s1 n2sync n3reada n3s1 n3sync n1readb n1s2 n1sync n2readc n2s2 n2sync n3reada n3readb n3s2 n3sync n1readb
+starting permutation: n1setup n2setup n1s1 n1sync n2reada n2readb n2readc n2s1 n2sync n3reada n3s1 n3sync n1readb n1s2 n1sync n2readc n2s2 n2sync n3reada n3readb n3s2 n3sync n1readb
+step n1setup: SET bdr.permit_ddl_locking = true;
+step n2setup: SET bdr.permit_ddl_locking = true;
 step n1s1: 
  INSERT INTO tsta (a, b) VALUES
   (1, ARRAY['aaa', 'bba', 'cca']),
index cd1a432125a2cadd28739d940efa295ccc538e22..9477c10d79acea5775fbbf3a2e7d8457f85a6014 100644 (file)
@@ -1,8 +1,9 @@
 Parsed test spec with 2 sessions
 
-starting permutation: s1b s1ct s2b s2ct s1c s2c s2dt s1wait s2wait s2ct2
-step s1b: BEGIN;
+starting permutation: s1b s1ct s2a s2b s2ct s1c s2c s2dt s1wait s2wait s2ct2
+step s1b: BEGIN; SET LOCAL bdr.permit_ddl_locking = true;
 step s1ct: CREATE TABLE bdr_ddl_conflict_a(f1 int);
+step s2a: SET bdr.permit_ddl_locking = true;
 step s2b: BEGIN;
 step s2ct: CREATE TABLE bdr_ddl_conflict_b(f1 int);
 ERROR:  database is locked against ddl by another node
index 1291a31c7cc9173a8f7db38170675be87427f59f..76deb152354944dace74cb08c901c2348c892839 100644 (file)
@@ -4,17 +4,20 @@ conninfo "node2" "dbname=node2"
 
 setup
 {
+ SET bdr.permit_ddl_locking = true;
  CREATE TABLE tst (a INTEGER PRIMARY KEY, b TEXT);
  INSERT INTO tst (a, b) VALUES (1, 'one'), (2, 'two'), (3, 'three');
 }
 
 teardown
 {
+ SET bdr.permit_ddl_locking = true;
  DROP TABLE tst;
 }
 
 session "s1"
 connection "node1"
+step "n1setup" { SET bdr.permit_ddl_locking = true; }
 step "n1read" { SELECT * FROM tst ORDER BY a; }
 step "n1sync" { SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), pid) FROM pg_stat_replication; }
 step "n1s1" { INSERT INTO tst (a, b) VALUES (4, 'four'); }
@@ -31,9 +34,10 @@ step "n1s11" { COMMIT; }
 
 session "s2"
 connection "node2"
+step "n2setup" { SET bdr.permit_ddl_locking = true; }
 step "n2sync" { SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), pid) FROM pg_stat_replication; }
 step "n2read" { SELECT * FROM tst ORDER BY a; }
 step "n2s1" { UPDATE tst SET c = 'changed' WHERE a = 1; }
 step "n2s2" { UPDATE tst SET b = 'changed' WHERE a = 1; }
 
-permutation "n1s1" "n1sync" "n2read" "n1s2" "n1sync" "n2read" "n1s3" "n1s4" "n1sync" "n2read" "n1s5" "n1s6" "n1sync" "n2read" "n1s7" "n1sync" "n2read" "n1s8" "n1s9" "n1s10" "n2s1" "n2sync" "n1s11" "n1sync" "n2sync" "n2read" "n1read" "n2s2" "n2sync" "n1read"
+permutation "n1setup" "n2setup" "n1s1" "n1sync" "n2read" "n1s2" "n1sync" "n2read" "n1s3" "n1s4" "n1sync" "n2read" "n1s5" "n1s6" "n1sync" "n2read" "n1s7" "n1sync" "n2read" "n1s8" "n1s9" "n1s10" "n2s1" "n2sync" "n1s11" "n1sync" "n2sync" "n2read" "n1read" "n2s2" "n2sync" "n1read"
index e3eb682f73fa5ac7e2b79bc6904f57c08b86ed21..e77994fe14bde2ab7b1886e6aed7862fb7064fdb 100644 (file)
@@ -4,6 +4,7 @@ conninfo "node3" "dbname=node3"
 
 setup
 {
+ SET bdr.permit_ddl_locking = true;
  CREATE TABLE tsta (a INTEGER PRIMARY KEY, b TEXT[]);
  CREATE TABLE tstb (a INTEGER PRIMARY KEY, b tstzrange);
  CREATE TABLE tstc (a INTEGER PRIMARY KEY, b jsonb);
@@ -11,6 +12,7 @@ setup
 
 teardown
 {
+ SET bdr.permit_ddl_locking = true;
  DROP TABLE tsta;
  DROP TABLE tstb;
  DROP TABLE tstc;
@@ -18,6 +20,7 @@ teardown
 
 session "s1"
 connection "node1"
+step "n1setup" { SET bdr.permit_ddl_locking = true; }
 step "n1sync" { SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), pid) FROM pg_stat_replication; }
 step "n1reada" { SELECT a, b FROM tsta ORDER BY a; }
 step "n1readb" { SELECT a, b FROM tstb ORDER BY a; }
@@ -44,6 +47,7 @@ step "n1s2"
 
 session "s2"
 connection "node2"
+step "n2setup" { SET bdr.permit_ddl_locking = true; }
 step "n2sync" { SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), pid) FROM pg_stat_replication; }
 step "n2reada" { SELECT a, b FROM tsta ORDER BY a; }
 step "n2readb" { SELECT a, b FROM tstb ORDER BY a; }
@@ -70,4 +74,4 @@ step "n3s2" {
   (3, '[2003-03-03 03:03:03, 2003-04-05 03:03:03]');
 }
 
-permutation "n1s1" "n1sync" "n2reada" "n2readb" "n2readc" "n2s1" "n2sync" "n3reada" "n3s1" "n3sync" "n1readb" "n1s2" "n1sync" "n2readc" "n2s2" "n2sync" "n3reada" "n3readb" "n3s2" "n3sync" "n1readb"
+permutation "n1setup" "n2setup" "n1s1" "n1sync" "n2reada" "n2readb" "n2readc" "n2s1" "n2sync" "n3reada" "n3s1" "n3sync" "n1readb" "n1s2" "n1sync" "n2readc" "n2s2" "n2sync" "n3reada" "n3readb" "n3s2" "n3sync" "n1readb"
index 0c3b6cf20f940d58bce46fab3d075dcccc4a8d64..2a58ca37ba84873ea6c7ed05b185cf3c0fc2acfc 100644 (file)
@@ -3,16 +3,18 @@ conninfo "node2" "dbname=node2"
 
 teardown
 {
+    SET bdr.permit_ddl_locking = true;
    DROP TABLE IF EXISTS bdr_ddl_conflict_a, bdr_ddl_conflict_b, bdr_ddl_conflict_c;
 }
 
 session "snode1"
-step "s1b" { BEGIN; }
+step "s1b" { BEGIN; SET LOCAL bdr.permit_ddl_locking = true; }
 step "s1ct" { CREATE TABLE bdr_ddl_conflict_a(f1 int); }
 step "s1c" { COMMIT; }
 step "s1wait" { SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), pid) FROM pg_stat_replication; }
 
 session "snode2"
+step "s2a" { SET bdr.permit_ddl_locking = true; }
 step "s2b" { BEGIN; }
 step "s2ct" { CREATE TABLE bdr_ddl_conflict_b(f1 int); }
 step "s2c" { COMMIT; }
@@ -20,4 +22,4 @@ step "s2dt" { DROP TABLE bdr_ddl_conflict_a; }
 step "s2wait" { SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), pid) FROM pg_stat_replication; select * from pg_sleep(1); }
 step "s2ct2" { CREATE TABLE bdr_ddl_conflict_c(f1 int); }
 
-permutation "s1b" "s1ct" "s2b" "s2ct" "s1c" "s2c" "s2dt" "s1wait" "s2wait" "s2ct2"
+permutation "s1b" "s1ct" "s2a" "s2b" "s2ct" "s1c" "s2c" "s2dt" "s1wait" "s2wait" "s2ct2"
index 7c91789a1498aae39d47d7721b70983a9f2bd2e5..ff5100f0b2da28bfb5be4113eea3442b57d1961f 100644 (file)
@@ -5,6 +5,7 @@ conninfo "node3" "dbname=node3"
 setup
 {
    BEGIN;
+    SET LOCAL bdr.permit_ddl_locking = true;
    CREATE TABLE test_dmlconflict(a text, b int primary key, c text);
    INSERT INTO test_dmlconflict VALUES('x', 1, 'foo');
    COMMIT;
@@ -13,6 +14,7 @@ setup
 
 teardown
 {
+    SET bdr.permit_ddl_locking = true;
    DROP TABLE test_dmlconflict;
 }
 
index 843eea052bd40e66355627299484cda99f9dc3c8..29a60d6b2f98356ec05ca493a8a627b1d107b2f2 100644 (file)
@@ -5,6 +5,7 @@ conninfo "node3" "dbname=node3"
 setup
 {
    BEGIN;
+    SET LOCAL bdr.permit_ddl_locking = true;
    CREATE TABLE test_dmlconflict(a text, b int primary key, c text);
    COMMIT;
    SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), pid) FROM pg_stat_replication;
@@ -12,6 +13,7 @@ setup
 
 teardown
 {
+    SET bdr.permit_ddl_locking = true;
    DROP TABLE test_dmlconflict;
 }
 
index 4385831b12e33505b0f305f8a9f8c00c28574781..ac7686ece72216a3d27b95d85fbbd61000078d47 100644 (file)
@@ -5,6 +5,7 @@ conninfo "node3" "dbname=node3"
 setup
 {
    BEGIN;
+    SET LOCAL bdr.permit_ddl_locking = true;
    CREATE TABLE test_dmlconflict(a text, b int primary key, c text);
    INSERT INTO test_dmlconflict VALUES('x', 1, 'foo');
    COMMIT;
@@ -13,6 +14,7 @@ setup
 
 teardown
 {
+    SET LOCAL bdr.permit_ddl_locking = true;
    DROP TABLE test_dmlconflict;
 }
 
index d065b0d0b7fddff70443f8d8bd2e2830546abb4e..4b082b49f5dc73067e8ea9f720fcd4b9270bae4f 100644 (file)
@@ -5,6 +5,7 @@ conninfo "node3" "dbname=node3"
 setup
 {
    BEGIN;
+    SET LOCAL bdr.permit_ddl_locking = true;
    CREATE TABLE test_dmlconflict(a text, b int primary key, c text);
    INSERT INTO test_dmlconflict VALUES('x', 1, 'foo');
    COMMIT;
@@ -13,6 +14,7 @@ setup
 
 teardown
 {
+    SET bdr.permit_ddl_locking = true;
    DROP TABLE test_dmlconflict;
 }
 
index 10c8d34f58735d52c52592f914e84854f135f583..7e4620b60c135e6498ab9eb4b845c985384dd603 100644 (file)
@@ -5,12 +5,14 @@ conninfo "node3" "dbname=node3"
 
 setup
 {
+ SET bdr.permit_ddl_locking = true;
  CREATE TABLE tst (a INTEGER PRIMARY KEY, b TEXT);
  INSERT INTO tst (a, b) VALUES (1, 'one');
 }
 
 teardown
 {
+ SET bdr.permit_ddl_locking = true;
  DROP TABLE tst;
 }
 
diff --git a/sql/ddl/disable_ddl.sql b/sql/ddl/disable_ddl.sql
new file mode 100644 (file)
index 0000000..cd270dc
--- /dev/null
@@ -0,0 +1,2 @@
+ALTER DATABASE regression RESET bdr.permit_ddl_locking;
+ALTER DATABASE postgres RESET bdr.permit_ddl_locking;
diff --git a/sql/ddl/enable_ddl.sql b/sql/ddl/enable_ddl.sql
new file mode 100644 (file)
index 0000000..f87f39d
--- /dev/null
@@ -0,0 +1,16 @@
+SET bdr.permit_ddl_locking = false;
+CREATE TABLE should_fail ( id integer );
+
+SET bdr.permit_ddl_locking = true;
+CREATE TABLE create_ok (id integer);
+
+SET bdr.permit_ddl_locking = false;
+ALTER TABLE create_ok ADD COLUMN alter_should_fail text;
+
+SET bdr.permit_ddl_locking = true;
+DROP TABLE create_ok;
+
+-- Now for the rest of the DDL tests, presume they're allowed,
+-- otherwise they'll get pointlessly verbose.
+ALTER DATABASE regression SET bdr.permit_ddl_locking = true;
+ALTER DATABASE postgres SET bdr.permit_ddl_locking = true;
index 53ae7cab4a4d6709b40c256dbeeba722d6cfef43..9586959a935fd412c3870c029b376ef7afe7ea92 100644 (file)
@@ -36,12 +36,14 @@ SELECT * FROM test_src_tbl;
 SELECT * FROM renamed_test_view;
 
 DROP VIEW renamed_test_view;
+SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), pid) FROM pg_stat_replication;
 \d renamed_test_view
 \c regression
 \d renamed_test_view
 
 CREATE VIEW test_view AS SELECT * FROM test_src_tbl;
 DROP TABLE test_src_tbl CASCADE;
+SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), pid) FROM pg_stat_replication;
 
 \d test_view
 \c postgres
index 8ed0ce98321bc431a0d9e570fde1fd8059d66341..cf8ba7d8a4b08890ee2ffb0161b779fb3290fec6 100644 (file)
@@ -4,6 +4,8 @@ SELECT * FROM public.bdr_regress_variables()
 
 \c :writedb1
 
+BEGIN;
+SET LOCAL bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($$
    CREATE TABLE public.basic_dml (
        id serial primary key,
@@ -12,6 +14,7 @@ SELECT bdr.bdr_replicate_ddl_command($$
        something interval
    );
 $$);
+COMMIT;
 
 -- check basic insert replication
 INSERT INTO basic_dml(other, data, something)
@@ -79,4 +82,7 @@ SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), 0);
 SELECT id, other, data, something FROM basic_dml ORDER BY id;
 
 \c :writedb1
+BEGIN;
+SET LOCAL bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($$DROP TABLE public.basic_dml;$$);
+COMMIT;
index bac9a8f526d2aece01a42fd139c419d5d545754a..23936eed190acf313145ff6a198a921dffd2ae47 100644 (file)
@@ -4,6 +4,8 @@ SELECT * FROM public.bdr_regress_variables()
 
 \c :writedb1
 
+BEGIN;
+SET LOCAL bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($$
    CREATE EXTENSION IF NOT EXISTS cube SCHEMA public;
    CREATE EXTENSION IF NOT EXISTS hstore SCHEMA public;
@@ -14,6 +16,7 @@ SELECT bdr.bdr_replicate_ddl_command($$
        variable public.hstore
    );
 $$);
+COMMIT;
 
 -- check basic insert replication
 INSERT INTO contrib_dml(fixed, variable)
@@ -64,4 +67,7 @@ SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), 0);
 SELECT id, fixed, variable FROM contrib_dml ORDER BY id;
 
 \c :writedb1
+BEGIN;
+SET LOCAL bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($$DROP TABLE public.contrib_dml;$$);
+COMMIT;
index ffd255d15b290ae2bfdfde680da1a5055e39dbef..0f972efe9991248349b336563206b257c57e4eaf 100644 (file)
@@ -4,6 +4,8 @@ SELECT * FROM public.bdr_regress_variables()
 
 \c :writedb1
 
+BEGIN;
+SET LOCAL bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($$
    CREATE TABLE public.test (
        id TEXT,
@@ -11,6 +13,7 @@ SELECT bdr.bdr_replicate_ddl_command($$
        PRIMARY KEY (id)
    );
 $$);
+COMMIT;
 
 SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), 0);
 
@@ -39,4 +42,7 @@ SELECT id FROM test ORDER BY ts;
 SELECT id FROM test ORDER BY ts;
 
 \c :writedb1
+BEGIN;
+SET LOCAL bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($$DROP TABLE public.test;$$);
+COMMIT;
index 7da128f9f1ddecb62196bd9c51e55d1fa962fcd1..14b73e972a73e18c52e44af6e5d497cf5f622f0b 100644 (file)
@@ -4,6 +4,8 @@ SELECT * FROM public.bdr_regress_variables()
 
 \c :writedb1
 
+BEGIN;
+SET LOCAL bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($$
    CREATE TABLE public.tst_one_array (
        a INTEGER PRIMARY KEY,
@@ -74,6 +76,7 @@ SELECT bdr.bdr_replicate_ddl_command($$
        c int8range[]
    );
 $$);
+COMMIT;
 
 SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), 0);
 
@@ -545,6 +548,8 @@ SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), 0);
 SELECT a, b, c FROM tst_range_array ORDER BY a;
 
 \c :writedb1
+BEGIN;
+SET LOCAL bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($$
    DROP TABLE public.tst_one_array;
    DROP TABLE public.tst_arrays;
@@ -566,3 +571,4 @@ SELECT bdr.bdr_replicate_ddl_command($$
    DROP TYPE public.tst_comp_basic_t;
    DROP TYPE public.tst_enum_t;
 $$);
+COMMIT;
index e383378c5de8aca76c13680689d8bda5e95abd53..63df87683ad1d99e599d7ff9238095f502da0170 100644 (file)
@@ -4,11 +4,14 @@ SELECT * FROM public.bdr_regress_variables()
 
 \c :writedb1
 
+BEGIN;
+SET LOCAL bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($$
    CREATE TABLE public.bdr_missing_pk_parent(a serial PRIMARY KEY);
    CREATE TABLE public.bdr_missing_pk(a serial) INHERITS (public.bdr_missing_pk_parent);
    CREATE VIEW public.bdr_missing_pk_view AS SELECT * FROM public.bdr_missing_pk;
 $$);
+COMMIT;
 
 INSERT INTO bdr_missing_pk SELECT generate_series(1, 10);
 SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), 0);
@@ -58,4 +61,7 @@ SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), 0);
 SELECT * FROM bdr_missing_pk;
 
 \c :writedb1
+BEGIN;
+SET LOCAL bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($$DROP TABLE public.bdr_missing_pk CASCADE;$$);
+COMMIT;
index 5b643797ef34025e35d41112d774ac0ef35163c4..70afc354a85d431775e2a934fedbc0d8b3136b77 100644 (file)
@@ -4,6 +4,8 @@ SELECT * FROM public.bdr_regress_variables()
 
 \c :writedb1
 
+BEGIN;
+SET LOCAL bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($$
    CREATE TABLE public.toasted (
        id serial primary key,
@@ -15,6 +17,7 @@ $$);
 SELECT bdr.bdr_replicate_ddl_command($$
    ALTER TABLE public.toasted ALTER COLUMN data SET STORAGE EXTERNAL;
 $$);
+COMMIT;
 
 -- check replication of toast values
 INSERT INTO toasted(other, data) VALUES('foo', repeat('1234567890', 300));
@@ -42,4 +45,7 @@ SELECT pg_xlog_wait_remote_apply(pg_current_xlog_location(), 0);
 SELECT * FROM toasted ORDER BY id;
 
 \c :writedb1
+BEGIN;
+SET LOCAL bdr.permit_ddl_locking = true;
 SELECT bdr.bdr_replicate_ddl_command($$DROP TABLE public.toasted;$$);
+COMMIT;
index 16b8dc4f07b9e8fc97f2de545cec1f9621ef8ed4..e977a5e8ccd276ce06d184d011db4a1d1f65e5d9 100644 (file)
@@ -30,6 +30,8 @@ SELECT node_status, node_local_dsn, node_init_from_dsn FROM bdr.bdr_nodes ORDER
 SELECT conn_dsn, conn_replication_sets FROM bdr.bdr_connections ORDER BY conn_dsn;
 SELECT node_status, node_local_dsn, node_init_from_dsn FROM bdr.bdr_nodes ORDER BY node_local_dsn;
 
+SET bdr.permit_ddl_locking = true;
+
 SELECT bdr.bdr_replicate_ddl_command($DDL$
 CREATE OR REPLACE FUNCTION public.bdr_regress_variables(
     OUT readdb1 text,