Cope with possible failure of the oldest MultiXact to exist.
Cope with possible failure of the oldest MultiXact to exist.

Recent commits, mainly b69bf30b9bfacafc733a9ba77c9587cf54d06c0c and
53bb309d2d5a9432d2602c93ed18e58bd2924e15, introduced mechanisms to
protect against wraparound of the MultiXact member space: the number
of multixacts that can exist at one time is limited to 2^32, but the
total number of members in those multixacts is also limited to 2^32,
and older code did not take care to enforce the second limit,
potentially allowing old data to be overwritten while it was still
needed.

Unfortunately, these new mechanisms failed to account for the fact
that the code paths in which they run might be executed during
recovery or while the cluster was in an inconsistent state.  Also,
they failed to account for the fact that users who used pg_upgrade
to upgrade a PostgreSQL version between 9.3.0 and 9.3.4 might have
might oldestMultiXid = 1 in the control file despite the true value
being larger.

To fix these problems, first, avoid unnecessarily examining the
mmembers of MultiXacts when the cluster is not known to be consistent.
TruncateMultiXact has done this for a long time, and this patch does
not fix that.  But the new calls used to prevent member wraparound
are not needed until we reach normal running, so avoid calling them
earlier.  (SetMultiXactIdLimit is actually called before InRecovery
is set, so we can't rely on that; we invent our own multixact-specific
flag instead.)

Second, make failure to look up the members of a MultiXact a non-fatal
error.  Instead, if we're unable to determine the member offset at
which wraparound would occur, postpone arming the member wraparound
defenses until we are able to do so.  If we're unable to determine the
member offset that should force autovacuum, force it continuously
until we are able to do so.  If we're unable to deterine the member
offset at which we should truncate the members SLRU, log a message and
skip truncation.

An important consequence of these changes is that anyone who does have
a bogus oldestMultiXid = 1 value in pg_control will experience
immediate emergency autovacuuming when upgrading to a release that
contains this fix.  The release notes should highlight this fact.  If
a user has no pg_multixact/offsets/0000 file, but has oldestMultiXid = 1
in the control file, they may wish to vacuum any tables with
relminmxid = 1 prior to upgrading in order to avoid an immediate
emergency autovacuum after the upgrade.  This must be done with a
PostgreSQL version 9.3.5 or newer and with vacuum_multixact_freeze_min_age
and vacuum_multixact_freeze_table_age set to 0.

This patch also adds an additional log message at each database server
startup, indicating either that protections against member wraparound
have been engaged, or that they have not.  In the latter case, once
autovacuum has advanced oldestMultiXid to a sane value, the message
indicating that the guards have been engaged will appear at the next
checkpoint.  A few additional messages have also been added at the DEBUG1
level so that the correct operation of this code can be properly audited.

Along the way, this patch fixes another, related bug in TruncateMultiXact
that has existed since PostgreSQL 9.3.0: when no MultiXacts exist at
all, the truncation code looks up NextMultiXactId, which doesn't exist
yet.  This can lead to TruncateMultiXact removing every file in
pg_multixact/offsets instead of keeping one around, as it should.
This in turn will cause the database server to refuse to start
afterwards.

Patch by me.  Review by Álvaro Herrera, Andres Freund, Noah Misch, and
Thomas Munro.

greenplum-db/gpdb,jmcatamney/gpdb,lisakowen/gpdb,xinzweb/gpdb,lisakowen/gpdb,xinzweb/gpdb,ashwinstar/gpdb,ashwinstar/gpdb,jmcatamney/gpdb,xinzweb/gpdb,ashwinstar/gpdb,xinzweb/gpdb,greenplum-db/gpdb,50wu/gpdb,adam8157/gpdb,50wu/gpdb,ashwinstar/gpdb,greenplum-db/gpdb,greenplum-db/gpdb,adam8157/gpdb,lisakowen/gpdb,adam8157/gpdb,adam8157/gpdb,lisakowen/gpdb,adam8157/gpdb,jmcatamney/gpdb,jmcatamney/gpdb,ashwinstar/gpdb,lisakowen/gpdb,xinzweb/gpdb,50wu/gpdb,xinzweb/gpdb,greenplum-db/gpdb,50wu/gpdb,greenplum-db/gpdb,jmcatamney/gpdb,lisakowen/gpdb,ashwinstar/gpdb,adam8157/gpdb,ashwinstar/gpdb,adam8157/gpdb,greenplum-db/gpdb,50wu/gpdb,50wu/gpdb,lisakowen/gpdb,jmcatamney/gpdb,xinzweb/gpdb,jmcatamney/gpdb,50wu/gpdb,xinzweb/gpdb,50wu/gpdb,lisakowen/gpdb,adam8157/gpdb,greenplum-db/gpdb,jmcatamney/gpdb,ashwinstar/gpdb