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

Commit fd078e7

Browse files
committed
Online upgrade implementation
1 parent e4e2e2a commit fd078e7

File tree

10 files changed

+134
-22
lines changed

10 files changed

+134
-22
lines changed

src/backend/port/sysv_shmem.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size)
243243
}
244244

245245
/* Register on-exit routine to delete the new segment */
246-
//on_shmem_exit(IpcMemoryDelete, Int32GetDatum(shmid));
246+
on_shmem_exit(IpcMemoryDelete, Int32GetDatum(shmid));
247247

248248
/* OK, should be able to attach to the segment */
249249
memAddress = shmat(shmid, requestedAddress, PG_SHMAT_FLAGS);
@@ -291,9 +291,12 @@ IpcMemoryDetach(int status, Datum shmaddr)
291291
static void
292292
IpcMemoryDelete(int status, Datum shmId)
293293
{
294-
if (shmctl(DatumGetInt32(shmId), IPC_RMID, NULL) < 0)
295-
elog(LOG, "shmctl(%d, %d, 0) failed: %m",
296-
DatumGetInt32(shmId), IPC_RMID);
294+
if (!IsOnlineUpgrade)
295+
{
296+
if (shmctl(DatumGetInt32(shmId), IPC_RMID, NULL) < 0)
297+
elog(LOG, "shmctl(%d, %d, 0) failed: %m",
298+
DatumGetInt32(shmId), IPC_RMID);
299+
}
297300
}
298301

299302
/*

src/backend/postmaster/bgworker.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,24 @@ BackgroundWorkerShmemSize(void)
152152
return size;
153153
}
154154

155+
void
156+
BackgroundWorkerShmemAttach(void)
157+
{
158+
slist_iter siter;
159+
int slotno = 0;
160+
161+
slist_foreach(siter, &BackgroundWorkerList)
162+
{
163+
RegisteredBgWorker *rw;
164+
165+
rw = slist_container(RegisteredBgWorker, rw_lnode, siter.cur);
166+
Assert(slotno < max_worker_processes);
167+
rw->rw_shmem_slot = slotno;
168+
rw->rw_worker.bgw_notify_pid = 0; /* might be reinit after crash */
169+
++slotno;
170+
}
171+
}
172+
155173
/*
156174
* Initialize shared memory.
157175
*/
@@ -377,7 +395,7 @@ BackgroundWorkerStateChange(void)
377395
rw->rw_worker.bgw_notify_pid = slot->worker.bgw_notify_pid;
378396
if (!PostmasterMarkPIDForWorkerNotify(rw->rw_worker.bgw_notify_pid))
379397
{
380-
elog(DEBUG1, "worker notification PID %lu is not valid",
398+
elog(LOG, "worker notification PID %lu is not valid",
381399
(long) rw->rw_worker.bgw_notify_pid);
382400
rw->rw_worker.bgw_notify_pid = 0;
383401
}
@@ -480,6 +498,7 @@ ReportBackgroundWorkerExit(slist_mutable_iter *cur)
480498
rw->rw_worker.bgw_restart_time == BGW_NEVER_RESTART)
481499
ForgetBackgroundWorker(cur);
482500

501+
elog(LOG, "Notify PID=%d", notify_pid);
483502
if (notify_pid != 0)
484503
kill(notify_pid, SIGUSR1);
485504
}
@@ -572,6 +591,18 @@ BackgroundWorkerEntry(int slotno)
572591
memcpy(&myEntry, &slot->worker, sizeof myEntry);
573592
return &myEntry;
574593
}
594+
595+
void*
596+
GetBackgroundWorkerEntries(void)
597+
{
598+
return BackgroundWorkerData;
599+
}
600+
601+
void
602+
SetBackgroundWorkerEntries(void* entries)
603+
{
604+
BackgroundWorkerData = entries;
605+
}
575606
#endif
576607

577608
/*
@@ -1147,6 +1178,7 @@ WaitForBackgroundWorkerShutdown(BackgroundWorkerHandle *handle)
11471178
CHECK_FOR_INTERRUPTS();
11481179

11491180
status = GetBackgroundWorkerPid(handle, &pid);
1181+
elog(LOG, "GetBackgroundWorkerPid(%d) = %d", pid, status);
11501182
if (status == BGWH_STOPPED)
11511183
break;
11521184

@@ -1184,6 +1216,7 @@ TerminateBackgroundWorker(BackgroundWorkerHandle *handle)
11841216

11851217
/* Set terminate flag in shared memory, unless slot has been reused. */
11861218
LWLockAcquire(BackgroundWorkerLock, LW_EXCLUSIVE);
1219+
elog(LOG, "Terminate worker slot %d", handle->slot);
11871220
if (handle->generation == slot->generation)
11881221
{
11891222
slot->terminate = true;

src/backend/postmaster/postmaster.c

Lines changed: 58 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,7 @@ typedef struct
511511
bool IsBinaryUpgrade;
512512
int max_safe_fds;
513513
int MaxBackends;
514+
void* BackgroundWorkers;
514515
#ifdef WIN32
515516
HANDLE PostmasterHandle;
516517
HANDLE initial_signal_pipe;
@@ -563,10 +564,16 @@ HANDLE PostmasterHandle;
563564
static void
564565
UpgradePostgres(void)
565566
{
567+
#ifdef EXEC_BACKEND
566568
char* PostmasterArgs[] = {"/home/knizhnik/postgresql/dist/bin/postgres", "-U", "-D", "." ,NULL};
567569
BackendParameters param;
568570
FILE *fp;
569571

572+
IsOnlineUpgrade = true;
573+
TerminateChildren(SIGTERM);
574+
if (CheckpointerPID != 0)
575+
signal_child(CheckpointerPID, SIGUSR2);
576+
570577
if (!save_backend_variables(&param, NULL))
571578
return; /* log made by save_backend_variables */
572579

@@ -600,8 +607,27 @@ UpgradePostgres(void)
600607

601608
elog(LOG, "Upgrade postgres");
602609
execv(PostmasterArgs[0], PostmasterArgs);
610+
#else
611+
elog(LOG, "Online upgrade is possible only postgres configured with EXEC_BACKEND");
612+
#endif
613+
}
614+
615+
616+
static void
617+
RestoreBackendList(void)
618+
{
619+
#ifdef EXEC_BACKEND
620+
int i;
621+
for (i = MaxLivePostmasterChildren() - 1; i >= 0; i--)
622+
{
623+
Backend* bp = (Backend *) &ShmemBackendArray[i];
624+
if (bp->bkend_type == BACKEND_TYPE_NORMAL)
625+
dlist_push_head(&BackendList, &bp->elem);
626+
}
627+
#endif
603628
}
604629

630+
605631
/*
606632
* Postmaster main entry point
607633
*/
@@ -900,8 +926,10 @@ PostmasterMain(int argc, char *argv[])
900926
}
901927

902928
if (IsOnlineUpgrade)
929+
{
903930
read_backend_variables("postmaster.params", NULL);
904-
931+
RegisterUnlinkLockFileCallback();
932+
}
905933

906934
/*
907935
* Locate the proper configuration files and data directory, and read
@@ -1038,20 +1066,23 @@ PostmasterMain(int argc, char *argv[])
10381066
*/
10391067
process_shared_preload_libraries();
10401068

1041-
/*
1042-
* Now that loadable modules have had their chance to register background
1043-
* workers, calculate MaxBackends.
1044-
*/
1045-
if (!IsOnlineUpgrade)
1046-
InitializeMaxBackends();
1047-
10481069
/*
10491070
* Set up shared memory and semaphores.
10501071
*/
10511072
if (IsOnlineUpgrade)
1073+
{
10521074
PGSharedMemoryReAttach();
1075+
RestoreBackendList();
1076+
}
10531077
else
1078+
{
1079+
/*
1080+
* Now that loadable modules have had their chance to register background
1081+
* workers, calculate MaxBackends.
1082+
*/
1083+
InitializeMaxBackends();
10541084
reset_shared();
1085+
}
10551086

10561087
/*
10571088
* Estimate number of openable files. This must happen after setting up
@@ -1435,10 +1466,18 @@ PostmasterMain(int argc, char *argv[])
14351466
/*
14361467
* We're ready to rock and roll...
14371468
*/
1438-
StartupPID = StartupDataBase();
1439-
Assert(StartupPID != 0);
1440-
StartupStatus = STARTUP_RUNNING;
1441-
pmState = PM_STARTUP;
1469+
if (!IsOnlineUpgrade)
1470+
{
1471+
StartupPID = StartupDataBase();
1472+
Assert(StartupPID != 0);
1473+
StartupStatus = STARTUP_RUNNING;
1474+
pmState = PM_STARTUP;
1475+
}
1476+
else
1477+
{
1478+
BackgroundWorkerShmemAttach();
1479+
pmState = PM_RUN;
1480+
}
14421481

14431482
/* Some workers may be scheduled to start now */
14441483
maybe_start_bgworkers();
@@ -1696,6 +1735,7 @@ ServerLoop(void)
16961735
last_lockfile_recheck_time = last_touch_time = time(NULL);
16971736

16981737
nSockets = initMasks(&readmask);
1738+
IsOnlineUpgrade = false;
16991739

17001740
for (;;)
17011741
{
@@ -4103,7 +4143,10 @@ SignalSomeChildren(int signal, int target)
41034143
static void
41044144
TerminateChildren(int signal)
41054145
{
4106-
SignalChildren(signal);
4146+
if (IsOnlineUpgrade)
4147+
SignalSomeChildren(signal, BACKEND_TYPE_WALSND | BACKEND_TYPE_WORKER);
4148+
else
4149+
SignalChildren(signal);
41074150
if (StartupPID != 0)
41084151
{
41094152
signal_child(StartupPID, signal);
@@ -6180,6 +6223,7 @@ save_backend_variables(BackendParameters *param, Port *port,
61806223
param->PgStartTime = PgStartTime;
61816224
param->PgReloadTime = PgReloadTime;
61826225
param->first_syslogger_file_time = first_syslogger_file_time;
6226+
param->BackgroundWorkers = GetBackgroundWorkerEntries();
61836227

61846228
param->redirection_done = redirection_done;
61856229
param->IsBinaryUpgrade = IsBinaryUpgrade;
@@ -6417,6 +6461,7 @@ restore_backend_variables(BackendParameters *param, Port *port)
64176461
PgStartTime = param->PgStartTime;
64186462
PgReloadTime = param->PgReloadTime;
64196463
first_syslogger_file_time = param->first_syslogger_file_time;
6464+
SetBackgroundWorkerEntries(param->BackgroundWorkers);
64206465

64216466
redirection_done = param->redirection_done;
64226467
IsBinaryUpgrade = param->IsBinaryUpgrade;

src/backend/replication/logical/launcher.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,9 @@ ApplyLauncherMain(Datum main_arg)
978978

979979
before_shmem_exit(logicalrep_launcher_onexit, (Datum) 0);
980980

981+
while (LogicalRepCtx->launcher_pid != 0)
982+
pg_usleep(1000000);
983+
981984
Assert(LogicalRepCtx->launcher_pid == 0);
982985
LogicalRepCtx->launcher_pid = MyProcPid;
983986

src/backend/storage/ipc/shmem.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ InitShmemAccess(void *seghdr)
101101
ShmemSegHdr = shmhdr;
102102
ShmemBase = (void *) shmhdr;
103103
ShmemEnd = (char *) ShmemBase + shmhdr->totalsize;
104+
104105
}
105106

106107
/*

src/backend/storage/lmgr/proc.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -542,11 +542,20 @@ InitAuxiliaryProcess(void)
542542
/*
543543
* Find a free auxproc ... *big* trouble if there isn't one ...
544544
*/
545-
for (proctype = 0; proctype < NUM_AUXILIARY_PROCS; proctype++)
545+
while (true)
546546
{
547-
auxproc = &AuxiliaryProcs[proctype];
548-
if (auxproc->pid == 0)
549-
break;
547+
for (proctype = 0; proctype < NUM_AUXILIARY_PROCS; proctype++)
548+
{
549+
auxproc = &AuxiliaryProcs[proctype];
550+
if (auxproc->pid == 0)
551+
break;
552+
}
553+
if (IsOnlineUpgrade && proctype >= NUM_AUXILIARY_PROCS)
554+
{
555+
pg_usleep(1000000);
556+
continue;
557+
}
558+
break;
550559
}
551560
if (proctype >= NUM_AUXILIARY_PROCS)
552561
{

src/backend/utils/init/miscinit.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -860,6 +860,20 @@ UnlinkLockFiles(int status, Datum arg)
860860
(errmsg("database system is shut down")));
861861
}
862862

863+
864+
static void
865+
UnlinkPostmasterLock(int status, Datum arg)
866+
{
867+
unlink("postmaster.pid");
868+
}
869+
870+
void
871+
RegisterUnlinkLockFileCallback(void)
872+
{
873+
on_proc_exit(UnlinkPostmasterLock, 0);
874+
}
875+
876+
863877
/*
864878
* Create a lockfile.
865879
*

src/include/miscadmin.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,5 +451,6 @@ extern bool has_rolreplication(Oid roleid);
451451
/* in access/transam/xlog.c */
452452
extern bool BackupInProgress(void);
453453
extern void CancelBackup(void);
454+
extern void RegisterUnlinkLockFileCallback(void);
454455

455456
#endif /* MISCADMIN_H */

src/include/postmaster/bgworker.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,5 +157,6 @@ extern void BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid, ui
157157
/* Block/unblock signals in a background worker process */
158158
extern void BackgroundWorkerBlockSignals(void);
159159
extern void BackgroundWorkerUnblockSignals(void);
160+
extern void BackgroundWorkerShmemAttach(void);
160161

161162
#endif /* BGWORKER_H */

src/include/postmaster/bgworker_internals.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ extern void StartBackgroundWorker(void) pg_attribute_noreturn();
5858

5959
#ifdef EXEC_BACKEND
6060
extern BackgroundWorker *BackgroundWorkerEntry(int slotno);
61+
extern void SetBackgroundWorkerEntries(void* entries);
62+
extern void* GetBackgroundWorkerEntries(void);
6163
#endif
6264

6365
#endif /* BGWORKER_INTERNALS_H */

0 commit comments

Comments
 (0)