Review of "pg_basebackup and pg_receivexlog to use non-blocking socket communication", was: Re: Re: [BUGS] BUG #7534: walreceiver takes long time to detect n/w breakdown

From: Boszormenyi Zoltan <zb(at)cybertec(dot)at>
To: Amit kapila <amit(dot)kapila(at)huawei(dot)com>
Cc: Fujii Masao <masao(dot)fujii(at)gmail(dot)com>, Heikki Linnakangas <hlinnakangas(at)vmware(dot)com>, "pgsql-hackers(at)postgresql(dot)org" <pgsql-hackers(at)postgresql(dot)org>
Subject: Review of "pg_basebackup and pg_receivexlog to use non-blocking socket communication", was: Re: Re: [BUGS] BUG #7534: walreceiver takes long time to detect n/w breakdown
Date: 2013-01-01 16:48:48
Message-ID: 50E31370.5030405@cybertec.at
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs pgsql-hackers

Hi,

2012-11-15 14:59 keltezéssel, Amit kapila írta:
> On Monday, November 12, 2012 8:23 PM Fujii Masao wrote:
> On Fri, Nov 9, 2012 at 3:03 PM, Amit Kapila <amit(dot)kapila(at)huawei(dot)com> wrote:
>> On Thursday, November 08, 2012 10:42 PM Fujii Masao wrote:
>>> On Thu, Nov 8, 2012 at 5:53 PM, Amit Kapila <amit(dot)kapila(at)huawei(dot)com>
>>> wrote:
>>>> On Thursday, November 08, 2012 2:04 PM Heikki Linnakangas wrote:
>>>>> On 19.10.2012 14:42, Amit kapila wrote:
>>>>>> On Thursday, October 18, 2012 8:49 PM Fujii Masao wrote:
>>>> Are you planning to introduce the timeout mechanism in pg_basebackup
>>>> main process? Or background process? It's useful to implement both.
>>> By background process, you mean ReceiveXlogStream?
>>> For both.
>>> I think for background process, it can be done in a way similar to what we
>>> have done for walreceiver.
>> Yes.
>>> But I have some doubts for how to do for main process:
>>> Logic similar to walreceiver can not be used incase network goes down during
>>> getting other database file from server.
>>> The reason for the same is to receive the data files PQgetCopyData() is
>>> called in synchronous mode, so it keeps waiting for infinite time till it
>>> gets some data.
>>> In order to solve this issue, I can think of following options:
>>> 1. Making this call also asynchronous (but now sure about impact of this).
>> +1
>> Walreceiver already calls PQgetCopyData() asynchronously. ISTM you can
>> solve the issue in the similar way to walreceiver's.
>>> 2. In function pqWait, instead of passing hard-code value -1 (i.e. infinite
>>> wait), we can send some finite time. This time can be received as command
>>> line argument
>>> from respective utility and set the same in PGconn structure.
>> Yes, I think that we should add something like --conninfo option to
>> pg_basebackup
>> and pg_receivexlog. We can easily set not only connect_timeout but also sslmode,
>> application_name, ... by using such option accepting conninfo string.
> I have prepared an attached patch to make pg_basebackup and pg_receivexlog as non-blocking.
> To do so I have to add new command line parameters in pg_basebackup and pg_receivexlog
> for now added two more command line arguments
> a. "-r" for pg_basebackup and pg_receivexlog to take receive time-out value. Default value for this parameter is 60 sec.
> b. "-t" for pg_basebackup and pg_receivexlog to take initial connection timeout value. Default value is infinite wait.
> We can change to accept --conninfo as well.
>
> I feel apart from above, remaining problem is for function call PQgetResult()
> 1. Wherever query is getting sent from BaseBackup, it calls the function PQgetResult to receive the result of query.
> As PQgetResult() is blocking function (it calls pqWait which can hang), so if network is down before sending the query itself,
> then there will not be any result, so it will keep hanging in PQgetResult .
> IMO, it can be solved in below ways:
> a. Create one corresponding non-blocking function. But this function is being called from inside some of the
> other libpq function (PQexec->PQexecFinish->PQgetResult). So it can be little tricky to solve this way.
> b. Add the receive_timeout variable in PGconn structure and use it in pqWait for timeout whenever it is set.
> c. any other better way?
>
>
>>> BTW, IIRC the walsender has no timeout mechanism during sending
>>> backup data to pg_basebackup. So it's also useful to implement the
>>> timeout mechanism for the walsender during backup.
>> What about using pq_putmessage_noblock()?
> I think may be some more functions also needs to be made as noblock. I am still evaluating.
>
> I will upload the attached patch in commitfest if you don't have any objections?
>
> More Suggestions/Comments?
>
> With Regards,
> Amit Kapila.

I am reviewing your patch.

* Is the patch in context diff format <http://en.wikipedia.org/wiki/Diff#Context_format>?

Yes.

* Does it apply cleanly to the current git master?

Not quite cleanly but it doesn't produce rejects or fuzz, only offset warnings:

[zozo(at)localhost postgresql]$ cat ../noblock_basebackup_and_receivexlog.patch | patch -p1
patching file src/bin/pg_basebackup/pg_basebackup.c
Hunk #1 succeeded at 41 (offset -6 lines).
Hunk #2 succeeded at 123 (offset -6 lines).
Hunk #3 succeeded at 239 (offset -6 lines).
Hunk #4 succeeded at 292 (offset -6 lines).
Hunk #5 succeeded at 470 (offset -6 lines).
Hunk #6 succeeded at 588 (offset -6 lines).
Hunk #7 succeeded at 601 (offset -6 lines).
Hunk #8 succeeded at 727 (offset -6 lines).
Hunk #9 succeeded at 779 (offset -6 lines).
Hunk #10 succeeded at 797 (offset -6 lines).
Hunk #11 succeeded at 811 (offset -6 lines).
Hunk #12 succeeded at 879 (offset -6 lines).
Hunk #13 succeeded at 1080 (offset -6 lines).
Hunk #14 succeeded at 1381 (offset -6 lines).
Hunk #15 succeeded at 1409 (offset -6 lines).
Hunk #16 succeeded at 1521 (offset -6 lines).
patching file src/bin/pg_basebackup/pg_receivexlog.c
Hunk #1 succeeded at 35 (offset -6 lines).
Hunk #2 succeeded at 65 (offset -6 lines).
Hunk #3 succeeded at 224 (offset -6 lines).
Hunk #4 succeeded at 281 (offset -6 lines).
Hunk #5 succeeded at 314 (offset -6 lines).
Hunk #6 succeeded at 341 (offset -5 lines).
Hunk #7 succeeded at 379 (offset -5 lines).
patching file src/bin/pg_basebackup/receivelog.c
Hunk #1 succeeded at 181 (offset -9 lines).
Hunk #2 succeeded at 201 (offset -9 lines).
Hunk #3 succeeded at 223 (offset -9 lines).
Hunk #4 succeeded at 333 (offset -9 lines).
Hunk #5 succeeded at 342 (offset -9 lines).
Hunk #6 succeeded at 397 (offset -9 lines).
Hunk #7 succeeded at 484 (offset -9 lines).
Hunk #8 succeeded at 533 (offset -9 lines).
Hunk #9 succeeded at 550 (offset -9 lines).
patching file src/bin/pg_basebackup/receivelog.h
patching file src/bin/pg_basebackup/streamutil.c
Hunk #1 succeeded at 66 (offset -6 lines).
Hunk #2 succeeded at 87 (offset -6 lines).
Hunk #3 succeeded at 118 (offset -6 lines).
patching file src/bin/pg_basebackup/streamutil.h

* Does it include reasonable tests, necessary doc patches, etc?

The test cases are not applicable. There is no test framework for
testing network outage in "make check".

There are no documentation patches for the new --recvtimeout=INTERVAL
and --conntimeout=INTERVAL options for either pg_basebackup or
pg_receivexlog.

* Does the patch actually implement that?

It seems so, the patch adds the connect_timeout parameter to
the connection options and uses PQgetCopyData(..., 1) to get
the data asynchronously and uses select(2) to watch for incoming
data.

* Do we want that?

It can speed up detecting network breakdown so yes.

* Do we already have it?

No.

* Does it follow SQL spec, or the community-agreed behavior?

There's no such SQL spec. The behaviour is desired.

* Does it include pg_dump support (if applicable)?

Not applicable.

* Are there dangers?

The patch author researched more functions that need
to be extended in a nonblocking way.
http://archives.postgresql.org/pgsql-hackers/2012-11/msg00863.php

* Have all the bases been covered?

For pg_basebackup/pg_receivexlog (for PQgetCopyData and
PQconnect), yes.

Per the previous comment, no. But those are for the backend
to notice network breakdowns and as such, they need a
separate patch.

* Does the feature work as advertised?

Yes.

I tested it between two machines and pulled the ethernet
plug while pg_basebackup was running. With "-r 2", pg_basebackup
detected the timeout after 2 seconds. Without the patch, I lost
patience after two minutes and pressed Ctrl-C in pg_basebackup.

I also tested pg_receivexlog and it also noticed the network error
in the specified timeout.

* Are there corner cases the author has failed to consider?

As far as I can see in the client-side libpq code flow, no.

* Are there any assertion failures or crashes?

Not applicable, the patch is for client applicatiions.

* Does the patch slow down simple tests?

No.

* If it claims to improve performance, does it?

Not applicable, not a performance patch. But it really
improves detecting network breakdown.

* Does it slow down other things?

No.

* Does it follow the project coding guidelines
<http://developer.postgresql.org/pgdocs/postgres/source.html>?

Yes.

* Are there portability issues?

No. It introduces atoi() and select() as new calls, these are portable.

* Will it work on Windows/BSD etc?

It should.

* Are the comments sufficient and accurate?

This chunk below removes a comment which seems obvious enough
so it's not needed:

***************
*** 518,524 **** ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline,
goto error;
}

! /* Check the message type. */
if (copybuf[0] == 'k')
{
int pos;
--- 559,568 ----
goto error;
}

! /* Set the last reply timestamp */
! last_recv_timestamp = localGetCurrentTimestamp();
! ping_sent = false;
!
if (copybuf[0] == 'k')
{
int pos;
***************

Other comments are sufficient and accurate.

* Does it do what it says, correctly?

This question is redundant with the above "Does the feature work as advertised?"
So yes.

* Does it produce compiler warnings?

No.

* Can you make it crash?

No.

* Is everything done in a way that fits together coherently with other features/modules?

Yes.

* Are there interdependencies that can cause problems?

No.

Best regards,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig & Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
http://www.postgresql.at/

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message giorgio.gallo 2013-01-01 22:09:05 BUG #7780: unaccent extension - dictionary not filtering?
Previous Message Magnus Hagander 2012-12-29 16:38:26 Re: BUG #7767: pg_ctl allows postgres running under administrator's privilege

Browse pgsql-hackers by date

  From Date Subject
Next Message Dimitri Fontaine 2013-01-01 16:52:57 Re: pg_retainxlog for inclusion in 9.3?
Previous Message Tomas Vondra 2013-01-01 16:43:53 Re: PATCH: optimized DROP of multiple tables within a transaction