Re: Refactoring backend fork+exec code
Heikki Linnakangas <hlinnaka@iki.fi>
Commits
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Avoid 0-length memcpy to NULL with EXEC_BACKEND
- 95219c020c3c 17.0 landed
- f3412a61f3f9 18.0 landed
-
Tighten check for --forkchild argument when spawning child process
- 1906b1e0ad96 17.0 landed
- a06e8f84a1ac 18.0 landed
-
Add missing PGDLLIMPORT markings
- 768ceeeaa127 17.0 cited
-
Remove assertions that some compiler say are tautological
- d63d486d6c39 17.0 landed
-
Move code for backend startup to separate file
- 05c3980e7f47 17.0 landed
-
Refactor postmaster child process launching
- aafc05de1bf5 17.0 landed
-
Move some functions from postmaster.c to a new source file
- f1baed18bc3d 17.0 landed
-
Split registration of Win32 deadchild callback to separate function
- 14cddee9cce3 17.0 landed
-
Improve log messages referring to background worker processes
- a3f349c61292 17.0 landed
-
Move initialization of the Port struct to the child process
- 4945e4ed4a72 17.0 landed
-
Pass CAC as an argument to the backend process
- d162c3a73bf1 17.0 landed
-
Set socket options in child process after forking
- 73f7fb2a4c44 17.0 landed
-
Fix references to renamed function in comments
- ef4cfdce0ef8 17.0 landed
-
Use MyBackendType in more places to check what process this is
- 393b5599e517 17.0 landed
-
Remove MyAuxProcType, use MyBackendType instead
- 067701f57758 17.0 landed
-
Replace BackendIds with 0-based ProcNumbers
- 024c52111757 17.0 landed
-
Redefine backend ID to be an index into the proc array
- ab355e3a88de 17.0 landed
-
Remove superfluous 'pgprocno' field from PGPROC
- 28f3915b73f7 17.0 landed
-
Fix incorrect comment on how BackendStatusArray is indexed
- 28215a32b515 14.11 landed
- 90ccc9bf90a9 15.6 landed
- 4cf9ef670e4c 16.2 landed
- 2b53a462cff0 17.0 landed
-
Refactor how InitProcess is called
- fd5e8b440dfd 17.0 landed
-
Pass BackgroundWorker entry in the parameter file in EXEC_BACKEND mode
- 388491f1e5e6 17.0 landed
-
Refactor CreateSharedMemoryAndSemaphores
- 69d903367cde 17.0 landed
-
Silence Valgrind complaint with EXEC_BACKEND
- b19890d49d12 17.0 landed
-
Adjust obsolete comment explaining set_stack_base().
- cf84755575d1 16.2 landed
- 3b51265ee307 17.0 landed
-
Print lwlock stats also for aux processes, when built with LWLOCK_STATS
- f93133a250c6 17.0 landed
-
Move canAcceptConnections check from ProcessStartupPacket to caller.
- 16671ba6e717 17.0 landed
-
Fix crash on syslogger startup
- 5da0a622e889 17.0 landed
-
Refactor ListenSocket array.
- e29c46439511 17.0 landed
-
Use FD_CLOEXEC on ListenSockets
- b0bea38705b2 17.0 landed
-
Don't leak descriptors into subprograms.
- 1da569ca1f1f 16.0 cited
-
Use WaitEventSet API for postmaster's event loop.
- 7389aad63666 16.0 cited
-
Rearrange postmaster's startup sequence for better syslogger results.
- 9a86f03b4e8c 13.0 cited
-
Fix and enhance the assertion of no palloc's in a critical section.
- 1c6821be31f9 9.5.0 cited
Attachments
- v13-0001-Improve-log-messages-referring-to-background-wor.patch (text/x-patch) patch v13-0001
- v13-0002-Extract-registration-of-Win32-deadchild-callback.patch (text/x-patch) patch v13-0002
- v13-0003-Move-some-functions-from-postmaster.c-to-a-new-s.patch (text/x-patch) patch v13-0003
- v13-0004-Refactor-AuxProcess-startup.patch (text/x-patch) patch v13-0004
- v13-0005-Refactor-postmaster-child-process-launching.patch (text/x-patch) patch v13-0005
- v13-0006-Move-code-for-backend-startup-to-separate-file.patch (text/x-patch) patch v13-0006
On 06/03/2024 01:02, Tristan Partin wrote:
> The first 3 patches seem good to go, in my opinion.
Committed these first patches, with a few more changes. Notably, I
realized that we should move the logic that I originally put in the new
InitClientConnection function to the existing pq_init() function. It
servers the same purpose, initialization of the socket in the child
process. Thanks for the review!
>> @@ -225,14 +331,13 @@ internal_forkexec(int argc, char *argv[], ClientSocket *client_sock, BackgroundW
>> return -1;
>> }
>>
>> - /* Make sure caller set up argv properly */
>> - Assert(argc >= 3);
>> - Assert(argv[argc] == NULL);
>> - Assert(strncmp(argv[1], "--fork", 6) == 0);
>> - Assert(argv[2] == NULL);
>> -
>> - /* Insert temp file name after --fork argument */
>> + /* set up argv properly */
>> + argv[0] = "postgres";
>> + snprintf(forkav, MAXPGPATH, "--forkchild=%s", child_kind);
>> + argv[1] = forkav;
>> + /* Insert temp file name after --forkchild argument */
>> argv[2] = tmpfilename;
>> + argv[3] = NULL;
>
> Should we use postgres_exec_path instead of the naked "postgres" here?
I don't know, but it's the same as on 'master' currently. The code just
got moved around.
>> + /* in postmaster, fork failed ... */
>> + ereport(LOG,
>> + (errmsg("could not fork worker process: %m")));
>> + /* undo what assign_backendlist_entry did */
>> + ReleasePostmasterChildSlot(rw->rw_child_slot);
>> + rw->rw_child_slot = 0;
>> + pfree(rw->rw_backend);
>> + rw->rw_backend = NULL;
>> + /* mark entry as crashed, so we'll try again later */
>> + rw->rw_crashed_at = GetCurrentTimestamp();
>> + return false;
>
> I think the error message should include the word "background." It would
> be more consistent with the log message above it.
This is also a pre-existing message I just moved around. But yeah, I
agree, so changed.
>> +typedef struct
>> +{
>> + int syslogFile;
>> + int csvlogFile;
>> + int jsonlogFile;
>> +} syslogger_startup_data;
>
> It would be nice if all of these startup data structs were named
> similarly. For instance, a previous one was BackendStartupInfo. It would
> help with greppability.
Renamed them to SysloggerStartupData and BackendStartupData. Background
worker startup still passes a struct called BackgroundWorker, however. I
left that as it is, because the struct is used for other purposes too.
> I noticed there were a few XXX comments left that you created. I'll
> highlight them here for more visibility.
>
>> +/* XXX: where does this belong? */
>> +extern bool LoadedSSL;
>
> Perhaps near the My* variables or maybe in the Port struct?
It is valid in the postmaster, too, though. The My* variables and Port
struct only make sense in the child process.
I think this is the best place after all, so I just removed the XXX comment.
>> +#ifdef EXEC_BACKEND
>> +
>> + /*
>> + * Need to reinitialize the SSL library in the backend, since the context
>> + * structures contain function pointers and cannot be passed through the
>> + * parameter file.
>> + *
>> + * If for some reason reload fails (maybe the user installed broken key
>> + * files), soldier on without SSL; that's better than all connections
>> + * becoming impossible.
>> + *
>> + * XXX should we do this in all child processes? For the moment it's
>> + * enough to do it in backend children. XXX good question indeed
>> + */
>> +#ifdef USE_SSL
>> + if (EnableSSL)
>> + {
>> + if (secure_initialize(false) == 0)
>> + LoadedSSL = true;
>> + else
>> + ereport(LOG,
>> + (errmsg("SSL configuration could not be loaded in child process")));
>> + }
>> +#endif
>> +#endif
>
> Here you added the "good question indeed." I am not sure what the best
> answer is either! :)
I just removed the extra XXX comment. It's still a valid question, but
this patch just moves it around, we don't need to answer it here.
>> + /* XXX: translation? */
>> + ereport(LOG,
>> + (errmsg("could not fork %s process: %m", PostmasterChildName(type))));
>
> I assume you are referring to the child name here?
Correct. Does the process name need to be translated? And this way of
constructing sentences is not translation-friendly anyway. In some
languages, the word 'process' might need to be inflected differently
depending on the child name, for example.
I put the process name in quotes, and didn't mark the process name for
translation.
>> XXX: We now have functions called AuxiliaryProcessInit() and
>> InitAuxiliaryProcess(). Confusing.
>
> Based on my analysis, the *Init() is called in the Main functions, while
> Init*() is called before the Main functions. Maybe
> AuxiliaryProcessInit() could be renamed to AuxiliaryProcessStartup()?
> Rename the other to AuxiliaryProcessInit().
Hmm. There's also BackendStartup() function in postmaster.c, which is
very different: it runs in the postmaster process and launches the
backend process. So the Startup suffix is not great either.
I renamed AuxiliaryProcessInit() to AuxiliaryProcessMainCommon(). As in
"the common parts of the main functions of all the aux processes".
(We should perhaps merge InitProcess() and InitAuxiliaryProcess() into
one function. There's a lot of duplicated code between them. And the
parts that differ should perhaps be refactored to be more similar
anyway. I don't want to take on that refactoring right now though.)
Attached is a new version of the remaining patches.
--
Heikki Linnakangas
Neon (https://neon.tech)