diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile
index 36929dd97d3..0912a1237ed 100644
--- a/contrib/test_decoding/Makefile
+++ b/contrib/test_decoding/Makefile
@@ -9,7 +9,7 @@ REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
 	sequence
 ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
 	oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
-	twophase_snapshot slot_creation_error
+	twophase_snapshot slot_creation_error messages2 sequences
 
 REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/test_decoding/logical.conf
 ISOLATION_OPTS = --temp-config $(top_srcdir)/contrib/test_decoding/logical.conf
diff --git a/contrib/test_decoding/expected/messages2.out b/contrib/test_decoding/expected/messages2.out
new file mode 100644
index 00000000000..c705693ed55
--- /dev/null
+++ b/contrib/test_decoding/expected/messages2.out
@@ -0,0 +1,78 @@
+Parsed test spec with 3 sessions
+
+starting permutation: s1init s2message s2insert s1start
+step s1init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding', false, true);
+?column?
+--------
+init    
+(1 row)
+
+step s2message: SELECT pg_logical_emit_message(false, 'test', 'msg non-transactional');
+pg_logical_emit_message
+-----------------------
+0/1882B00              
+(1 row)
+
+step s2insert: INSERT INTO t1_message VALUES ('msg');
+step s1start: SELECT data  FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'skip-empty-xacts', '1');
+data                                                                        
+----------------------------------------------------------------------------
+message: transactional: 0 prefix: test, sz: 21 content:msg non-transactional
+BEGIN                                                                       
+table public.t1_message: INSERT: msg[text]:'msg'                            
+COMMIT                                                                      
+(4 rows)
+
+?column?
+--------
+stop    
+(1 row)
+
+
+starting permutation: s2begin s2txid s1init s3begin s3txid s2commit s2begin s2message s2insert s3commit s2commit s1start
+step s2begin: BEGIN;
+step s2txid: SELECT pg_current_xact_id();
+pg_current_xact_id
+------------------
+               728
+(1 row)
+
+step s1init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding', false, true); <waiting ...>
+step s3begin: BEGIN;
+step s3txid: SELECT pg_current_xact_id();
+pg_current_xact_id
+------------------
+               729
+(1 row)
+
+step s2commit: COMMIT;
+step s2begin: BEGIN;
+step s2message: SELECT pg_logical_emit_message(false, 'test', 'msg non-transactional');
+pg_logical_emit_message
+-----------------------
+0/1887998              
+(1 row)
+
+step s2insert: INSERT INTO t1_message VALUES ('msg');
+step s3commit: COMMIT;
+step s1init: <... completed>
+?column?
+--------
+init    
+(1 row)
+
+step s2commit: COMMIT;
+step s1start: SELECT data  FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'skip-empty-xacts', '1');
+data                                            
+------------------------------------------------
+message: transactional: 0 prefix: test, sz: 21 content:msg non-transactional
+BEGIN                                           
+table public.t1_message: INSERT: msg[text]:'msg'
+COMMIT                                          
+(3 rows)
+
+?column?
+--------
+stop    
+(1 row)
+
diff --git a/contrib/test_decoding/expected/sequences.out b/contrib/test_decoding/expected/sequences.out
new file mode 100644
index 00000000000..36f27d9848b
--- /dev/null
+++ b/contrib/test_decoding/expected/sequences.out
@@ -0,0 +1,272 @@
+Parsed test spec with 3 sessions
+
+starting permutation: s1init s2restart s2insert s1start
+step s1init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding', false, true);
+?column?
+--------
+init    
+(1 row)
+
+step s2restart: 
+step s2insert: INSERT INTO t1_seq SELECT nextval('seq1') FROM generate_series(1,100);
+step s1start: SELECT data  FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'skip-empty-xacts', '1');
+data                                                                        
+----------------------------------------------------------------------------
+sequence public.seq1: transactional:0 last_value: 33 log_cnt: 0 is_called:1 
+sequence public.seq1: transactional:0 last_value: 66 log_cnt: 0 is_called:1 
+sequence public.seq1: transactional:0 last_value: 99 log_cnt: 0 is_called:1 
+sequence public.seq1: transactional:0 last_value: 132 log_cnt: 0 is_called:1
+BEGIN                                                                       
+table public.t1_seq: INSERT: c1[integer]:1                                  
+table public.t1_seq: INSERT: c1[integer]:2                                  
+table public.t1_seq: INSERT: c1[integer]:3                                  
+table public.t1_seq: INSERT: c1[integer]:4                                  
+table public.t1_seq: INSERT: c1[integer]:5                                  
+table public.t1_seq: INSERT: c1[integer]:6                                  
+table public.t1_seq: INSERT: c1[integer]:7                                  
+table public.t1_seq: INSERT: c1[integer]:8                                  
+table public.t1_seq: INSERT: c1[integer]:9                                  
+table public.t1_seq: INSERT: c1[integer]:10                                 
+table public.t1_seq: INSERT: c1[integer]:11                                 
+table public.t1_seq: INSERT: c1[integer]:12                                 
+table public.t1_seq: INSERT: c1[integer]:13                                 
+table public.t1_seq: INSERT: c1[integer]:14                                 
+table public.t1_seq: INSERT: c1[integer]:15                                 
+table public.t1_seq: INSERT: c1[integer]:16                                 
+table public.t1_seq: INSERT: c1[integer]:17                                 
+table public.t1_seq: INSERT: c1[integer]:18                                 
+table public.t1_seq: INSERT: c1[integer]:19                                 
+table public.t1_seq: INSERT: c1[integer]:20                                 
+table public.t1_seq: INSERT: c1[integer]:21                                 
+table public.t1_seq: INSERT: c1[integer]:22                                 
+table public.t1_seq: INSERT: c1[integer]:23                                 
+table public.t1_seq: INSERT: c1[integer]:24                                 
+table public.t1_seq: INSERT: c1[integer]:25                                 
+table public.t1_seq: INSERT: c1[integer]:26                                 
+table public.t1_seq: INSERT: c1[integer]:27                                 
+table public.t1_seq: INSERT: c1[integer]:28                                 
+table public.t1_seq: INSERT: c1[integer]:29                                 
+table public.t1_seq: INSERT: c1[integer]:30                                 
+table public.t1_seq: INSERT: c1[integer]:31                                 
+table public.t1_seq: INSERT: c1[integer]:32                                 
+table public.t1_seq: INSERT: c1[integer]:33                                 
+table public.t1_seq: INSERT: c1[integer]:34                                 
+table public.t1_seq: INSERT: c1[integer]:35                                 
+table public.t1_seq: INSERT: c1[integer]:36                                 
+table public.t1_seq: INSERT: c1[integer]:37                                 
+table public.t1_seq: INSERT: c1[integer]:38                                 
+table public.t1_seq: INSERT: c1[integer]:39                                 
+table public.t1_seq: INSERT: c1[integer]:40                                 
+table public.t1_seq: INSERT: c1[integer]:41                                 
+table public.t1_seq: INSERT: c1[integer]:42                                 
+table public.t1_seq: INSERT: c1[integer]:43                                 
+table public.t1_seq: INSERT: c1[integer]:44                                 
+table public.t1_seq: INSERT: c1[integer]:45                                 
+table public.t1_seq: INSERT: c1[integer]:46                                 
+table public.t1_seq: INSERT: c1[integer]:47                                 
+table public.t1_seq: INSERT: c1[integer]:48                                 
+table public.t1_seq: INSERT: c1[integer]:49                                 
+table public.t1_seq: INSERT: c1[integer]:50                                 
+table public.t1_seq: INSERT: c1[integer]:51                                 
+table public.t1_seq: INSERT: c1[integer]:52                                 
+table public.t1_seq: INSERT: c1[integer]:53                                 
+table public.t1_seq: INSERT: c1[integer]:54                                 
+table public.t1_seq: INSERT: c1[integer]:55                                 
+table public.t1_seq: INSERT: c1[integer]:56                                 
+table public.t1_seq: INSERT: c1[integer]:57                                 
+table public.t1_seq: INSERT: c1[integer]:58                                 
+table public.t1_seq: INSERT: c1[integer]:59                                 
+table public.t1_seq: INSERT: c1[integer]:60                                 
+table public.t1_seq: INSERT: c1[integer]:61                                 
+table public.t1_seq: INSERT: c1[integer]:62                                 
+table public.t1_seq: INSERT: c1[integer]:63                                 
+table public.t1_seq: INSERT: c1[integer]:64                                 
+table public.t1_seq: INSERT: c1[integer]:65                                 
+table public.t1_seq: INSERT: c1[integer]:66                                 
+table public.t1_seq: INSERT: c1[integer]:67                                 
+table public.t1_seq: INSERT: c1[integer]:68                                 
+table public.t1_seq: INSERT: c1[integer]:69                                 
+table public.t1_seq: INSERT: c1[integer]:70                                 
+table public.t1_seq: INSERT: c1[integer]:71                                 
+table public.t1_seq: INSERT: c1[integer]:72                                 
+table public.t1_seq: INSERT: c1[integer]:73                                 
+table public.t1_seq: INSERT: c1[integer]:74                                 
+table public.t1_seq: INSERT: c1[integer]:75                                 
+table public.t1_seq: INSERT: c1[integer]:76                                 
+table public.t1_seq: INSERT: c1[integer]:77                                 
+table public.t1_seq: INSERT: c1[integer]:78                                 
+table public.t1_seq: INSERT: c1[integer]:79                                 
+table public.t1_seq: INSERT: c1[integer]:80                                 
+table public.t1_seq: INSERT: c1[integer]:81                                 
+table public.t1_seq: INSERT: c1[integer]:82                                 
+table public.t1_seq: INSERT: c1[integer]:83                                 
+table public.t1_seq: INSERT: c1[integer]:84                                 
+table public.t1_seq: INSERT: c1[integer]:85                                 
+table public.t1_seq: INSERT: c1[integer]:86                                 
+table public.t1_seq: INSERT: c1[integer]:87                                 
+table public.t1_seq: INSERT: c1[integer]:88                                 
+table public.t1_seq: INSERT: c1[integer]:89                                 
+table public.t1_seq: INSERT: c1[integer]:90                                 
+table public.t1_seq: INSERT: c1[integer]:91                                 
+table public.t1_seq: INSERT: c1[integer]:92                                 
+table public.t1_seq: INSERT: c1[integer]:93                                 
+table public.t1_seq: INSERT: c1[integer]:94                                 
+table public.t1_seq: INSERT: c1[integer]:95                                 
+table public.t1_seq: INSERT: c1[integer]:96                                 
+table public.t1_seq: INSERT: c1[integer]:97                                 
+table public.t1_seq: INSERT: c1[integer]:98                                 
+table public.t1_seq: INSERT: c1[integer]:99                                 
+table public.t1_seq: INSERT: c1[integer]:100                                
+COMMIT                                                                      
+(106 rows)
+
+?column?
+--------
+stop    
+(1 row)
+
+
+starting permutation: s2begin s2txid s1init s3begin s3txid s2commit s2begin s2restart s2insert s3commit s2commit s1start
+step s2begin: BEGIN;
+step s2txid: SELECT pg_current_xact_id();
+pg_current_xact_id
+------------------
+               728
+(1 row)
+
+step s1init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding', false, true); <waiting ...>
+step s3begin: BEGIN;
+step s3txid: SELECT pg_current_xact_id();
+pg_current_xact_id
+------------------
+               729
+(1 row)
+
+step s2commit: COMMIT;
+step s2begin: BEGIN;
+step s2restart: 
+step s2insert: INSERT INTO t1_seq SELECT nextval('seq1') FROM generate_series(1,100);
+step s3commit: COMMIT;
+step s1init: <... completed>
+?column?
+--------
+init    
+(1 row)
+
+step s2commit: COMMIT;
+step s1start: SELECT data  FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'skip-empty-xacts', '1');
+data                                        
+--------------------------------------------
+sequence public.seq1: transactional:0 last_value: 33 log_cnt: 0 is_called:1 
+sequence public.seq1: transactional:0 last_value: 66 log_cnt: 0 is_called:1 
+sequence public.seq1: transactional:0 last_value: 99 log_cnt: 0 is_called:1 
+sequence public.seq1: transactional:0 last_value: 132 log_cnt: 0 is_called:1
+BEGIN                                       
+table public.t1_seq: INSERT: c1[integer]:1  
+table public.t1_seq: INSERT: c1[integer]:2  
+table public.t1_seq: INSERT: c1[integer]:3  
+table public.t1_seq: INSERT: c1[integer]:4  
+table public.t1_seq: INSERT: c1[integer]:5  
+table public.t1_seq: INSERT: c1[integer]:6  
+table public.t1_seq: INSERT: c1[integer]:7  
+table public.t1_seq: INSERT: c1[integer]:8  
+table public.t1_seq: INSERT: c1[integer]:9  
+table public.t1_seq: INSERT: c1[integer]:10 
+table public.t1_seq: INSERT: c1[integer]:11 
+table public.t1_seq: INSERT: c1[integer]:12 
+table public.t1_seq: INSERT: c1[integer]:13 
+table public.t1_seq: INSERT: c1[integer]:14 
+table public.t1_seq: INSERT: c1[integer]:15 
+table public.t1_seq: INSERT: c1[integer]:16 
+table public.t1_seq: INSERT: c1[integer]:17 
+table public.t1_seq: INSERT: c1[integer]:18 
+table public.t1_seq: INSERT: c1[integer]:19 
+table public.t1_seq: INSERT: c1[integer]:20 
+table public.t1_seq: INSERT: c1[integer]:21 
+table public.t1_seq: INSERT: c1[integer]:22 
+table public.t1_seq: INSERT: c1[integer]:23 
+table public.t1_seq: INSERT: c1[integer]:24 
+table public.t1_seq: INSERT: c1[integer]:25 
+table public.t1_seq: INSERT: c1[integer]:26 
+table public.t1_seq: INSERT: c1[integer]:27 
+table public.t1_seq: INSERT: c1[integer]:28 
+table public.t1_seq: INSERT: c1[integer]:29 
+table public.t1_seq: INSERT: c1[integer]:30 
+table public.t1_seq: INSERT: c1[integer]:31 
+table public.t1_seq: INSERT: c1[integer]:32 
+table public.t1_seq: INSERT: c1[integer]:33 
+table public.t1_seq: INSERT: c1[integer]:34 
+table public.t1_seq: INSERT: c1[integer]:35 
+table public.t1_seq: INSERT: c1[integer]:36 
+table public.t1_seq: INSERT: c1[integer]:37 
+table public.t1_seq: INSERT: c1[integer]:38 
+table public.t1_seq: INSERT: c1[integer]:39 
+table public.t1_seq: INSERT: c1[integer]:40 
+table public.t1_seq: INSERT: c1[integer]:41 
+table public.t1_seq: INSERT: c1[integer]:42 
+table public.t1_seq: INSERT: c1[integer]:43 
+table public.t1_seq: INSERT: c1[integer]:44 
+table public.t1_seq: INSERT: c1[integer]:45 
+table public.t1_seq: INSERT: c1[integer]:46 
+table public.t1_seq: INSERT: c1[integer]:47 
+table public.t1_seq: INSERT: c1[integer]:48 
+table public.t1_seq: INSERT: c1[integer]:49 
+table public.t1_seq: INSERT: c1[integer]:50 
+table public.t1_seq: INSERT: c1[integer]:51 
+table public.t1_seq: INSERT: c1[integer]:52 
+table public.t1_seq: INSERT: c1[integer]:53 
+table public.t1_seq: INSERT: c1[integer]:54 
+table public.t1_seq: INSERT: c1[integer]:55 
+table public.t1_seq: INSERT: c1[integer]:56 
+table public.t1_seq: INSERT: c1[integer]:57 
+table public.t1_seq: INSERT: c1[integer]:58 
+table public.t1_seq: INSERT: c1[integer]:59 
+table public.t1_seq: INSERT: c1[integer]:60 
+table public.t1_seq: INSERT: c1[integer]:61 
+table public.t1_seq: INSERT: c1[integer]:62 
+table public.t1_seq: INSERT: c1[integer]:63 
+table public.t1_seq: INSERT: c1[integer]:64 
+table public.t1_seq: INSERT: c1[integer]:65 
+table public.t1_seq: INSERT: c1[integer]:66 
+table public.t1_seq: INSERT: c1[integer]:67 
+table public.t1_seq: INSERT: c1[integer]:68 
+table public.t1_seq: INSERT: c1[integer]:69 
+table public.t1_seq: INSERT: c1[integer]:70 
+table public.t1_seq: INSERT: c1[integer]:71 
+table public.t1_seq: INSERT: c1[integer]:72 
+table public.t1_seq: INSERT: c1[integer]:73 
+table public.t1_seq: INSERT: c1[integer]:74 
+table public.t1_seq: INSERT: c1[integer]:75 
+table public.t1_seq: INSERT: c1[integer]:76 
+table public.t1_seq: INSERT: c1[integer]:77 
+table public.t1_seq: INSERT: c1[integer]:78 
+table public.t1_seq: INSERT: c1[integer]:79 
+table public.t1_seq: INSERT: c1[integer]:80 
+table public.t1_seq: INSERT: c1[integer]:81 
+table public.t1_seq: INSERT: c1[integer]:82 
+table public.t1_seq: INSERT: c1[integer]:83 
+table public.t1_seq: INSERT: c1[integer]:84 
+table public.t1_seq: INSERT: c1[integer]:85 
+table public.t1_seq: INSERT: c1[integer]:86 
+table public.t1_seq: INSERT: c1[integer]:87 
+table public.t1_seq: INSERT: c1[integer]:88 
+table public.t1_seq: INSERT: c1[integer]:89 
+table public.t1_seq: INSERT: c1[integer]:90 
+table public.t1_seq: INSERT: c1[integer]:91 
+table public.t1_seq: INSERT: c1[integer]:92 
+table public.t1_seq: INSERT: c1[integer]:93 
+table public.t1_seq: INSERT: c1[integer]:94 
+table public.t1_seq: INSERT: c1[integer]:95 
+table public.t1_seq: INSERT: c1[integer]:96 
+table public.t1_seq: INSERT: c1[integer]:97 
+table public.t1_seq: INSERT: c1[integer]:98 
+table public.t1_seq: INSERT: c1[integer]:99 
+table public.t1_seq: INSERT: c1[integer]:100
+COMMIT                                      
+(102 rows)
+
+?column?
+--------
+stop    
+(1 row)
+
diff --git a/contrib/test_decoding/specs/messages2.spec b/contrib/test_decoding/specs/messages2.spec
new file mode 100644
index 00000000000..1300b781b6c
--- /dev/null
+++ b/contrib/test_decoding/specs/messages2.spec
@@ -0,0 +1,45 @@
+# Test decoding of two-phase transactions during the build of a consistent snapshot.
+setup
+{
+    DROP TABLE IF EXISTS t1_message;
+    CREATE TABLE t1_message(msg text);
+}
+
+teardown
+{
+    DROP TABLE t1_message;
+    SELECT 'stop' FROM pg_drop_replication_slot('isolation_slot');
+}
+
+
+session "s1"
+setup { SET synchronous_commit=on; }
+
+step "s1init" {SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding', false, true);}
+step "s1start" {SELECT data  FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'skip-empty-xacts', '1');}
+
+
+session "s2"
+setup { SET synchronous_commit=on; }
+
+step "s2txid" {SELECT pg_current_xact_id();}
+step "s2begin" {BEGIN;}
+step "s2commit" {COMMIT;}
+step "s2message" {SELECT pg_logical_emit_message(false, 'test', 'msg non-transactional');}
+#step "s2message" {SELECT pg_logical_emit_message(true, 'test', 'msg transactional');}
+step "s2insert" {INSERT INTO t1_message VALUES ('msg');}
+
+session "s3"
+setup { SET synchronous_commit=on; }
+
+step "s3txid" {SELECT pg_current_xact_id();}
+step "s3begin" {BEGIN;}
+step "s3commit" {COMMIT;}
+
+# Simple case, with consistent state before the whole insert, non-transactional
+#
+permutation "s1init" "s2message" "s2insert" "s1start"
+
+# Force building of a consistent snapshot after the INSERT but before COMMIT, non-transactional
+#
+permutation "s2begin" "s2txid" "s1init" "s3begin" "s3txid" "s2commit" "s2begin" "s2message" "s2insert" "s3commit" "s2commit" "s1start"
diff --git a/contrib/test_decoding/specs/sequences.spec b/contrib/test_decoding/specs/sequences.spec
new file mode 100644
index 00000000000..0f2cd06a7d3
--- /dev/null
+++ b/contrib/test_decoding/specs/sequences.spec
@@ -0,0 +1,49 @@
+# Test decoding of two-phase transactions during the build of a consistent snapshot.
+setup
+{
+    DROP TABLE IF EXISTS t1_seq;
+    DROP SEQUENCE IF EXISTS seq1;
+
+    CREATE TABLE t1_seq(c1 INT);
+    CREATE SEQUENCE seq1;
+}
+
+teardown
+{
+    DROP TABLE t1_seq;
+    DROP SEQUENCE seq1;
+    SELECT 'stop' FROM pg_drop_replication_slot('isolation_slot');
+}
+
+
+session "s1"
+setup { SET synchronous_commit=on; }
+
+step "s1init" {SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding', false, true);}
+step "s1start" {SELECT data  FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'skip-empty-xacts', '1');}
+
+
+session "s2"
+setup { SET synchronous_commit=on; }
+
+step "s2txid" {SELECT pg_current_xact_id();}
+step "s2begin" {BEGIN;}
+step "s2commit" {COMMIT;}
+step "s2insert" {INSERT INTO t1_seq SELECT nextval('seq1') FROM generate_series(1,100);}
+#step "s2restart" {ALTER SEQUENCE seq1 RESTART;}
+step "s2restart" {}
+
+session "s3"
+setup { SET synchronous_commit=on; }
+
+step "s3txid" {SELECT pg_current_xact_id();}
+step "s3begin" {BEGIN;}
+step "s3commit" {COMMIT;}
+
+# Simple case, with consistent state before the whole insert
+#
+permutation "s1init" "s2restart" "s2insert" "s1start"
+
+# Force building of a consistent snapshot after the INSERT but before COMMIT
+#
+permutation "s2begin" "s2txid" "s1init" "s3begin" "s3txid" "s2commit" "s2begin" "s2restart" "s2insert" "s3commit" "s2commit" "s1start"
