pgsql: Don't use "cp -i" in the example WAL archive_command.

Started by Tom Laneover 14 years ago15 messages
#1Tom Lane
tgl@sss.pgh.pa.us

Don't use "cp -i" in the example WAL archive_command.

This is a dangerous example to provide because on machines with GNU cp,
it will silently do the wrong thing and risk archive corruption. Worse,
during the 9.0 cycle somebody "improved" the discussion by removing the
warning that used to be there about that, and instead leaving the
impression that the command would work as desired on most Unixen.
It doesn't. Try to rectify the damage by providing an example that is safe
most everywhere, and then noting that you can try cp -i if you want but
you'd better test that.

In back-patching this to all supported branches, I also added an example
command for Windows, which wasn't provided before 9.0.

Branch
------
REL8_3_STABLE

Details
-------
http://git.postgresql.org/pg/commitdiff/23843d242f00e6597af91d4f4d08b655b2b362ba

Modified Files
--------------
doc/src/sgml/backup.sgml | 25 ++++++++++++++-----------
1 files changed, 14 insertions(+), 11 deletions(-)

#2Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#1)
Re: [COMMITTERS] pgsql: Don't use "cp -i" in the example WAL archive_command.

Wow, this is the first I am hearing GNU cp -i can return zero exit if it
doesn't do the copy. I tested this on Ubuntu 10.04 using cp 7.4 and
got:

$ touch x y
$ cp -i x y; echo $?
cp: overwrite `y'? n
0

I see the same on my anchent BSD/OS machine too:

$ touch x y
$ cp -i x y; echo $?
overwrite y? n
0

Were we expecting an error if the file already existed? Assuming that,
we should assume the file will always exist so basically archiving will
never progress. Is this what we want? I just wasn't aware we were
expecting an already-existing this to be an error --- I thought we just
didn't want to overwrite it.

---------------------------------------------------------------------------

Tom Lane wrote:

Don't use "cp -i" in the example WAL archive_command.

This is a dangerous example to provide because on machines with GNU cp,
it will silently do the wrong thing and risk archive corruption. Worse,
during the 9.0 cycle somebody "improved" the discussion by removing the
warning that used to be there about that, and instead leaving the
impression that the command would work as desired on most Unixen.
It doesn't. Try to rectify the damage by providing an example that is safe
most everywhere, and then noting that you can try cp -i if you want but
you'd better test that.

In back-patching this to all supported branches, I also added an example
command for Windows, which wasn't provided before 9.0.

Branch
------
REL8_3_STABLE

Details
-------
http://git.postgresql.org/pg/commitdiff/23843d242f00e6597af91d4f4d08b655b2b362ba

Modified Files
--------------
doc/src/sgml/backup.sgml | 25 ++++++++++++++-----------
1 files changed, 14 insertions(+), 11 deletions(-)

--
Sent via pgsql-committers mailing list (pgsql-committers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-committers

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ It's impossible for everything to be true. +

#3Bruce Momjian
bruce@momjian.us
In reply to: Bruce Momjian (#2)
Re: Re: [COMMITTERS] pgsql: Don't use "cp -i" in the example WAL archive_command.

Bruce Momjian wrote:

Wow, this is the first I am hearing GNU cp -i can return zero exit if it
doesn't do the copy. I tested this on Ubuntu 10.04 using cp 7.4 and
got:

$ touch x y
$ cp -i x y; echo $?
cp: overwrite `y'? n
0

I see the same on my anchent BSD/OS machine too:

$ touch x y
$ cp -i x y; echo $?
overwrite y? n
0

Were we expecting an error if the file already existed? Assuming that,
we should assume the file will always exist so basically archiving will
never progress. Is this what we want? I just wasn't aware we were
expecting an already-existing this to be an error --- I thought we just
didn't want to overwrite it.

I tested on FreeBSD 7.4 and saw a 1 error return:

$ touch x y
$ cp -i x y; echo $?
overwrite y? (y/n [n]) n
not overwritten
1

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ It's impossible for everything to be true. +

#4Thom Brown
thom@linux.com
In reply to: Bruce Momjian (#3)
Re: Re: [COMMITTERS] pgsql: Don't use "cp -i" in the example WAL archive_command.

On 18 June 2011 04:13, Bruce Momjian <bruce@momjian.us> wrote:

Bruce Momjian wrote:

Wow, this is the first I am hearing GNU cp -i can return zero exit if it
doesn't do the copy.  I tested this on Ubuntu 10.04 using cp 7.4 and
got:

      $ touch x y
      $ cp -i x y; echo $?
      cp: overwrite `y'? n
      0

I see the same on my anchent BSD/OS machine too:

      $ touch x y
      $ cp -i x y; echo $?
      overwrite y? n
      0

Were we expecting an error if the file already existed?  Assuming that,
we should assume the file will always exist so basically archiving will
never progress.  Is this what we want?  I just wasn't aware we were
expecting an already-existing this to be an error --- I thought we just
didn't want to overwrite it.

I tested on FreeBSD 7.4 and saw a 1 error return:

       $ touch x y
       $ cp -i x y; echo $?
       overwrite y? (y/n [n]) n
       not overwritten
       1

And on a Mac (so through Darwin 10.7.0 a BSD version too):

toucan:tmp thom$ touch x y
toucan:tmp thom$ cp -i x y; echo $?
overwrite y? (y/n [n]) n
not overwritten
1

Thom

#5Dickson S. Guedes
listas@guedesoft.net
In reply to: Thom Brown (#4)
Re: Re: [COMMITTERS] pgsql: Don't use "cp -i" in the example WAL archive_command.

2011/6/18 Thom Brown <thom@linux.com>:
[.. cut ..]

And on a Mac (so through Darwin 10.7.0 a BSD version too):

toucan:tmp thom$ touch x y
toucan:tmp thom$ cp -i x y; echo $?
overwrite y? (y/n [n]) n
not overwritten
1

On AIX 5.3

bash-3.00$ touch x y
bash-3.00$ cp -i x y; echo $?
overwrite y? n
0

--
Dickson S. Guedes
mail/xmpp: guedes@guedesoft.net - skype: guediz
http://guedesoft.net - http://www.postgresql.org.br

#6Tom Lane
tgl@sss.pgh.pa.us
In reply to: Thom Brown (#4)
Re: Re: [COMMITTERS] pgsql: Don't use "cp -i" in the example WAL archive_command.

Thom Brown <thom@linux.com> writes:

On 18 June 2011 04:13, Bruce Momjian <bruce@momjian.us> wrote:

I tested on FreeBSD 7.4 and saw a 1 error return:

And on a Mac (so through Darwin 10.7.0 a BSD version too):

Yeah, see yesterday's discussion on pgsql-admin. I think the behavior
with the error return may be a BSD-ism. In any case, GNU cp does *not*
do what we want, and that accounts for a sufficiently large fraction of
machines in the field that I think it's just unsafe to suggest using
"cp -i" so prominently. There are too many people who'll just copy and
paste the first example provided, especially if the warning to test it
is buried several paragraphs later.

regards, tom lane

#7Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#6)
Re: Re: [COMMITTERS] pgsql: Don't use "cp -i" in the example WAL archive_command.

Tom Lane wrote:

Thom Brown <thom@linux.com> writes:

On 18 June 2011 04:13, Bruce Momjian <bruce@momjian.us> wrote:

I tested on FreeBSD 7.4 and saw a 1 error return:

And on a Mac (so through Darwin 10.7.0 a BSD version too):

Yeah, see yesterday's discussion on pgsql-admin. I think the behavior
with the error return may be a BSD-ism. In any case, GNU cp does *not*
do what we want, and that accounts for a sufficiently large fraction of
machines in the field that I think it's just unsafe to suggest using
"cp -i" so prominently. There are too many people who'll just copy and
paste the first example provided, especially if the warning to test it
is buried several paragraphs later.

Agreed. Even if we could decide whether we want an existing file to
cause cp to fail or succeed, the bigger problem is that 'test ! -f $FILE
&& cp' and 'cp -i' often don't do the same thing, to the point where it
doesn't even seem worth mentioning the idea of using 'cp -i' at all.

I frankly don't think most users are competent enough to be able to test
their cp -i command, end even if they are, that script might migrate to
a machine that handles cp -i differently.

I think we should just document the test ! -f version and be done with
it, and maybe mention cp -i as non-portable.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ It's impossible for everything to be true. +

#8Andrew Dunstan
andrew@dunslane.net
In reply to: Tom Lane (#6)
Re: Re: [COMMITTERS] pgsql: Don't use "cp -i" in the example WAL archive_command.

On 06/18/2011 09:19 AM, Tom Lane wrote:

Thom Brown<thom@linux.com> writes:

On 18 June 2011 04:13, Bruce Momjian<bruce@momjian.us> wrote:

I tested on FreeBSD 7.4 and saw a 1 error return:

And on a Mac (so through Darwin 10.7.0 a BSD version too):

Yeah, see yesterday's discussion on pgsql-admin. I think the behavior
with the error return may be a BSD-ism. In any case, GNU cp does *not*
do what we want, and that accounts for a sufficiently large fraction of
machines in the field that I think it's just unsafe to suggest using
"cp -i" so prominently. There are too many people who'll just copy and
paste the first example provided, especially if the warning to test it
is buried several paragraphs later.

Yeah, I'm glad to see this go anyway. I always thought the example was
too cute by half. Using an explicit test is much nicer and more obvious.

cheers

andrew

#9Bruce Momjian
bruce@momjian.us
In reply to: Andrew Dunstan (#8)
Re: Re: [COMMITTERS] pgsql: Don't use "cp -i" in the example WAL archive_command.

Andrew Dunstan wrote:

On 06/18/2011 09:19 AM, Tom Lane wrote:

Thom Brown<thom@linux.com> writes:

On 18 June 2011 04:13, Bruce Momjian<bruce@momjian.us> wrote:

I tested on FreeBSD 7.4 and saw a 1 error return:

And on a Mac (so through Darwin 10.7.0 a BSD version too):

Yeah, see yesterday's discussion on pgsql-admin. I think the behavior
with the error return may be a BSD-ism. In any case, GNU cp does *not*
do what we want, and that accounts for a sufficiently large fraction of
machines in the field that I think it's just unsafe to suggest using
"cp -i" so prominently. There are too many people who'll just copy and
paste the first example provided, especially if the warning to test it
is buried several paragraphs later.

Yeah, I'm glad to see this go anyway. I always thought the example was
too cute by half. Using an explicit test is much nicer and more obvious.

I think the only real risk to the 'test' example is the possibility that
they will mistype the pathname in one of the two places it is required,
or forget to change both of them at the same time.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ It's impossible for everything to be true. +

#10Bruce Momjian
bruce@momjian.us
In reply to: Bruce Momjian (#9)
Re: Re: [COMMITTERS] pgsql: Don't use "cp -i" in the example WAL archive_command.

Bruce Momjian wrote:

Andrew Dunstan wrote:

On 06/18/2011 09:19 AM, Tom Lane wrote:

Thom Brown<thom@linux.com> writes:

On 18 June 2011 04:13, Bruce Momjian<bruce@momjian.us> wrote:

I tested on FreeBSD 7.4 and saw a 1 error return:

And on a Mac (so through Darwin 10.7.0 a BSD version too):

Yeah, see yesterday's discussion on pgsql-admin. I think the behavior
with the error return may be a BSD-ism. In any case, GNU cp does *not*
do what we want, and that accounts for a sufficiently large fraction of
machines in the field that I think it's just unsafe to suggest using
"cp -i" so prominently. There are too many people who'll just copy and
paste the first example provided, especially if the warning to test it
is buried several paragraphs later.

Yeah, I'm glad to see this go anyway. I always thought the example was
too cute by half. Using an explicit test is much nicer and more obvious.

I think the only real risk to the 'test' example is the possibility that
they will mistype the pathname in one of the two places it is required,
or forget to change both of them at the same time.

Perhaps we should recommend:

cd /path && test ! -f %f && cp %p %f

That is shorter and removes the duplicate problem.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ It's impossible for everything to be true. +

#11Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#10)
Re: Re: [COMMITTERS] pgsql: Don't use "cp -i" in the example WAL archive_command.

Bruce Momjian <bruce@momjian.us> writes:

Perhaps we should recommend:
cd /path && test ! -f %f && cp %p %f
That is shorter and removes the duplicate problem.

Um ... %p is relative to the database directory.

regards, tom lane

#12Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#11)
Re: Re: [COMMITTERS] pgsql: Don't use "cp -i" in the example WAL archive_command.

Tom Lane wrote:

Bruce Momjian <bruce@momjian.us> writes:

Perhaps we should recommend:
cd /path && test ! -f %f && cp %p %f
That is shorter and removes the duplicate problem.

Um ... %p is relative to the database directory.

Oh, I see now. I had thought it was an absolute path, but good thing it
isn't because of the possible need for quoting characters in the path
name.

The only other idea I have is:

NEW=/path && test ! -f $NEW/%f && cp %p $NEW/%f

but that is not going to work with csh-based shells, while I think the
original is fine.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ It's impossible for everything to be true. +

#13Andrew Dunstan
andrew@dunslane.net
In reply to: Bruce Momjian (#12)
Re: Re: [COMMITTERS] pgsql: Don't use "cp -i" in the example WAL archive_command.

On 06/19/2011 08:00 AM, Bruce Momjian wrote:

Tom Lane wrote:

Bruce Momjian<bruce@momjian.us> writes:

Perhaps we should recommend:
cd /path&& test ! -f %f&& cp %p %f
That is shorter and removes the duplicate problem.

Um ... %p is relative to the database directory.

Oh, I see now. I had thought it was an absolute path, but good thing it
isn't because of the possible need for quoting characters in the path
name.

The only other idea I have is:

NEW=/path&& test ! -f $NEW/%f&& cp %p $NEW/%f

but that is not going to work with csh-based shells, while I think the
original is fine.

Isn't this invoked via system()? AFAIK that should always invoke a
Bourne shell or equivalent on Unix. But in any case, I think you're
trying to solve a problem that doesn't really exist.

cheers

andrew

#14Fujii Masao
masao.fujii@gmail.com
In reply to: Tom Lane (#6)
Re: Re: [COMMITTERS] pgsql: Don't use "cp -i" in the example WAL archive_command.

On Sat, Jun 18, 2011 at 10:19 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Thom Brown <thom@linux.com> writes:

On 18 June 2011 04:13, Bruce Momjian <bruce@momjian.us> wrote:

I tested on FreeBSD 7.4 and saw a 1 error return:

And on a Mac (so through Darwin 10.7.0 a BSD version too):

Yeah, see yesterday's discussion on pgsql-admin.  I think the behavior
with the error return may be a BSD-ism.  In any case, GNU cp does *not*
do what we want, and that accounts for a sufficiently large fraction of
machines in the field that I think it's just unsafe to suggest using
"cp -i" so prominently.  There are too many people who'll just copy and
paste the first example provided, especially if the warning to test it
is buried several paragraphs later.

Anyway, you seem to have forgotten to fix the example of archive_command
in "24.3.5.1. Standalone Hot Backups".

archive_command = 'test ! -f /var/lib/pgsql/backup_in_progress ||
cp -i %p /var/lib/pgsql/archive/%f < /dev/null'

Regards,

--
Fujii Masao
NIPPON TELEGRAPH AND TELEPHONE CORPORATION
NTT Open Source Software Center

#15Tom Lane
tgl@sss.pgh.pa.us
In reply to: Fujii Masao (#14)
Re: Re: [COMMITTERS] pgsql: Don't use "cp -i" in the example WAL archive_command.

Fujii Masao <masao.fujii@gmail.com> writes:

Anyway, you seem to have forgotten to fix the example of archive_command
in "24.3.5.1. Standalone Hot Backups".

archive_command = 'test ! -f /var/lib/pgsql/backup_in_progress ||
cp -i %p /var/lib/pgsql/archive/%f < /dev/null'

You're right, I didn't see that one. Fixed, thanks.

regards, tom lane