DSM segment handle generation in background workers

Thomas Munro <thomas.munro@enterprisedb.com>

From: Thomas Munro <thomas.munro@enterprisedb.com>
To: Pg Hackers <pgsql-hackers@postgresql.org>
Date: 2018-10-07T12:17:31Z
Lists: pgsql-hackers
Hello,

I noticed that every parallel worker generates the same sequence of
handles here:

        /*
         * Loop until we find an unused identifier for the new control
segment. We
         * sometimes use 0 as a sentinel value indicating that no
control segment
         * is known to exist, so avoid using that value for a real control
         * segment.
         */
        for (;;)
        {
                Assert(dsm_control_address == NULL);
                Assert(dsm_control_mapped_size == 0);
                dsm_control_handle = random();
                if (dsm_control_handle == DSM_HANDLE_INVALID)
                        continue;
                if (dsm_impl_op(DSM_OP_CREATE, dsm_control_handle, segsize,

&dsm_control_impl_private, &dsm_control_address,

&dsm_control_mapped_size, ERROR))
                        break;
        }

It's harmless AFAICS, but it produces sequences of syscalls like this
when Parallel Hash is building the hash table:

shm_open("/PostgreSQL.240477264",O_RDWR|O_CREAT|O_EXCL,0600) ERR#17
'File exists'
shm_open("/PostgreSQL.638747851",O_RDWR|O_CREAT|O_EXCL,0600) ERR#17
'File exists'
shm_open("/PostgreSQL.1551053007",O_RDWR|O_CREAT|O_EXCL,0600) = 5 (0x5)

That's because the bgworker startup path doesn't contain a call to
srandom(...distinguishing stuff...), unlike BackendRun().  I suppose
do_start_bgworker() could gain a similar call... or perhaps that call
should be moved into InitPostmasterChild().  If we put it in there
right after MyStartTime is assigned a new value, we could use the same
incantation that PostmasterMain() uses.

I noticed that the comment in PostmasterMain() refers to
PostmasterRandom(), which is gone.

-- 
Thomas Munro
http://www.enterprisedb.com


Commits

  1. Increase the number of possible random seeds per time period.

  2. Refactor pid, random seed and start time initialization.

  3. Increase the number of different values used when seeding random().