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

Commit 865c45f

Browse files
committed
dmq integration: fixes for commit.c to handle neighbours disconnects
1 parent 8705f90 commit 865c45f

File tree

6 files changed

+96
-64
lines changed

6 files changed

+96
-64
lines changed

commit.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ MtmTwoPhaseCommit(MtmCurrentTrans* x)
104104
if (i + 1 != MtmNodeId)
105105
{
106106
dmq_stream_subscribe(psprintf("node%d", i + 1),
107-
psprintf("be%d", MyProc->pgprocno));
107+
psprintf("be%d", MyProc->pgprocno),
108+
i);
108109
sender_to_node[sender_id++] = i + 1;
109110
}
110111
}
@@ -162,7 +163,7 @@ GatherPrepares(MtmCurrentTrans* x, nodemask_t participantsMask, int *failed_at)
162163
StringInfoData buffer;
163164
MtmArbiterMessage *msg;
164165

165-
dmq_pop(&sender_id, &buffer);
166+
dmq_pop(&sender_id, &buffer, participantsMask);
166167
msg = (MtmArbiterMessage *) buffer.data;
167168

168169
// elog(LOG, "GatherPrepares: got %s from node%d", msg->gid, sender_to_node[sender_id]);
@@ -199,7 +200,7 @@ GatherPrecommits(MtmCurrentTrans* x, nodemask_t participantsMask)
199200
StringInfoData buffer;
200201
MtmArbiterMessage *msg;
201202

202-
dmq_pop(&sender_id, &buffer);
203+
dmq_pop(&sender_id, &buffer, participantsMask);
203204
msg = (MtmArbiterMessage *) buffer.data;
204205

205206
elog(LOG, "GatherPrecommits: got %s from node%d", msg->gid, sender_to_node[sender_id]);

dmq.c

Lines changed: 83 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@
4242
#define DMQ_MQ_SIZE ((Size) 65536)
4343
#define DMQ_MQ_MAGIC 0x646d71
4444

45+
// XXX: move to common
46+
#define BIT_CHECK(mask, bit) (((mask) & ((int64)1 << (bit))) != 0)
47+
4548
/*
4649
* Shared data structures to hold current connections topology.
4750
* All that stuff can be moved to persistent tables to avoid hardcoded
@@ -76,6 +79,7 @@ typedef struct {
7679
typedef struct
7780
{
7881
char stream_name[DMQ_NAME_MAXLEN];
82+
int mask_pos;
7983
int procno;
8084
} DmqStreamSubscription;
8185

@@ -88,6 +92,7 @@ typedef struct DmqSharedState
8892
HTAB *subscriptions;
8993
char receiver[DMQ_MAX_RECEIVERS][DMQ_NAME_MAXLEN];
9094
dsm_handle receiver_dsm[DMQ_MAX_RECEIVERS];
95+
int receiver_procno[DMQ_MAX_RECEIVERS];
9196
int nreceivers;
9297

9398
pid_t sender_pid;
@@ -99,8 +104,10 @@ static DmqSharedState *dmq_state;
99104
typedef struct DmqBackendState
100105
{
101106
shm_mq_handle *mq_outh;
102-
shm_mq_handle *mq_inh[DMQ_MAX_DESTINATIONS];
107+
shm_mq_handle *mq_inh[DMQ_MAX_RECEIVERS];
103108
int n_inhandles;
109+
char receiver_names[DMQ_MAX_RECEIVERS][DMQ_NAME_MAXLEN];
110+
int mask_pos[DMQ_MAX_RECEIVERS];
104111
} DmqBackendState;
105112

106113
/* Flags set by signal handlers */
@@ -529,8 +536,8 @@ dmq_sender_main(Datum main_arg)
529536
{
530537
conns[conn_id].state = Idle;
531538
DeleteWaitEvent(set, event.pos);
532-
elog(LOG, "[DMQ] [B1] failed to connect: %s",
533-
PQerrorMessage(conns[conn_id].pgconn));
539+
// elog(LOG, "[DMQ] [B1] failed to connect: %s",
540+
// PQerrorMessage(conns[conn_id].pgconn));
534541
}
535542
else
536543
Assert(status == PGRES_POLLING_WRITING);
@@ -646,14 +653,6 @@ dmq_handle_message(StringInfo msg, shm_mq_handle **mq_handles, dsm_segment *seg)
646653
return;
647654
}
648655

649-
/* select queue and reconnect it if needed */
650-
mq = shm_mq_get_queue(mq_handles[sub->procno]);
651-
if (shm_mq_get_sender(mq) == NULL)
652-
{
653-
shm_mq_set_sender(mq, MyProc);
654-
mq_handles[sub->procno] = shm_mq_attach(mq, seg, NULL);
655-
}
656-
657656
elog(LOG, "got message %s.%s, passing to %d", stream_name, body, sub->procno);
658657

659658
/* and send it */
@@ -843,11 +842,12 @@ dmq_receiver_at_exit(int status, Datum sender)
843842
char sender_name[DMQ_NAME_MAXLEN];
844843

845844
LWLockAcquire(dmq_state->lock, LW_EXCLUSIVE);
846-
strncmp(sender_name, dmq_state->receiver[sender_id], DMQ_NAME_MAXLEN);
845+
strncpy(sender_name, dmq_state->receiver[sender_id], DMQ_NAME_MAXLEN);
847846
dmq_state->receiver[sender_id][0] = '\0';
848847
LWLockRelease(dmq_state->lock);
849848

850-
dmq_receiver_stop_hook(sender_name);
849+
if (dmq_receiver_stop_hook)
850+
dmq_receiver_stop_hook(sender_name);
851851
}
852852

853853

@@ -897,6 +897,7 @@ dmq_receiver_loop(PG_FUNCTION_ARGS)
897897
dmq_state->receiver_dsm[receiver_id] = dsm_segment_handle(seg);
898898
strncpy(dmq_state->receiver[receiver_id], sender_name, DMQ_NAME_MAXLEN);
899899
dmq_state->nreceivers++;
900+
dmq_state->receiver_procno[receiver_id] = MyProc->pgprocno;
900901
LWLockRelease(dmq_state->lock);
901902

902903
on_shmem_exit(dmq_receiver_at_exit, Int32GetDatum(receiver_id));
@@ -1052,53 +1053,34 @@ dmq_push(DmqDestinationId dest_id, char *stream_name, char *msg)
10521053
resetStringInfo(&buf);
10531054
}
10541055

1055-
void
1056-
dmq_stream_subscribe(char *sender_name, char *stream_name)
1056+
static bool
1057+
dmq_reattach_shm_mq(int handle_id)
10571058
{
1058-
bool found;
1059-
DmqStreamSubscription *sub;
1060-
int receiver_id = -1;
1061-
10621059
dsm_segment *seg;
10631060
shm_toc *toc;
10641061
shm_mq *inq;
10651062
MemoryContext oldctx;
10661063

1067-
LWLockAcquire(dmq_state->lock, LW_EXCLUSIVE);
1068-
sub = (DmqStreamSubscription *) hash_search(dmq_state->subscriptions, stream_name,
1069-
HASH_ENTER, &found);
1070-
if (found && sub->procno != MyProc->pgprocno)
1071-
{
1072-
elog(ERROR, "procno%d: %s: subscription is already active for procno %d / %s",
1073-
MyProc->pgprocno, stream_name, sub->procno, sub->stream_name);
1074-
}
1075-
else
1076-
sub->procno = MyProc->pgprocno;
1077-
LWLockRelease(dmq_state->lock);
1064+
int receiver_id = -1;
1065+
int receiver_procno;
1066+
int i;
10781067

10791068
/* await for sender to connect */
10801069
LWLockAcquire(dmq_state->lock, LW_SHARED);
1081-
for (;;)
1070+
for (i = 0; i < DMQ_MAX_RECEIVERS; i++)
10821071
{
1083-
int i;
1084-
1085-
for (i = 0; i < DMQ_MAX_RECEIVERS; i++)
1072+
// XXX: change to hash
1073+
if (strcmp(dmq_state->receiver[i], dmq_local.receiver_names[handle_id]) == 0)
10861074
{
1087-
if (strcmp(dmq_state->receiver[i], sender_name) == 0)
1088-
{
1089-
receiver_id = i;
1090-
break;
1091-
}
1092-
}
1093-
1094-
if (receiver_id >= 0)
1075+
receiver_id = i;
1076+
receiver_procno = dmq_state->receiver_procno[i];
10951077
break;
1096-
1097-
LWLockRelease(dmq_state->lock);
1098-
pg_usleep(100000L);
1099-
CHECK_FOR_INTERRUPTS();
1100-
LWLockAcquire(dmq_state->lock, LW_SHARED);
1078+
}
11011079
}
1080+
LWLockRelease(dmq_state->lock);
1081+
1082+
if (receiver_id < 0)
1083+
return false;
11021084

11031085
Assert(dmq_state->receiver_dsm[receiver_id] != DSM_HANDLE_INVALID);
11041086

@@ -1108,8 +1090,6 @@ dmq_stream_subscribe(char *sender_name, char *stream_name)
11081090
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11091091
errmsg("unable to map dynamic shared memory segment")));
11101092

1111-
LWLockRelease(dmq_state->lock);
1112-
11131093
dsm_pin_mapping(seg);
11141094

11151095
toc = shm_toc_attach(DMQ_MQ_MAGIC, dsm_segment_address(seg));
@@ -1118,30 +1098,74 @@ dmq_stream_subscribe(char *sender_name, char *stream_name)
11181098
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
11191099
errmsg("bad magic number in dynamic shared memory segment")));
11201100

1101+
if (dmq_local.mq_inh[handle_id])
1102+
{
1103+
shm_mq_detach(dmq_local.mq_inh[handle_id]);
1104+
}
1105+
11211106
inq = shm_toc_lookup(toc, MyProc->pgprocno, false);
1122-
// xxx memleak
1107+
1108+
/* re-create */
11231109
inq = shm_mq_create(inq, DMQ_MQ_SIZE);
11241110
shm_mq_set_receiver(inq, MyProc);
1111+
shm_mq_set_sender(inq, &ProcGlobal->allProcs[receiver_procno]);
11251112

11261113
oldctx = MemoryContextSwitchTo(TopMemoryContext);
1127-
dmq_local.mq_inh[dmq_local.n_inhandles++] = shm_mq_attach(inq, seg, NULL);
1114+
dmq_local.mq_inh[handle_id] = shm_mq_attach(inq, seg, NULL);
11281115
MemoryContextSwitchTo(oldctx);
1116+
1117+
return true;
11291118
}
11301119

1120+
11311121
void
1132-
dmq_pop(DmqSenderId *sender_id, StringInfo msg)
1122+
dmq_stream_subscribe(char *sender_name, char *stream_name, int mask_pos)
1123+
{
1124+
bool found;
1125+
DmqStreamSubscription *sub;
1126+
1127+
LWLockAcquire(dmq_state->lock, LW_EXCLUSIVE);
1128+
sub = (DmqStreamSubscription *) hash_search(dmq_state->subscriptions, stream_name,
1129+
HASH_ENTER, &found);
1130+
if (found && sub->procno != MyProc->pgprocno)
1131+
{
1132+
elog(ERROR, "procno%d: %s: subscription is already active for procno %d / %s",
1133+
MyProc->pgprocno, stream_name, sub->procno, sub->stream_name);
1134+
}
1135+
sub->procno = MyProc->pgprocno;
1136+
sub->mask_pos = mask_pos;
1137+
LWLockRelease(dmq_state->lock);
1138+
1139+
dmq_local.mq_inh[dmq_local.n_inhandles] = NULL;
1140+
strncpy(dmq_local.receiver_names[dmq_local.n_inhandles], sender_name,
1141+
DMQ_NAME_MAXLEN);
1142+
dmq_local.mask_pos[dmq_local.n_inhandles] = mask_pos;
1143+
1144+
dmq_reattach_shm_mq(dmq_local.n_inhandles);
1145+
1146+
dmq_local.n_inhandles++;
1147+
}
1148+
1149+
void
1150+
dmq_pop(DmqSenderId *sender_id, StringInfo msg, int64 mask)
11331151
{
11341152
shm_mq_result res;
11351153

11361154
for (;;)
11371155
{
11381156
int i;
1157+
bool nowait = false;
1158+
1159+
CHECK_FOR_INTERRUPTS();
11391160

11401161
for (i = 0; i < dmq_local.n_inhandles; i++)
11411162
{
11421163
Size len;
11431164
void *data;
11441165

1166+
if (!BIT_CHECK(mask, dmq_local.mask_pos[i]))
1167+
continue;
1168+
11451169
res = shm_mq_receive(dmq_local.mq_inh[i], &len, &data, true);
11461170
if (res == SHM_MQ_SUCCESS)
11471171
{
@@ -1155,14 +1179,19 @@ dmq_pop(DmqSenderId *sender_id, StringInfo msg)
11551179
}
11561180
else if (res == SHM_MQ_DETACHED)
11571181
{
1158-
elog(ERROR, "dmq_pop: queue detached");
1182+
if (dmq_reattach_shm_mq(i))
1183+
nowait = true;
1184+
else
1185+
elog(ERROR, "dmq_pop: queue detached");
11591186
}
11601187
}
11611188

1189+
if (nowait)
1190+
continue;
1191+
11621192
// XXX cache that
11631193
WaitLatch(MyLatch, WL_LATCH_SET, 10, WAIT_EVENT_MQ_RECEIVE);
11641194
ResetLatch(MyLatch);
1165-
CHECK_FOR_INTERRUPTS();
11661195
}
11671196
}
11681197

dmq.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ extern void dmq_init(void);
1212
extern DmqDestinationId dmq_destination_add(char *connstr, char *sender_name, int ping_period);
1313

1414
extern void dmq_push(DmqDestinationId dest_id, char *stream_name, char *msg);
15-
extern void dmq_stream_subscribe(char *sender_name, char *stream_name);
16-
extern void dmq_pop(DmqSenderId *sender_id, StringInfo msg);
15+
extern void dmq_stream_subscribe(char *sender_name, char *stream_name, int mask_pos);
16+
extern void dmq_pop(DmqSenderId *sender_id, StringInfo msg, int64 mask);
1717
extern bool dmq_pop_nb(DmqSenderId *sender_id, StringInfo msg);
1818
extern void dmq_push_buffer(DmqDestinationId dest_id, char *stream_name, const void *buffer, size_t len);
1919

pglogical_apply.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -844,7 +844,7 @@ process_remote_commit(StringInfo in)
844844
{
845845
MTM_LOG1("%d: PGLOGICAL_COMMIT %s, (%llx,%llx,%llx)", MyProcPid, gid, commit_lsn, end_lsn, origin_lsn);
846846
if (IsTransactionState()) {
847-
Assert(TransactionIdIsValid(MtmGetCurrentTransactionId()));
847+
// Assert(TransactionIdIsValid(MtmGetCurrentTransactionId()));
848848
MtmBeginSession(origin_node);
849849
CommitTransactionCommand();
850850
MtmEndSession(origin_node, true);

resolver.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ ResolverMain(void)
400400
{
401401
if (i + 1 != MtmNodeId)
402402
{
403-
dmq_stream_subscribe(psprintf("node%d", i + 1), "txresp");
403+
dmq_stream_subscribe(psprintf("node%d", i + 1), "txresp", i);
404404
sender_to_node[sender_id++] = i + 1;
405405
}
406406
}

state.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -498,9 +498,11 @@ MtmRefreshClusterStatus()
498498
* See comment to MTM_RECOVERED -> MTM_ONLINE transition in MtmCheckState()
499499
*/
500500
MtmLock(LW_EXCLUSIVE);
501-
MtmCheckState(LOG);
501+
MtmCheckState(DEBUG1);
502502
MtmUnlock();
503503

504+
return;
505+
504506
/*
505507
* Check for referee decision when only half of nodes are visible.
506508
* Do not hold lock here, but recheck later wheter mask changed.
@@ -1018,7 +1020,7 @@ MtmMonitor(Datum arg)
10181020
{
10191021
if (i + 1 != MtmNodeId)
10201022
{
1021-
dmq_stream_subscribe(psprintf("node%d", i + 1), "txresp");
1023+
dmq_stream_subscribe(psprintf("node%d", i + 1), "txreq", i);
10221024
sender_to_node[sender_id++] = i + 1;
10231025
}
10241026
}
@@ -1035,7 +1037,7 @@ MtmMonitor(Datum arg)
10351037
ProcessConfigFile(PGC_SIGHUP);
10361038
}
10371039

1038-
// MtmRefreshClusterStatus();
1040+
MtmRefreshClusterStatus();
10391041

10401042
check_status_requests();
10411043

0 commit comments

Comments
 (0)