Re: [HACKERS] Bug with pg_basebackup and 'shared' tablespace

2017-09-19 Thread Pierre Ducroquet
On Tuesday, September 19, 2017 12:52:37 PM CEST you wrote:
> On Thu, Sep 14, 2017 at 2:17 AM, Pierre Ducroquet  
wrote:
> > All my apologies for the schockingly long time with no answer on this
> > topic.
> No problem. That's the concept called life I suppose.
> 
> > I will do my best to help review some patches in the current CF.
> 
> Thanks for the potential help!
> 
> > Attached to this email is the new version of the patch, checked against
> > HEAD and REL_10_STABLE, with the small change required by Michael (affect
> > true/ false to the boolean instead of 1/0) applied.
> 
> Thanks for the new version.
> 
> So I have been pondering about this patch, and allowing multiple
> versions of Postgres to run in the same tablespace is mainly here for
> upgrade purposes, so I don't think that we should encourage such
> practices for performance reasons. There is as well
> --tablespace-mapping which is here to cover a similar need and we know
> that this solution works, at least people have spent time to make sure
> it does.
> 
> Another problem that I have with this patch is that on HEAD,
> permission checks are done before receiving any data. I think that
> this is really saner to do any checks like that first, so as you can
> know if the tablespace is available for write access before writing
> any data to it. With this patch, you may finish by writing a bunch of
> data to a tablespace path, but then fail on another tablespace because
> of permission issues so the backup becomes useless after transferring
> and writing potentially hundreds of gigabytes. This is no fun to
> detect that potentially too late, and can impact the responsiveness of
> instances to get backups and restore from them.
> 
> All in all, this patch gets a -1 from me in its current shape. If
> Horiguchi-san or yourself want to process further with this patch, of
> course feel free to do so, but I don't feel that we are actually
> trying to solve a new problem here. I am switching the patch to
> "waiting on author".

Hi

The point of this patch has never been to 'promote' sharing tablespaces 
between PostgreSQL versions. This is not a documented feature, and it would be 
imho a bad idea to promote it because of bugs like this one.
But that bug is a problem for people who are migrating between postgresql 
releases one database at a time on the same server (maybe not a best practice, 
but a real use case nevertheless). That's how I met this bug, and that's why I 
wanted to patch it. I know there is a workaround, but to me it seems counter-
intuitive that with no warning I can create a postgresql cluster that can not 
be restored without additional pg_basebackup settings.
If it is indeed forbidden to share a tablespace between postgresql releases, 
why don't we enforce it ? Or at least show a warning when CREATE TABLESPACE 
encounter a non-empty folder ?

Regarding the permission check, I don't really see how this is a real problem 
with the patch. I have to check on master, but it seems to me that the 
permission check can still be done before starting writing data on disc. We 
could just delay the 'empty' folder check, and keep checking the folder 
permissions.

And I will do the pgindent run, thanks for the nitpick :)


 Pierre



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


Re: [HACKERS] Small patch for pg_basebackup argument parsing

2017-09-18 Thread Pierre Ducroquet
On Monday, September 18, 2017 5:13:38 PM CEST Tom Lane wrote:
> Ryan Murphy  writes:
> > Looked thru the diffs and it looks fine to me.
> > Changing a lot of a integer/long arguments that were being read directly
> > via atoi / atol to be read as strings first, to give better error
> > handling.
> > 
> > This looks good to go to me.  Reviewing this as "Ready for Committer".
> > Thanks for the patch, Pierre!
> 
> I took a quick look through this and had a few thoughts:

I agree with your suggestions, I will try to produce a new patch before the 
end of the week.

> * If we're taking the trouble to sanity-check the input, I think we should
> also check for ERANGE (i.e., overflow).
> 
> * I concur with Robert that you might as well just test for "*endptr !=
> '\0'" instead of adding a strlen() call.
> 
> * Replicating fiddly little code sequences like this all over the place
> makes me itch.  There's too much chance to get it wrong, and even more
> risk of someone taking shortcuts.  It has to be not much more complicated
> than using atoi(), or we'll just be doing this exercise again in a few
> years.  So I'm thinking we need to introduce a convenience function,
> perhaps located in src/common/, or else src/fe_utils/.
> 
> * Changing variables from int to long int is likely to have unpleasant
> consequences on platforms where they're different; or at least, I don't
> particularly feel like auditing the patch to ensure that that's not a
> problem anywhere.  So I think we should not do that but just make the
> convenience function return int, with a suitable overflow test for that
> result size.  There's existing logic you can copy in
> src/backend/nodes/read.c:
> 
> errno = 0;
> val = strtol(token, &endptr, 10);
> if (endptr != token + length || errno == ERANGE
> #ifdef HAVE_LONG_INT_64
> /* if long > 32 bits, check for overflow of int4 */
> 
> || val != (long) ((int32) val)
> 
> #endif
> )
> ... bad integer ...
> 
> If there are places where we actually do want a long result, we
> could have two convenience functions, one returning int and one long.
> 
> 
> The exact form of the convenience function is up for grabs, but one
> way we could do it is
> 
> bool pg_int_convert(const char *str, int *value)
> 
> (where a true result indicates a valid integer value).
> Then typical usage would be like
> 
> if (!pg_int_convert(optarg, &compresslevel) ||
> compresslevel < 0 || compresslevel > 9)
> ... complain-and-exit ...
> 
> There might be something to be said for folding the range checks
> into the convenience function:
> 
> bool pg_int_convert(const char *str, int min, int max, int *value)
> 
> if (!pg_int_convert(optarg, 0, 9, &compresslevel))
> ... complain-and-exit ...
> 
> That way you could protect code like
> 
>   standby_message_timeout = atoi(optarg) * 1000;
> 
> fairly easily:
> 
> if (!pg_int_convert(optarg, 0, INT_MAX/1000,
> &standby_message_timeout))
> ... complain-and-exit ...
> standby_message_timeout *= 1000;
> 
>   regards, tom lane




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


Re: [HACKERS] Small patch for pg_basebackup argument parsing

2017-09-13 Thread Pierre Ducroquet
On Wednesday, September 13, 2017 2:06:50 AM CEST Daniel Gustafsson wrote:
> > On 05 Jul 2017, at 08:32, Michael Paquier 
> > wrote:> 
> > On Wed, Jul 5, 2017 at 2:57 PM, Ryan Murphy  wrote:
> >> I tried to apply your patch to test it (though reading Robert's last
> >> comment it seems we wish to have it adjusted before committing)... but
> >> in any case I was not able to apply your patch to the tip of the master
> >> branch (my git apply failed).  I'm setting this to Waiting On Author for
> >> a new patch, and I also agree with Robert that the test can be simpler
> >> and can go in the other order.  If you don't have time to make another
> >> patch, let me know, I may be able to make one.> 
> > git is unhappy even if forcibly applied with patch -p1. You should
> > check for whitespaces at the same time:
> > $ git diff --check
> > src/bin/pg_basebackup/pg_receivewal.c:483: indent with spaces.
> > +char   *strtol_endptr = NULL
> > And there are more than this one.
> 
> Like Michael said above, this patch no longer applies and have some
> whitespace issues.  The conflicts in applying are quite trivial though, so
> it should be easy to create a new version.  Do you plan to work on this
> during this Commitfest so we can move this patch forward?

Yes, my bad. Attached to this email is the new version, that now applies on 
master.

Sorry for the delay :(
>From 7efc1573c1bcc07c0eaa80912e6e035f2e0d203d Mon Sep 17 00:00:00 2001
From: Pierre Ducroquet 
Date: Wed, 13 Sep 2017 19:51:09 +0200
Subject: [PATCH] Port most calls of atoi(optarg) to strcol

atoi does not allow any kind of data check. If the input data is invalid,
the result will be silently truncated to the valid part of input, or just
0 if no digit was found at the beginning of input.
---
 src/bin/pg_basebackup/pg_basebackup.c  | 11 ++-
 src/bin/pg_basebackup/pg_receivewal.c  | 11 ++-
 src/bin/pg_basebackup/pg_recvlogical.c | 11 ++-
 src/bin/pg_ctl/pg_ctl.c|  9 -
 src/bin/pg_dump/pg_dump.c  | 12 +---
 src/bin/pg_dump/pg_restore.c   |  8 +++-
 src/bin/pg_upgrade/option.c|  5 +++--
 src/bin/pgbench/pgbench.c  | 33 +
 8 files changed, 62 insertions(+), 38 deletions(-)

diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
index 51509d150e..b51b62cc21 100644
--- a/src/bin/pg_basebackup/pg_basebackup.c
+++ b/src/bin/pg_basebackup/pg_basebackup.c
@@ -87,7 +87,7 @@ static IncludeWal includewal = STREAM_WAL;
 static bool fastcheckpoint = false;
 static bool writerecoveryconf = false;
 static bool do_sync = true;
-static int	standby_message_timeout = 10 * 1000;	/* 10 sec = default */
+static long int	standby_message_timeout = 10 * 1000;	/* 10 sec = default */
 static pg_time_t last_progress_report = 0;
 static int32 maxrate = 0;		/* no limit by default */
 static char *replication_slot = NULL;
@@ -2072,6 +2072,7 @@ BaseBackup(void)
 int
 main(int argc, char **argv)
 {
+	char *strtol_endptr = NULL;
 	static struct option long_options[] = {
 		{"help", no_argument, NULL, '?'},
 		{"version", no_argument, NULL, 'V'},
@@ -2212,8 +2213,8 @@ main(int argc, char **argv)
 #endif
 break;
 			case 'Z':
-compresslevel = atoi(optarg);
-if (compresslevel < 0 || compresslevel > 9)
+compresslevel = strtol(optarg, &strtol_endptr, 10);
+if (compresslevel < 0 || compresslevel > 9 || (strtol_endptr != optarg + strlen(optarg)))
 {
 	fprintf(stderr, _("%s: invalid compression level \"%s\"\n"),
 			progname, optarg);
@@ -2251,8 +2252,8 @@ main(int argc, char **argv)
 dbgetpassword = 1;
 break;
 			case 's':
-standby_message_timeout = atoi(optarg) * 1000;
-if (standby_message_timeout < 0)
+standby_message_timeout = strtol(optarg, &strtol_endptr, 10) * 1000;
+if ((standby_message_timeout < 0) || (strtol_endptr != optarg + strlen(optarg)))
 {
 	fprintf(stderr, _("%s: invalid status interval \"%s\"\n"),
 			progname, optarg);
diff --git a/src/bin/pg_basebackup/pg_receivewal.c b/src/bin/pg_basebackup/pg_receivewal.c
index 710a33ab4d..c1651961b5 100644
--- a/src/bin/pg_basebackup/pg_receivewal.c
+++ b/src/bin/pg_basebackup/pg_receivewal.c
@@ -494,6 +494,7 @@ main(int argc, char **argv)
 	int			c;
 	int			option_index;
 	char	   *db_name;
+	char	   *strtol_endptr = NULL;
 	uint32		hi, lo;
 
 	progname = get_progname(argv[0]);
@@ -529,7 +530,7 @@ main(int argc, char **argv)
 dbhost = pg_strdup(optarg);
 break;
 			case 'p':
-if (atoi(optarg) <= 0)
+if ((strtol(optarg, &strtol_endptr, 10) <= 0) || (strtol_endptr != optar

Re: [HACKERS] Bug with pg_basebackup and 'shared' tablespace

2017-09-13 Thread Pierre Ducroquet
On Wednesday, September 13, 2017 6:01:43 PM CEST you wrote:
> > On 15 May 2017, at 07:26, Michael Paquier 
> > wrote:> 
> > On Tue, May 2, 2017 at 2:28 AM, Pierre Ducroquet  
wrote:
> >> I will submit this patch in the current commit fest.
> > 
> > I have not spotted any flaws in the refactored logic.
> 
> This patch no longer applies, could you take a look at it and submit a new
> version rebased on top of HEAD?
> 
> cheers ./daniel

Hi

All my apologies for the schockingly long time with no answer on this topic.
Attached to this email is the new version of the patch, checked against HEAD 
and REL_10_STABLE, with the small change required by Michael (affect true/
false to the boolean instead of 1/0) applied.
I will do my best to help review some patches in the current CF.

 Pierre>From cfb47eb5db398c1a30c5f83c680b59b4aa3d196a Mon Sep 17 00:00:00 2001
From: Pierre Ducroquet 
Date: Wed, 13 Sep 2017 19:09:32 +0200
Subject: [PATCH] Allow a pg_basebackup when a tablespace is shared between two
 versions

When a tablespace folder is shared between two PostgreSQL versions,
pg_basebackup fails because its tablespace folder checking is stricter
than what is done in the server.
That behaviour makes it possible to create clusters that will then be
complicated to replicate whithout playing with symlinks.

This patch fixes this by delaying the tablespace folder verification.
The folder name is using the PG catalog version, that can not be
obtained from the server. It is a compile-time constant that is not
exposed publicly.
The fix is thus to simply delay the checking of folders and use the
folder name from the tablespace tarball.
---
 src/bin/pg_basebackup/pg_basebackup.c | 24 +++-
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
index dfb9b5ddcb..080468d846 100644
--- a/src/bin/pg_basebackup/pg_basebackup.c
+++ b/src/bin/pg_basebackup/pg_basebackup.c
@@ -1310,6 +1310,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
 	pgoff_t		current_len_left = 0;
 	int			current_padding = 0;
 	bool		basetablespace;
+	boolfirstfile = 1;
 	char	   *copybuf = NULL;
 	FILE	   *file = NULL;
 
@@ -1403,7 +1404,15 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
 	 * Directory
 	 */
 	filename[strlen(filename) - 1] = '\0';	/* Remove trailing slash */
-	if (mkdir(filename, S_IRWXU) != 0)
+	if (firstfile && !basetablespace)
+	{
+		/*
+		 * The first file in the tablespace is its main folder, whose name can not be guessed (PG_MAJORVER_CATVER)
+		 * So we must check here that this folder can be created or is empty.
+		 */
+		verify_dir_is_empty_or_create(filename, &made_tablespace_dirs, &found_tablespace_dirs);
+	}
+	else if (mkdir(filename, S_IRWXU) != 0)
 	{
 		/*
 		 * When streaming WAL, pg_wal (or pg_xlog for pre-9.6
@@ -1534,6 +1543,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
 continue;
 			}
 		}		/* continuing data in existing file */
+		firstfile = 0;	/* mark that we are done with the first file of the tarball */
 	}			/* loop over all data blocks */
 	progress_report(rownum, filename, true);
 
@@ -1848,18 +1858,6 @@ BaseBackup(void)
 	for (i = 0; i < PQntuples(res); i++)
 	{
 		totalsize += atol(PQgetvalue(res, i, 2));
-
-		/*
-		 * Verify tablespace directories are empty. Don't bother with the
-		 * first once since it can be relocated, and it will be checked before
-		 * we do anything anyway.
-		 */
-		if (format == 'p' && !PQgetisnull(res, i, 1))
-		{
-			char	   *path = (char *) get_tablespace_mapping(PQgetvalue(res, i, 1));
-
-			verify_dir_is_empty_or_create(path, &made_tablespace_dirs, &found_tablespace_dirs);
-		}
 	}
 
 	/*
-- 
2.14.1


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


Re: [HACKERS] Bug with pg_basebackup and 'shared' tablespace

2017-05-01 Thread Pierre Ducroquet

On Friday, April 7, 2017 3:12:58 AM CEST, Kyotaro HORIGUCHI wrote:

Hi, Pierre.

Maybe you're the winner:p

At Thu, 06 Apr 2017 12:34:09 +0200, Pierre Ducroquet 
 wrote in <1714428.BHRm6e8A2D@peanuts2>

On Thursday, April 6, 2017 2:00:55 PM CEST Kyotaro HORIGUCHI wrote: ...


That being said, it is a different matter if the behavior is
preferable. The discussion on the behavior is continued here.

https://www.postgresql.org/message-id/20170406.160844.120459562.horiguchi.kyot...@lab.ntt.co.jp

Right now, there is a conflict between pg_basebackup and the 
server since they 
do not allow the same behaviour. I can submit a patch either 
way, but I won't 
decide what is the right way to do it.
I know tricks will allow to work around that issue, I found 
them hopefully and 
I guess most people affected by this issue would be able to 
find and use them, 
but nevertheless being able to build a server that can no longer be base-

backuped does not seem right.


regards,


Hi

I didn't have much time to spend on that issue until today, and I found a 
way to solve it that seems acceptable to me.


The biggest drawback will be that if the backup is interrupted, previous 
tablespaces already copied will stay on disk, but since that issue could 
already happen, I don't think it's too much a drawback.
The patch simply delays the empty folder checking until we start reading 
the tablespace tarball. The first entry of the tarball being the 
PG_MAJOR_CATVER folder, that can not be found otherwise, there is no real 
alternative to that.


I will submit this patch in the current commit fest.


Regards

Pierre
From f3e6b078d4159c90237d966c56289cb59b54ede1 Mon Sep 17 00:00:00 2001
From: Pierre Ducroquet 
Date: Mon, 1 May 2017 11:38:52 +0200
Subject: [PATCH] Allow a pg_basebackup when a tablespace is shared between two
 versions

When a tablespace folder is shared between two PostgreSQL versions,
pg_basebackup fails because its tablespace folder checking is stricter
than what is done in the server.
That behaviour makes it possible to create clusters that will then be
complicated to replicate whithout playing with symlinks.

This patch fixes this by delaying the tablespace folder verification.
The folder name is using the PG catalog version, that can not be
obtained from the server. It is a compile-time constant that is not
exposed publicly.
The fix is thus to simply delay the checking of folders and use the
folder name from the tablespace tarball.
---
 src/bin/pg_basebackup/pg_basebackup.c | 24 +++-
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
index e2a2ebb30f..2e687a2880 100644
--- a/src/bin/pg_basebackup/pg_basebackup.c
+++ b/src/bin/pg_basebackup/pg_basebackup.c
@@ -1306,6 +1306,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
 	pgoff_t		current_len_left = 0;
 	int			current_padding = 0;
 	bool		basetablespace;
+	bool		firstfile = 1;
 	char	   *copybuf = NULL;
 	FILE	   *file = NULL;
 
@@ -1399,7 +1400,15 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
 	 * Directory
 	 */
 	filename[strlen(filename) - 1] = '\0';		/* Remove trailing slash */
-	if (mkdir(filename, S_IRWXU) != 0)
+	if (firstfile && !basetablespace)
+	{
+		/*
+		 * The first file in the tablespace is its main folder, whose name can not be guessed (PG_MAJORVER_CATVER)
+		 * So we must check here that this folder can be created or is empty.
+		 */
+		verify_dir_is_empty_or_create(filename, &made_tablespace_dirs, &found_tablespace_dirs);
+	}
+	else if (mkdir(filename, S_IRWXU) != 0)
 	{
 		/*
 		 * When streaming WAL, pg_wal (or pg_xlog for pre-9.6
@@ -1530,6 +1539,7 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
 continue;
 			}
 		}		/* continuing data in existing file */
+		firstfile = 0;			/* mark that we are done with the first file of the tarball */
 	}			/* loop over all data blocks */
 	progress_report(rownum, filename, true);
 
@@ -1844,18 +1854,6 @@ BaseBackup(void)
 	for (i = 0; i < PQntuples(res); i++)
 	{
 		totalsize += atol(PQgetvalue(res, i, 2));
-
-		/*
-		 * Verify tablespace directories are empty. Don't bother with the
-		 * first once since it can be relocated, and it will be checked before
-		 * we do anything anyway.
-		 */
-		if (format == 'p' && !PQgetisnull(res, i, 1))
-		{
-			char	   *path = (char *) get_tablespace_mapping(PQgetvalue(res, i, 1));
-
-			verify_dir_is_empty_or_create(path, &made_tablespace_dirs, &found_tablespace_dirs);
-		}
 	}
 
 	/*
-- 
2.11.0


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


Re: [HACKERS] Small patch for pg_basebackup argument parsing

2017-04-22 Thread Pierre Ducroquet
On Saturday, April 22, 2017 11:31:58 PM CEST Michael Paquier wrote:
> On Sat, Apr 22, 2017 at 11:12 PM, Pierre Ducroquet  
wrote:
> > Following your advice, I went through the source tree and cleaned up most
> > instances of that pattern.
> > I have attached the corresponding patch to this mail.
> > If you think this patch is indeed interesting, what would be the next way
> > to have it reviewed ?
> 
> Here are the general guidelines about patch submission:
> https://wiki.postgresql.org/wiki/Submitting_a_Patch
> And the best thing would be to register it to the next commit fest so
> as it does not get lost:
> https://commitfest.postgresql.org/

Thank you, I added an entry in the next commit fest.


signature.asc
Description: This is a digitally signed message part.


Re: [HACKERS] Small patch for pg_basebackup argument parsing

2017-04-22 Thread Pierre Ducroquet
On Friday, April 14, 2017 8:59:03 AM CEST Robert Haas wrote:
> On Fri, Apr 14, 2017 at 2:32 AM, Pierre Ducroquet 
wrote:
> > On Friday, April 14, 2017 8:44:37 AM CEST Michael Paquier wrote:
> >> On Fri, Apr 14, 2017 at 6:32 AM, Pierre Ducroquet 
> >
> > wrote:
> >> > Yesterday while doing a few pg_basebackup, I realized that the integer
> >> > parameters were not properly checked against invalid input.
> >> > It is not a critical issue, but this could be misleading for an user
> >> > who
> >> > writes -z max or -s 0.5…
> >> > I've attached the patch to this mail. Should I add it to the next
> >> > commit
> >> > fest or is it not needed for such small patches ?
> >>
> >> A call to atoi is actually equivalent to strtol with the rounding:
> >> (int)strtol(str, (char **)NULL, 10);
> >> So I don't think this is worth caring.
> >
> > The problem with atoi is that it simply ignores any invalid input and
> > returns 0 instead.
> > That's why I did this patch, because I did a typo when calling
> > pg_basebackup and was not warned for an invalid input.
>
> I agree.  I think it would be worth going through and cleaning up
> every instance of this in the source tree.

Hi

Following your advice, I went through the source tree and cleaned up most
instances of that pattern.
I have attached the corresponding patch to this mail.
If you think this patch is indeed interesting, what would be the next way to
have it reviewed ?

Thanks

 Pierre
From da448337bd050518323b45fd5d2929d04b552802 Mon Sep 17 00:00:00 2001
From: Pierre Ducroquet 
Date: Tue, 18 Apr 2017 09:40:40 +0200
Subject: [PATCH] Port most calls of atoi(optarg) to strcol

atoi does not allow any kind of data check. If the input data is invalid,
the result will be silently truncated to the valid part of input, or just
0 if no digit was found at the beginning of input.
---
 src/bin/pg_basebackup/pg_basebackup.c  | 11 ++-
 src/bin/pg_basebackup/pg_receivewal.c  | 11 ++-
 src/bin/pg_basebackup/pg_recvlogical.c | 11 ++-
 src/bin/pg_ctl/pg_ctl.c|  8 +++-
 src/bin/pg_dump/pg_dump.c  | 12 +---
 src/bin/pg_dump/pg_restore.c   |  8 +++-
 src/bin/pg_upgrade/option.c|  5 +++--
 src/bin/pgbench/pgbench.c  | 34 ++
 8 files changed, 62 insertions(+), 38 deletions(-)

diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
index 40ec0e17dc..34884fce4f 100644
--- a/src/bin/pg_basebackup/pg_basebackup.c
+++ b/src/bin/pg_basebackup/pg_basebackup.c
@@ -87,7 +87,7 @@ static IncludeWal includewal = STREAM_WAL;
 static bool fastcheckpoint = false;
 static bool writerecoveryconf = false;
 static bool do_sync = true;
-static int	standby_message_timeout = 10 * 1000;		/* 10 sec = default */
+static long int	standby_message_timeout = 10 * 1000;		/* 10 sec = default */
 static pg_time_t last_progress_report = 0;
 static int32 maxrate = 0;		/* no limit by default */
 static char *replication_slot = NULL;
@@ -2063,6 +2063,7 @@ BaseBackup(void)
 int
 main(int argc, char **argv)
 {
+	char *strtol_endptr = NULL;
 	static struct option long_options[] = {
 		{"help", no_argument, NULL, '?'},
 		{"version", no_argument, NULL, 'V'},
@@ -2203,8 +2204,8 @@ main(int argc, char **argv)
 #endif
 break;
 			case 'Z':
-compresslevel = atoi(optarg);
-if (compresslevel < 0 || compresslevel > 9)
+compresslevel = strtol(optarg, &strtol_endptr, 10);
+if (compresslevel < 0 || compresslevel > 9 || (strtol_endptr != optarg + strlen(optarg)))
 {
 	fprintf(stderr, _("%s: invalid compression level \"%s\"\n"),
 			progname, optarg);
@@ -2242,8 +2243,8 @@ main(int argc, char **argv)
 dbgetpassword = 1;
 break;
 			case 's':
-standby_message_timeout = atoi(optarg) * 1000;
-if (standby_message_timeout < 0)
+standby_message_timeout = strtol(optarg, &strtol_endptr, 10) * 1000;
+if ((standby_message_timeout < 0) || (strtol_endptr != optarg + strlen(optarg)))
 {
 	fprintf(stderr, _("%s: invalid status interval \"%s\"\n"),
 			progname, optarg);
diff --git a/src/bin/pg_basebackup/pg_receivewal.c b/src/bin/pg_basebackup/pg_receivewal.c
index 1a9fe81be1..f470406678 100644
--- a/src/bin/pg_basebackup/pg_receivewal.c
+++ b/src/bin/pg_basebackup/pg_receivewal.c
@@ -479,6 +479,7 @@ main(int argc, char **argv)
 	int			c;
 	int			option_index;
 	char	   *db_name;
+char   *strtol_endptr = NULL;

 	progname = get_progname(argv[0]);
 	set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_basebackup"));
@@ -513,7 +514,7 @@ main(int argc, char **argv)
 dbhos

Re: [HACKERS] Small patch for pg_basebackup argument parsing

2017-04-14 Thread Pierre Ducroquet
On Friday, April 14, 2017 8:59:03 AM CEST Robert Haas wrote:
> On Fri, Apr 14, 2017 at 2:32 AM, Pierre Ducroquet  
wrote:
> > On Friday, April 14, 2017 8:44:37 AM CEST Michael Paquier wrote:
> >> On Fri, Apr 14, 2017 at 6:32 AM, Pierre Ducroquet 
> > 
> > wrote:
> >> > Yesterday while doing a few pg_basebackup, I realized that the integer
> >> > parameters were not properly checked against invalid input.
> >> > It is not a critical issue, but this could be misleading for an user
> >> > who
> >> > writes -z max or -s 0.5…
> >> > I've attached the patch to this mail. Should I add it to the next
> >> > commit
> >> > fest or is it not needed for such small patches ?
> >> 
> >> A call to atoi is actually equivalent to strtol with the rounding:
> >> (int)strtol(str, (char **)NULL, 10);
> >> So I don't think this is worth caring.
> > 
> > The problem with atoi is that it simply ignores any invalid input and
> > returns 0 instead.
> > That's why I did this patch, because I did a typo when calling
> > pg_basebackup and was not warned for an invalid input.
> 
> I agree.  I think it would be worth going through and cleaning up
> every instance of this in the source tree.

Well, I don't have much to do during a train travel next week. I'll look into 
it and post my results here.

signature.asc
Description: This is a digitally signed message part.


Re: [HACKERS] Small patch for pg_basebackup argument parsing

2017-04-13 Thread Pierre Ducroquet
On Friday, April 14, 2017 8:44:37 AM CEST Michael Paquier wrote:
> On Fri, Apr 14, 2017 at 6:32 AM, Pierre Ducroquet  
wrote:
> > Yesterday while doing a few pg_basebackup, I realized that the integer
> > parameters were not properly checked against invalid input.
> > It is not a critical issue, but this could be misleading for an user who
> > writes -z max or -s 0.5…
> > I've attached the patch to this mail. Should I add it to the next commit
> > fest or is it not needed for such small patches ?
> 
> A call to atoi is actually equivalent to strtol with the rounding:
> (int)strtol(str, (char **)NULL, 10);
> So I don't think this is worth caring.

The problem with atoi is that it simply ignores any invalid input and returns 
0 instead.
That's why I did this patch, because I did a typo when calling pg_basebackup 
and was not warned for an invalid input.
But it doesn't matter that much, so if you don't think that's interesting, no 
problem.

signature.asc
Description: This is a digitally signed message part.


[HACKERS] Small patch for pg_basebackup argument parsing

2017-04-13 Thread Pierre Ducroquet
Hi

Yesterday while doing a few pg_basebackup, I realized that the integer
parameters were not properly checked against invalid input.
It is not a critical issue, but this could be misleading for an user who
writes -z max or -s 0.5…
I've attached the patch to this mail. Should I add it to the next commit fest
or is it not needed for such small patches ?

Thanks

 PierreFrom c5301085514b8e5acd9ffa5b10ae6521677b4d72 Mon Sep 17 00:00:00 2001
From: Pierre Ducroquet 
Date: Thu, 13 Apr 2017 23:25:51 +0200
Subject: [PATCH] Check the results of atoi in pg_basebackup

Passing invalid strings in integer parameters does not trigger any error
in pg_basebackup right now. This behaviour could be misleading and give
the impression that a setting is considered (-z max, -s 0.5) while it
was reset to 0 instead.
---
 src/bin/pg_basebackup/pg_basebackup.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
index 40ec0e17dc..e69dbd1ed6 100644
--- a/src/bin/pg_basebackup/pg_basebackup.c
+++ b/src/bin/pg_basebackup/pg_basebackup.c
@@ -87,7 +87,7 @@ static IncludeWal includewal = STREAM_WAL;
 static bool fastcheckpoint = false;
 static bool writerecoveryconf = false;
 static bool do_sync = true;
-static int	standby_message_timeout = 10 * 1000;		/* 10 sec = default */
+static long int	standby_message_timeout = 10 * 1000;		/* 10 sec = default */
 static pg_time_t last_progress_report = 0;
 static int32 maxrate = 0;		/* no limit by default */
 static char *replication_slot = NULL;
@@ -2063,6 +2063,7 @@ BaseBackup(void)
 int
 main(int argc, char **argv)
 {
+	char *strtol_endptr = NULL;
 	static struct option long_options[] = {
 		{"help", no_argument, NULL, '?'},
 		{"version", no_argument, NULL, 'V'},
@@ -2203,8 +2204,8 @@ main(int argc, char **argv)
 #endif
 break;
 			case 'Z':
-compresslevel = atoi(optarg);
-if (compresslevel < 0 || compresslevel > 9)
+compresslevel = strtol(optarg, &strtol_endptr, 10);
+if (compresslevel < 0 || compresslevel > 9 || (strtol_endptr != optarg + strlen(optarg))
 {
 	fprintf(stderr, _("%s: invalid compression level \"%s\"\n"),
 			progname, optarg);
@@ -2242,8 +2243,8 @@ main(int argc, char **argv)
 dbgetpassword = 1;
 break;
 			case 's':
-standby_message_timeout = atoi(optarg) * 1000;
-if (standby_message_timeout < 0)
+standby_message_timeout = strtol(optarg, &strtol_endptr, 10) * 1000;
+if ((standby_message_timeout < 0) || (strtol_endptr != optarg + strlen(optarg)))
 {
 	fprintf(stderr, _("%s: invalid status interval \"%s\"\n"),
 			progname, optarg);
--
2.11.0



signature.asc
Description: This is a digitally signed message part.


Re: [HACKERS] Bug with pg_basebackup and 'shared' tablespace

2017-04-06 Thread Pierre Ducroquet
On Thursday, April 6, 2017 2:00:55 PM CEST Kyotaro HORIGUCHI wrote:
> At Thu, 06 Apr 2017 00:59:49 +0200, Pierre Ducroquet 
> wrote in <2008148.rxBNyNRHPZ@peanuts2>
> > But it all gets messy when we want to create a streaming standby server
> > using pg_basebackup. When backuping Pg 9.5, there is no issue, but
> > backuping Pg 9.6 afterwards will say "directory "/mnt/ssd/postgres"
> > exists but is not empty".
> The documentation says as follows.
> 
> https://www.postgresql.org/docs/9.6/static/manage-ag-tablespaces.html
> 
> | The location must be an existing, empty directory that is owned
> | by the PostgreSQL operating system user.
> 
> This explicitly prohibits to share one tablespace directory among
> multiple servers. The code is just missing the case of multiple
> servers with different versions. I think the bug is rather that
> Pg9.6 in the case allowed to create the tablespace.
> 
> The current naming rule of tablespace directory was introduced as
> of 9.0 so that pg_upgrade (or pg_migrator at the time) can
> perform in-place migration. It is not intended to share a
> directory among multiple instances with different versions.
> 
> That being said, an additional trick in the attached file will
> work for you.

Thanks for your answer.
Indeed, either PostgreSQL should enforce that empty folder restriction, or 
pg_basebackup should lift it and the documentation should reflect this.
Right now, there is a conflict between pg_basebackup and the server since they 
do not allow the same behaviour. I can submit a patch either way, but I won't 
decide what is the right way to do it.
I know tricks will allow to work around that issue, I found them hopefully and 
I guess most people affected by this issue would be able to find and use them, 
but nevertheless being able to build a server that can no longer be base-
backuped does not seem right.

 Pierre


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


[HACKERS] Bug with pg_basebackup and 'shared' tablespace

2017-04-05 Thread Pierre Ducroquet
Hi

On our servers, we are running different PostgreSQL versions because we can 
not migrate every application at the same time to Pg 9.6…
Since we have several disks, we use tablespaces and, for historical reasons, 
we used the same folder for both Pg versions, say /mnt/ssd/postgres
The server has absolutely no issue with that, there is not a single warning 
when running CREATE TABLESPACE.
But it all gets messy when we want to create a streaming standby server using 
pg_basebackup. When backuping Pg 9.5, there is no issue, but backuping Pg 9.6 
afterwards will say "directory "/mnt/ssd/postgres" exists but is not empty".
The attached script to this mail will easily reproduce that issue if you did 
not understand me. Just... read it before launching it, it's a dirty script to 
reproduce the issue. :)

I have looked a bit at the pg_basebackup code and the replication protocol, 
and I did not find any simple way to solve the issue. PostgreSQL use the 
CATALOG_VERSION_NO to have one folder per Pg version, but that constant is not 
accessible out of the PostgreSQL code and is not exposed in the replication 
protocol as described in the documentation 
https://www.postgresql.org/docs/current/static/protocol-replication.html
The only easy way I see to fix that issue is to alter the replication protocol 
to expose the CATALOG_VERSION_NO constant, making it possible for 
pg_basebackup to know the proper path to check. Another way would be to change 
the pg_basebackup logic and backup the main data folder in order to be able to 
read the pg_control file… but this seems ugly too.

I am willing to write the patch for this issue, but I would appreciate some 
help to find a proper way to fix it.

Thanks

 Pierre

reproduce-bug-tblspace.sh
Description: application/shellscript


signature.asc
Description: This is a digitally signed message part.


Re: [HACKERS] Other formats in pset like markdown, rst, mediawiki

2017-03-31 Thread Pierre Ducroquet

On Friday, March 31, 2017 7:17:08 AM CEST, Jan Michálek wrote:



2017-03-30 21:53 GMT+02:00 Pavel Stehule :


2017-03-29 20:11 GMT+02:00 Jan Michálek :


2017-03-27 19:41 GMT+02:00 Jan Michálek :


2017-03-23 17:26 GMT+01:00 Pierre Ducroquet :
The following review has been posted through the commitfest application:
make installcheck-world:  tested, passed
Implements feature:   tested, passed
Spec compliant:   tested, passed
Documentation:tested, passed

Hi

This is my first review (Magnus said in his presentation in 
PGDay Paris that volunteers should just come and help, so here I 
am), so please notify me for any mistake I do when using the 
review tools...


The feature seems to work as expected, but I don't claim to be 
a markdown and rst expert.

Some minor issues with the code itself :
- some indentation issues (documentation and code itself with 
mix between space based and tab based indentation) and a few 
trailing spaces in code


corrected
 
- typographic issues in the documentation :
  - "The html, asciidoc, latex, latex-longtable, troff-ms, and 
markdown and rst formats" ==> duplicated and


corrected 
  - "Sets the output format to one of unaligned, aligned, 
wrapped, html, asciidoc, latex (uses tabular), latex-longtable, 
rst, markdown, or troff-ms." ==> extra comma at the end of the 
list
- the comment " dont add line after last row, because line is 
added after every row" is misleading, it should warn that it's 
only for rst

- there is a block of commented out code left
- in the print_aligned_vertical function, there is a mix 
between "cont->opt->format == PRINT_RST" and "format == &pg_rst" 
and I don't see any obvious reason for that
corrected 
- the documentation doesn't mention (but ok, it's kind of 
obvious) that the linestyle option will not work with rst and 
markdown



In this patch are corrected (i hope, i had correct changes in 
vimrc) indentation issues. Plese, look at this if it is OK (i 
men indentats) and some minor errors. And it should work on 
current master (probably).


Added \x option form markdown
In markdown works multiline cels (newline replaced by )
regre tests passed

\pset format rst
\x
select 10
crash on segfault

Program received signal SIGSEGV, Segmentation fault.
0x7f77673a866c in vfprintf () from /lib64/libc.so.6
(gdb) bt
#0  0x7f77673a866c in vfprintf () from /lib64/libc.so.6
#1  0x7f77673b1574 in fprintf () from /lib64/libc.so.6
#2  0x00437bc5 in print_aligned_vertical 
(cont=0x7fffade43da0, fout=, 
is_pager=) at print.c:1755
#3  0x0043a70d in printTable 
(cont=cont@entry=0x7fffade43da0, fout=, 
fout@entry=0x7f77677255e0 <_IO_2_1_stdout_>, 
is_pager=, is_pager@entry=0 '\000', 
flog=flog@entry=0x0) at print.c:3466
#4  0x0043c37f in printQuery 
(result=result@entry=0x9c4b60, opt=opt@entry=0x7fffade43f00, 
fout=0x7f77677255e0 <_IO_2_1_stdout_>, 
is_pager=is_pager@entry=0 '\000', flog=0x0) at print.c:3551
#5  0x0040da6d in PrintQueryTuples (results=0x9c4b60) 
at common.c:808

#6  PrintQueryResults (results=0x9c4b60) at common.c:1140
#7  SendQuery (query=0x9c1700 "select 10;") at common.c:1317
#8  0x0041c3d4 in MainLoop (source=0x7f77677248a0 
<_IO_2_1_stdin_>) at mainloop.c:319
#9  0x00405d5d in main (argc=, 
argv=) at startup.c:396


Regards

On source from monday it works (last commit on master I have is 
from 27.3 14:30). Or, maybe I didn`t generate diff well, or some 
gitt issue. 


I agree with Pavel, there is a segfault when you do these with your current 
patch. The current patch does not pass make check-world.
How did you generate the diff ? Basically, the simplest way to generate a 
patch serie is through git format-patch.
For instance, say you have a rstFormat branch freshly rebased upon 
origin/master, just do git format-patch origin/master..rstFormat and you 
will 
have one patch file per commit.

And don't forget to commit everything :)

I hope this helps, I don't have enough time to go through the patch and 
find 
out what is causing the segfault right now.



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


Re: [HACKERS] Other formats in pset like markdown, rst, mediawiki

2017-03-23 Thread Pierre Ducroquet
The following review has been posted through the commitfest application:
make installcheck-world:  tested, passed
Implements feature:   tested, passed
Spec compliant:   tested, passed
Documentation:tested, passed

Hi

This is my first review (Magnus said in his presentation in PGDay Paris that 
volunteers should just come and help, so here I am), so please notify me for 
any mistake I do when using the review tools...

The feature seems to work as expected, but I don't claim to be a markdown and 
rst expert.
Some minor issues with the code itself :
- some indentation issues (documentation and code itself with mix between space 
based and tab based indentation) and a few trailing spaces in code
- typographic issues in the documentation : 
  - "The html, asciidoc, latex, latex-longtable, troff-ms, and markdown and rst 
formats" ==> duplicated and
  - "Sets the output format to one of unaligned, aligned, wrapped, html, 
asciidoc, latex (uses tabular), latex-longtable, rst, markdown, or troff-ms." 
==> extra comma at the end of the list
- the comment " dont add line after last row, because line is added after every 
row" is misleading, it should warn that it's only for rst
- there is a block of commented out code left
- in the print_aligned_vertical function, there is a mix between 
"cont->opt->format == PRINT_RST" and "format == &pg_rst" and I don't see any 
obvious reason for that
- the documentation doesn't mention (but ok, it's kind of obvious) that the 
linestyle option will not work with rst and markdown

Thanks !

The new status of this patch is: Waiting on Author

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