mirror of
https://github.com/postgres/postgres.git
synced 2025-05-25 00:04:05 -04:00
Revert "Improve handling of parameter differences in physical replication"
This reverts commit 246f136e76ecd26844840f2b2057e2c87ec9868d. That patch wasn't quite complete enough. Discussion: https://www.postgresql.org/message-id/flat/E1jIpJu-0007Ql-CL%40gemulon.postgresql.org
This commit is contained in:
parent
df3b181499
commit
552fcebff0
@ -2148,14 +2148,18 @@ LOG: database system is ready to accept read only connections
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The settings of some parameters determine the size of shared memory for
|
The setting of some parameters on the standby will need reconfiguration
|
||||||
tracking transaction IDs, locks, and prepared transactions. These shared
|
if they have been changed on the primary. For these parameters,
|
||||||
memory structures should be no smaller on a standby than on the primary.
|
the value on the standby must
|
||||||
Otherwise, it could happen that the standby runs out of shared memory
|
be equal to or greater than the value on the primary.
|
||||||
during recovery. For example, if the primary uses a prepared transaction
|
Therefore, if you want to increase these values, you should do so on all
|
||||||
but the standby did not allocate any shared memory for tracking prepared
|
standby servers first, before applying the changes to the primary server.
|
||||||
transactions, then recovery will abort and cannot continue until the
|
Conversely, if you want to decrease these values, you should do so on the
|
||||||
standby's configuration is changed. The parameters affected are:
|
primary server first, before applying the changes to all standby servers.
|
||||||
|
If these parameters
|
||||||
|
are not set high enough then the standby will refuse to start.
|
||||||
|
Higher values can then be supplied and the server
|
||||||
|
restarted to begin recovery again. These parameters are:
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
@ -2184,34 +2188,6 @@ LOG: database system is ready to accept read only connections
|
|||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
The easiest way to ensure this does not become a problem is to have these
|
|
||||||
parameters set on the standbys to values equal to or greater than on the
|
|
||||||
primary. Therefore, if you want to increase these values, you should do
|
|
||||||
so on all standby servers first, before applying the changes to the
|
|
||||||
primary server. Conversely, if you want to decrease these values, you
|
|
||||||
should do so on the primary server first, before applying the changes to
|
|
||||||
all standby servers. The WAL tracks changes to these parameters on the
|
|
||||||
primary, and if a standby processes WAL that indicates that the current
|
|
||||||
value on the primary is higher than its own value, it will log a warning, for example:
|
|
||||||
<screen>
|
|
||||||
WARNING: insufficient setting for parameter max_connections
|
|
||||||
DETAIL: max_connections = 80 is a lower setting than on the master server (where its value was 100).
|
|
||||||
HINT: Change parameters and restart the server, or there may be resource exhaustion errors sooner or later.
|
|
||||||
</screen>
|
|
||||||
Recovery will continue but could abort at any time thereafter. (It could
|
|
||||||
also never end up failing if the activity on the primary does not actually
|
|
||||||
require the full extent of the allocated shared memory resources.) If
|
|
||||||
recovery reaches a point where it cannot continue due to lack of shared
|
|
||||||
memory, recovery will pause and another warning will be logged, for example:
|
|
||||||
<screen>
|
|
||||||
WARNING: recovery paused because of insufficient parameter settings
|
|
||||||
DETAIL: See earlier in the log about which settings are insufficient.
|
|
||||||
HINT: Recovery cannot continue unless the configuration is changed and the server restarted.
|
|
||||||
</screen>
|
|
||||||
This warning will repeated once a minute. At that point, the settings on
|
|
||||||
the standby need to be updated and the instance restarted before recovery
|
|
||||||
can continue.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
@ -2360,14 +2360,11 @@ PrepareRedoAdd(char *buf, XLogRecPtr start_lsn,
|
|||||||
|
|
||||||
/* Get a free gxact from the freelist */
|
/* Get a free gxact from the freelist */
|
||||||
if (TwoPhaseState->freeGXacts == NULL)
|
if (TwoPhaseState->freeGXacts == NULL)
|
||||||
{
|
|
||||||
StandbyParamErrorPauseRecovery();
|
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_OUT_OF_MEMORY),
|
(errcode(ERRCODE_OUT_OF_MEMORY),
|
||||||
errmsg("maximum number of prepared transactions reached"),
|
errmsg("maximum number of prepared transactions reached"),
|
||||||
errhint("Increase max_prepared_transactions (currently %d).",
|
errhint("Increase max_prepared_transactions (currently %d).",
|
||||||
max_prepared_xacts)));
|
max_prepared_xacts)));
|
||||||
}
|
|
||||||
gxact = TwoPhaseState->freeGXacts;
|
gxact = TwoPhaseState->freeGXacts;
|
||||||
TwoPhaseState->freeGXacts = gxact->next;
|
TwoPhaseState->freeGXacts = gxact->next;
|
||||||
|
|
||||||
|
@ -266,8 +266,6 @@ bool InArchiveRecovery = false;
|
|||||||
static bool standby_signal_file_found = false;
|
static bool standby_signal_file_found = false;
|
||||||
static bool recovery_signal_file_found = false;
|
static bool recovery_signal_file_found = false;
|
||||||
|
|
||||||
static bool need_restart_for_parameter_values = false;
|
|
||||||
|
|
||||||
/* Was the last xlog file restored from archive, or local? */
|
/* Was the last xlog file restored from archive, or local? */
|
||||||
static bool restoredFromArchive = false;
|
static bool restoredFromArchive = false;
|
||||||
|
|
||||||
@ -6020,54 +6018,6 @@ SetRecoveryPause(bool recoveryPause)
|
|||||||
SpinLockRelease(&XLogCtl->info_lck);
|
SpinLockRelease(&XLogCtl->info_lck);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* If in hot standby, pause recovery because of a parameter conflict.
|
|
||||||
*
|
|
||||||
* Similar to recoveryPausesHere() but with a different messaging. The user
|
|
||||||
* is expected to make the parameter change and restart the server. If they
|
|
||||||
* just unpause recovery, they will then run into whatever error is after this
|
|
||||||
* function call for the non-hot-standby case.
|
|
||||||
*
|
|
||||||
* We intentionally do not give advice about specific parameters or values
|
|
||||||
* here because it might be misleading. For example, if we run out of lock
|
|
||||||
* space, then in the single-server case we would recommend raising
|
|
||||||
* max_locks_per_transaction, but in recovery it could equally be the case
|
|
||||||
* that max_connections is out of sync with the primary. If we get here, we
|
|
||||||
* have already logged any parameter discrepancies in
|
|
||||||
* RecoveryRequiresIntParameter(), so users can go back to that and get
|
|
||||||
* concrete and accurate information.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
StandbyParamErrorPauseRecovery(void)
|
|
||||||
{
|
|
||||||
TimestampTz last_warning = 0;
|
|
||||||
|
|
||||||
if (!AmStartupProcess() || !need_restart_for_parameter_values)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SetRecoveryPause(true);
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
TimestampTz now = GetCurrentTimestamp();
|
|
||||||
|
|
||||||
if (TimestampDifferenceExceeds(last_warning, now, 60000))
|
|
||||||
{
|
|
||||||
ereport(WARNING,
|
|
||||||
(errmsg("recovery paused because of insufficient parameter settings"),
|
|
||||||
errdetail("See earlier in the log about which settings are insufficient."),
|
|
||||||
errhint("Recovery cannot continue unless the configuration is changed and the server restarted.")));
|
|
||||||
last_warning = now;
|
|
||||||
}
|
|
||||||
|
|
||||||
pgstat_report_wait_start(WAIT_EVENT_RECOVERY_PAUSE);
|
|
||||||
pg_usleep(1000000L); /* 1000 ms */
|
|
||||||
pgstat_report_wait_end();
|
|
||||||
HandleStartupProcInterrupts();
|
|
||||||
}
|
|
||||||
while (RecoveryIsPaused());
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When recovery_min_apply_delay is set, we wait long enough to make sure
|
* When recovery_min_apply_delay is set, we wait long enough to make sure
|
||||||
* certain record types are applied at least that interval behind the master.
|
* certain record types are applied at least that interval behind the master.
|
||||||
@ -6247,20 +6197,16 @@ GetXLogReceiptTime(TimestampTz *rtime, bool *fromStream)
|
|||||||
* Note that text field supplied is a parameter name and does not require
|
* Note that text field supplied is a parameter name and does not require
|
||||||
* translation
|
* translation
|
||||||
*/
|
*/
|
||||||
static void
|
#define RecoveryRequiresIntParameter(param_name, currValue, minValue) \
|
||||||
RecoveryRequiresIntParameter(const char *param_name, int currValue, int minValue)
|
do { \
|
||||||
{
|
if ((currValue) < (minValue)) \
|
||||||
if (currValue < minValue)
|
ereport(ERROR, \
|
||||||
{
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), \
|
||||||
ereport(WARNING,
|
errmsg("hot standby is not possible because %s = %d is a lower setting than on the master server (its value was %d)", \
|
||||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
param_name, \
|
||||||
errmsg("insufficient setting for parameter %s", param_name),
|
currValue, \
|
||||||
errdetail("%s = %d is a lower setting than on the master server (where its value was %d).",
|
minValue))); \
|
||||||
param_name, currValue, minValue),
|
} while(0)
|
||||||
errhint("Change parameters and restart the server, or there may be resource exhaustion errors sooner or later.")));
|
|
||||||
need_restart_for_parameter_values = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check to see if required parameters are set high enough on this server
|
* Check to see if required parameters are set high enough on this server
|
||||||
|
@ -3654,14 +3654,7 @@ KnownAssignedXidsAdd(TransactionId from_xid, TransactionId to_xid,
|
|||||||
* If it still won't fit then we're out of memory
|
* If it still won't fit then we're out of memory
|
||||||
*/
|
*/
|
||||||
if (head + nxids > pArray->maxKnownAssignedXids)
|
if (head + nxids > pArray->maxKnownAssignedXids)
|
||||||
{
|
elog(ERROR, "too many KnownAssignedXids");
|
||||||
StandbyParamErrorPauseRecovery();
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_OUT_OF_MEMORY),
|
|
||||||
errmsg("out of shared memory"),
|
|
||||||
errdetail("There are no more KnownAssignedXids slots."),
|
|
||||||
errhint("You might need to increase max_connections.")));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now we can insert the xids into the space starting at head */
|
/* Now we can insert the xids into the space starting at head */
|
||||||
|
@ -965,13 +965,10 @@ LockAcquireExtended(const LOCKTAG *locktag,
|
|||||||
if (locallockp)
|
if (locallockp)
|
||||||
*locallockp = NULL;
|
*locallockp = NULL;
|
||||||
if (reportMemoryError)
|
if (reportMemoryError)
|
||||||
{
|
|
||||||
StandbyParamErrorPauseRecovery();
|
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_OUT_OF_MEMORY),
|
(errcode(ERRCODE_OUT_OF_MEMORY),
|
||||||
errmsg("out of shared memory"),
|
errmsg("out of shared memory"),
|
||||||
errhint("You might need to increase max_locks_per_transaction.")));
|
errhint("You might need to increase max_locks_per_transaction.")));
|
||||||
}
|
|
||||||
else
|
else
|
||||||
return LOCKACQUIRE_NOT_AVAIL;
|
return LOCKACQUIRE_NOT_AVAIL;
|
||||||
}
|
}
|
||||||
@ -1006,13 +1003,10 @@ LockAcquireExtended(const LOCKTAG *locktag,
|
|||||||
if (locallockp)
|
if (locallockp)
|
||||||
*locallockp = NULL;
|
*locallockp = NULL;
|
||||||
if (reportMemoryError)
|
if (reportMemoryError)
|
||||||
{
|
|
||||||
StandbyParamErrorPauseRecovery();
|
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_OUT_OF_MEMORY),
|
(errcode(ERRCODE_OUT_OF_MEMORY),
|
||||||
errmsg("out of shared memory"),
|
errmsg("out of shared memory"),
|
||||||
errhint("You might need to increase max_locks_per_transaction.")));
|
errhint("You might need to increase max_locks_per_transaction.")));
|
||||||
}
|
|
||||||
else
|
else
|
||||||
return LOCKACQUIRE_NOT_AVAIL;
|
return LOCKACQUIRE_NOT_AVAIL;
|
||||||
}
|
}
|
||||||
@ -2834,7 +2828,6 @@ FastPathGetRelationLockEntry(LOCALLOCK *locallock)
|
|||||||
{
|
{
|
||||||
LWLockRelease(partitionLock);
|
LWLockRelease(partitionLock);
|
||||||
LWLockRelease(&MyProc->backendLock);
|
LWLockRelease(&MyProc->backendLock);
|
||||||
StandbyParamErrorPauseRecovery();
|
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_OUT_OF_MEMORY),
|
(errcode(ERRCODE_OUT_OF_MEMORY),
|
||||||
errmsg("out of shared memory"),
|
errmsg("out of shared memory"),
|
||||||
@ -4165,7 +4158,6 @@ lock_twophase_recover(TransactionId xid, uint16 info,
|
|||||||
if (!lock)
|
if (!lock)
|
||||||
{
|
{
|
||||||
LWLockRelease(partitionLock);
|
LWLockRelease(partitionLock);
|
||||||
StandbyParamErrorPauseRecovery();
|
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_OUT_OF_MEMORY),
|
(errcode(ERRCODE_OUT_OF_MEMORY),
|
||||||
errmsg("out of shared memory"),
|
errmsg("out of shared memory"),
|
||||||
@ -4231,7 +4223,6 @@ lock_twophase_recover(TransactionId xid, uint16 info,
|
|||||||
elog(PANIC, "lock table corrupted");
|
elog(PANIC, "lock table corrupted");
|
||||||
}
|
}
|
||||||
LWLockRelease(partitionLock);
|
LWLockRelease(partitionLock);
|
||||||
StandbyParamErrorPauseRecovery();
|
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_OUT_OF_MEMORY),
|
(errcode(ERRCODE_OUT_OF_MEMORY),
|
||||||
errmsg("out of shared memory"),
|
errmsg("out of shared memory"),
|
||||||
@ -4524,7 +4515,6 @@ VirtualXactLock(VirtualTransactionId vxid, bool wait)
|
|||||||
{
|
{
|
||||||
LWLockRelease(partitionLock);
|
LWLockRelease(partitionLock);
|
||||||
LWLockRelease(&proc->backendLock);
|
LWLockRelease(&proc->backendLock);
|
||||||
StandbyParamErrorPauseRecovery();
|
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_OUT_OF_MEMORY),
|
(errcode(ERRCODE_OUT_OF_MEMORY),
|
||||||
errmsg("out of shared memory"),
|
errmsg("out of shared memory"),
|
||||||
|
@ -288,7 +288,6 @@ extern XLogRecPtr GetXLogInsertRecPtr(void);
|
|||||||
extern XLogRecPtr GetXLogWriteRecPtr(void);
|
extern XLogRecPtr GetXLogWriteRecPtr(void);
|
||||||
extern bool RecoveryIsPaused(void);
|
extern bool RecoveryIsPaused(void);
|
||||||
extern void SetRecoveryPause(bool recoveryPause);
|
extern void SetRecoveryPause(bool recoveryPause);
|
||||||
extern void StandbyParamErrorPauseRecovery(void);
|
|
||||||
extern TimestampTz GetLatestXTime(void);
|
extern TimestampTz GetLatestXTime(void);
|
||||||
extern TimestampTz GetCurrentChunkReplayStartTime(void);
|
extern TimestampTz GetCurrentChunkReplayStartTime(void);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user