Thread

Commits

  1. Factor out InitControlFile() from BootStrapXLOG()

  2. Reformat code comment

  3. pg_resetwal: Rename function to avoid potential conflict

  4. Expose PQbackendPID() through walreceiver API

  5. walreceiver uses a temporary replication slot by default

  6. Make lsn argument of walrcv_create_slot() optional

  7. More precise errors from initial pg_control check

  1. base backup client as auxiliary backend process

    Peter Eisentraut <peter.eisentraut@2ndquadrant.com> — 2019-06-29T20:05:22Z

    Setting up a standby instance is still quite complicated.  You need to
    run pg_basebackup with all the right options.  You need to make sure
    pg_basebackup has the right permissions for the target directories.  The
    created instance has to be integrated into the operating system's start
    scripts.  There is this slightly awkward business of the --recovery-conf
    option and how it interacts with other features.  And you should
    probably run pg_basebackup under screen.  And then how do you get
    notified when it's done.  And when it's done you have to log back in and
    finish up.  Too many steps.
    
    My idea is that the postmaster can launch a base backup worker, wait
    till it's done, then proceed with the rest of the startup.  initdb gets
    a special option to create a "minimal" data directory with only a few
    files, directories, and the usual configuration files.  Then you create
    a $PGDATA/basebackup.signal, start the postmaster as normal.  It sees
    the signal file, launches an auxiliary process that runs the base
    backup, then proceeds with normal startup in standby mode.
    
    This makes a whole bunch of things much nicer: The connection
    information for where to get the base backup from comes from
    postgresql.conf, so you only need to specify it in one place.
    pg_basebackup is completely out of the picture; no need to deal with
    command-line options, --recovery-conf, screen, monitoring for
    completion, etc.  If something fails, the base backup process can
    automatically be restarted (maybe).  Operating system integration is
    much easier: You only call initdb and then pg_ctl or postgres, as you
    are already doing.  Automated deployment systems don't need to wait for
    pg_basebackup to finish: You only call initdb, then start the server,
    and then you're done -- waiting for the base backup to finish can be
    done by the regular monitoring system.
    
    Attached is a very hackish patch to implement this.  It works like this:
    
        # (assuming you have a primary already running somewhere)
        initdb -D data2 --minimal
        $EDITOR data2/postgresql.conf  # set primary_conninfo
        pg_ctl -D data2 start
    
    (Curious side note: If you don’t set primary_conninfo in these steps,
    then libpq defaults apply, so the default behavior might end up being
    that a given instance attempts to replicate from itself.)
    
    It works for basic cases.  It's missing tablespace support, proper
    fsyncing, progress reporting, probably more.  Those would be pretty
    straightforward I think.  The interesting bit is the delicate ordering
    of the postmaster startup:  Normally, the pg_control file is read quite
    early, but if starting from a minimal data directory, we need to wait
    until the base backup is done.  There is also the question what you do
    if the base backup fails halfway through.  Currently you probably need
    to delete the whole data directory and start again with initdb.  Better
    might be a way to start again and overwrite any existing files, but that
    can clearly also be dangerous.  All this needs some careful analysis,
    but I think it's doable.
    
    Any thoughts?
    
    -- 
    Peter Eisentraut              http://www.2ndQuadrant.com/
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
    
  2. Re: base backup client as auxiliary backend process

    Thomas Munro <thomas.munro@gmail.com> — 2019-07-05T03:07:40Z

    On Sun, Jun 30, 2019 at 8:05 AM Peter Eisentraut
    <peter.eisentraut@2ndquadrant.com> wrote:
    > Attached is a very hackish patch to implement this.  It works like this:
    >
    >     # (assuming you have a primary already running somewhere)
    >     initdb -D data2 --minimal
    >     $EDITOR data2/postgresql.conf  # set primary_conninfo
    >     pg_ctl -D data2 start
    
    +1, very nice.  How about --replica?
    
    FIY Windows doesn't like your patch:
    
    src/backend/postmaster/postmaster.c(1396): warning C4013: 'sleep'
    undefined; assuming extern returning int
    [C:\projects\postgresql\postgres.vcxproj]
    
    https://ci.appveyor.com/project/postgresql-cfbot/postgresql/build/1.0.45930
    
    -- 
    Thomas Munro
    https://enterprisedb.com
    
    
    
    
  3. Re: base backup client as auxiliary backend process

    Sergei Kornilov <sk@zsrv.org> — 2019-07-11T11:12:36Z

    Hello
    
    >>  Attached is a very hackish patch to implement this. It works like this:
    >>
    >>      # (assuming you have a primary already running somewhere)
    >>      initdb -D data2 --minimal
    >>      $EDITOR data2/postgresql.conf # set primary_conninfo
    >>      pg_ctl -D data2 start
    >
    > +1, very nice. How about --replica?
    
    +1
    
    Also not works with -DEXEC_BACKEND for me.
    
    > There is also the question what you do
    > if the base backup fails halfway through. Currently you probably need
    > to delete the whole data directory and start again with initdb. Better
    > might be a way to start again and overwrite any existing files, but that
    > can clearly also be dangerous.
    
    I think the need for delete directory and rerun initdb is better than overwrite files.
    
    - we need check major version. Basebackup can works with different versions, but would be useless to copying cluster which we can not run
    - basebackup silently overwrite configs (pg_hba.conf, postgresql.conf, postgresql.auto.conf) in $PGDATA. This is ok for pg_basebackup but not for backend process
    - I think we need start walreceiver. At best, without interruption during startup replay (if possible)
    
    > XXX Is there a use for
    > 		 * switching into (non-standby) recovery here?
    
    I think not.
    
    regards, Sergei
    
    
    
    
  4. Re: base backup client as auxiliary backend process

    Euler Taveira <euler@timbira.com.br> — 2019-07-11T14:05:38Z

    Em sáb, 29 de jun de 2019 às 17:05, Peter Eisentraut
    <peter.eisentraut@2ndquadrant.com> escreveu:
    >
    > Setting up a standby instance is still quite complicated.  You need to
    > run pg_basebackup with all the right options.  You need to make sure
    > Attached is a very hackish patch to implement this.  It works like this:
    >
    >     # (assuming you have a primary already running somewhere)
    >     initdb -D data2 --minimal
    >     $EDITOR data2/postgresql.conf  # set primary_conninfo
    >     pg_ctl -D data2 start
    >
    Great! The main complaints about pg_basebackup usage in TB clusters
    are: (a) it can't be restarted and (b) it can't be parallelized.
    AFAICS your proposal doesn't solve them. It would be nice if it can be
    solved in future releases (using rsync or another in-house tool is as
    fragile as using pg_basebackup).
    
    
    -- 
       Euler Taveira                                   Timbira -
    http://www.timbira.com.br/
       PostgreSQL: Consultoria, Desenvolvimento, Suporte 24x7 e Treinamento
    
    
    
    
  5. Re: base backup client as auxiliary backend process

    Robert Haas <robertmhaas@gmail.com> — 2019-07-11T14:23:17Z

    On Sat, Jun 29, 2019 at 4:05 PM Peter Eisentraut
    <peter.eisentraut@2ndquadrant.com> wrote:
    > My idea is that the postmaster can launch a base backup worker, wait
    > till it's done, then proceed with the rest of the startup.  initdb gets
    > a special option to create a "minimal" data directory with only a few
    > files, directories, and the usual configuration files.
    
    Why do we even have to do that much?  Can we remove the need for an
    initdb altogether?
    
    -- 
    Robert Haas
    EnterpriseDB: http://www.enterprisedb.com
    The Enterprise PostgreSQL Company
    
    
    
    
  6. Re: base backup client as auxiliary backend process

    Tom Lane <tgl@sss.pgh.pa.us> — 2019-07-11T14:36:43Z

    Robert Haas <robertmhaas@gmail.com> writes:
    > On Sat, Jun 29, 2019 at 4:05 PM Peter Eisentraut
    > <peter.eisentraut@2ndquadrant.com> wrote:
    >> My idea is that the postmaster can launch a base backup worker, wait
    >> till it's done, then proceed with the rest of the startup.  initdb gets
    >> a special option to create a "minimal" data directory with only a few
    >> files, directories, and the usual configuration files.
    
    > Why do we even have to do that much?  Can we remove the need for an
    > initdb altogether?
    
    Gotta have config files in place already, no?
    
    			regards, tom lane
    
    
    
    
  7. Re: base backup client as auxiliary backend process

    Robert Haas <robertmhaas@gmail.com> — 2019-07-11T19:07:20Z

    On Thu, Jul 11, 2019 at 10:36 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    > Gotta have config files in place already, no?
    
    Why?
    
    -- 
    Robert Haas
    EnterpriseDB: http://www.enterprisedb.com
    The Enterprise PostgreSQL Company
    
    
    
    
  8. Re: base backup client as auxiliary backend process

    Tom Lane <tgl@sss.pgh.pa.us> — 2019-07-11T20:10:43Z

    Robert Haas <robertmhaas@gmail.com> writes:
    > On Thu, Jul 11, 2019 at 10:36 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    >> Gotta have config files in place already, no?
    
    > Why?
    
    How's the postmaster to know that it's supposed to run pg_basebackup
    rather than start normally?  Where will it get the connection information?
    Seem to need configuration data *somewhere*.
    
    			regards, tom lane
    
    
    
    
  9. Re: base backup client as auxiliary backend process

    Robert Haas <robertmhaas@gmail.com> — 2019-07-11T20:20:26Z

    On Thu, Jul 11, 2019 at 4:10 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    > Robert Haas <robertmhaas@gmail.com> writes:
    > > On Thu, Jul 11, 2019 at 10:36 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    > >> Gotta have config files in place already, no?
    >
    > > Why?
    >
    > How's the postmaster to know that it's supposed to run pg_basebackup
    > rather than start normally?  Where will it get the connection information?
    > Seem to need configuration data *somewhere*.
    
    Maybe just:
    
    ./postgres --replica='connstr' -D createme
    
    ?
    
    -- 
    Robert Haas
    EnterpriseDB: http://www.enterprisedb.com
    The Enterprise PostgreSQL Company
    
    
    
    
  10. Re: base backup client as auxiliary backend process

    Peter Eisentraut <peter.eisentraut@2ndquadrant.com> — 2019-07-11T20:56:31Z

    On 2019-07-11 22:20, Robert Haas wrote:
    > On Thu, Jul 11, 2019 at 4:10 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    >> Robert Haas <robertmhaas@gmail.com> writes:
    >>> On Thu, Jul 11, 2019 at 10:36 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    >>>> Gotta have config files in place already, no?
    >>
    >>> Why?
    >>
    >> How's the postmaster to know that it's supposed to run pg_basebackup
    >> rather than start normally?  Where will it get the connection information?
    >> Seem to need configuration data *somewhere*.
    > 
    > Maybe just:
    > 
    > ./postgres --replica='connstr' -D createme
    
    What you are describing is of course theoretically possible, but it
    doesn't really fit with how existing tooling normally deals with this,
    which is one of the problems I want to address.
    
    initdb has all the knowledge of how to create the data *directory*, how
    to set permissions, deal with existing and non-empty directories, how to
    set up a separate WAL directory.  Packaged environments might wrap this
    further by using the correct OS users, creating the directory first as
    root, then changing owner, etc.  This is all logic that we can reuse and
    probably don't want to duplicate elsewhere.
    
    Furthermore, we have for the longest time encouraged packagers *not* to
    create data directories automatically when a service is started, because
    this might store data in places that will be hidden by a later mount.
    Keeping this property requires making the initialization of the data
    directory a separate step somehow.  That step doesn't have to be called
    "initdb", it could be a new "pg_mkdirs", but for the reasons described
    above, this would create a fair mount of code duplication and not really
    gain anything.
    
    Finally, many installations want to have the configuration files under
    control of some centralized configuration management system.  The way
    those want to work is usually: (1) create file system structures, (2)
    install configuration files from some templates, (3) start service.
    This is of course how setting up a primary works.  Having such a system
    set up a standby is currently seemingly impossible in an elegant way,
    because the order and timing of how things work is all wrong.  My
    proposed change would fix this because things would be set up in the
    same three-step process.  (As has been pointed out, this would require
    that the base backup does not copy over the configuration files from the
    remote, which my patch currently doesn't do correctly.)
    
    -- 
    Peter Eisentraut              http://www.2ndQuadrant.com/
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
    
    
    
    
  11. Re: base backup client as auxiliary backend process

    Tom Lane <tgl@sss.pgh.pa.us> — 2019-07-11T21:28:27Z

    Peter Eisentraut <peter.eisentraut@2ndquadrant.com> writes:
    > On 2019-07-11 22:20, Robert Haas wrote:
    >> On Thu, Jul 11, 2019 at 4:10 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
    >>> How's the postmaster to know that it's supposed to run pg_basebackup
    >>> rather than start normally?  Where will it get the connection information?
    >>> Seem to need configuration data *somewhere*.
    >> 
    >> Maybe just:
    >> 
    >> ./postgres --replica='connstr' -D createme
    
    > What you are describing is of course theoretically possible, but it
    > doesn't really fit with how existing tooling normally deals with this,
    > which is one of the problems I want to address.
    
    I don't care for Robert's suggestion for a different reason: it presumes
    that all data that can possibly be needed to set up a new replica is
    feasible to cram onto the postmaster command line, and always will be.
    
    An immediate counterexample is that's not where you want to be specifying
    the password for a replication connection.  But even without that sort of
    security issue, this approach won't scale.  It also does not work even a
    little bit nicely for tooling in which the postmaster is not supposed to
    be started directly by the user.  (Which is to say, all postgres-service
    tooling everywhere.)
    
    			regards, tom lane
    
    
    
    
  12. Re: base backup client as auxiliary backend process

    Kyotaro Horiguchi <horikyota.ntt@gmail.com> — 2019-07-12T01:00:19Z

    Hello.
    
    At Sat, 29 Jun 2019 22:05:22 +0200, Peter Eisentraut <peter.eisentraut@2ndquadrant.com> wrote in <61b8d18d-c922-ac99-b990-a31ba63cdcbb@2ndquadrant.com>
    > Setting up a standby instance is still quite complicated.  You need to
    > run pg_basebackup with all the right options.  You need to make sure
    > pg_basebackup has the right permissions for the target directories.  The
    > created instance has to be integrated into the operating system's start
    > scripts.  There is this slightly awkward business of the --recovery-conf
    > option and how it interacts with other features.  And you should
    > probably run pg_basebackup under screen.  And then how do you get
    > notified when it's done.  And when it's done you have to log back in and
    > finish up.  Too many steps.
    > 
    > My idea is that the postmaster can launch a base backup worker, wait
    > till it's done, then proceed with the rest of the startup.  initdb gets
    > a special option to create a "minimal" data directory with only a few
    > files, directories, and the usual configuration files.  Then you create
    > a $PGDATA/basebackup.signal, start the postmaster as normal.  It sees
    > the signal file, launches an auxiliary process that runs the base
    > backup, then proceeds with normal startup in standby mode.
    > 
    > This makes a whole bunch of things much nicer: The connection
    > information for where to get the base backup from comes from
    > postgresql.conf, so you only need to specify it in one place.
    > pg_basebackup is completely out of the picture; no need to deal with
    > command-line options, --recovery-conf, screen, monitoring for
    > completion, etc.  If something fails, the base backup process can
    > automatically be restarted (maybe).  Operating system integration is
    > much easier: You only call initdb and then pg_ctl or postgres, as you
    > are already doing.  Automated deployment systems don't need to wait for
    > pg_basebackup to finish: You only call initdb, then start the server,
    > and then you're done -- waiting for the base backup to finish can be
    > done by the regular monitoring system.
    > 
    > Attached is a very hackish patch to implement this.  It works like this:
    > 
    >     # (assuming you have a primary already running somewhere)
    >     initdb -D data2 --minimal
    >     $EDITOR data2/postgresql.conf  # set primary_conninfo
    >     pg_ctl -D data2 start
    
    Nice idea! 
    
    > (Curious side note: If you don’t set primary_conninfo in these steps,
    > then libpq defaults apply, so the default behavior might end up being
    > that a given instance attempts to replicate from itself.)
    
    We may be able to have different setting for primary and replica
    for other settings if we could have sections in the configuration
    file, defining, say, [replica] section gives us more frexibility.
    Though it is a bit far from the topic, dedicate command-line
    configuration editor that can find and replace specified
    parameter would elimite the sublte editing step. It is annoying
    that finding specific separator in conf file then trim then add
    new contnet.
    
    > It works for basic cases.  It's missing tablespace support, proper
    > fsyncing, progress reporting, probably more.  Those would be pretty
    
    While catching up master, connections to replica are once
    accepted then result in FATAL error. I now and then receive
    inquiries for that. With the new feature, we get FATAL also while
    basebackup phase. That can let users fear more frequently.
    
    > straightforward I think.  The interesting bit is the delicate ordering
    > of the postmaster startup:  Normally, the pg_control file is read quite
    > early, but if starting from a minimal data directory, we need to wait
    > until the base backup is done.  There is also the question what you do
    > if the base backup fails halfway through.  Currently you probably need
    > to delete the whole data directory and start again with initdb.  Better
    > might be a way to start again and overwrite any existing files, but that
    > can clearly also be dangerous.  All this needs some careful analysis,
    > but I think it's doable.
    > 
    > Any thoughts?
    
    Just overwriting won't work since files removed just before
    retrying are left alon in replica. I think it should work
    similarly to initdb, that is, removing all then retrying.
    
    It's easy if we don't consider reducing startup time. Just do
    initdb then start exising postmaster internally. But melding them
    together makes room for reducing the startup time. We even could
    redirect read-only queries to master while setting up the server.
    
    regards.
    
    -- 
    Kyotaro Horiguchi
    NTT Open Source Software Center
    
  13. Re: base backup client as auxiliary backend process

    Peter Eisentraut <peter.eisentraut@2ndquadrant.com> — 2019-08-30T19:10:10Z

    > Attached is a very hackish patch to implement this.  It works like this:
    > 
    >     # (assuming you have a primary already running somewhere)
    >     initdb -D data2 --replica
    >     $EDITOR data2/postgresql.conf  # set primary_conninfo
    >     pg_ctl -D data2 start
    
    Attached is an updated patch for this.  I have changed the initdb option
    name per suggestion.  The WAL receiver is now started concurrently with
    the base backup.  There is progress reporting (ps display), fsyncing.
    Configuration files are not copied anymore.  There is a simple test
    suite.  Tablespace support is still missing, but it would be
    straightforward.
    
    It's still all to be considered experimental, but it's taking shape and
    working pretty well.
    
    -- 
    Peter Eisentraut              http://www.2ndQuadrant.com/
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
    
  14. Re: base backup client as auxiliary backend process

    Alvaro Herrera <alvherre@2ndquadrant.com> — 2019-09-11T22:15:24Z

    On 2019-Aug-30, Peter Eisentraut wrote:
    
    > Attached is an updated patch for this.  I have changed the initdb option
    > name per suggestion.  The WAL receiver is now started concurrently with
    > the base backup.  There is progress reporting (ps display), fsyncing.
    > Configuration files are not copied anymore.  There is a simple test
    > suite.  Tablespace support is still missing, but it would be
    > straightforward.
    
    This is an amazing feature.  How come we don't have people cramming to
    review this?
    
    -- 
    Álvaro Herrera                https://www.2ndQuadrant.com/
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
    
    
    
    
  15. Re: base backup client as auxiliary backend process

    Kyotaro Horiguchi <horikyota.ntt@gmail.com> — 2019-09-12T02:47:09Z

    Hello, thanks for pinging.
    
    At Wed, 11 Sep 2019 19:15:24 -0300, Alvaro Herrera <alvherre@2ndquadrant.com> wrote in <20190911221524.GA16563@alvherre.pgsql>
    > On 2019-Aug-30, Peter Eisentraut wrote:
    > 
    > > Attached is an updated patch for this.  I have changed the initdb option
    > > name per suggestion.  The WAL receiver is now started concurrently with
    > > the base backup.  There is progress reporting (ps display), fsyncing.
    > > Configuration files are not copied anymore.  There is a simple test
    > > suite.  Tablespace support is still missing, but it would be
    > > straightforward.
    > 
    > This is an amazing feature.  How come we don't have people cramming to
    > review this?
    
    I love it, too. As for me, the reason for hesitating review this
    is the patch is said to be experimental. That means 'the details
    don't matter, let's discuss it's design/outline.'. So I wanted to
    see what the past reviewers comment on the revised shape before I
    would stir up the discussion by maybe-pointless comment. (Then
    forgotten..)
    
    I'll re-look on this.
    
    regards.
    
    -- 
    Kyotaro Horiguchi
    NTT Open Source Software Center
    
    
    
    
  16. Re: base backup client as auxiliary backend process

    Michael Paquier <michael@paquier.xyz> — 2019-09-18T08:31:10Z

    On Fri, Aug 30, 2019 at 09:10:10PM +0200, Peter Eisentraut wrote:
    > > Attached is a very hackish patch to implement this.  It works like this:
    > > 
    > >     # (assuming you have a primary already running somewhere)
    > >     initdb -D data2 --replica
    > >     $EDITOR data2/postgresql.conf  # set primary_conninfo
    > >     pg_ctl -D data2 start
    > 
    > Attached is an updated patch for this.  I have changed the initdb option
    > name per suggestion.  The WAL receiver is now started concurrently with
    > the base backup.  There is progress reporting (ps display), fsyncing.
    > Configuration files are not copied anymore.  There is a simple test
    > suite.  Tablespace support is still missing, but it would be
    > straightforward.
    
    I find this idea and this spec neat.
    
    -    * Verify XLOG status looks valid.
    +    * Check that contents look valid.
         */
    -   if (ControlFile->state < DB_SHUTDOWNED ||
    -       ControlFile->state > DB_IN_PRODUCTION ||
    -       !XRecOffIsValid(ControlFile->checkPoint))
    +   if (!XRecOffIsValid(ControlFile->checkPoint))
                 ereport(FATAL,
    Doesn't seem like a good idea to me to remove this sanity check for
    normal deployments, but actually you moved that down in StartupXLOG().
    It seems to me tha this is unrelated and could be a separate patch so
    as the errors produced are more verbose.  I think that we should also
    change that code to use a switch/case on ControlFile->state.
    
    The current defaults of pg_basebackup have been thought so as the
    backups taken have a good stability and so as monitoring is eased
    thanks to --wal-method=stream and the use of replication slots.
    Shouldn't the use of a least a temporary replication slot be mandatory
    for the stability of the copy?  It seems to me that there is a good
    argument for having a second process which streams WAL on top of the
    main backup process, and just use a WAL receiver for that.
    
    One problem which is not tackled here is what to do for the tablespace
    map.  pg_basebackup has its own specific trick for that, and with that
    new feature we may want something equivalent?  Not something to
    consider as a first stage of course.
    
      */
    -static void
    +void
     WriteControlFile(void)
    [...]
    -static void
    +void
     ReadControlFile(void)
    [...]
    If you begin to publish those routines, it seems to me that there
    could be more consolidation with controldata_utils.c which includes
    now a routine to update a control file.
    
    +#ifndef FRONTEND
    +extern void InitControlFile(uint64 sysidentifier);
    +extern void WriteControlFile(void);
    +extern void ReadControlFile(void);
    +#endif
    It would be nice to avoid that.
    
    -extern char *cluster_name;
    +extern PGDLLIMPORT char *cluster_name;
    Separate patch here?
    
    +   if (stat(BASEBACKUP_SIGNAL_FILE, &stat_buf) == 0)
    +   {
    +       int         fd;
    +
    +       fd = BasicOpenFilePerm(STANDBY_SIGNAL_FILE, O_RDWR |
    PG_BINARY,
    +                              S_IRUSR | S_IWUSR);
    +       if (fd >= 0)
    +       {
    +           (void) pg_fsync(fd);
    +           close(fd);
    +       }
    +       basebackup_signal_file_found = true;
    +   }
    I would put that in a different routine.
    
    +       /*
    +        * Wait until done.  Start WAL receiver in the meantime, once
    base
    +        * backup has received the starting position.
    +        */
    +       while (BaseBackupPID != 0)
    +       {
    +           PG_SETMASK(&UnBlockSig);
    +           pg_usleep(1000000L);
    +           PG_SETMASK(&BlockSig);
    
    +   primary_sysid = strtoull(walrcv_identify_system(wrconn,
    &primaryTLI), NULL, 10);
    No more strtol with base 10 stuff please :)
    --
    Michael
    
  17. Re: base backup client as auxiliary backend process

    Peter Eisentraut <peter.eisentraut@2ndquadrant.com> — 2019-10-28T08:30:52Z

    Updated patch attached.
    
    On 2019-09-18 10:31, Michael Paquier wrote:
    > -    * Verify XLOG status looks valid.
    > +    * Check that contents look valid.
    >       */
    > -   if (ControlFile->state < DB_SHUTDOWNED ||
    > -       ControlFile->state > DB_IN_PRODUCTION ||
    > -       !XRecOffIsValid(ControlFile->checkPoint))
    > +   if (!XRecOffIsValid(ControlFile->checkPoint))
    >               ereport(FATAL,
    > Doesn't seem like a good idea to me to remove this sanity check for
    > normal deployments, but actually you moved that down in StartupXLOG().
    > It seems to me tha this is unrelated and could be a separate patch so
    > as the errors produced are more verbose.  I think that we should also
    > change that code to use a switch/case on ControlFile->state.
    
    Done.  Yes, this was really a change made to get more precise error 
    messaged during debugging.  It could be committed separately.
    
    > The current defaults of pg_basebackup have been thought so as the
    > backups taken have a good stability and so as monitoring is eased
    > thanks to --wal-method=stream and the use of replication slots.
    > Shouldn't the use of a least a temporary replication slot be mandatory
    > for the stability of the copy?  It seems to me that there is a good
    > argument for having a second process which streams WAL on top of the
    > main backup process, and just use a WAL receiver for that.
    
    Is this something that the walreceiver should be doing independent of 
    this patch?
    
    > One problem which is not tackled here is what to do for the tablespace
    > map.  pg_basebackup has its own specific trick for that, and with that
    > new feature we may want something equivalent?  Not something to
    > consider as a first stage of course.
    
    The updated has support for tablespaces without mapping.  I'm thinking 
    about putting the mapping specification into a GUC list somehow. 
    Shouldn't be too hard.
    
    >    */
    > -static void
    > +void
    >   WriteControlFile(void)
    > [...]
    > -static void
    > +void
    >   ReadControlFile(void)
    > [...]
    > If you begin to publish those routines, it seems to me that there
    > could be more consolidation with controldata_utils.c which includes
    > now a routine to update a control file.
    
    Hmm, maybe long-term, but it seems too much dangerous surgery for this 
    patch.
    
    > +#ifndef FRONTEND
    > +extern void InitControlFile(uint64 sysidentifier);
    > +extern void WriteControlFile(void);
    > +extern void ReadControlFile(void);
    > +#endif
    > It would be nice to avoid that.
    
    Fixed by renaming a function in pg_resetwal.c.
    
    > +       /*
    > +        * Wait until done.  Start WAL receiver in the meantime, once
    > base
    > +        * backup has received the starting position.
    > +        */
    > +       while (BaseBackupPID != 0)
    > +       {
    > +           PG_SETMASK(&UnBlockSig);
    > +           pg_usleep(1000000L);
    > +           PG_SETMASK(&BlockSig);
    > 
    > +   primary_sysid = strtoull(walrcv_identify_system(wrconn,
    > &primaryTLI), NULL, 10);
    > No more strtol with base 10 stuff please :)
    
    Hmm, why not?  What's the replacement?
    
    -- 
    Peter Eisentraut              http://www.2ndQuadrant.com/
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
    
  18. Re: base backup client as auxiliary backend process

    Michael Paquier <michael@paquier.xyz> — 2019-11-07T04:16:30Z

    On Mon, Oct 28, 2019 at 09:30:52AM +0100, Peter Eisentraut wrote:
    > On 2019-09-18 10:31, Michael Paquier wrote:
    >> -    * Verify XLOG status looks valid.
    >> +    * Check that contents look valid.
    >>       */
    >> -   if (ControlFile->state < DB_SHUTDOWNED ||
    >> -       ControlFile->state > DB_IN_PRODUCTION ||
    >> -       !XRecOffIsValid(ControlFile->checkPoint))
    >> +   if (!XRecOffIsValid(ControlFile->checkPoint))
    >>               ereport(FATAL,
    >> Doesn't seem like a good idea to me to remove this sanity check for
    >> normal deployments, but actually you moved that down in StartupXLOG().
    >> It seems to me tha this is unrelated and could be a separate patch so
    >> as the errors produced are more verbose.  I think that we should also
    >> change that code to use a switch/case on ControlFile->state.
    > 
    > Done.  Yes, this was really a change made to get more precise error messaged
    > during debugging.  It could be committed separately.
    
    If you wish to do so now, that's fine by me.
    
    >> The current defaults of pg_basebackup have been thought so as the
    >> backups taken have a good stability and so as monitoring is eased
    >> thanks to --wal-method=stream and the use of replication slots.
    >> Shouldn't the use of a least a temporary replication slot be mandatory
    >> for the stability of the copy?  It seems to me that there is a good
    >> argument for having a second process which streams WAL on top of the
    >> main backup process, and just use a WAL receiver for that.
    > 
    > Is this something that the walreceiver should be doing independent of this
    > patch?
    
    There could be an argument for switching a WAL receiver to use a
    temporary replication slot by default.  Still, it seems to me that
    this backup solution suffers from the same set of problems we have
    spent years to fix with pg_basebackup with missing WAL files caused by
    concurrent checkpoints removing things needed while the copy of the
    main data folder and other tablespaces happens.
    
    >> One problem which is not tackled here is what to do for the tablespace
    >> map.  pg_basebackup has its own specific trick for that, and with that
    >> new feature we may want something equivalent?  Not something to
    >> consider as a first stage of course.
    > 
    > The updated has support for tablespaces without mapping.  I'm thinking about
    > putting the mapping specification into a GUC list somehow. Shouldn't be too
    > hard.
    
    That may become ugly if there are many tablespaces to take care of.
    Another idea I can come up with would be to pass the new mapping to
    initdb, still this requires an extra intermediate step to store the
    new map, and then compare it with the mapping received at BASE_BACKUP
    time.  But perhaps you are looking for an experience different than
    pg_basebackup.  The first version of the patch does not actually
    require that anyway..
    
    >> No more strtol with base 10 stuff please :)
    > 
    > Hmm, why not?  What's the replacement?
    
    I was referring to this patch:
    https://commitfest.postgresql.org/25/2272/
    It happens that all our calls of strtol in core use a base of 10.  But
    please just ignore this part.
    
    ReceiveAndUnpackTarFile() is in both libpqwalreceiver.c and
    pg_basebackup.c.  It would be nice to refactor that.
    --
    Michael
    
  19. Re: base backup client as auxiliary backend process

    Peter Eisentraut <peter.eisentraut@2ndquadrant.com> — 2019-11-09T21:13:13Z

    On 2019-11-07 05:16, Michael Paquier wrote:
    >>> The current defaults of pg_basebackup have been thought so as the
    >>> backups taken have a good stability and so as monitoring is eased
    >>> thanks to --wal-method=stream and the use of replication slots.
    >>> Shouldn't the use of a least a temporary replication slot be mandatory
    >>> for the stability of the copy?  It seems to me that there is a good
    >>> argument for having a second process which streams WAL on top of the
    >>> main backup process, and just use a WAL receiver for that.
    >> Is this something that the walreceiver should be doing independent of this
    >> patch?
    > There could be an argument for switching a WAL receiver to use a
    > temporary replication slot by default.  Still, it seems to me that
    > this backup solution suffers from the same set of problems we have
    > spent years to fix with pg_basebackup with missing WAL files caused by
    > concurrent checkpoints removing things needed while the copy of the
    > main data folder and other tablespaces happens.
    
    I looked into this.  It seems trivial to make walsender create and use a 
    temporary replication slot by default if no permanent replication slot 
    is specified.  This is basically the logic that pg_basebackup has but 
    done server-side.  See attached patch for a demonstration.  Any reason 
    not to do that?
    
    -- 
    Peter Eisentraut              http://www.2ndQuadrant.com/
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
    
  20. Re: base backup client as auxiliary backend process

    Sergei Kornilov <sk@zsrv.org> — 2019-11-15T13:52:27Z

    Hello
    
    Could you rebase patch please? I have errors during patch apply. CFbot checks latest demonstration patch.
    
    > I looked into this. It seems trivial to make walsender create and use a
    > temporary replication slot by default if no permanent replication slot
    > is specified. This is basically the logic that pg_basebackup has but
    > done server-side. See attached patch for a demonstration. Any reason
    > not to do that?
    
    Seems this would break pg_basebackup --no-slot option?
    
    > +          Do not copy configuration files, that is, files that end in
    > +          <filename>.conf</filename>.
    
    possible we need ignore *.signal files too?
    
    > +/*
    > + * XXX copied from pg_basebackup.c
    > + */
    > +
    > +unsigned long long totaldone;
    > +unsigned long long totalsize_kb;
    > +int tablespacenum;
    > +int tablespacecount;
    
    Variable declaration in the middle of file is correct for coding style? Not a problem for me, I just want to clarify.
    Should not be declared "static"?
    Also how about tablespacedone instead of tablespacenum?
    
    > The updated has support for tablespaces without mapping.  I'm thinking 
    > about putting the mapping specification into a GUC list somehow. 
    > Shouldn't be too hard.
    
    I think we can leave tablespace mapping for pg_basebackup only. More powerful tool for less common scenarios. Or for another future patch.
    
    regards, Sergei
    
    
    
    
  21. Re: base backup client as auxiliary backend process

    Peter Eisentraut <peter.eisentraut@2ndquadrant.com> — 2019-11-22T10:21:53Z

    On 2019-11-15 14:52, Sergei Kornilov wrote:
    >> I looked into this. It seems trivial to make walsender create and use a
    >> temporary replication slot by default if no permanent replication slot
    >> is specified. This is basically the logic that pg_basebackup has but
    >> done server-side. See attached patch for a demonstration. Any reason
    >> not to do that?
    > Seems this would break pg_basebackup --no-slot option?
    
    After thinking about this a bit more, doing the temporary slot stuff on 
    the walsender side might lead to too many complications in practice.
    
    Here is another patch set that implements the temporary slot use on the 
    walreceiver side, essentially mirroring what pg_basebackup already does.
    
    I think this patch set might be useful on its own, even without the base 
    backup stuff to follow.
    
    -- 
    Peter Eisentraut              http://www.2ndQuadrant.com/
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
    
  22. Re: base backup client as auxiliary backend process

    Michael Paquier <michael@paquier.xyz> — 2019-11-22T12:56:03Z

    On Fri, Nov 22, 2019 at 11:21:53AM +0100, Peter Eisentraut wrote:
    > After thinking about this a bit more, doing the temporary slot stuff on the
    > walsender side might lead to too many complications in practice.
    > 
    > Here is another patch set that implements the temporary slot use on the
    > walreceiver side, essentially mirroring what pg_basebackup already does.
    
    I have not looked at the patch, but controlling the generation of the
    slot from the client feels much more natural to me.  This reuses the
    existing interface, which is consistent, and we avoid a new class of
    bugs if there is any need to deal with the cleanup of the slot on the
    WAL sender side it itself created.
    --
    Michael
    
  23. Re: base backup client as auxiliary backend process

    Alexandra Wang <lewang@pivotal.io> — 2020-01-09T10:57:52Z

    Hi Peter,
    
    On Fri, Nov 22, 2019 at 6:22 PM Peter Eisentraut <
    peter.eisentraut@2ndquadrant.com> wrote:
    
    > Here is another patch set that implements the temporary slot use on the
    > walreceiver side, essentially mirroring what pg_basebackup already does.
    >
    > I think this patch set might be useful on its own, even without the base
    > backup stuff to follow.
    
    
    I very much like this idea of every replication connection should have a
    replication slot, either permanent or temporary if user didn't specify. I
    agree
    that this patch is useful on its own.
    
    > This makes a whole bunch of things much nicer: The connection
    > information for where to get the base backup from comes from
    > postgresql.conf, so you only need to specify it in one place.
    > pg_basebackup is completely out of the picture; no need to deal with
    > command-line options, --recovery-conf, screen, monitoring for
    > completion, etc.  If something fails, the base backup process can
    > automatically be restarted (maybe).  Operating system integration is
    > much easier: You only call initdb and then pg_ctl or postgres, as you
    > are already doing.  Automated deployment systems don't need to wait for
    > pg_basebackup to finish: You only call initdb, then start the server,
    > and then you're done -- waiting for the base backup to finish can be
    > done by the regular monitoring system.
    
    Back to the base backup stuff, I don't quite understand all the benefits you
    mentioned above. It seems to me the greatest benefit with this patch is that
    postmaster takes care of pg_basebackup itself, which reduces the human wait
    in
    between running the pg_basebackup and pg_ctl/postgres commands. Is that
    right?
    I personally don't mind the --write-recovery-conf option because it helps me
    write the primary_conninfo and primary_slot_name gucs into
    postgresql.auto.conf, which to me as a developer is easier than editing
    postgres.conf without automation.  Sorry about the dumb question but what's
    so
    bad about --write-recovery-conf?  Are you planning to completely replace
    pg_basebackup with this? Is there any use case that a user just need a
    basebackup but not immediately start the backend process?
    
    Also the patch doesn't apply to master any more, need a rebase.
    
    --
    Alexandra
    
  24. Re: base backup client as auxiliary backend process

    Masahiko Sawada <masahiko.sawada@2ndquadrant.com> — 2020-01-10T03:32:19Z

    On Fri, 22 Nov 2019 at 19:22, Peter Eisentraut
    <peter.eisentraut@2ndquadrant.com> wrote:
    >
    > On 2019-11-15 14:52, Sergei Kornilov wrote:
    > >> I looked into this. It seems trivial to make walsender create and use a
    > >> temporary replication slot by default if no permanent replication slot
    > >> is specified. This is basically the logic that pg_basebackup has but
    > >> done server-side. See attached patch for a demonstration. Any reason
    > >> not to do that?
    > > Seems this would break pg_basebackup --no-slot option?
    >
    > After thinking about this a bit more, doing the temporary slot stuff on
    > the walsender side might lead to too many complications in practice.
    >
    > Here is another patch set that implements the temporary slot use on the
    > walreceiver side, essentially mirroring what pg_basebackup already does.
    >
    > I think this patch set might be useful on its own, even without the base
    > backup stuff to follow.
    >
    
    I agreed that these patches are useful on its own and 0001 patch and
    0002 patch look good to me. For 0003 patch,
    
    +      linkend="guc-primary-slot-name"/>.  Otherwise, the WAL receiver may use
    +      a temporary replication slot (determined by <xref
    +      linkend="guc-wal-receiver-create-temp-slot"/>), but these are not shown
    +      here.
    
    I think it's better to show the temporary slot name on
    pg_stat_wal_receiver view. Otherwise user would have no idea about
    what wal receiver is using the temporary slot.
    
    Regards,
    
    -- 
    Masahiko Sawada            http://www.2ndQuadrant.com/
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
    
    
    
    
  25. Re: base backup client as auxiliary backend process

    Peter Eisentraut <peter.eisentraut@2ndquadrant.com> — 2020-01-11T09:52:30Z

    On 2020-01-10 04:32, Masahiko Sawada wrote:
    > I agreed that these patches are useful on its own and 0001 patch and
    
    committed 0001
    
    > 0002 patch look good to me. For 0003 patch,
    > 
    > +      linkend="guc-primary-slot-name"/>.  Otherwise, the WAL receiver may use
    > +      a temporary replication slot (determined by <xref
    > +      linkend="guc-wal-receiver-create-temp-slot"/>), but these are not shown
    > +      here.
    > 
    > I think it's better to show the temporary slot name on
    > pg_stat_wal_receiver view. Otherwise user would have no idea about
    > what wal receiver is using the temporary slot.
    
    Makes sense.  It makes the code a bit more fiddly, but it seems worth 
    it.  New patches attached.
    
    -- 
    Peter Eisentraut              http://www.2ndQuadrant.com/
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
    
  26. Re: base backup client as auxiliary backend process

    Masahiko Sawada <masahiko.sawada@2ndquadrant.com> — 2020-01-14T06:32:39Z

    On Sat, 11 Jan 2020 at 18:52, Peter Eisentraut
    <peter.eisentraut@2ndquadrant.com> wrote:
    >
    > On 2020-01-10 04:32, Masahiko Sawada wrote:
    > > I agreed that these patches are useful on its own and 0001 patch and
    >
    > committed 0001
    >
    > > 0002 patch look good to me. For 0003 patch,
    > >
    > > +      linkend="guc-primary-slot-name"/>.  Otherwise, the WAL receiver may use
    > > +      a temporary replication slot (determined by <xref
    > > +      linkend="guc-wal-receiver-create-temp-slot"/>), but these are not shown
    > > +      here.
    > >
    > > I think it's better to show the temporary slot name on
    > > pg_stat_wal_receiver view. Otherwise user would have no idea about
    > > what wal receiver is using the temporary slot.
    >
    > Makes sense.  It makes the code a bit more fiddly, but it seems worth
    > it.  New patches attached.
    
    Thank you for updating the patch!
    
    -     <entry>Replication slot name used by this WAL receiver</entry>
    +     <entry>
    +      Replication slot name used by this WAL receiver.  This is only set if a
    +      permanent replication slot is set using <xref
    +      linkend="guc-primary-slot-name"/>.  Otherwise, the WAL receiver may use
    +      a temporary replication slot (determined by <xref
    +      linkend="guc-wal-receiver-create-temp-slot"/>), but these are not shown
    +      here.
    +     </entry>
    
    Now that the slot name is shown even if it's a temp slot the above
    documentation changes needs to be changed. Other changes look good to
    me.
    
    Regards,
    
    -- 
    Masahiko Sawada            http://www.2ndQuadrant.com/
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
    
    
    
    
  27. Re: base backup client as auxiliary backend process

    Peter Eisentraut <peter.eisentraut@2ndquadrant.com> — 2020-01-14T13:58:23Z

    On 2020-01-14 07:32, Masahiko Sawada wrote:
    > -     <entry>Replication slot name used by this WAL receiver</entry>
    > +     <entry>
    > +      Replication slot name used by this WAL receiver.  This is only set if a
    > +      permanent replication slot is set using <xref
    > +      linkend="guc-primary-slot-name"/>.  Otherwise, the WAL receiver may use
    > +      a temporary replication slot (determined by <xref
    > +      linkend="guc-wal-receiver-create-temp-slot"/>), but these are not shown
    > +      here.
    > +     </entry>
    > 
    > Now that the slot name is shown even if it's a temp slot the above
    > documentation changes needs to be changed. Other changes look good to
    > me.
    
    committed, thanks
    
    -- 
    Peter Eisentraut              http://www.2ndQuadrant.com/
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
    
    
    
    
  28. Re: base backup client as auxiliary backend process

    Masahiko Sawada <masahiko.sawada@2ndquadrant.com> — 2020-01-15T00:40:38Z

    On Tue, 14 Jan 2020 at 22:58, Peter Eisentraut
    <peter.eisentraut@2ndquadrant.com> wrote:
    >
    > On 2020-01-14 07:32, Masahiko Sawada wrote:
    > > -     <entry>Replication slot name used by this WAL receiver</entry>
    > > +     <entry>
    > > +      Replication slot name used by this WAL receiver.  This is only set if a
    > > +      permanent replication slot is set using <xref
    > > +      linkend="guc-primary-slot-name"/>.  Otherwise, the WAL receiver may use
    > > +      a temporary replication slot (determined by <xref
    > > +      linkend="guc-wal-receiver-create-temp-slot"/>), but these are not shown
    > > +      here.
    > > +     </entry>
    > >
    > > Now that the slot name is shown even if it's a temp slot the above
    > > documentation changes needs to be changed. Other changes look good to
    > > me.
    >
    > committed, thanks
    
    Thank you for committing these patches.
    
    Could you rebase the main patch that adds base backup client as
    auxiliary backend process since the previous version patch (v3)
    conflicts with the current HEAD?
    
    Regards,
    
    -- 
    Masahiko Sawada            http://www.2ndQuadrant.com/
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
    
    
    
    
  29. Re: base backup client as auxiliary backend process

    Peter Eisentraut <peter.eisentraut@2ndquadrant.com> — 2020-01-15T15:17:29Z

    On 2020-01-15 01:40, Masahiko Sawada wrote:
    > Could you rebase the main patch that adds base backup client as
    > auxiliary backend process since the previous version patch (v3)
    > conflicts with the current HEAD?
    
    attached
    
    -- 
    Peter Eisentraut              http://www.2ndQuadrant.com/
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
    
  30. Re: base backup client as auxiliary backend process

    Peter Eisentraut <peter.eisentraut@2ndquadrant.com> — 2020-01-15T15:20:35Z

    On 2020-01-09 11:57, Alexandra Wang wrote:
    > Back to the base backup stuff, I don't quite understand all the benefits you
    > mentioned above. It seems to me the greatest benefit with this patch is that
    > postmaster takes care of pg_basebackup itself, which reduces the human 
    > wait in
    > between running the pg_basebackup and pg_ctl/postgres commands. Is that 
    > right?
    > I personally don't mind the --write-recovery-conf option because it helps me
    > write the primary_conninfo and primary_slot_name gucs into
    > postgresql.auto.conf, which to me as a developer is easier than editing
    > postgres.conf without automation.  Sorry about the dumb question but 
    > what's so
    > bad about --write-recovery-conf?
    
    Making it easier to automate is one major appeal of my proposal.  The 
    current way of setting up a standby is very difficult to automate correctly.
    
    > Are you planning to completely replace
    > pg_basebackup with this? Is there any use case that a user just need a
    > basebackup but not immediately start the backend process?
    
    I'm not planning to replace or change pg_basebackup.
    
    -- 
    Peter Eisentraut              http://www.2ndQuadrant.com/
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
    
    
    
    
  31. Re: base backup client as auxiliary backend process

    Masahiko Sawada <masahiko.sawada@2ndquadrant.com> — 2020-01-20T07:46:50Z

    On Thu, 16 Jan 2020 at 00:17, Peter Eisentraut
    <peter.eisentraut@2ndquadrant.com> wrote:
    >
    > On 2020-01-15 01:40, Masahiko Sawada wrote:
    > > Could you rebase the main patch that adds base backup client as
    > > auxiliary backend process since the previous version patch (v3)
    > > conflicts with the current HEAD?
    >
    > attached
    
    Thanks. I used and briefly looked at this patch. Here are some comments:
    
    1.
    +        /*
    +         * Wait until done.  Start WAL receiver in the meantime, once base
    +         * backup has received the starting position.
    +         */
    +        while (BaseBackupPID != 0)
    +        {
    +            PG_SETMASK(&UnBlockSig);
    +            pg_usleep(1000000L);
    +            PG_SETMASK(&BlockSig);
    +            MaybeStartWalReceiver();
    +        }
    
    Since the postmaster is sleeping the new connection hangs without any
    message whereas normally we can get the message like "the database
    system is starting up" during not accepting new connections. I think
    some programs that checks the connectivity of PostgreSQL starting up
    might not work fine with this. So many we might want to refuse all new
    connections while waiting for taking basebackup.
    
    2.
    +    initStringInfo(&stmt);
    +    appendStringInfo(&stmt, "BASE_BACKUP PROGRESS NOWAIT EXCLUDE_CONF");
    +    if (cluster_name && cluster_name[0])
    
    While using this patch I realized that the standby server cannot start
    when the master server has larger value of some GUC parameter such as
    max_connections and max_prepared_transactions than the default values.
    And unlike taking basebackup using pg_basebacup or other methods the
    database cluster initialized by this feature use default values for
    all configuration parameters regardless of values in the master. So I
    think it's better to include .conf files but we will end up with
    overwriting the local .conf files instead. So I thought that
    basebackup process can fetch .conf files from the master server and
    add primary_conninfo to postgresql.auto.conf but I'm not sure.
    
    3.
    +    if (stat(BASEBACKUP_SIGNAL_FILE, &stat_buf) == 0)
    +    {
    +        int         fd;
    +
    +        fd = BasicOpenFilePerm(STANDBY_SIGNAL_FILE, O_RDWR | PG_BINARY,
    +                               S_IRUSR | S_IWUSR);
    +        if (fd >= 0)
    +        {
    +            (void) pg_fsync(fd);
    +            close(fd);
    +        }
    +        basebackup_signal_file_found = true;
    +    }
    +
    
    Why do we open and just close the file?
    
    Regards,
    
    -- 
    Masahiko Sawada            http://www.2ndQuadrant.com/
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
    
    
    
    
  32. Re: base backup client as auxiliary backend process

    Andres Freund <andres@anarazel.de> — 2020-02-03T09:37:25Z

    Hi,
    
    On 2020-01-11 10:52:30 +0100, Peter Eisentraut wrote:
    > On 2020-01-10 04:32, Masahiko Sawada wrote:
    > > I agreed that these patches are useful on its own and 0001 patch and
    > 
    > committed 0001
    
    over on -committers Robert complained:
    
    On 2020-01-23 15:49:37 -0500, Robert Haas wrote:
    > On Tue, Jan 14, 2020 at 8:57 AM Peter Eisentraut <peter@eisentraut.org> wrote:
    > > walreceiver uses a temporary replication slot by default
    > >
    > > If no permanent replication slot is configured using
    > > primary_slot_name, the walreceiver now creates and uses a temporary
    > > replication slot.  A new setting wal_receiver_create_temp_slot can be
    > > used to disable this behavior, for example, if the remote instance is
    > > out of replication slots.
    > >
    > > Reviewed-by: Masahiko Sawada <masahiko.sawada@2ndquadrant.com>
    > > Discussion: https://www.postgresql.org/message-id/CA%2Bfd4k4dM0iEPLxyVyme2RAFsn8SUgrNtBJOu81YqTY4V%2BnqZA%40mail.gmail.com
    > 
    > Neither the commit message for this patch nor any of the comments in
    > the patch seem to explain why this is a desirable change.
    > 
    > I assume that's probably discussed on the thread that is linked here,
    > but you shouldn't have to dig through the discussion thread to figure
    > out what the benefits of a change like this are.
    
    which I fully agree with.
    
    
    It's not at all clear to me that the potential downsides of this have
    been fully thought through. And even if they have, they've not been
    documented.
    
    Previously if a standby without a slot was slow receiving WAL,
    e.g. because the network bandwidth was insufficient, it'd at some point
    just fail because the required WAL is removed. But with this patch that
    won't happen - instead the primary will just run out of space. At the
    very least this would need to add documentation of this caveat to a few
    places.
    
    Perhaps that's worth doing anyway, because it's probably more common for
    a standby to just temporarily run behind - but given that this feature
    doesn't actually provide any robustness, due to e.g. the possibility of
    temporary disconnections or restarts, I'm not sure it's providing all
    that much compared to the dangers, for a feature on by default.
    
    Greetings,
    
    Andres Freund
    
    
    
    
  33. Re: base backup client as auxiliary backend process

    Andres Freund <andres@anarazel.de> — 2020-02-03T12:47:31Z

    Hi,
    
    Comment:
    
    - It'd be good to split out the feature independent refactorings, like
      the introduction of InitControlFile(), into their own commit. Right
      now it's hard to separate out what should just should be moved code,
      and what should be behavioural changes. Especially when there's stuff
      like just reindenting comments as part of the patch.
    
    
    > @@ -886,12 +891,27 @@ PostmasterMain(int argc, char *argv[])
    >  	/* Verify that DataDir looks reasonable */
    >  	checkDataDir();
    >
    > -	/* Check that pg_control exists */
    > -	checkControlFile();
    > -
    >  	/* And switch working directory into it */
    >  	ChangeToDataDir();
    >
    > +	if (stat(BASEBACKUP_SIGNAL_FILE, &stat_buf) == 0)
    > +	{
    > +		int         fd;
    > +
    > +		fd = BasicOpenFilePerm(STANDBY_SIGNAL_FILE, O_RDWR | PG_BINARY,
    > +							   S_IRUSR | S_IWUSR);
    > +		if (fd >= 0)
    > +		{
    > +			(void) pg_fsync(fd);
    > +			close(fd);
    > +		}
    > +		basebackup_signal_file_found = true;
    > +	}
    > +
    > +	/* Check that pg_control exists */
    > +	if (!basebackup_signal_file_found)
    > +		checkControlFile();
    > +
    
    This should be moved into its own function, rather than open coded in
    PostmasterMain(). Imagine how PostmasterMain() would look if all the
    check/initialization functions weren't extracted into functions.
    
    
    >  	/*
    >  	 * Check for invalid combinations of GUC settings.
    >  	 */
    > @@ -970,7 +990,8 @@ PostmasterMain(int argc, char *argv[])
    >  	 * processes will inherit the correct function pointer and not need to
    >  	 * repeat the test.
    >  	 */
    > -	LocalProcessControlFile(false);
    > +	if (!basebackup_signal_file_found)
    > +		LocalProcessControlFile(false);
    >
    >  	/*
    >  	 * Initialize SSL library, if specified.
    > @@ -1386,6 +1407,39 @@ PostmasterMain(int argc, char *argv[])
    >  	 */
    >  	AddToDataDirLockFile(LOCK_FILE_LINE_PM_STATUS, PM_STATUS_STARTING);
    >
    > +	if (basebackup_signal_file_found)
    > +	{
    
    This imo *really* should be a separate function.
    
    
    > +		BaseBackupPID = StartBaseBackup();
    > +
    > +		/*
    > +		 * Wait until done.  Start WAL receiver in the meantime, once base
    > +		 * backup has received the starting position.
    > +		 */
    > +		while (BaseBackupPID != 0)
    > +		{
    > +			PG_SETMASK(&UnBlockSig);
    > +			pg_usleep(1000000L);
    > +			PG_SETMASK(&BlockSig);
    > +			MaybeStartWalReceiver();
    > +		}
    
    
    Is there seriously no better signalling that we can use than just
    looping for a couple hours?
    
    Is it actully guaranteed that a compiler wouldn't just load
    BaseBackupPID into a register, and never see a change to it done in a
    signal handler?
    
    There should be a note mentioning that we'll just FATAL out if the base
    backup process fails. Otherwise it's the obvious question reading this
    code.   Also - we have handling to restart WAL receiver, but there's no
    handling for the base backup temporarily failing: Is that just because
    its easy to do in one, but not the other case?
    
    
    > +		/*
    > +		 * Reread the control file that came in with the base backup.
    > +		 */
    > +		ReadControlFile();
    > +	}
    
    Is it actualy rereading? I'm just reading the diff, so maybe I'm missing
    something, but you've made LocalProcessControlFile not enter this code
    path...
    
    
    > @@ -2824,6 +2880,8 @@ pmdie(SIGNAL_ARGS)
    >
    >  			if (StartupPID != 0)
    >  				signal_child(StartupPID, SIGTERM);
    > +			if (BaseBackupPID != 0)
    > +				signal_child(BaseBackupPID, SIGTERM);
    >  			if (BgWriterPID != 0)
    >  				signal_child(BgWriterPID, SIGTERM);
    >  			if (WalReceiverPID != 0)
    > @@ -3062,6 +3120,23 @@ reaper(SIGNAL_ARGS)
    
    
    >  			continue;
    >  		}
    >
    > +		/*
    > +		 * Was it the base backup process?
    > +		 */
    > +		if (pid == BaseBackupPID)
    > +		{
    > +			BaseBackupPID = 0;
    > +			if (EXIT_STATUS_0(exitstatus))
    > +				;
    > +			else if (EXIT_STATUS_1(exitstatus))
    > +				ereport(FATAL,
    > +						(errmsg("base backup failed")));
    > +			else
    > +				HandleChildCrash(pid, exitstatus,
    > +								 _("base backup process"));
    > +			continue;
    > +		}
    > +
    
    What's the error handling for the case we shut down either because of
    SIGTERM above, or here? Does all the code just deal with that the next
    start? If not, what makes this safe?
    
    
    
    > +/*
    > + * base backup worker process (client) main function
    > + */
    > +void
    > +BaseBackupMain(void)
    > +{
    > +	WalReceiverConn *wrconn = NULL;
    > +	char	   *err;
    > +	TimeLineID	primaryTLI;
    > +	uint64		primary_sysid;
    > +
    > +	/* Load the libpq-specific functions */
    > +	load_file("libpqwalreceiver", false);
    > +	if (WalReceiverFunctions == NULL)
    > +		elog(ERROR, "libpqwalreceiver didn't initialize correctly");
    > +
    > +	/* Establish the connection to the primary */
    > +	wrconn = walrcv_connect(PrimaryConnInfo, false, cluster_name[0] ? cluster_name : "basebackup", &err);
    > +	if (!wrconn)
    > +		ereport(ERROR,
    > +				(errmsg("could not connect to the primary server: %s", err)));
    > +
    > +	/*
    > +	 * Get the remote sysid and stick it into the local control file, so that
    > +	 * the walreceiver is happy.  The control file will later be overwritten
    > +	 * by the base backup.
    > +	 */
    > +	primary_sysid = strtoull(walrcv_identify_system(wrconn, &primaryTLI), NULL, 10);
    > +	InitControlFile(primary_sysid);
    > +	WriteControlFile();
    > +
    > +	walrcv_base_backup(wrconn);
    > +
    > +	walrcv_disconnect(wrconn);
    > +
    > +	SyncDataDirectory(false, ERROR);
    > +
    > +	ereport(LOG,
    > +			(errmsg("base backup completed")));
    > +	proc_exit(0);
    > +}
    
    So there's no error handling here (as in a sigsetjmp)? Nor any signal
    handlers set up, despite
    +		case BaseBackupProcess:
    +			/* don't set signals, basebackup has its own agenda */
    +			BaseBackupMain();
    +			proc_exit(1);		/* should never return */
    +
    
    You did set up forwarding of things like SIGHUP - but afaict that's not
    correctly wired up?
    
    
    > diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
    > index e4fd1f9bb6..52819d504c 100644
    > --- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
    > +++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
    > @@ -17,20 +17,29 @@
    > +#include "pgtar.h"
    >  #include "pqexpbuffer.h"
    >  #include "replication/walreceiver.h"
    >  #include "utils/builtins.h"
    > +#include "utils/guc.h"
    >  #include "utils/memutils.h"
    >  #include "utils/pg_lsn.h"
    > +#include "utils/ps_status.h"
    >  #include "utils/tuplestore.h"
    >
    >  PG_MODULE_MAGIC;
    > @@ -61,6 +70,7 @@ static int	libpqrcv_server_version(WalReceiverConn *conn);
    >  static void libpqrcv_readtimelinehistoryfile(WalReceiverConn *conn,
    >  											 TimeLineID tli, char **filename,
    >  											 char **content, int *len);
    > +static void libpqrcv_base_backup(WalReceiverConn *conn);
    >  static bool libpqrcv_startstreaming(WalReceiverConn *conn,
    >  									const WalRcvStreamOptions *options);
    >  static void libpqrcv_endstreaming(WalReceiverConn *conn,
    > @@ -89,6 +99,7 @@ static WalReceiverFunctionsType PQWalReceiverFunctions = {
    >  	libpqrcv_identify_system,
    >  	libpqrcv_server_version,
    >  	libpqrcv_readtimelinehistoryfile,
    > +	libpqrcv_base_backup,
    >  	libpqrcv_startstreaming,
    >  	libpqrcv_endstreaming,
    >  	libpqrcv_receive,
    > @@ -358,6 +369,395 @@ libpqrcv_server_version(WalReceiverConn *conn)
    >  	return PQserverVersion(conn->streamConn);
    >  }
    >
    > +/*
    > + * XXX copied from pg_basebackup.c
    > + */
    > +
    > +unsigned long long totaldone;
    > +unsigned long long totalsize_kb;
    > +int tablespacenum;
    > +int tablespacecount;
    > +
    > +static void
    > +base_backup_report_progress(void)
    > +{
    
    Putting all of this into libpqwalreceiver.c seems like quite a
    significant modularity violation. The header says:
    
     * libpqwalreceiver.c
     *
     * This file contains the libpq-specific parts of walreceiver. It's
     * loaded as a dynamic module to avoid linking the main server binary with
     * libpq.
    
    which really doesn't agree with all of the new stuff you're putting
    here.
    
    > --- a/src/backend/storage/file/fd.c
    > +++ b/src/backend/storage/file/fd.c
    > @@ -3154,21 +3154,14 @@ looks_like_temp_rel_name(const char *name)
    >   * Other symlinks are presumed to point at files we're not responsible
    >   * for fsyncing, and might not have privileges to write at all.
    >   *
    > - * Errors are logged but not considered fatal; that's because this is used
    > - * only during database startup, to deal with the possibility that there are
    > - * issued-but-unsynced writes pending against the data directory.  We want to
    > - * ensure that such writes reach disk before anything that's done in the new
    > - * run.  However, aborting on error would result in failure to start for
    > - * harmless cases such as read-only files in the data directory, and that's
    > - * not good either.
    > - *
    > - * Note that if we previously crashed due to a PANIC on fsync(), we'll be
    > - * rewriting all changes again during recovery.
    > + * If pre_sync is true, issue flush requests to the kernel before starting the
    > + * actual fsync calls.  This can be skipped if the caller has already done it
    > + * itself.
    >   *
    
    Huh, what happened with the previous comments here?
    
    
    > diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c
    > index f9cfeae264..c9edeb54d3 100644
    > --- a/src/bin/pg_resetwal/pg_resetwal.c
    > +++ b/src/bin/pg_resetwal/pg_resetwal.c
    > @@ -76,7 +76,7 @@ static int	WalSegSz;
    >  static int	set_wal_segsize;
    >
    >  static void CheckDataVersion(void);
    > -static bool ReadControlFile(void);
    > +static bool read_controlfile(void);
    >  static void GuessControlValues(void);
    >  static void PrintControlValues(bool guessed);
    >  static void PrintNewControlValues(void);
    > @@ -393,7 +393,7 @@ main(int argc, char *argv[])
    >  	/*
    >  	 * Attempt to read the existing pg_control file
    >  	 */
    > -	if (!ReadControlFile())
    > +	if (!read_controlfile())
    >  		GuessControlValues();
    >
    >  	/*
    > @@ -578,7 +578,7 @@ CheckDataVersion(void)
    >   * to the current format.  (Currently we don't do anything of the sort.)
    >   */
    >  static bool
    > -ReadControlFile(void)
    > +read_controlfile(void)
    >  {
    >  	int			fd;
    >  	int			len;
    
    Huh?
    
    
    Greetings,
    
    Andres Freund
    
    
    
    
  34. Re: base backup client as auxiliary backend process

    Michael Paquier <michael@paquier.xyz> — 2020-02-04T05:28:57Z

    On Mon, Feb 03, 2020 at 01:37:25AM -0800, Andres Freund wrote:
    > On 2020-01-23 15:49:37 -0500, Robert Haas wrote:
    >> I assume that's probably discussed on the thread that is linked here,
    >> but you shouldn't have to dig through the discussion thread to figure
    >> out what the benefits of a change like this are.
    > 
    > which I fully agree with.
    > 
    > It's not at all clear to me that the potential downsides of this have
    > been fully thought through. And even if they have, they've not been
    > documented.
    
    There is this, and please let me add a reference to another complaint
    I had about this commit:
    https://www.postgresql.org/message-id/20200122055510.GH174860@paquier.xyz
    --
    Michael
    
  35. Re: base backup client as auxiliary backend process

    Masahiko Sawada <masahiko.sawada@2ndquadrant.com> — 2020-02-05T04:52:05Z

    On Mon, 3 Feb 2020 at 20:06, Andres Freund <andres@anarazel.de> wrote:
    >
    > Hi,
    >
    > On 2020-01-11 10:52:30 +0100, Peter Eisentraut wrote:
    > > On 2020-01-10 04:32, Masahiko Sawada wrote:
    > > > I agreed that these patches are useful on its own and 0001 patch and
    > >
    > > committed 0001
    >
    > over on -committers Robert complained:
    >
    > On 2020-01-23 15:49:37 -0500, Robert Haas wrote:
    > > On Tue, Jan 14, 2020 at 8:57 AM Peter Eisentraut <peter@eisentraut.org> wrote:
    > > > walreceiver uses a temporary replication slot by default
    > > >
    > > > If no permanent replication slot is configured using
    > > > primary_slot_name, the walreceiver now creates and uses a temporary
    > > > replication slot.  A new setting wal_receiver_create_temp_slot can be
    > > > used to disable this behavior, for example, if the remote instance is
    > > > out of replication slots.
    > > >
    > > > Reviewed-by: Masahiko Sawada <masahiko.sawada@2ndquadrant.com>
    > > > Discussion: https://www.postgresql.org/message-id/CA%2Bfd4k4dM0iEPLxyVyme2RAFsn8SUgrNtBJOu81YqTY4V%2BnqZA%40mail.gmail.com
    > >
    > > Neither the commit message for this patch nor any of the comments in
    > > the patch seem to explain why this is a desirable change.
    > >
    > > I assume that's probably discussed on the thread that is linked here,
    > > but you shouldn't have to dig through the discussion thread to figure
    > > out what the benefits of a change like this are.
    >
    > which I fully agree with.
    >
    >
    > It's not at all clear to me that the potential downsides of this have
    > been fully thought through. And even if they have, they've not been
    > documented.
    >
    > Previously if a standby without a slot was slow receiving WAL,
    > e.g. because the network bandwidth was insufficient, it'd at some point
    > just fail because the required WAL is removed. But with this patch that
    > won't happen - instead the primary will just run out of space. At the
    > very least this would need to add documentation of this caveat to a few
    > places.
    
    +1 to add downsides to the documentation.
    
    It might not normally happen but with this parameter we will need to
    have enough setting of max_replication_slots because the standby will
    fail to start after failover due to full of slots.
    
    WAL required by the standby could be removed on the primary due to the
    standby delaying much, for example when the standby stopped for a long
    time or when the standby is running but delayed for some reason. This
    feature prevents WAL from removal for the latter case. That is, we can
    ensure that required WAL is not removed during replication running.
    For the former case we can use a permanent replication slot. Although
    there is a risk of running out of space but I personally think this
    behavior is better for most cases.
    
    Regards,
    
    -- 
    Masahiko Sawada            http://www.2ndQuadrant.com/
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
    
    
    
    
  36. Re: base backup client as auxiliary backend process

    Peter Eisentraut <peter.eisentraut@2ndquadrant.com> — 2020-02-17T17:42:52Z

    On 2020-02-03 13:47, Andres Freund wrote:
    > Comment:
    > 
    > - It'd be good to split out the feature independent refactorings, like
    >    the introduction of InitControlFile(), into their own commit. Right
    >    now it's hard to separate out what should just should be moved code,
    >    and what should be behavioural changes. Especially when there's stuff
    >    like just reindenting comments as part of the patch.
    
    Agreed.  Here are three refactoring patches extracted that seem useful 
    on their own.
    
    -- 
    Peter Eisentraut              http://www.2ndQuadrant.com/
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
    
  37. Re: base backup client as auxiliary backend process

    Peter Eisentraut <peter.eisentraut@2ndquadrant.com> — 2020-02-22T15:12:27Z

    On 2020-02-17 18:42, Peter Eisentraut wrote:
    > On 2020-02-03 13:47, Andres Freund wrote:
    >> Comment:
    >>
    >> - It'd be good to split out the feature independent refactorings, like
    >>     the introduction of InitControlFile(), into their own commit. Right
    >>     now it's hard to separate out what should just should be moved code,
    >>     and what should be behavioural changes. Especially when there's stuff
    >>     like just reindenting comments as part of the patch.
    > 
    > Agreed.  Here are three refactoring patches extracted that seem useful
    > on their own.
    
    These have been committed.
    
    -- 
    Peter Eisentraut              http://www.2ndQuadrant.com/
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
    
    
    
    
  38. Re: base backup client as auxiliary backend process

    Peter Eisentraut <peter.eisentraut@2ndquadrant.com> — 2020-02-28T09:02:40Z

    I have set this patch to "returned with feedback" in the upcoming commit 
    fest, because I will not be able to finish it.
    
    Unsurprisingly, the sequencing of startup actions in postmaster.c is 
    extremely tricky and needs more thinking.  All the rest worked pretty 
    well, I thought.
    
    -- 
    Peter Eisentraut              http://www.2ndQuadrant.com/
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
    
    
    
    
  39. Re: base backup client as auxiliary backend process

    Alvaro Herrera <alvherre@2ndquadrant.com> — 2020-03-28T13:49:02Z

    On 2020-Jan-14, Peter Eisentraut wrote:
    
    > On 2020-01-14 07:32, Masahiko Sawada wrote:
    > > -     <entry>Replication slot name used by this WAL receiver</entry>
    > > +     <entry>
    > > +      Replication slot name used by this WAL receiver.  This is only set if a
    > > +      permanent replication slot is set using <xref
    > > +      linkend="guc-primary-slot-name"/>.  Otherwise, the WAL receiver may use
    > > +      a temporary replication slot (determined by <xref
    > > +      linkend="guc-wal-receiver-create-temp-slot"/>), but these are not shown
    > > +      here.
    > > +     </entry>
    > > 
    > > Now that the slot name is shown even if it's a temp slot the above
    > > documentation changes needs to be changed. Other changes look good to
    > > me.
    > 
    > committed, thanks
    
    Sergei has just proposed a change in semantics: if primary_slot_name is
    specified as well as wal_receiver_create_temp_slot, then a temp slot is
    used and it uses the specified name, instead of ignoring the temp-slot
    option as currently.
    
    Patch is at https://postgr.es/m/3109511585392143@myt6-887fb48a9c29.qloud-c.yandex.net
    
    (To clarify: the current semantics if both options are set is that an
    existing permanent slot is sought with the given name, and an error is
    raised if it doesn't exist.)
    
    What do you think?  Preliminarly I think the proposed semantics are
    saner.
    
    -- 
    Álvaro Herrera                https://www.2ndQuadrant.com/
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services