@@ -391,7 +391,7 @@ static void pmdie(SIGNAL_ARGS);
391391static void reaper (SIGNAL_ARGS );
392392static void sigusr1_handler (SIGNAL_ARGS );
393393static void startup_die (SIGNAL_ARGS );
394- static void dummy_handler (SIGNAL_ARGS );
394+ static void upgrade_handler (SIGNAL_ARGS );
395395static void StartupPacketTimeoutHandler (void );
396396static void CleanupBackend (int pid , int exitstatus );
397397static bool CleanupBackgroundWorker (int pid , int exitstatus );
@@ -560,6 +560,48 @@ int postmaster_alive_fds[2] = {-1, -1};
560560HANDLE PostmasterHandle ;
561561#endif
562562
563+ static void
564+ UpgradePostgres (void )
565+ {
566+ char * PostmasterArgs [] = {"/home/knizhnik/postgresql/dist/bin/postgres" , "-U" , "-D" , "." ,NULL };
567+ BackendParameters param ;
568+ FILE * fp ;
569+
570+ if (!save_backend_variables (& param , NULL ))
571+ return ; /* log made by save_backend_variables */
572+
573+ /* Open file */
574+ fp = AllocateFile ("postmaster.params" , PG_BINARY_W );
575+ if (!fp )
576+ {
577+ ereport (LOG ,
578+ (errcode_for_file_access (),
579+ errmsg ("could not create file \"postmaster.params\": %m" )));
580+ return ;
581+ }
582+
583+ if (fwrite (& param , sizeof (param ), 1 , fp ) != 1 )
584+ {
585+ ereport (LOG ,
586+ (errcode_for_file_access (),
587+ errmsg ("could not write to file \"postmaster.params\": %m" )));
588+ FreeFile (fp );
589+ return ;
590+ }
591+
592+ /* Release file */
593+ if (FreeFile (fp ))
594+ {
595+ ereport (LOG ,
596+ (errcode_for_file_access (),
597+ errmsg ("could not write to file \"postmaster.params\": %m" )));
598+ return ;
599+ }
600+
601+ elog (LOG , "Upgrade postgres" );
602+ execv (PostmasterArgs [0 ], PostmasterArgs );
603+ }
604+
563605/*
564606 * Postmaster main entry point
565607 */
@@ -634,9 +676,10 @@ PostmasterMain(int argc, char *argv[])
634676 pqsignal (SIGPIPE , SIG_IGN ); /* ignored */
635677 pqsignal_no_restart (SIGUSR1 , sigusr1_handler ); /* message from child
636678 * process */
637- pqsignal_no_restart (SIGUSR2 , dummy_handler ); /* unused, reserve for
679+ pqsignal_no_restart (SIGUSR2 , upgrade_handler ); /* unused, reserve for
638680 * children */
639681 pqsignal_no_restart (SIGCHLD , reaper ); /* handle child termination */
682+ pqsignal_no_restart (SIGCHLD , reaper ); /* handle child termination */
640683
641684 /*
642685 * No other place in Postgres should touch SIGTTIN/SIGTTOU handling. We
@@ -669,13 +712,16 @@ PostmasterMain(int argc, char *argv[])
669712 * tcop/postgres.c (the option sets should not conflict) and with the
670713 * common help() function in main/main.c.
671714 */
672- while ((opt = getopt (argc , argv , "B:bc:C:D:d:EeFf:h:ijk:lN:nOo:Pp:r:S:sTt:W :-:" )) != -1 )
715+ while ((opt = getopt (argc , argv , "B:bc:C:D:d:EeFf:h:ijk:lN:nOo:Pp:r:S:sTt:UW :-:" )) != -1 )
673716 {
674717 switch (opt )
675718 {
676719 case 'B' :
677720 SetConfigOption ("shared_buffers" , optarg , PGC_POSTMASTER , PGC_S_ARGV );
678721 break ;
722+ case 'U' :
723+ IsOnlineUpgrade = true;
724+ break ;
679725
680726 case 'b' :
681727 /* Undocumented flag used for binary upgrades */
@@ -853,6 +899,10 @@ PostmasterMain(int argc, char *argv[])
853899 ExitPostmaster (1 );
854900 }
855901
902+ if (IsOnlineUpgrade )
903+ read_backend_variables ("postmaster.params" , NULL );
904+
905+
856906 /*
857907 * Locate the proper configuration files and data directory, and read
858908 * postgresql.conf for the first time.
@@ -950,7 +1000,8 @@ PostmasterMain(int argc, char *argv[])
9501000 * so it must happen before opening sockets so that at exit, the socket
9511001 * lockfiles go away after CloseServerPorts runs.
9521002 */
953- CreateDataDirLockFile (true);
1003+ if (!IsOnlineUpgrade )
1004+ CreateDataDirLockFile (true);
9541005
9551006 /*
9561007 * Read the control file (for error checking and config info).
@@ -991,12 +1042,16 @@ PostmasterMain(int argc, char *argv[])
9911042 * Now that loadable modules have had their chance to register background
9921043 * workers, calculate MaxBackends.
9931044 */
994- InitializeMaxBackends ();
1045+ if (!IsOnlineUpgrade )
1046+ InitializeMaxBackends ();
9951047
9961048 /*
9971049 * Set up shared memory and semaphores.
9981050 */
999- reset_shared ();
1051+ if (IsOnlineUpgrade )
1052+ PGSharedMemoryReAttach ();
1053+ else
1054+ reset_shared ();
10001055
10011056 /*
10021057 * Estimate number of openable files. This must happen after setting up
@@ -4980,6 +5035,10 @@ SubPostmasterMain(int argc, char *argv[])
49805035 /* And run the backend */
49815036 BackendRun (& port ); /* does not return */
49825037 }
5038+ if (strcmp (argv [1 ], "--forkpostmaster" ) == 0 )
5039+ {
5040+ InitShmemAccess (UsedShmemSegAddr );
5041+ }
49835042 if (strcmp (argv [1 ], "--forkboot" ) == 0 )
49845043 {
49855044 /* Restore basic shared memory pointers */
@@ -5296,8 +5355,9 @@ startup_die(SIGNAL_ARGS)
52965355 * tcop/postgres.c.)
52975356 */
52985357static void
5299- dummy_handler (SIGNAL_ARGS )
5358+ upgrade_handler (SIGNAL_ARGS )
53005359{
5360+ UpgradePostgres ();
53015361}
53025362
53035363/*
@@ -6079,10 +6139,12 @@ save_backend_variables(BackendParameters *param, Port *port,
60796139 HANDLE childProcess , pid_t childPid )
60806140#endif
60816141{
6082- memcpy (& param -> port , port , sizeof (Port ));
6083- if (!write_inheritable_socket (& param -> portsocket , port -> sock , childPid ))
6084- return false;
6085-
6142+ if (port )
6143+ {
6144+ memcpy (& param -> port , port , sizeof (Port ));
6145+ if (!write_inheritable_socket (& param -> portsocket , port -> sock , childPid ))
6146+ return false;
6147+ }
60866148 strlcpy (param -> DataDir , DataDir , MAXPGPATH );
60876149
60886150 memcpy (& param -> ListenSocket , & ListenSocket , sizeof (ListenSocket ));
@@ -6316,9 +6378,11 @@ read_backend_variables(char *id, Port *port)
63166378static void
63176379restore_backend_variables (BackendParameters * param , Port * port )
63186380{
6319- memcpy (port , & param -> port , sizeof (Port ));
6320- read_inheritable_socket (& port -> sock , & param -> portsocket );
6321-
6381+ if (port )
6382+ {
6383+ memcpy (port , & param -> port , sizeof (Port ));
6384+ read_inheritable_socket (& port -> sock , & param -> portsocket );
6385+ }
63226386 SetDataDir (param -> DataDir );
63236387
63246388 memcpy (& ListenSocket , & param -> ListenSocket , sizeof (ListenSocket ));
0 commit comments