37
37
38
38
#include "multimaster.h"
39
39
40
- typedef struct PGLogicalProtoMM
41
- {
42
- PGLogicalProtoAPI api ;
43
- int nodeId ;
44
- bool isLocal ;
45
- } PGLogicalProtoMM ;
40
+ static bool MtmIsFilteredTxn ;
46
41
47
42
static void pglogical_write_rel (StringInfo out , PGLogicalOutputData * data , Relation rel );
48
43
@@ -72,30 +67,31 @@ static char decide_datum_transfer(Form_pg_attribute att,
72
67
static void
73
68
pglogical_write_rel (StringInfo out , PGLogicalOutputData * data , Relation rel )
74
69
{
75
- PGLogicalProtoMM * mm = (PGLogicalProtoMM * )data -> api ;
76
- if (!mm -> isLocal ) {
77
- const char * nspname ;
78
- uint8 nspnamelen ;
79
- const char * relname ;
80
- uint8 relnamelen ;
81
-
82
- pq_sendbyte (out , 'R' ); /* sending RELATION */
83
-
84
- nspname = get_namespace_name (rel -> rd_rel -> relnamespace );
85
- if (nspname == NULL )
86
- elog (ERROR , "cache lookup failed for namespace %u" ,
87
- rel -> rd_rel -> relnamespace );
88
- nspnamelen = strlen (nspname ) + 1 ;
89
-
90
- relname = NameStr (rel -> rd_rel -> relname );
91
- relnamelen = strlen (relname ) + 1 ;
92
-
93
- pq_sendbyte (out , nspnamelen ); /* schema name length */
94
- pq_sendbytes (out , nspname , nspnamelen );
95
-
96
- pq_sendbyte (out , relnamelen ); /* table name length */
97
- pq_sendbytes (out , relname , relnamelen );
98
- }
70
+ const char * nspname ;
71
+ uint8 nspnamelen ;
72
+ const char * relname ;
73
+ uint8 relnamelen ;
74
+
75
+ if (MtmIsFilteredTxn ) {
76
+ return ;
77
+ }
78
+
79
+ pq_sendbyte (out , 'R' ); /* sending RELATION */
80
+
81
+ nspname = get_namespace_name (rel -> rd_rel -> relnamespace );
82
+ if (nspname == NULL )
83
+ elog (ERROR , "cache lookup failed for namespace %u" ,
84
+ rel -> rd_rel -> relnamespace );
85
+ nspnamelen = strlen (nspname ) + 1 ;
86
+
87
+ relname = NameStr (rel -> rd_rel -> relname );
88
+ relnamelen = strlen (relname ) + 1 ;
89
+
90
+ pq_sendbyte (out , nspnamelen ); /* schema name length */
91
+ pq_sendbytes (out , nspname , nspnamelen );
92
+
93
+ pq_sendbyte (out , relnamelen ); /* table name length */
94
+ pq_sendbytes (out , relname , relnamelen );
99
95
}
100
96
101
97
/*
@@ -105,21 +101,19 @@ static void
105
101
pglogical_write_begin (StringInfo out , PGLogicalOutputData * data ,
106
102
ReorderBufferTXN * txn )
107
103
{
108
- PGLogicalProtoMM * mm = ( PGLogicalProtoMM * ) data -> api ;
104
+ bool isRecovery = MtmIsRecoveredNode ( MtmReplicationNodeId ) ;
109
105
csn_t csn = MtmTransactionSnapshot (txn -> xid );
110
- bool isRecovery = MtmIsRecoveredNode (mm -> nodeId );
111
106
MTM_TRACE ("pglogical_write_begin %d CSN=%ld\n" , txn -> xid , csn );
112
- if (csn == INVALID_CSN && !isRecovery ) {
113
- //Assert(txn->origin_id != InvalidRepOriginId);
114
- mm -> isLocal = true;
115
- } else {
116
- mm -> isLocal = false;
117
- //Assert(txn->origin_id == InvalidRepOriginId || isRecovery);
118
- pq_sendbyte (out , 'B' ); /* BEGIN */
107
+
108
+ if (csn == INVALID_CSN && !isRecovery ) {
109
+ MtmIsFilteredTxn = true;
110
+ } else {
111
+ pq_sendbyte (out , 'B' ); /* BEGIN */
119
112
pq_sendint (out , MtmNodeId , 4 );
120
113
pq_sendint (out , isRecovery ? InvalidTransactionId : txn -> xid , 4 );
121
- pq_sendint64 (out , csn );
122
- }
114
+ pq_sendint64 (out , csn );
115
+ MtmIsFilteredTxn = false;
116
+ }
123
117
}
124
118
125
119
/*
@@ -129,9 +123,11 @@ static void
129
123
pglogical_write_commit (StringInfo out , PGLogicalOutputData * data ,
130
124
ReorderBufferTXN * txn , XLogRecPtr commit_lsn )
131
125
{
132
- PGLogicalProtoMM * mm = (PGLogicalProtoMM * )data -> api ;
133
126
uint8 flags = 0 ;
134
127
128
+ if (MtmIsFilteredTxn ) {
129
+ return ;
130
+ }
135
131
if (txn -> xact_action == XLOG_XACT_COMMIT )
136
132
flags = PGLOGICAL_COMMIT ;
137
133
else if (txn -> xact_action == XLOG_XACT_PREPARE )
@@ -143,18 +139,19 @@ pglogical_write_commit(StringInfo out, PGLogicalOutputData *data,
143
139
else
144
140
Assert (false);
145
141
146
-
142
+ #if 0
147
143
if (flags == PGLOGICAL_COMMIT || flags == PGLOGICAL_PREPARE ) {
148
144
if (mm -> isLocal ) {
149
145
return ;
150
146
}
151
147
} else {
152
148
csn_t csn = MtmTransactionSnapshot (txn -> xid );
153
- bool isRecovery = MtmIsRecoveredNode (mm -> nodeId );
149
+ bool isRecovery = MtmIsRecoveredNode (MtmReplicationNodeId );
154
150
if (csn == INVALID_CSN && !isRecovery ) {
155
151
return ;
156
152
}
157
153
}
154
+ #endif
158
155
159
156
pq_sendbyte (out , 'C' ); /* sending COMMIT */
160
157
@@ -185,11 +182,10 @@ static void
185
182
pglogical_write_insert (StringInfo out , PGLogicalOutputData * data ,
186
183
Relation rel , HeapTuple newtuple )
187
184
{
188
- PGLogicalProtoMM * mm = (PGLogicalProtoMM * )data -> api ;
189
- if (!mm -> isLocal ) {
190
- pq_sendbyte (out , 'I' ); /* action INSERT */
191
- pglogical_write_tuple (out , data , rel , newtuple );
192
- }
185
+ if (!MtmIsFilteredTxn ) {
186
+ pq_sendbyte (out , 'I' ); /* action INSERT */
187
+ pglogical_write_tuple (out , data , rel , newtuple );
188
+ }
193
189
}
194
190
195
191
/*
@@ -199,32 +195,31 @@ static void
199
195
pglogical_write_update (StringInfo out , PGLogicalOutputData * data ,
200
196
Relation rel , HeapTuple oldtuple , HeapTuple newtuple )
201
197
{
202
- PGLogicalProtoMM * mm = (PGLogicalProtoMM * )data -> api ;
203
- if (!mm -> isLocal ) {
204
- pq_sendbyte (out , 'U' ); /* action UPDATE */
205
- /* FIXME support whole tuple (O tuple type) */
206
- if (oldtuple != NULL )
207
- {
208
- pq_sendbyte (out , 'K' ); /* old key follows */
209
- pglogical_write_tuple (out , data , rel , oldtuple );
210
- }
211
-
212
- pq_sendbyte (out , 'N' ); /* new tuple follows */
213
- pglogical_write_tuple (out , data , rel , newtuple );
214
- }
198
+ if (!MtmIsFilteredTxn ) {
199
+ pq_sendbyte (out , 'U' ); /* action UPDATE */
200
+ /* FIXME support whole tuple (O tuple type) */
201
+ if (oldtuple != NULL )
202
+ {
203
+ pq_sendbyte (out , 'K' ); /* old key follows */
204
+ pglogical_write_tuple (out , data , rel , oldtuple );
205
+ }
206
+
207
+ pq_sendbyte (out , 'N' ); /* new tuple follows */
208
+ pglogical_write_tuple (out , data , rel , newtuple );
209
+ }
215
210
}
211
+
216
212
/*
217
213
* Write DELETE to the output stream.
218
214
*/
219
215
static void
220
216
pglogical_write_delete (StringInfo out , PGLogicalOutputData * data ,
221
217
Relation rel , HeapTuple oldtuple )
222
218
{
223
- PGLogicalProtoMM * mm = (PGLogicalProtoMM * )data -> api ;
224
- if (!mm -> isLocal ) {
225
- pq_sendbyte (out , 'D' ); /* action DELETE */
226
- pglogical_write_tuple (out , data , rel , oldtuple );
227
- }
219
+ if (!MtmIsFilteredTxn ) {
220
+ pq_sendbyte (out , 'D' ); /* action DELETE */
221
+ pglogical_write_tuple (out , data , rel , oldtuple );
222
+ }
228
223
}
229
224
230
225
/*
@@ -422,16 +417,16 @@ decide_datum_transfer(Form_pg_attribute att, Form_pg_type typclass,
422
417
PGLogicalProtoAPI *
423
418
pglogical_init_api (PGLogicalProtoType typ )
424
419
{
425
- PGLogicalProtoMM * pmm = palloc0 (sizeof (PGLogicalProtoMM ));
426
- PGLogicalProtoAPI * res = & pmm -> api ;
427
- pmm -> isLocal = false;
428
- sscanf (MyReplicationSlot -> data .name .data , MULTIMASTER_SLOT_PATTERN , & pmm -> nodeId );
420
+ PGLogicalProtoAPI * res = palloc0 (sizeof (PGLogicalProtoAPI ));
421
+ sscanf (MyReplicationSlot -> data .name .data , MULTIMASTER_SLOT_PATTERN , & MtmReplicationNodeId );
422
+ elog (WARNING , "%d: PRGLOGICAL init API for slot %s node %d" , MyProcPid , MyReplicationSlot -> data .name .data , MtmReplicationNodeId );
429
423
res -> write_rel = pglogical_write_rel ;
430
424
res -> write_begin = pglogical_write_begin ;
431
425
res -> write_commit = pglogical_write_commit ;
432
426
res -> write_insert = pglogical_write_insert ;
433
427
res -> write_update = pglogical_write_update ;
434
428
res -> write_delete = pglogical_write_delete ;
429
+ res -> setup_hooks = MtmSetupReplicationHooks ;
435
430
res -> write_startup_message = write_startup_message ;
436
431
return res ;
437
432
}
0 commit comments