Re: Race condition in SyncRepGetSyncStandbysPriority
Kyotaro Horiguchi <horikyota.ntt@gmail.com>
From: Kyotaro Horiguchi <horikyota.ntt@gmail.com>
To: tgl@sss.pgh.pa.us
Cc: masahiko.sawada@2ndquadrant.com, masao.fujii@oss.nttdata.com,
pgsql-hackers@lists.postgresql.org
Date: 2020-04-16T07:22:41Z
Lists: pgsql-hackers
Attachments
- syncrep-fixes-3.patch (text/x-patch) patch
At Wed, 15 Apr 2020 11:31:49 -0400, Tom Lane <tgl@sss.pgh.pa.us> wrote in
> Kyotaro Horiguchi <horikyota.ntt@gmail.com> writes:
> > At Tue, 14 Apr 2020 16:32:40 -0400, Tom Lane <tgl@sss.pgh.pa.us> wrote in
> > + stby->is_sync_standby = true; /* might change below */
>
> > I'm uneasy with that. In quorum mode all running standbys are marked
> > as "sync" and that's bogus.
>
> I don't follow that? The existing coding of SyncRepGetSyncStandbysQuorum
> returns all the candidates in its list, so this is isomorphic to that.
The existing code actully does that. On the other hand
SyncRepGetSyncStandbysPriority returns standbys that *are known to be*
synchronous, but *Quorum returns standbys that *can be* synchronous.
What the two functions return are different from each other. So it
should be is_sync_standby for -Priority and is_sync_candidate for
-Quorum.
> Possibly a different name for the flag would be more suited?
>
> > On the other hand sync_standbys is already sorted in priority order so I think we can get rid of the member by setting *am_sync as the follows.
>
> > SyncRepGetSyncRecPtr:
> > if (sync_standbys[i].is_me)
> > {
> > *am_sync = (i < SyncRepConfig->num_sync);
> > break;
> > }
>
> I disagree with this, it will change the behavior in the quorum case.
Oops, you're right. I find the whole thing there (and me) is a bit
confusing. syncrep_method affects how some values (specifically
am_sync and sync_standbys) are translated at several calling depths.
And the *am_sync informs nothing in quorum mode.
> In any case, a change like this will cause callers to know way more than
> they ought to about the ordering of the array. In my mind, the fact that
> SyncRepGetSyncStandbysPriority is sorting the array is an internal
> implementation detail; I do not want it to be part of the API.
Anyway the am_sync and is_sync_standby is utterly useless in quorum
mode. That discussion is pretty persuasive if not, but actually the
upper layers (SyncRepReleaseWaiters and SyncRepGetSyncRecPtr) referes
to syncrep_method to differentiate the interpretation of the am_sync
flag and sync_standbys list. So anyway the difference is actually a
part of API.
After thinking some more, I concluded that some of the variables are
wrongly named or considered, and redundant. The fucntion of am_sync is
covered by got_recptr in SyncRepReleaseWaiters, so it's enough that
SyncRepGetSyncRecPtr just reports to the caller whether the caller may
release some of the waiter processes. This simplifies the related
functions and make it (to me) clearer.
Please find the attached.
> (Apropos to that, I realized from working on this patch that there's
> another, completely undocumented assumption in the existing code, that
> the integer list will be sorted by walsender index for equal priorities.
> I don't like that either, and not just because it's undocumented.)
That seems accidentally. Sorting by priority is the disigned behavior
and documented, in contrast, entries of the same priority are ordered
in index order by accident and not documented, that means it can be
changed anytime. I think we don't define everyting in such detail.
regards.
Commits
-
Fix race conditions in synchronous standby management.
- c65c1aa82105 9.6.18 landed
- f332241a60aa 13.0 landed
- b3fa6d016d82 11.8 landed
- 63ecdaf758c5 10.13 landed
- 00ef5d52c577 12.3 landed
-
When WalSndCaughtUp, sleep only in WalSndWaitForWal().
- 421685812290 13.0 cited