Обсуждение: base backup client as auxiliary backend process

Поиск
Список
Период
Сортировка

base backup client as auxiliary backend process

От
Peter Eisentraut
Дата:
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

Вложения

Re: base backup client as auxiliary backend process

От
Thomas Munro
Дата:
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



Re: base backup client as auxiliary backend process

От
Sergei Kornilov
Дата:
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
whichwe can not run
 
- basebackup silently overwrite configs (pg_hba.conf, postgresql.conf, postgresql.auto.conf) in $PGDATA. This is ok for
pg_basebackupbut 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



Re: base backup client as auxiliary backend process

От
Euler Taveira
Дата:
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



Re: base backup client as auxiliary backend process

От
Robert Haas
Дата:
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



Re: base backup client as auxiliary backend process

От
Tom Lane
Дата:
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



Re: base backup client as auxiliary backend process

От
Robert Haas
Дата:
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



Re: base backup client as auxiliary backend process

От
Tom Lane
Дата:
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



Re: base backup client as auxiliary backend process

От
Robert Haas
Дата:
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



Re: base backup client as auxiliary backend process

От
Peter Eisentraut
Дата:
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



Re: base backup client as auxiliary backend process

От
Tom Lane
Дата:
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



Re: base backup client as auxiliary backend process

От
Kyotaro Horiguchi
Дата:
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

Re: base backup client as auxiliary backend process

От
Peter Eisentraut
Дата:
> 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

Вложения

Re: base backup client as auxiliary backend process

От
Alvaro Herrera
Дата:
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



Re: base backup client as auxiliary backend process

От
Kyotaro Horiguchi
Дата:
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



Re: base backup client as auxiliary backend process

От
Michael Paquier
Дата:
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

Вложения

Re: base backup client as auxiliary backend process

От
Peter Eisentraut
Дата:
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

Вложения

Re: base backup client as auxiliary backend process

От
Michael Paquier
Дата:
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

Вложения

Re: base backup client as auxiliary backend process

От
Peter Eisentraut
Дата:
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

Вложения

Re: base backup client as auxiliary backend process

От
Sergei Kornilov
Дата:
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
anotherfuture patch.
 

regards, Sergei



Re: base backup client as auxiliary backend process

От
Peter Eisentraut
Дата:
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

Вложения

Re: base backup client as auxiliary backend process

От
Michael Paquier
Дата:
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

Вложения

Re: base backup client as auxiliary backend process

От
Alexandra Wang
Дата:
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

Re: base backup client as auxiliary backend process

От
Masahiko Sawada
Дата:
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



Re: base backup client as auxiliary backend process

От
Peter Eisentraut
Дата:
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

Вложения

Re: base backup client as auxiliary backend process

От
Masahiko Sawada
Дата:
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



Re: base backup client as auxiliary backend process

От
Peter Eisentraut
Дата:
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



Re: base backup client as auxiliary backend process

От
Masahiko Sawada
Дата:
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



Re: base backup client as auxiliary backend process

От
Peter Eisentraut
Дата:
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

Вложения

Re: base backup client as auxiliary backend process

От
Peter Eisentraut
Дата:
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



Re: base backup client as auxiliary backend process

От
Masahiko Sawada
Дата:
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



Re: base backup client as auxiliary backend process

От
Andres Freund
Дата:
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



Re: base backup client as auxiliary backend process

От
Andres Freund
Дата:
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



Re: base backup client as auxiliary backend process

От
Michael Paquier
Дата:
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

Вложения

Re: base backup client as auxiliary backend process

От
Masahiko Sawada
Дата:
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



Re: base backup client as auxiliary backend process

От
Peter Eisentraut
Дата:
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

Вложения

Re: base backup client as auxiliary backend process

От
Peter Eisentraut
Дата:
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



Re: base backup client as auxiliary backend process

От
Peter Eisentraut
Дата:
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



Re: base backup client as auxiliary backend process

От
Alvaro Herrera
Дата:
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