mirror of
https://git.postgresql.org/git/postgresql.git
synced 2026-02-20 05:17:00 +08:00
Some background activity (like checkpoints, archive timeout, standby snapshots) is not supposed to happen on an idle system. Unfortunately so far it was not easy to determine when a system is idle, which defeated some of the attempts to avoid redundant activity on an idle system. To make that easier, allow to make individual WAL insertions as not being "important". By checking whether any important activity happened since the last time an activity was performed, it now is easy to check whether some action needs to be repeated. Use the new facility for checkpoints, archive timeout and standby snapshots. The lack of a facility causes some issues in older releases, but in my opinion the consequences (superflous checkpoints / archived segments) aren't grave enough to warrant backpatching. Author: Michael Paquier, editorialized by Andres Freund Reviewed-By: Andres Freund, David Steele, Amit Kapila, Kyotaro HORIGUCHI Bug: #13685 Discussion: https://www.postgresql.org/message-id/20151016203031.3019.72930@wrigleys.postgresql.org https://www.postgresql.org/message-id/CAB7nPqQcPqxEM3S735Bd2RzApNqSNJVietAC=6kfkYv_45dKwA@mail.gmail.com Backpatch: -
94 lines
2.6 KiB
C
94 lines
2.6 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* message.c
|
|
* Generic logical messages.
|
|
*
|
|
* Copyright (c) 2013-2016, PostgreSQL Global Development Group
|
|
*
|
|
* IDENTIFICATION
|
|
* src/backend/replication/logical/message.c
|
|
*
|
|
* NOTES
|
|
*
|
|
* Generic logical messages allow XLOG logging of arbitrary binary blobs that
|
|
* get passed to the logical decoding plugin. In normal XLOG processing they
|
|
* are same as NOOP.
|
|
*
|
|
* These messages can be either transactional or non-transactional.
|
|
* Transactional messages are part of current transaction and will be sent to
|
|
* decoding plugin using in a same way as DML operations.
|
|
* Non-transactional messages are sent to the plugin at the time when the
|
|
* logical decoding reads them from XLOG. This also means that transactional
|
|
* messages won't be delivered if the transaction was rolled back but the
|
|
* non-transactional one will be delivered always.
|
|
*
|
|
* Every message carries prefix to avoid conflicts between different decoding
|
|
* plugins. The plugin authors must take extra care to use unique prefix,
|
|
* good options seems to be for example to use the name of the extension.
|
|
*
|
|
* ---------------------------------------------------------------------------
|
|
*/
|
|
|
|
#include "postgres.h"
|
|
|
|
#include "miscadmin.h"
|
|
|
|
#include "access/xact.h"
|
|
|
|
#include "catalog/indexing.h"
|
|
|
|
#include "nodes/execnodes.h"
|
|
|
|
#include "replication/message.h"
|
|
#include "replication/logical.h"
|
|
|
|
#include "utils/memutils.h"
|
|
|
|
/*
|
|
* Write logical decoding message into XLog.
|
|
*/
|
|
XLogRecPtr
|
|
LogLogicalMessage(const char *prefix, const char *message, size_t size,
|
|
bool transactional)
|
|
{
|
|
xl_logical_message xlrec;
|
|
|
|
/*
|
|
* Force xid to be allocated if we're emitting a transactional message.
|
|
*/
|
|
if (transactional)
|
|
{
|
|
Assert(IsTransactionState());
|
|
GetCurrentTransactionId();
|
|
}
|
|
|
|
xlrec.dbId = MyDatabaseId;
|
|
xlrec.transactional = transactional;
|
|
xlrec.prefix_size = strlen(prefix) + 1;
|
|
xlrec.message_size = size;
|
|
|
|
XLogBeginInsert();
|
|
XLogRegisterData((char *) &xlrec, SizeOfLogicalMessage);
|
|
XLogRegisterData((char *) prefix, xlrec.prefix_size);
|
|
XLogRegisterData((char *) message, size);
|
|
|
|
/* allow origin filtering */
|
|
XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN);
|
|
|
|
return XLogInsert(RM_LOGICALMSG_ID, XLOG_LOGICAL_MESSAGE);
|
|
}
|
|
|
|
/*
|
|
* Redo is basically just noop for logical decoding messages.
|
|
*/
|
|
void
|
|
logicalmsg_redo(XLogReaderState *record)
|
|
{
|
|
uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
|
|
|
|
if (info != XLOG_LOGICAL_MESSAGE)
|
|
elog(PANIC, "logicalmsg_redo: unknown op code %u", info);
|
|
|
|
/* This is only interesting for logical decoding, see decode.c. */
|
|
}
|