Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit be65edd

Browse files
committed
Add required database and origin filtering for logical messages.
Logical messages, added in 3fe3511, during decoding failed to filter messages emitted in other databases and messages emitted "under" a replication origin the output plugin isn't interested in. Add tests to verify that both types of filtering actually work. While touching message.sql remove hunk obsoleted by d25379e. Bump XLOG_PAGE_MAGIC because xl_logical_message changed and because 3fe3511 had omitted doing so. 3fe3511 additionally didn't bump catversion, but 7a54270 has done so since. Author: Petr Jelinek Reported-By: Andres Freund Discussion: 20160406142513.wotqy3ba3kanr423@alap3.anarazel.de
1 parent 80abbeb commit be65edd

File tree

8 files changed

+64
-15
lines changed

8 files changed

+64
-15
lines changed

contrib/test_decoding/expected/messages.out

+23-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
-- predictability
22
SET synchronous_commit = on;
3-
SET client_encoding = 'utf8';
43
SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding');
54
?column?
65
----------
@@ -71,9 +70,30 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'for
7170
message: transactional: 1 prefix: test, sz: 11 content:czechtastic
7271
(7 rows)
7372

74-
SELECT 'init' FROM pg_drop_replication_slot('regression_slot');
73+
-- test db filtering
74+
\set prevdb :DBNAME
75+
\c template1
76+
SELECT 'otherdb1' FROM pg_logical_emit_message(false, 'test', 'otherdb1');
7577
?column?
7678
----------
77-
init
79+
otherdb1
80+
(1 row)
81+
82+
SELECT 'otherdb2' FROM pg_logical_emit_message(true, 'test', 'otherdb2');
83+
?column?
84+
----------
85+
otherdb2
86+
(1 row)
87+
88+
\c :prevdb
89+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'force-binary', '0', 'skip-empty-xacts', '1');
90+
data
91+
------
92+
(0 rows)
93+
94+
SELECT 'cleanup' FROM pg_drop_replication_slot('regression_slot');
95+
?column?
96+
----------
97+
cleanup
7898
(1 row)
7999

contrib/test_decoding/expected/replorigin.out

+6
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ SELECT pg_replication_origin_session_setup('test_decoding: regression_slot');
5959
-- ensure we prevent duplicate setup
6060
SELECT pg_replication_origin_session_setup('test_decoding: regression_slot');
6161
ERROR: cannot setup replication origin when one is already setup
62+
SELECT '' FROM pg_logical_emit_message(false, 'test', 'this message will not be decoded');
63+
?column?
64+
----------
65+
66+
(1 row)
67+
6268
BEGIN;
6369
-- setup transaction origin
6470
SELECT pg_replication_origin_xact_setup('0/aabbccdd', '2013-01-01 00:00');

contrib/test_decoding/sql/messages.sql

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
-- predictability
22
SET synchronous_commit = on;
3-
SET client_encoding = 'utf8';
43

54
SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding');
65

@@ -22,4 +21,14 @@ SELECT 'ignorethis' FROM pg_logical_emit_message(true, 'test', 'czechtastic');
2221

2322
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'force-binary', '0', 'skip-empty-xacts', '1');
2423

25-
SELECT 'init' FROM pg_drop_replication_slot('regression_slot');
24+
-- test db filtering
25+
\set prevdb :DBNAME
26+
\c template1
27+
28+
SELECT 'otherdb1' FROM pg_logical_emit_message(false, 'test', 'otherdb1');
29+
SELECT 'otherdb2' FROM pg_logical_emit_message(true, 'test', 'otherdb2');
30+
31+
\c :prevdb
32+
SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'force-binary', '0', 'skip-empty-xacts', '1');
33+
34+
SELECT 'cleanup' FROM pg_drop_replication_slot('regression_slot');

contrib/test_decoding/sql/replorigin.sql

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ SELECT pg_replication_origin_session_setup('test_decoding: regression_slot');
3131
-- ensure we prevent duplicate setup
3232
SELECT pg_replication_origin_session_setup('test_decoding: regression_slot');
3333

34+
SELECT '' FROM pg_logical_emit_message(false, 'test', 'this message will not be decoded');
35+
3436
BEGIN;
3537
-- setup transaction origin
3638
SELECT pg_replication_origin_xact_setup('0/aabbccdd', '2013-01-01 00:00');

src/backend/replication/logical/decode.c

+14-9
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,15 @@ DecodeHeapOp(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
464464
}
465465
}
466466

467+
static inline bool
468+
FilterByOrigin(LogicalDecodingContext *ctx, RepOriginId origin_id)
469+
{
470+
if (ctx->callbacks.filter_by_origin_cb == NULL)
471+
return false;
472+
473+
return filter_by_origin_cb_wrapper(ctx, origin_id);
474+
}
475+
467476
/*
468477
* Handle rmgr LOGICALMSG_ID records for DecodeRecordIntoReorderBuffer().
469478
*/
@@ -474,6 +483,7 @@ DecodeLogicalMsgOp(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
474483
XLogReaderState *r = buf->record;
475484
TransactionId xid = XLogRecGetXid(r);
476485
uint8 info = XLogRecGetInfo(r) & ~XLR_INFO_MASK;
486+
RepOriginId origin_id = XLogRecGetOrigin(r);
477487
Snapshot snapshot;
478488
xl_logical_message *message;
479489

@@ -488,6 +498,10 @@ DecodeLogicalMsgOp(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
488498

489499
message = (xl_logical_message *) XLogRecGetData(r);
490500

501+
if (message->dbId != ctx->slot->data.database ||
502+
FilterByOrigin(ctx, origin_id))
503+
return;
504+
491505
if (message->transactional &&
492506
!SnapBuildProcessChange(builder, xid, buf->origptr))
493507
return;
@@ -504,15 +518,6 @@ DecodeLogicalMsgOp(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
504518
message->message + message->prefix_size);
505519
}
506520

507-
static inline bool
508-
FilterByOrigin(LogicalDecodingContext *ctx, RepOriginId origin_id)
509-
{
510-
if (ctx->callbacks.filter_by_origin_cb == NULL)
511-
return false;
512-
513-
return filter_by_origin_cb_wrapper(ctx, origin_id);
514-
}
515-
516521
/*
517522
* Consolidated commit record handling between the different form of commit
518523
* records.

src/backend/replication/logical/message.c

+6
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131

3232
#include "postgres.h"
3333

34+
#include "miscadmin.h"
35+
3436
#include "access/xact.h"
3537

3638
#include "catalog/indexing.h"
@@ -60,6 +62,7 @@ LogLogicalMessage(const char *prefix, const char *message, size_t size,
6062
GetCurrentTransactionId();
6163
}
6264

65+
xlrec.dbId = MyDatabaseId;
6366
xlrec.transactional = transactional;
6467
xlrec.prefix_size = strlen(prefix) + 1;
6568
xlrec.message_size = size;
@@ -69,6 +72,9 @@ LogLogicalMessage(const char *prefix, const char *message, size_t size,
6972
XLogRegisterData((char *) prefix, xlrec.prefix_size);
7073
XLogRegisterData((char *) message, size);
7174

75+
/* allow origin filtering */
76+
XLogIncludeOrigin();
77+
7278
return XLogInsert(RM_LOGICALMSG_ID, XLOG_LOGICAL_MESSAGE);
7379
}
7480

src/include/access/xlog_internal.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
/*
3232
* Each page of XLOG file has a header like this:
3333
*/
34-
#define XLOG_PAGE_MAGIC 0xD090 /* can be used as WAL version indicator */
34+
#define XLOG_PAGE_MAGIC 0xD091 /* can be used as WAL version indicator */
3535

3636
typedef struct XLogPageHeaderData
3737
{

src/include/replication/message.h

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
*/
2020
typedef struct xl_logical_message
2121
{
22+
Oid dbId; /* database Oid emitted from */
2223
bool transactional; /* is message transactional? */
2324
Size prefix_size; /* length of prefix */
2425
Size message_size; /* size of the message */

0 commit comments

Comments
 (0)