@@ -43,6 +43,7 @@ typedef struct Cmd
43
43
static Cmd * next_cmd (void );
44
44
static void update_cmd_status (int64 id , const char * new_status );
45
45
static PGconn * listen_cmd_log_inserts (void );
46
+ static void publicate_metadata (void );
46
47
static void wait_notify (PGconn * conn );
47
48
static void shardmaster_sigterm (SIGNAL_ARGS );
48
49
static void shardmaster_sigusr1 (SIGNAL_ARGS );
@@ -60,11 +61,11 @@ static bool shardman_master = false;
60
61
static char * shardman_master_dbname = "postgres" ;
61
62
static int shardman_cmd_retry_naptime = 10000 ;
62
63
63
- /* just global vars */
64
+ /* Just global vars. */
64
65
/* Connection to local server for LISTEN notifications. Is is global for easy
65
66
* cleanup after receiving SIGTERM.
66
67
*/
67
- static PGconn * conn ;
68
+ static PGconn * conn = NULL ;
68
69
69
70
/*
70
71
* Entrypoint of the module. Define variables and register background worker.
@@ -125,6 +126,7 @@ _PG_init()
125
126
shardmaster_worker .bgw_notify_pid = 0 ;
126
127
RegisterBackgroundWorker (& shardmaster_worker );
127
128
}
129
+ /* TODO: clean up publications if we were master before */
128
130
}
129
131
130
132
/*
134
136
shardmaster_main (Datum main_arg )
135
137
{
136
138
Cmd * cmd ;
137
- elog (LOG , "Shardmaster started" );
139
+ shmn_elog (LOG , "Shardmaster started" );
138
140
139
141
/* Connect to the database to use SPI*/
140
142
BackgroundWorkerInitializeConnection (shardman_master_dbname , NULL );
@@ -147,6 +149,7 @@ shardmaster_main(Datum main_arg)
147
149
/* We're now ready to receive signals */
148
150
BackgroundWorkerUnblockSignals ();
149
151
152
+ publicate_metadata ();
150
153
conn = listen_cmd_log_inserts ();
151
154
152
155
/* main loop */
@@ -156,28 +159,50 @@ shardmaster_main(Datum main_arg)
156
159
while ((cmd = next_cmd ()) != NULL )
157
160
{
158
161
update_cmd_status (cmd -> id , "in progress" );
159
- elog (LOG , "Working on command %ld, %s, opts are" , cmd -> id , cmd -> cmd_type );
162
+ shmn_elog (LOG , "Working on command %ld, %s, opts are" ,
163
+ cmd -> id , cmd -> cmd_type );
160
164
for (char * * opts = cmd -> opts ; * opts ; opts ++ )
161
- elog (LOG , "%s" , * opts );
165
+ shmn_elog (LOG , "%s" , * opts );
162
166
if (strcmp (cmd -> cmd_type , "add_node" ) == 0 )
163
167
add_node (cmd );
164
168
else
165
- elog (FATAL , "Unknown cmd type %s" , cmd -> cmd_type );
169
+ shmn_elog (FATAL , "Unknown cmd type %s" , cmd -> cmd_type );
166
170
}
167
171
wait_notify (conn );
168
172
check_for_sigterm ();
169
173
}
170
174
171
175
}
172
176
177
+ /*
178
+ * Create publication on tables with metadata.
179
+ */
180
+ void
181
+ publicate_metadata (void )
182
+ {
183
+ const char * cmd_sql = "select shardman.create_meta_pub();" ;
184
+ int e ;
185
+
186
+ StartTransactionCommand ();
187
+ SPI_connect ();
188
+ PushActiveSnapshot (GetTransactionSnapshot ());
189
+
190
+ e = SPI_execute (cmd_sql , true, 0 );
191
+ if (e < 0 )
192
+ shmn_elog (FATAL , "Stmt failed: %s" , cmd_sql );
193
+
194
+ PopActiveSnapshot ();
195
+ SPI_finish ();
196
+ CommitTransactionCommand ();
197
+ }
198
+
173
199
/*
174
200
* Open libpq connection to our server and start listening to cmd_log inserts
175
201
* notifications.
176
202
*/
177
203
PGconn *
178
204
listen_cmd_log_inserts (void )
179
205
{
180
- PGconn * conn ;
181
206
char * conninfo ;
182
207
PGresult * res ;
183
208
@@ -186,13 +211,13 @@ listen_cmd_log_inserts(void)
186
211
pfree (conninfo );
187
212
/* Check to see that the backend connection was successfully made */
188
213
if (PQstatus (conn ) != CONNECTION_OK )
189
- elog (FATAL , "Connection to database failed: %s" ,
214
+ shmn_elog (FATAL , "Connection to local database failed: %s" ,
190
215
PQerrorMessage (conn ));
191
216
192
217
res = PQexec (conn , "LISTEN shardman_cmd_log_update" );
193
218
if (PQresultStatus (res ) != PGRES_COMMAND_OK )
194
219
{
195
- elog (FATAL , "LISTEN command failed: %s" , PQerrorMessage (conn ));
220
+ shmn_elog (FATAL , "LISTEN command failed: %s" , PQerrorMessage (conn ));
196
221
}
197
222
PQclear (res );
198
223
@@ -212,7 +237,7 @@ wait_notify(PGconn *conn)
212
237
213
238
sock = PQsocket (conn );
214
239
if (sock < 0 )
215
- elog (FATAL , "Couldn't get sock from pgconn" );
240
+ shmn_elog (FATAL , "Couldn't get sock from pgconn" );
216
241
217
242
FD_ZERO (& input_mask );
218
243
FD_SET (sock , & input_mask );
@@ -221,14 +246,14 @@ wait_notify(PGconn *conn)
221
246
{
222
247
if (errno == EINTR )
223
248
return ; /* signal has arrived */
224
- elog (FATAL , "select() failed: %s" , strerror (errno ));
249
+ shmn_elog (FATAL , "select() failed: %s" , strerror (errno ));
225
250
}
226
251
227
252
PQconsumeInput (conn );
228
253
/* eat all notifications at once */
229
254
while ((notify = PQnotifies (conn )) != NULL )
230
255
{
231
- elog (LOG , "NOTIFY %s received from backend PID %d" ,
256
+ shmn_elog (LOG , "NOTIFY %s received from backend PID %d" ,
232
257
notify -> relname , notify -> be_pid );
233
258
PQfreemem (notify );
234
259
}
@@ -257,7 +282,7 @@ next_cmd(void)
257
282
" status = 'in progress') t2 using (id);" ;
258
283
e = SPI_execute (cmd_sql , true, 0 );
259
284
if (e < 0 )
260
- elog (FATAL , "Stmt failed: %s" , cmd_sql );
285
+ shmn_elog (FATAL , "Stmt failed: %s" , cmd_sql );
261
286
262
287
if (SPI_processed > 0 )
263
288
{
@@ -281,7 +306,7 @@ next_cmd(void)
281
306
" cmd_id = %ld order by id;" , cmd -> id );
282
307
e = SPI_execute (cmd_sql , true, 0 );
283
308
if (e < 0 )
284
- elog (FATAL , "Stmt failed: %s" , cmd_sql );
309
+ shmn_elog (FATAL , "Stmt failed: %s" , cmd_sql );
285
310
286
311
MemoryContextSwitchTo (oldcxt );
287
312
/* +1 for NULL in the end */
@@ -323,7 +348,7 @@ update_cmd_status(int64 id, const char *new_status)
323
348
pfree (sql );
324
349
if (e < 0 )
325
350
{
326
- elog (FATAL , "Stmt failed: %s" , sql );
351
+ shmn_elog (FATAL , "Stmt failed: %s" , sql );
327
352
}
328
353
329
354
PopActiveSnapshot ();
@@ -345,12 +370,13 @@ pg_shardman_installed_local(void)
345
370
if (get_extension_oid ("pg_shardman" , true) == InvalidOid )
346
371
{
347
372
installed = false;
348
- elog (WARNING , "pg_shardman library is preloaded, but extenstion is not created" );
373
+ shmn_elog (WARNING , "pg_shardman library is preloaded, but extenstion is not created" );
349
374
}
350
375
PopActiveSnapshot ();
351
376
CommitTransactionCommand ();
352
377
353
378
/* shardmaster won't run without extension */
379
+ /* TODO: unregister bgw? */
354
380
if (!installed )
355
381
proc_exit (1 );
356
382
}
@@ -383,8 +409,9 @@ check_for_sigterm(void)
383
409
{
384
410
if (got_sigterm )
385
411
{
386
- elog (LOG , "Shardmaster received SIGTERM, exiting" );
387
- PQfinish (conn );
412
+ shmn_elog (LOG , "Shardmaster received SIGTERM, exiting" );
413
+ if (conn != NULL )
414
+ PQfinish (conn );
388
415
proc_exit (0 );
389
416
}
390
417
}
@@ -402,15 +429,16 @@ static void add_node(Cmd *cmd)
402
429
const char * conninfo = cmd -> opts [0 ];
403
430
PGresult * res = NULL ;
404
431
bool pg_shardman_installed ;
432
+ int node_id ;
405
433
406
- elog (LOG , "Adding node %s" , conninfo );
434
+ shmn_elog (LOG , "Adding node %s" , conninfo );
407
435
/* Try to execute command indefinitely until it succeeded or canceled */
408
436
while (!got_sigusr1 && !got_sigterm )
409
437
{
410
438
conn = PQconnectdb (conninfo );
411
439
if (PQstatus (conn ) != CONNECTION_OK )
412
440
{
413
- elog (NOTICE , "Connection to add_node node failed: %s" ,
441
+ shmn_elog (NOTICE , "Connection to add_node node failed: %s" ,
414
442
PQerrorMessage (conn ));
415
443
goto attempt_failed ;
416
444
}
@@ -421,7 +449,7 @@ static void add_node(Cmd *cmd)
421
449
" where name = 'pg_shardman';" );
422
450
if (PQresultStatus (res ) != PGRES_TUPLES_OK )
423
451
{
424
- elog (NOTICE , "Failed to check whether pg_shardman is installed on"
452
+ shmn_elog (NOTICE , "Failed to check whether pg_shardman is installed on"
425
453
" node to add%s" , PQerrorMessage (conn ));
426
454
goto attempt_failed ;
427
455
}
@@ -435,22 +463,37 @@ static void add_node(Cmd *cmd)
435
463
res = PQexec (conn , "select shardman.get_node_id();" );
436
464
if (PQresultStatus (res ) != PGRES_TUPLES_OK )
437
465
{
438
- elog (NOTICE , "Failed to get node id, %s" , PQerrorMessage (conn ));
466
+ shmn_elog (NOTICE , "Failed to get node id, %s" , PQerrorMessage (conn ));
439
467
goto attempt_failed ;
440
468
}
441
- int node_id = atoi (PQgetvalue (res , 0 , 0 ));
469
+ node_id = atoi (PQgetvalue (res , 0 , 0 ));
470
+ PQclear (res );
442
471
if (node_in_cluster (node_id ))
443
472
{
444
- elog (WARNING , "node %d with connstring %s is already in cluster,"
473
+ shmn_elog (WARNING , "node %d with connstring %s is already in cluster,"
445
474
" won't add it." , node_id , conninfo );
446
- PQclear (res );
447
475
PQfinish (conn );
448
476
update_cmd_status (cmd -> id , "failed" );
449
477
return ;
450
478
}
451
479
}
452
480
481
+ /* Now, when we are sure that node is not in the cluster, we reinstall
482
+ * the extension to reset its state, whether is was installed before
483
+ * or not.
484
+ */
485
+ res = PQexec (conn , "drop extension if exists pg_shardman; "
486
+ " create extension pg_shardman;" );
487
+ if (PQresultStatus (res ) != PGRES_TUPLES_OK )
488
+ {
489
+ shmn_elog (NOTICE , "Failed to reinstall pg_shardman, %s" , PQerrorMessage (conn ));
490
+ goto attempt_failed ;
491
+ }
453
492
PQclear (res );
493
+
494
+ /* TODO */
495
+
496
+ /* done */
454
497
PQfinish (conn );
455
498
update_cmd_status (cmd -> id , "success" );
456
499
return ;
@@ -461,14 +504,14 @@ static void add_node(Cmd *cmd)
461
504
if (conn != NULL )
462
505
PQfinish (conn );
463
506
464
- elog (LOG , "Attempt to execute add_node failed, sleeping and retrying" );
465
- pg_usleep (shardman_cmd_retry_naptime * 1000 );
507
+ shmn_elog (LOG , "Attempt to execute add_node failed, sleeping and retrying" );
508
+ pg_usleep (shardman_cmd_retry_naptime * 1000L );
466
509
}
467
510
468
511
check_for_sigterm ();
469
512
470
513
/* Command canceled via sigusr1 */
471
- elog (LOG , "Command %ld canceled" , cmd -> id );
514
+ shmn_elog (LOG , "Command %ld canceled" , cmd -> id );
472
515
update_cmd_status (cmd -> id , "canceled" );
473
516
got_sigusr1 = false;
474
517
return ;
@@ -481,7 +524,7 @@ static bool
481
524
node_in_cluster (int id )
482
525
{
483
526
int e ;
484
- char * sql = "select id from shardman.nodes;" ;
527
+ const char * sql = "select id from shardman.nodes;" ;
485
528
bool res = false;
486
529
HeapTuple tuple ;
487
530
TupleDesc rowdesc ;
@@ -492,9 +535,9 @@ node_in_cluster(int id)
492
535
SPI_connect ();
493
536
PushActiveSnapshot (GetTransactionSnapshot ());
494
537
495
- e = SPI_exec (sql , 0 );
538
+ e = SPI_execute (sql , true , 0 );
496
539
if (e < 0 )
497
- elog (FATAL , "Stmt failed: %s" , sql );
540
+ shmn_elog (FATAL , "Stmt failed: %s" , sql );
498
541
499
542
rowdesc = SPI_tuptable -> tupdesc ;
500
543
for (i = 0 ; i < SPI_processed ; i ++ )
0 commit comments