mirror of
https://github.com/postgres/postgres.git
synced 2026-04-15 22:10:45 -04:00
Convert all remaining subsystems to use the new shmem allocation API
This removes all remaining uses of ShmemInitStruct() and ShmemInitHash() from built-in code. Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com> Reviewed-by: Matthias van de Meent <boekewurm+postgres@gmail.com> Reviewed-by: Daniel Gustafsson <daniel@yesql.se> Discussion: https://www.postgresql.org/message-id/CAExHW5vM1bneLYfg0wGeAa=52UiJ3z4vKd3AJ72X8Fw6k3KKrg@mail.gmail.com
This commit is contained in:
parent
a4b6139dcc
commit
9b5acad3f4
54 changed files with 939 additions and 1220 deletions
|
|
@ -50,6 +50,7 @@
|
|||
#include "miscadmin.h"
|
||||
#include "storage/lwlock.h"
|
||||
#include "storage/shmem.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/rel.h"
|
||||
|
||||
|
||||
|
|
@ -111,6 +112,14 @@ typedef struct ss_scan_locations_t
|
|||
#define SizeOfScanLocations(N) \
|
||||
(offsetof(ss_scan_locations_t, items) + (N) * sizeof(ss_lru_item_t))
|
||||
|
||||
static void SyncScanShmemRequest(void *arg);
|
||||
static void SyncScanShmemInit(void *arg);
|
||||
|
||||
const ShmemCallbacks SyncScanShmemCallbacks = {
|
||||
.request_fn = SyncScanShmemRequest,
|
||||
.init_fn = SyncScanShmemInit,
|
||||
};
|
||||
|
||||
/* Pointer to struct in shared memory */
|
||||
static ss_scan_locations_t *scan_locations;
|
||||
|
||||
|
|
@ -120,58 +129,47 @@ static BlockNumber ss_search(RelFileLocator relfilelocator,
|
|||
|
||||
|
||||
/*
|
||||
* SyncScanShmemSize --- report amount of shared memory space needed
|
||||
* SyncScanShmemRequest --- register this module's shared memory
|
||||
*/
|
||||
Size
|
||||
SyncScanShmemSize(void)
|
||||
static void
|
||||
SyncScanShmemRequest(void *arg)
|
||||
{
|
||||
return SizeOfScanLocations(SYNC_SCAN_NELEM);
|
||||
ShmemRequestStruct(.name = "Sync Scan Locations List",
|
||||
.size = SizeOfScanLocations(SYNC_SCAN_NELEM),
|
||||
.ptr = (void **) &scan_locations,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* SyncScanShmemInit --- initialize this module's shared memory
|
||||
*/
|
||||
void
|
||||
SyncScanShmemInit(void)
|
||||
static void
|
||||
SyncScanShmemInit(void *arg)
|
||||
{
|
||||
int i;
|
||||
bool found;
|
||||
|
||||
scan_locations = (ss_scan_locations_t *)
|
||||
ShmemInitStruct("Sync Scan Locations List",
|
||||
SizeOfScanLocations(SYNC_SCAN_NELEM),
|
||||
&found);
|
||||
scan_locations->head = &scan_locations->items[0];
|
||||
scan_locations->tail = &scan_locations->items[SYNC_SCAN_NELEM - 1];
|
||||
|
||||
if (!IsUnderPostmaster)
|
||||
for (i = 0; i < SYNC_SCAN_NELEM; i++)
|
||||
{
|
||||
/* Initialize shared memory area */
|
||||
Assert(!found);
|
||||
ss_lru_item_t *item = &scan_locations->items[i];
|
||||
|
||||
scan_locations->head = &scan_locations->items[0];
|
||||
scan_locations->tail = &scan_locations->items[SYNC_SCAN_NELEM - 1];
|
||||
/*
|
||||
* Initialize all slots with invalid values. As scans are started,
|
||||
* these invalid entries will fall off the LRU list and get replaced
|
||||
* with real entries.
|
||||
*/
|
||||
item->location.relfilelocator.spcOid = InvalidOid;
|
||||
item->location.relfilelocator.dbOid = InvalidOid;
|
||||
item->location.relfilelocator.relNumber = InvalidRelFileNumber;
|
||||
item->location.location = InvalidBlockNumber;
|
||||
|
||||
for (i = 0; i < SYNC_SCAN_NELEM; i++)
|
||||
{
|
||||
ss_lru_item_t *item = &scan_locations->items[i];
|
||||
|
||||
/*
|
||||
* Initialize all slots with invalid values. As scans are started,
|
||||
* these invalid entries will fall off the LRU list and get
|
||||
* replaced with real entries.
|
||||
*/
|
||||
item->location.relfilelocator.spcOid = InvalidOid;
|
||||
item->location.relfilelocator.dbOid = InvalidOid;
|
||||
item->location.relfilelocator.relNumber = InvalidRelFileNumber;
|
||||
item->location.location = InvalidBlockNumber;
|
||||
|
||||
item->prev = (i > 0) ?
|
||||
(&scan_locations->items[i - 1]) : NULL;
|
||||
item->next = (i < SYNC_SCAN_NELEM - 1) ?
|
||||
(&scan_locations->items[i + 1]) : NULL;
|
||||
}
|
||||
item->prev = (i > 0) ?
|
||||
(&scan_locations->items[i - 1]) : NULL;
|
||||
item->next = (i < SYNC_SCAN_NELEM - 1) ?
|
||||
(&scan_locations->items[i + 1]) : NULL;
|
||||
}
|
||||
else
|
||||
Assert(found);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "lib/qunique.h"
|
||||
#include "miscadmin.h"
|
||||
#include "storage/lwlock.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/datum.h"
|
||||
#include "utils/lsyscache.h"
|
||||
#include "utils/rel.h"
|
||||
|
|
@ -417,6 +418,13 @@ typedef struct BTVacInfo
|
|||
|
||||
static BTVacInfo *btvacinfo;
|
||||
|
||||
static void BTreeShmemRequest(void *arg);
|
||||
static void BTreeShmemInit(void *arg);
|
||||
|
||||
const ShmemCallbacks BTreeShmemCallbacks = {
|
||||
.request_fn = BTreeShmemRequest,
|
||||
.init_fn = BTreeShmemInit,
|
||||
};
|
||||
|
||||
/*
|
||||
* _bt_vacuum_cycleid --- get the active vacuum cycle ID for an index,
|
||||
|
|
@ -553,47 +561,37 @@ _bt_end_vacuum_callback(int code, Datum arg)
|
|||
}
|
||||
|
||||
/*
|
||||
* BTreeShmemSize --- report amount of shared memory space needed
|
||||
* BTreeShmemRequest --- register this module's shared memory
|
||||
*/
|
||||
Size
|
||||
BTreeShmemSize(void)
|
||||
static void
|
||||
BTreeShmemRequest(void *arg)
|
||||
{
|
||||
Size size;
|
||||
|
||||
size = offsetof(BTVacInfo, vacuums);
|
||||
size = add_size(size, mul_size(MaxBackends, sizeof(BTOneVacInfo)));
|
||||
return size;
|
||||
|
||||
ShmemRequestStruct(.name = "BTree Vacuum State",
|
||||
.size = size,
|
||||
.ptr = (void **) &btvacinfo,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* BTreeShmemInit --- initialize this module's shared memory
|
||||
*/
|
||||
void
|
||||
BTreeShmemInit(void)
|
||||
static void
|
||||
BTreeShmemInit(void *arg)
|
||||
{
|
||||
bool found;
|
||||
/*
|
||||
* It doesn't really matter what the cycle counter starts at, but having
|
||||
* it always start the same doesn't seem good. Seed with low-order bits
|
||||
* of time() instead.
|
||||
*/
|
||||
btvacinfo->cycle_ctr = (BTCycleId) time(NULL);
|
||||
|
||||
btvacinfo = (BTVacInfo *) ShmemInitStruct("BTree Vacuum State",
|
||||
BTreeShmemSize(),
|
||||
&found);
|
||||
|
||||
if (!IsUnderPostmaster)
|
||||
{
|
||||
/* Initialize shared memory area */
|
||||
Assert(!found);
|
||||
|
||||
/*
|
||||
* It doesn't really matter what the cycle counter starts at, but
|
||||
* having it always start the same doesn't seem good. Seed with
|
||||
* low-order bits of time() instead.
|
||||
*/
|
||||
btvacinfo->cycle_ctr = (BTCycleId) time(NULL);
|
||||
|
||||
btvacinfo->num_vacuums = 0;
|
||||
btvacinfo->max_vacuums = MaxBackends;
|
||||
}
|
||||
else
|
||||
Assert(found);
|
||||
btvacinfo->num_vacuums = 0;
|
||||
btvacinfo->max_vacuums = MaxBackends;
|
||||
}
|
||||
|
||||
bytea *
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@
|
|||
#include "storage/predicate.h"
|
||||
#include "storage/proc.h"
|
||||
#include "storage/procarray.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/injection_point.h"
|
||||
#include "utils/memutils.h"
|
||||
|
|
@ -189,6 +190,14 @@ typedef struct TwoPhaseStateData
|
|||
|
||||
static TwoPhaseStateData *TwoPhaseState;
|
||||
|
||||
static void TwoPhaseShmemRequest(void *arg);
|
||||
static void TwoPhaseShmemInit(void *arg);
|
||||
|
||||
const ShmemCallbacks TwoPhaseShmemCallbacks = {
|
||||
.request_fn = TwoPhaseShmemRequest,
|
||||
.init_fn = TwoPhaseShmemInit,
|
||||
};
|
||||
|
||||
/*
|
||||
* Global transaction entry currently locked by us, if any. Note that any
|
||||
* access to the entry pointed to by this variable must be protected by
|
||||
|
|
@ -234,10 +243,10 @@ static void RemoveTwoPhaseFile(FullTransactionId fxid, bool giveWarning);
|
|||
static void RecreateTwoPhaseFile(FullTransactionId fxid, void *content, int len);
|
||||
|
||||
/*
|
||||
* Initialization of shared memory
|
||||
* Register shared memory for two-phase state.
|
||||
*/
|
||||
Size
|
||||
TwoPhaseShmemSize(void)
|
||||
static void
|
||||
TwoPhaseShmemRequest(void *arg)
|
||||
{
|
||||
Size size;
|
||||
|
||||
|
|
@ -248,46 +257,40 @@ TwoPhaseShmemSize(void)
|
|||
size = MAXALIGN(size);
|
||||
size = add_size(size, mul_size(max_prepared_xacts,
|
||||
sizeof(GlobalTransactionData)));
|
||||
|
||||
return size;
|
||||
ShmemRequestStruct(.name = "Prepared Transaction Table",
|
||||
.size = size,
|
||||
.ptr = (void **) &TwoPhaseState,
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
TwoPhaseShmemInit(void)
|
||||
/*
|
||||
* Initialize shared memory for two-phase state.
|
||||
*/
|
||||
static void
|
||||
TwoPhaseShmemInit(void *arg)
|
||||
{
|
||||
bool found;
|
||||
GlobalTransaction gxacts;
|
||||
int i;
|
||||
|
||||
TwoPhaseState = ShmemInitStruct("Prepared Transaction Table",
|
||||
TwoPhaseShmemSize(),
|
||||
&found);
|
||||
if (!IsUnderPostmaster)
|
||||
TwoPhaseState->freeGXacts = NULL;
|
||||
TwoPhaseState->numPrepXacts = 0;
|
||||
|
||||
/*
|
||||
* Initialize the linked list of free GlobalTransactionData structs
|
||||
*/
|
||||
gxacts = (GlobalTransaction)
|
||||
((char *) TwoPhaseState +
|
||||
MAXALIGN(offsetof(TwoPhaseStateData, prepXacts) +
|
||||
sizeof(GlobalTransaction) * max_prepared_xacts));
|
||||
for (i = 0; i < max_prepared_xacts; i++)
|
||||
{
|
||||
GlobalTransaction gxacts;
|
||||
int i;
|
||||
/* insert into linked list */
|
||||
gxacts[i].next = TwoPhaseState->freeGXacts;
|
||||
TwoPhaseState->freeGXacts = &gxacts[i];
|
||||
|
||||
Assert(!found);
|
||||
TwoPhaseState->freeGXacts = NULL;
|
||||
TwoPhaseState->numPrepXacts = 0;
|
||||
|
||||
/*
|
||||
* Initialize the linked list of free GlobalTransactionData structs
|
||||
*/
|
||||
gxacts = (GlobalTransaction)
|
||||
((char *) TwoPhaseState +
|
||||
MAXALIGN(offsetof(TwoPhaseStateData, prepXacts) +
|
||||
sizeof(GlobalTransaction) * max_prepared_xacts));
|
||||
for (i = 0; i < max_prepared_xacts; i++)
|
||||
{
|
||||
/* insert into linked list */
|
||||
gxacts[i].next = TwoPhaseState->freeGXacts;
|
||||
TwoPhaseState->freeGXacts = &gxacts[i];
|
||||
|
||||
/* associate it with a PGPROC assigned by ProcGlobalShmemInit */
|
||||
gxacts[i].pgprocno = GetNumberFromPGProc(&PreparedXactProcs[i]);
|
||||
}
|
||||
/* associate it with a PGPROC assigned by ProcGlobalShmemInit */
|
||||
gxacts[i].pgprocno = GetNumberFromPGProc(&PreparedXactProcs[i]);
|
||||
}
|
||||
else
|
||||
Assert(found);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@
|
|||
#include "storage/procsignal.h"
|
||||
#include "storage/reinit.h"
|
||||
#include "storage/spin.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "storage/sync.h"
|
||||
#include "utils/guc_hooks.h"
|
||||
#include "utils/guc_tables.h"
|
||||
|
|
@ -579,8 +580,19 @@ static WALInsertLockPadded *WALInsertLocks = NULL;
|
|||
/*
|
||||
* We maintain an image of pg_control in shared memory.
|
||||
*/
|
||||
static ControlFileData *LocalControlFile = NULL;
|
||||
static ControlFileData *ControlFile = NULL;
|
||||
|
||||
static void XLOGShmemRequest(void *arg);
|
||||
static void XLOGShmemInit(void *arg);
|
||||
static void XLOGShmemAttach(void *arg);
|
||||
|
||||
const ShmemCallbacks XLOGShmemCallbacks = {
|
||||
.request_fn = XLOGShmemRequest,
|
||||
.init_fn = XLOGShmemInit,
|
||||
.attach_fn = XLOGShmemAttach,
|
||||
};
|
||||
|
||||
/*
|
||||
* Calculate the amount of space left on the page after 'endptr'. Beware
|
||||
* multiple evaluation!
|
||||
|
|
@ -5257,7 +5269,8 @@ void
|
|||
LocalProcessControlFile(bool reset)
|
||||
{
|
||||
Assert(reset || ControlFile == NULL);
|
||||
ControlFile = palloc_object(ControlFileData);
|
||||
LocalControlFile = palloc_object(ControlFileData);
|
||||
ControlFile = LocalControlFile;
|
||||
ReadControlFile();
|
||||
SetLocalDataChecksumState(ControlFile->data_checksum_version);
|
||||
}
|
||||
|
|
@ -5274,10 +5287,10 @@ GetActiveWalLevelOnStandby(void)
|
|||
}
|
||||
|
||||
/*
|
||||
* Initialization of shared memory for XLOG
|
||||
* Register shared memory for XLOG.
|
||||
*/
|
||||
Size
|
||||
XLOGShmemSize(void)
|
||||
static void
|
||||
XLOGShmemRequest(void *arg)
|
||||
{
|
||||
Size size;
|
||||
|
||||
|
|
@ -5317,23 +5330,24 @@ XLOGShmemSize(void)
|
|||
/* and the buffers themselves */
|
||||
size = add_size(size, mul_size(XLOG_BLCKSZ, XLOGbuffers));
|
||||
|
||||
/*
|
||||
* Note: we don't count ControlFileData, it comes out of the "slop factor"
|
||||
* added by CreateSharedMemoryAndSemaphores. This lets us use this
|
||||
* routine again below to compute the actual allocation size.
|
||||
*/
|
||||
|
||||
return size;
|
||||
ShmemRequestStruct(.name = "XLOG Ctl",
|
||||
.size = size,
|
||||
.ptr = (void **) &XLogCtl,
|
||||
);
|
||||
ShmemRequestStruct(.name = "Control File",
|
||||
.size = sizeof(ControlFileData),
|
||||
.ptr = (void **) &ControlFile,
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
XLOGShmemInit(void)
|
||||
/*
|
||||
* XLOGShmemInit - initialize the XLogCtl shared memory area.
|
||||
*/
|
||||
static void
|
||||
XLOGShmemInit(void *arg)
|
||||
{
|
||||
bool foundCFile,
|
||||
foundXLog;
|
||||
char *allocptr;
|
||||
int i;
|
||||
ControlFileData *localControlFile;
|
||||
|
||||
#ifdef WAL_DEBUG
|
||||
|
||||
|
|
@ -5351,36 +5365,17 @@ XLOGShmemInit(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
XLogCtl = (XLogCtlData *)
|
||||
ShmemInitStruct("XLOG Ctl", XLOGShmemSize(), &foundXLog);
|
||||
|
||||
localControlFile = ControlFile;
|
||||
ControlFile = (ControlFileData *)
|
||||
ShmemInitStruct("Control File", sizeof(ControlFileData), &foundCFile);
|
||||
|
||||
if (foundCFile || foundXLog)
|
||||
{
|
||||
/* both should be present or neither */
|
||||
Assert(foundCFile && foundXLog);
|
||||
|
||||
/* Initialize local copy of WALInsertLocks */
|
||||
WALInsertLocks = XLogCtl->Insert.WALInsertLocks;
|
||||
|
||||
if (localControlFile)
|
||||
pfree(localControlFile);
|
||||
return;
|
||||
}
|
||||
memset(XLogCtl, 0, sizeof(XLogCtlData));
|
||||
|
||||
/*
|
||||
* Already have read control file locally, unless in bootstrap mode. Move
|
||||
* contents into shared memory.
|
||||
*/
|
||||
if (localControlFile)
|
||||
if (LocalControlFile)
|
||||
{
|
||||
memcpy(ControlFile, localControlFile, sizeof(ControlFileData));
|
||||
pfree(localControlFile);
|
||||
memcpy(ControlFile, LocalControlFile, sizeof(ControlFileData));
|
||||
pfree(LocalControlFile);
|
||||
LocalControlFile = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -5442,6 +5437,15 @@ XLOGShmemInit(void)
|
|||
pg_atomic_init_u64(&XLogCtl->unloggedLSN, InvalidXLogRecPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* XLOGShmemAttach - re-establish WALInsertLocks pointer after attaching.
|
||||
*/
|
||||
static void
|
||||
XLOGShmemAttach(void *arg)
|
||||
{
|
||||
WALInsertLocks = XLogCtl->Insert.WALInsertLocks;
|
||||
}
|
||||
|
||||
/*
|
||||
* This func must be called ONCE on system install. It creates pg_control
|
||||
* and the initial XLOG segment.
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include "storage/fd.h"
|
||||
#include "storage/shmem.h"
|
||||
#include "storage/smgr.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/fmgrprotos.h"
|
||||
#include "utils/guc_hooks.h"
|
||||
#include "utils/hsearch.h"
|
||||
|
|
@ -200,6 +201,14 @@ static LsnReadQueueNextStatus XLogPrefetcherNextBlock(uintptr_t pgsr_private,
|
|||
|
||||
static XLogPrefetchStats *SharedStats;
|
||||
|
||||
static void XLogPrefetchShmemRequest(void *arg);
|
||||
static void XLogPrefetchShmemInit(void *arg);
|
||||
|
||||
const ShmemCallbacks XLogPrefetchShmemCallbacks = {
|
||||
.request_fn = XLogPrefetchShmemRequest,
|
||||
.init_fn = XLogPrefetchShmemInit,
|
||||
};
|
||||
|
||||
static inline LsnReadQueue *
|
||||
lrq_alloc(uint32 max_distance,
|
||||
uint32 max_inflight,
|
||||
|
|
@ -292,10 +301,25 @@ lrq_complete_lsn(LsnReadQueue *lrq, XLogRecPtr lsn)
|
|||
lrq_prefetch(lrq);
|
||||
}
|
||||
|
||||
size_t
|
||||
XLogPrefetchShmemSize(void)
|
||||
static void
|
||||
XLogPrefetchShmemRequest(void *arg)
|
||||
{
|
||||
return sizeof(XLogPrefetchStats);
|
||||
ShmemRequestStruct(.name = "XLogPrefetchStats",
|
||||
.size = sizeof(XLogPrefetchStats),
|
||||
.ptr = (void **) &SharedStats,
|
||||
);
|
||||
}
|
||||
|
||||
static void
|
||||
XLogPrefetchShmemInit(void *arg)
|
||||
{
|
||||
pg_atomic_init_u64(&SharedStats->reset_time, GetCurrentTimestamp());
|
||||
pg_atomic_init_u64(&SharedStats->prefetch, 0);
|
||||
pg_atomic_init_u64(&SharedStats->hit, 0);
|
||||
pg_atomic_init_u64(&SharedStats->skip_init, 0);
|
||||
pg_atomic_init_u64(&SharedStats->skip_new, 0);
|
||||
pg_atomic_init_u64(&SharedStats->skip_fpw, 0);
|
||||
pg_atomic_init_u64(&SharedStats->skip_rep, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -313,27 +337,6 @@ XLogPrefetchResetStats(void)
|
|||
pg_atomic_write_u64(&SharedStats->skip_rep, 0);
|
||||
}
|
||||
|
||||
void
|
||||
XLogPrefetchShmemInit(void)
|
||||
{
|
||||
bool found;
|
||||
|
||||
SharedStats = (XLogPrefetchStats *)
|
||||
ShmemInitStruct("XLogPrefetchStats",
|
||||
sizeof(XLogPrefetchStats),
|
||||
&found);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
pg_atomic_init_u64(&SharedStats->reset_time, GetCurrentTimestamp());
|
||||
pg_atomic_init_u64(&SharedStats->prefetch, 0);
|
||||
pg_atomic_init_u64(&SharedStats->hit, 0);
|
||||
pg_atomic_init_u64(&SharedStats->skip_init, 0);
|
||||
pg_atomic_init_u64(&SharedStats->skip_new, 0);
|
||||
pg_atomic_init_u64(&SharedStats->skip_fpw, 0);
|
||||
pg_atomic_init_u64(&SharedStats->skip_rep, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when any GUC is changed that affects prefetching.
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@
|
|||
#include "storage/pmsignal.h"
|
||||
#include "storage/procarray.h"
|
||||
#include "storage/spin.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/datetime.h"
|
||||
#include "utils/fmgrprotos.h"
|
||||
#include "utils/guc_hooks.h"
|
||||
|
|
@ -307,6 +308,14 @@ static char *primary_image_masked = NULL;
|
|||
|
||||
XLogRecoveryCtlData *XLogRecoveryCtl = NULL;
|
||||
|
||||
static void XLogRecoveryShmemRequest(void *arg);
|
||||
static void XLogRecoveryShmemInit(void *arg);
|
||||
|
||||
const ShmemCallbacks XLogRecoveryShmemCallbacks = {
|
||||
.request_fn = XLogRecoveryShmemRequest,
|
||||
.init_fn = XLogRecoveryShmemInit,
|
||||
};
|
||||
|
||||
/*
|
||||
* abortedRecPtr is the start pointer of a broken record at end of WAL when
|
||||
* recovery completes; missingContrecPtr is the location of the first
|
||||
|
|
@ -385,28 +394,20 @@ static void SetCurrentChunkStartTime(TimestampTz xtime);
|
|||
static void SetLatestXTime(TimestampTz xtime);
|
||||
|
||||
/*
|
||||
* Initialization of shared memory for WAL recovery
|
||||
* Register shared memory for WAL recovery
|
||||
*/
|
||||
Size
|
||||
XLogRecoveryShmemSize(void)
|
||||
static void
|
||||
XLogRecoveryShmemRequest(void *arg)
|
||||
{
|
||||
Size size;
|
||||
|
||||
/* XLogRecoveryCtl */
|
||||
size = sizeof(XLogRecoveryCtlData);
|
||||
|
||||
return size;
|
||||
ShmemRequestStruct(.name = "XLOG Recovery Ctl",
|
||||
.size = sizeof(XLogRecoveryCtlData),
|
||||
.ptr = (void **) &XLogRecoveryCtl,
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
XLogRecoveryShmemInit(void)
|
||||
static void
|
||||
XLogRecoveryShmemInit(void *arg)
|
||||
{
|
||||
bool found;
|
||||
|
||||
XLogRecoveryCtl = (XLogRecoveryCtlData *)
|
||||
ShmemInitStruct("XLOG Recovery Ctl", XLogRecoveryShmemSize(), &found);
|
||||
if (found)
|
||||
return;
|
||||
memset(XLogRecoveryCtl, 0, sizeof(XLogRecoveryCtlData));
|
||||
|
||||
SpinLockInit(&XLogRecoveryCtl->info_lck);
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
#include "storage/latch.h"
|
||||
#include "storage/proc.h"
|
||||
#include "storage/shmem.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/fmgrprotos.h"
|
||||
#include "utils/pg_lsn.h"
|
||||
#include "utils/snapmgr.h"
|
||||
|
|
@ -68,6 +69,14 @@ static int waitlsn_cmp(const pairingheap_node *a, const pairingheap_node *b,
|
|||
|
||||
struct WaitLSNState *waitLSNState = NULL;
|
||||
|
||||
static void WaitLSNShmemRequest(void *arg);
|
||||
static void WaitLSNShmemInit(void *arg);
|
||||
|
||||
const ShmemCallbacks WaitLSNShmemCallbacks = {
|
||||
.request_fn = WaitLSNShmemRequest,
|
||||
.init_fn = WaitLSNShmemInit,
|
||||
};
|
||||
|
||||
/*
|
||||
* Wait event for each WaitLSNType, used with WaitLatch() to report
|
||||
* the wait in pg_stat_activity.
|
||||
|
|
@ -109,41 +118,34 @@ GetCurrentLSNForWaitType(WaitLSNType lsnType)
|
|||
pg_unreachable();
|
||||
}
|
||||
|
||||
/* Report the amount of shared memory space needed for WaitLSNState. */
|
||||
Size
|
||||
WaitLSNShmemSize(void)
|
||||
/* Register the shared memory space needed for WaitLSNState. */
|
||||
static void
|
||||
WaitLSNShmemRequest(void *arg)
|
||||
{
|
||||
Size size;
|
||||
|
||||
size = offsetof(WaitLSNState, procInfos);
|
||||
size = add_size(size, mul_size(MaxBackends + NUM_AUXILIARY_PROCS, sizeof(WaitLSNProcInfo)));
|
||||
return size;
|
||||
ShmemRequestStruct(.name = "WaitLSNState",
|
||||
.size = size,
|
||||
.ptr = (void **) &waitLSNState,
|
||||
);
|
||||
}
|
||||
|
||||
/* Initialize the WaitLSNState in the shared memory. */
|
||||
void
|
||||
WaitLSNShmemInit(void)
|
||||
static void
|
||||
WaitLSNShmemInit(void *arg)
|
||||
{
|
||||
bool found;
|
||||
|
||||
waitLSNState = (WaitLSNState *) ShmemInitStruct("WaitLSNState",
|
||||
WaitLSNShmemSize(),
|
||||
&found);
|
||||
if (!found)
|
||||
/* Initialize heaps and tracking */
|
||||
for (int i = 0; i < WAIT_LSN_TYPE_COUNT; i++)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Initialize heaps and tracking */
|
||||
for (i = 0; i < WAIT_LSN_TYPE_COUNT; i++)
|
||||
{
|
||||
pg_atomic_init_u64(&waitLSNState->minWaitedLSN[i], PG_UINT64_MAX);
|
||||
pairingheap_initialize(&waitLSNState->waitersHeap[i], waitlsn_cmp, NULL);
|
||||
}
|
||||
|
||||
/* Initialize process info array */
|
||||
memset(&waitLSNState->procInfos, 0,
|
||||
(MaxBackends + NUM_AUXILIARY_PROCS) * sizeof(WaitLSNProcInfo));
|
||||
pg_atomic_init_u64(&waitLSNState->minWaitedLSN[i], PG_UINT64_MAX);
|
||||
pairingheap_initialize(&waitLSNState->waitersHeap[i], waitlsn_cmp, NULL);
|
||||
}
|
||||
|
||||
/* Initialize process info array */
|
||||
memset(&waitLSNState->procInfos, 0,
|
||||
(MaxBackends + NUM_AUXILIARY_PROCS) * sizeof(WaitLSNProcInfo));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@
|
|||
#include "storage/proc.h"
|
||||
#include "storage/procsignal.h"
|
||||
#include "storage/smgr.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "tcop/tcopprot.h"
|
||||
#include "utils/fmgroids.h"
|
||||
#include "utils/fmgrprotos.h"
|
||||
|
|
@ -309,6 +310,14 @@ typedef struct
|
|||
|
||||
static AutoVacuumShmemStruct *AutoVacuumShmem;
|
||||
|
||||
static void AutoVacuumShmemRequest(void *arg);
|
||||
static void AutoVacuumShmemInit(void *arg);
|
||||
|
||||
const ShmemCallbacks AutoVacuumShmemCallbacks = {
|
||||
.request_fn = AutoVacuumShmemRequest,
|
||||
.init_fn = AutoVacuumShmemInit,
|
||||
};
|
||||
|
||||
/*
|
||||
* the database list (of avl_dbase elements) in the launcher, and the context
|
||||
* that contains it
|
||||
|
|
@ -3545,11 +3554,11 @@ autovac_init(void)
|
|||
}
|
||||
|
||||
/*
|
||||
* AutoVacuumShmemSize
|
||||
* Compute space needed for autovacuum-related shared memory
|
||||
* AutoVacuumShmemRequest
|
||||
* Register shared memory space needed for autovacuum
|
||||
*/
|
||||
Size
|
||||
AutoVacuumShmemSize(void)
|
||||
static void
|
||||
AutoVacuumShmemRequest(void *arg)
|
||||
{
|
||||
Size size;
|
||||
|
||||
|
|
@ -3560,53 +3569,41 @@ AutoVacuumShmemSize(void)
|
|||
size = MAXALIGN(size);
|
||||
size = add_size(size, mul_size(autovacuum_worker_slots,
|
||||
sizeof(WorkerInfoData)));
|
||||
return size;
|
||||
|
||||
ShmemRequestStruct(.name = "AutoVacuum Data",
|
||||
.size = size,
|
||||
.ptr = (void **) &AutoVacuumShmem,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* AutoVacuumShmemInit
|
||||
* Allocate and initialize autovacuum-related shared memory
|
||||
* Initialize autovacuum-related shared memory
|
||||
*/
|
||||
void
|
||||
AutoVacuumShmemInit(void)
|
||||
static void
|
||||
AutoVacuumShmemInit(void *arg)
|
||||
{
|
||||
bool found;
|
||||
WorkerInfo worker;
|
||||
|
||||
AutoVacuumShmem = (AutoVacuumShmemStruct *)
|
||||
ShmemInitStruct("AutoVacuum Data",
|
||||
AutoVacuumShmemSize(),
|
||||
&found);
|
||||
AutoVacuumShmem->av_launcherpid = 0;
|
||||
dclist_init(&AutoVacuumShmem->av_freeWorkers);
|
||||
dlist_init(&AutoVacuumShmem->av_runningWorkers);
|
||||
AutoVacuumShmem->av_startingWorker = NULL;
|
||||
memset(AutoVacuumShmem->av_workItems, 0,
|
||||
sizeof(AutoVacuumWorkItem) * NUM_WORKITEMS);
|
||||
|
||||
if (!IsUnderPostmaster)
|
||||
worker = (WorkerInfo) ((char *) AutoVacuumShmem +
|
||||
MAXALIGN(sizeof(AutoVacuumShmemStruct)));
|
||||
|
||||
/* initialize the WorkerInfo free list */
|
||||
for (int i = 0; i < autovacuum_worker_slots; i++)
|
||||
{
|
||||
WorkerInfo worker;
|
||||
int i;
|
||||
|
||||
Assert(!found);
|
||||
|
||||
AutoVacuumShmem->av_launcherpid = 0;
|
||||
dclist_init(&AutoVacuumShmem->av_freeWorkers);
|
||||
dlist_init(&AutoVacuumShmem->av_runningWorkers);
|
||||
AutoVacuumShmem->av_startingWorker = NULL;
|
||||
memset(AutoVacuumShmem->av_workItems, 0,
|
||||
sizeof(AutoVacuumWorkItem) * NUM_WORKITEMS);
|
||||
|
||||
worker = (WorkerInfo) ((char *) AutoVacuumShmem +
|
||||
MAXALIGN(sizeof(AutoVacuumShmemStruct)));
|
||||
|
||||
/* initialize the WorkerInfo free list */
|
||||
for (i = 0; i < autovacuum_worker_slots; i++)
|
||||
{
|
||||
dclist_push_head(&AutoVacuumShmem->av_freeWorkers,
|
||||
&worker[i].wi_links);
|
||||
pg_atomic_init_flag(&worker[i].wi_dobalance);
|
||||
}
|
||||
|
||||
pg_atomic_init_u32(&AutoVacuumShmem->av_nworkersForBalance, 0);
|
||||
|
||||
dclist_push_head(&AutoVacuumShmem->av_freeWorkers,
|
||||
&worker[i].wi_links);
|
||||
pg_atomic_init_flag(&worker[i].wi_dobalance);
|
||||
}
|
||||
else
|
||||
Assert(found);
|
||||
|
||||
pg_atomic_init_u32(&AutoVacuumShmem->av_nworkersForBalance, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "storage/procarray.h"
|
||||
#include "storage/procsignal.h"
|
||||
#include "storage/shmem.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "tcop/tcopprot.h"
|
||||
#include "utils/ascii.h"
|
||||
#include "utils/memutils.h"
|
||||
|
|
@ -110,6 +111,14 @@ struct BackgroundWorkerHandle
|
|||
|
||||
static BackgroundWorkerArray *BackgroundWorkerData;
|
||||
|
||||
static void BackgroundWorkerShmemRequest(void *arg);
|
||||
static void BackgroundWorkerShmemInit(void *arg);
|
||||
|
||||
const ShmemCallbacks BackgroundWorkerShmemCallbacks = {
|
||||
.request_fn = BackgroundWorkerShmemRequest,
|
||||
.init_fn = BackgroundWorkerShmemInit,
|
||||
};
|
||||
|
||||
/*
|
||||
* List of internal background worker entry points. We need this for
|
||||
* reasons explained in LookupBackgroundWorkerFunction(), below.
|
||||
|
|
@ -160,10 +169,10 @@ static bgworker_main_type LookupBackgroundWorkerFunction(const char *libraryname
|
|||
|
||||
|
||||
/*
|
||||
* Calculate shared memory needed.
|
||||
* Register shared memory needed for background workers.
|
||||
*/
|
||||
Size
|
||||
BackgroundWorkerShmemSize(void)
|
||||
static void
|
||||
BackgroundWorkerShmemRequest(void *arg)
|
||||
{
|
||||
Size size;
|
||||
|
||||
|
|
@ -171,66 +180,58 @@ BackgroundWorkerShmemSize(void)
|
|||
size = offsetof(BackgroundWorkerArray, slot);
|
||||
size = add_size(size, mul_size(max_worker_processes,
|
||||
sizeof(BackgroundWorkerSlot)));
|
||||
|
||||
return size;
|
||||
ShmemRequestStruct(.name = "Background Worker Data",
|
||||
.size = size,
|
||||
.ptr = (void **) &BackgroundWorkerData,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize shared memory.
|
||||
* Initialize shared memory for background workers.
|
||||
*/
|
||||
void
|
||||
BackgroundWorkerShmemInit(void)
|
||||
static void
|
||||
BackgroundWorkerShmemInit(void *arg)
|
||||
{
|
||||
bool found;
|
||||
dlist_iter iter;
|
||||
int slotno = 0;
|
||||
|
||||
BackgroundWorkerData = ShmemInitStruct("Background Worker Data",
|
||||
BackgroundWorkerShmemSize(),
|
||||
&found);
|
||||
if (!IsUnderPostmaster)
|
||||
BackgroundWorkerData->total_slots = max_worker_processes;
|
||||
BackgroundWorkerData->parallel_register_count = 0;
|
||||
BackgroundWorkerData->parallel_terminate_count = 0;
|
||||
|
||||
/*
|
||||
* Copy contents of worker list into shared memory. Record the shared
|
||||
* memory slot assigned to each worker. This ensures a 1-to-1
|
||||
* correspondence between the postmaster's private list and the array in
|
||||
* shared memory.
|
||||
*/
|
||||
dlist_foreach(iter, &BackgroundWorkerList)
|
||||
{
|
||||
dlist_iter iter;
|
||||
int slotno = 0;
|
||||
BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno];
|
||||
RegisteredBgWorker *rw;
|
||||
|
||||
BackgroundWorkerData->total_slots = max_worker_processes;
|
||||
BackgroundWorkerData->parallel_register_count = 0;
|
||||
BackgroundWorkerData->parallel_terminate_count = 0;
|
||||
|
||||
/*
|
||||
* Copy contents of worker list into shared memory. Record the shared
|
||||
* memory slot assigned to each worker. This ensures a 1-to-1
|
||||
* correspondence between the postmaster's private list and the array
|
||||
* in shared memory.
|
||||
*/
|
||||
dlist_foreach(iter, &BackgroundWorkerList)
|
||||
{
|
||||
BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno];
|
||||
RegisteredBgWorker *rw;
|
||||
|
||||
rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
|
||||
Assert(slotno < max_worker_processes);
|
||||
slot->in_use = true;
|
||||
slot->terminate = false;
|
||||
slot->pid = InvalidPid;
|
||||
slot->generation = 0;
|
||||
rw->rw_shmem_slot = slotno;
|
||||
rw->rw_worker.bgw_notify_pid = 0; /* might be reinit after crash */
|
||||
memcpy(&slot->worker, &rw->rw_worker, sizeof(BackgroundWorker));
|
||||
++slotno;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark any remaining slots as not in use.
|
||||
*/
|
||||
while (slotno < max_worker_processes)
|
||||
{
|
||||
BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno];
|
||||
|
||||
slot->in_use = false;
|
||||
++slotno;
|
||||
}
|
||||
rw = dlist_container(RegisteredBgWorker, rw_lnode, iter.cur);
|
||||
Assert(slotno < max_worker_processes);
|
||||
slot->in_use = true;
|
||||
slot->terminate = false;
|
||||
slot->pid = InvalidPid;
|
||||
slot->generation = 0;
|
||||
rw->rw_shmem_slot = slotno;
|
||||
rw->rw_worker.bgw_notify_pid = 0; /* might be reinit after crash */
|
||||
memcpy(&slot->worker, &rw->rw_worker, sizeof(BackgroundWorker));
|
||||
++slotno;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark any remaining slots as not in use.
|
||||
*/
|
||||
while (slotno < max_worker_processes)
|
||||
{
|
||||
BackgroundWorkerSlot *slot = &BackgroundWorkerData->slot[slotno];
|
||||
|
||||
slot->in_use = false;
|
||||
++slotno;
|
||||
}
|
||||
else
|
||||
Assert(found);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@
|
|||
#include "storage/shmem.h"
|
||||
#include "storage/smgr.h"
|
||||
#include "storage/spin.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/acl.h"
|
||||
#include "utils/guc.h"
|
||||
#include "utils/memutils.h"
|
||||
|
|
@ -143,6 +144,14 @@ typedef struct
|
|||
|
||||
static CheckpointerShmemStruct *CheckpointerShmem;
|
||||
|
||||
static void CheckpointerShmemRequest(void *arg);
|
||||
static void CheckpointerShmemInit(void *arg);
|
||||
|
||||
const ShmemCallbacks CheckpointerShmemCallbacks = {
|
||||
.request_fn = CheckpointerShmemRequest,
|
||||
.init_fn = CheckpointerShmemInit,
|
||||
};
|
||||
|
||||
/* interval for calling AbsorbSyncRequests in CheckpointWriteDelay */
|
||||
#define WRITES_PER_ABSORB 1000
|
||||
|
||||
|
|
@ -950,11 +959,11 @@ ReqShutdownXLOG(SIGNAL_ARGS)
|
|||
*/
|
||||
|
||||
/*
|
||||
* CheckpointerShmemSize
|
||||
* Compute space needed for checkpointer-related shared memory
|
||||
* CheckpointerShmemRequest
|
||||
* Register shared memory space needed for checkpointer
|
||||
*/
|
||||
Size
|
||||
CheckpointerShmemSize(void)
|
||||
static void
|
||||
CheckpointerShmemRequest(void *arg)
|
||||
{
|
||||
Size size;
|
||||
|
||||
|
|
@ -967,39 +976,24 @@ CheckpointerShmemSize(void)
|
|||
size = add_size(size, mul_size(Min(NBuffers,
|
||||
MAX_CHECKPOINT_REQUESTS),
|
||||
sizeof(CheckpointerRequest)));
|
||||
|
||||
return size;
|
||||
ShmemRequestStruct(.name = "Checkpointer Data",
|
||||
.size = size,
|
||||
.ptr = (void **) &CheckpointerShmem,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* CheckpointerShmemInit
|
||||
* Allocate and initialize checkpointer-related shared memory
|
||||
* Initialize checkpointer-related shared memory
|
||||
*/
|
||||
void
|
||||
CheckpointerShmemInit(void)
|
||||
static void
|
||||
CheckpointerShmemInit(void *arg)
|
||||
{
|
||||
Size size = CheckpointerShmemSize();
|
||||
bool found;
|
||||
|
||||
CheckpointerShmem = (CheckpointerShmemStruct *)
|
||||
ShmemInitStruct("Checkpointer Data",
|
||||
size,
|
||||
&found);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
/*
|
||||
* First time through, so initialize. Note that we zero the whole
|
||||
* requests array; this is so that CompactCheckpointerRequestQueue can
|
||||
* assume that any pad bytes in the request structs are zeroes.
|
||||
*/
|
||||
MemSet(CheckpointerShmem, 0, size);
|
||||
SpinLockInit(&CheckpointerShmem->ckpt_lck);
|
||||
CheckpointerShmem->max_requests = Min(NBuffers, MAX_CHECKPOINT_REQUESTS);
|
||||
CheckpointerShmem->head = CheckpointerShmem->tail = 0;
|
||||
ConditionVariableInit(&CheckpointerShmem->start_cv);
|
||||
ConditionVariableInit(&CheckpointerShmem->done_cv);
|
||||
}
|
||||
SpinLockInit(&CheckpointerShmem->ckpt_lck);
|
||||
CheckpointerShmem->max_requests = Min(NBuffers, MAX_CHECKPOINT_REQUESTS);
|
||||
CheckpointerShmem->head = CheckpointerShmem->tail = 0;
|
||||
ConditionVariableInit(&CheckpointerShmem->start_cv);
|
||||
ConditionVariableInit(&CheckpointerShmem->done_cv);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -211,6 +211,7 @@
|
|||
#include "storage/lwlock.h"
|
||||
#include "storage/procarray.h"
|
||||
#include "storage/smgr.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "tcop/tcopprot.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/fmgroids.h"
|
||||
|
|
@ -346,6 +347,7 @@ static volatile sig_atomic_t launcher_running = false;
|
|||
static DataChecksumsWorkerOperation operation;
|
||||
|
||||
/* Prototypes */
|
||||
static void DataChecksumsShmemRequest(void *arg);
|
||||
static bool DatabaseExists(Oid dboid);
|
||||
static List *BuildDatabaseList(void);
|
||||
static List *BuildRelationList(bool temp_relations, bool include_shared);
|
||||
|
|
@ -356,6 +358,10 @@ static bool ProcessSingleRelationFork(Relation reln, ForkNumber forkNum, BufferA
|
|||
static void launcher_cancel_handler(SIGNAL_ARGS);
|
||||
static void WaitForAllTransactionsToFinish(void);
|
||||
|
||||
const ShmemCallbacks DataChecksumsShmemCallbacks = {
|
||||
.request_fn = DataChecksumsShmemRequest,
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* Functionality for manipulating the data checksum state in the cluster
|
||||
*/
|
||||
|
|
@ -1236,35 +1242,16 @@ ProcessAllDatabases(void)
|
|||
}
|
||||
|
||||
/*
|
||||
* DataChecksumStateSize
|
||||
* Compute required space for datachecksumsworker-related shared memory
|
||||
* DataChecksumShmemRequest
|
||||
* Request datachecksumsworker-related shared memory
|
||||
*/
|
||||
Size
|
||||
DataChecksumsShmemSize(void)
|
||||
static void
|
||||
DataChecksumsShmemRequest(void *arg)
|
||||
{
|
||||
Size size;
|
||||
|
||||
size = sizeof(DataChecksumsStateStruct);
|
||||
size = MAXALIGN(size);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/*
|
||||
* DataChecksumStateInit
|
||||
* Allocate and initialize datachecksumsworker-related shared memory
|
||||
*/
|
||||
void
|
||||
DataChecksumsShmemInit(void)
|
||||
{
|
||||
bool found;
|
||||
|
||||
DataChecksumState = (DataChecksumsStateStruct *)
|
||||
ShmemInitStruct("DataChecksumsWorker Data",
|
||||
DataChecksumsShmemSize(),
|
||||
&found);
|
||||
if (!found)
|
||||
MemSet(DataChecksumState, 0, DataChecksumsShmemSize());
|
||||
ShmemRequestStruct(.name = "DataChecksumsWorker Data",
|
||||
.size = sizeof(DataChecksumsStateStruct),
|
||||
.ptr = (void **) &DataChecksumState,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
#include "storage/proc.h"
|
||||
#include "storage/procsignal.h"
|
||||
#include "storage/shmem.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/guc.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/ps_status.h"
|
||||
|
|
@ -154,33 +155,31 @@ static int ready_file_comparator(Datum a, Datum b, void *arg);
|
|||
static void LoadArchiveLibrary(void);
|
||||
static void pgarch_call_module_shutdown_cb(int code, Datum arg);
|
||||
|
||||
/* Report shared memory space needed by PgArchShmemInit */
|
||||
Size
|
||||
PgArchShmemSize(void)
|
||||
static void PgArchShmemRequest(void *arg);
|
||||
static void PgArchShmemInit(void *arg);
|
||||
|
||||
const ShmemCallbacks PgArchShmemCallbacks = {
|
||||
.request_fn = PgArchShmemRequest,
|
||||
.init_fn = PgArchShmemInit,
|
||||
};
|
||||
|
||||
/* Register shared memory space needed by the archiver */
|
||||
static void
|
||||
PgArchShmemRequest(void *arg)
|
||||
{
|
||||
Size size = 0;
|
||||
|
||||
size = add_size(size, sizeof(PgArchData));
|
||||
|
||||
return size;
|
||||
ShmemRequestStruct(.name = "Archiver Data",
|
||||
.size = sizeof(PgArchData),
|
||||
.ptr = (void **) &PgArch,
|
||||
);
|
||||
}
|
||||
|
||||
/* Allocate and initialize archiver-related shared memory */
|
||||
void
|
||||
PgArchShmemInit(void)
|
||||
/* Initialize archiver-related shared memory */
|
||||
static void
|
||||
PgArchShmemInit(void *arg)
|
||||
{
|
||||
bool found;
|
||||
|
||||
PgArch = (PgArchData *)
|
||||
ShmemInitStruct("Archiver Data", PgArchShmemSize(), &found);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
/* First time through, so initialize */
|
||||
MemSet(PgArch, 0, PgArchShmemSize());
|
||||
PgArch->pgprocno = INVALID_PROC_NUMBER;
|
||||
pg_atomic_init_u32(&PgArch->force_dir_scan, 0);
|
||||
}
|
||||
MemSet(PgArch, 0, sizeof(PgArchData));
|
||||
PgArch->pgprocno = INVALID_PROC_NUMBER;
|
||||
pg_atomic_init_u32(&PgArch->force_dir_scan, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
#include "storage/proc.h"
|
||||
#include "storage/procsignal.h"
|
||||
#include "storage/shmem.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/guc.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/wait_event.h"
|
||||
|
|
@ -109,6 +110,14 @@ typedef struct
|
|||
/* Pointer to shared memory state. */
|
||||
static WalSummarizerData *WalSummarizerCtl;
|
||||
|
||||
static void WalSummarizerShmemRequest(void *arg);
|
||||
static void WalSummarizerShmemInit(void *arg);
|
||||
|
||||
const ShmemCallbacks WalSummarizerShmemCallbacks = {
|
||||
.request_fn = WalSummarizerShmemRequest,
|
||||
.init_fn = WalSummarizerShmemInit,
|
||||
};
|
||||
|
||||
/*
|
||||
* When we reach end of WAL and need to read more, we sleep for a number of
|
||||
* milliseconds that is an integer multiple of MS_PER_SLEEP_QUANTUM. This is
|
||||
|
|
@ -168,43 +177,34 @@ static void summarizer_wait_for_wal(void);
|
|||
static void MaybeRemoveOldWalSummaries(void);
|
||||
|
||||
/*
|
||||
* Amount of shared memory required for this module.
|
||||
* Register shared memory space needed by this module.
|
||||
*/
|
||||
Size
|
||||
WalSummarizerShmemSize(void)
|
||||
static void
|
||||
WalSummarizerShmemRequest(void *arg)
|
||||
{
|
||||
return sizeof(WalSummarizerData);
|
||||
ShmemRequestStruct(.name = "Wal Summarizer Ctl",
|
||||
.size = sizeof(WalSummarizerData),
|
||||
.ptr = (void **) &WalSummarizerCtl,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create or attach to shared memory segment for this module.
|
||||
* Initialize shared memory for this module.
|
||||
*/
|
||||
void
|
||||
WalSummarizerShmemInit(void)
|
||||
static void
|
||||
WalSummarizerShmemInit(void *arg)
|
||||
{
|
||||
bool found;
|
||||
|
||||
WalSummarizerCtl = (WalSummarizerData *)
|
||||
ShmemInitStruct("Wal Summarizer Ctl", WalSummarizerShmemSize(),
|
||||
&found);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
/*
|
||||
* First time through, so initialize.
|
||||
*
|
||||
* We're just filling in dummy values here -- the real initialization
|
||||
* will happen when GetOldestUnsummarizedLSN() is called for the first
|
||||
* time.
|
||||
*/
|
||||
WalSummarizerCtl->initialized = false;
|
||||
WalSummarizerCtl->summarized_tli = 0;
|
||||
WalSummarizerCtl->summarized_lsn = InvalidXLogRecPtr;
|
||||
WalSummarizerCtl->lsn_is_exact = false;
|
||||
WalSummarizerCtl->summarizer_pgprocno = INVALID_PROC_NUMBER;
|
||||
WalSummarizerCtl->pending_lsn = InvalidXLogRecPtr;
|
||||
ConditionVariableInit(&WalSummarizerCtl->summary_file_cv);
|
||||
}
|
||||
/*
|
||||
* We're just filling in dummy values here -- the real initialization will
|
||||
* happen when GetOldestUnsummarizedLSN() is called for the first time.
|
||||
*/
|
||||
WalSummarizerCtl->initialized = false;
|
||||
WalSummarizerCtl->summarized_tli = 0;
|
||||
WalSummarizerCtl->summarized_lsn = InvalidXLogRecPtr;
|
||||
WalSummarizerCtl->lsn_is_exact = false;
|
||||
WalSummarizerCtl->summarizer_pgprocno = INVALID_PROC_NUMBER;
|
||||
WalSummarizerCtl->pending_lsn = InvalidXLogRecPtr;
|
||||
ConditionVariableInit(&WalSummarizerCtl->summary_file_cv);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include "storage/ipc.h"
|
||||
#include "storage/proc.h"
|
||||
#include "storage/procarray.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "tcop/tcopprot.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/memutils.h"
|
||||
|
|
@ -71,6 +72,14 @@ typedef struct LogicalRepCtxStruct
|
|||
|
||||
static LogicalRepCtxStruct *LogicalRepCtx;
|
||||
|
||||
static void ApplyLauncherShmemRequest(void *arg);
|
||||
static void ApplyLauncherShmemInit(void *arg);
|
||||
|
||||
const ShmemCallbacks ApplyLauncherShmemCallbacks = {
|
||||
.request_fn = ApplyLauncherShmemRequest,
|
||||
.init_fn = ApplyLauncherShmemInit,
|
||||
};
|
||||
|
||||
/* an entry in the last-start-times shared hash table */
|
||||
typedef struct LauncherLastStartTimesEntry
|
||||
{
|
||||
|
|
@ -972,11 +981,11 @@ logicalrep_pa_worker_count(Oid subid)
|
|||
}
|
||||
|
||||
/*
|
||||
* ApplyLauncherShmemSize
|
||||
* Compute space needed for replication launcher shared memory
|
||||
* ApplyLauncherShmemRequest
|
||||
* Register shared memory space needed for replication launcher
|
||||
*/
|
||||
Size
|
||||
ApplyLauncherShmemSize(void)
|
||||
static void
|
||||
ApplyLauncherShmemRequest(void *arg)
|
||||
{
|
||||
Size size;
|
||||
|
||||
|
|
@ -987,7 +996,10 @@ ApplyLauncherShmemSize(void)
|
|||
size = MAXALIGN(size);
|
||||
size = add_size(size, mul_size(max_logical_replication_workers,
|
||||
sizeof(LogicalRepWorker)));
|
||||
return size;
|
||||
ShmemRequestStruct(.name = "Logical Replication Launcher Data",
|
||||
.size = size,
|
||||
.ptr = (void **) &LogicalRepCtx,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1028,35 +1040,23 @@ ApplyLauncherRegister(void)
|
|||
|
||||
/*
|
||||
* ApplyLauncherShmemInit
|
||||
* Allocate and initialize replication launcher shared memory
|
||||
* Initialize replication launcher shared memory
|
||||
*/
|
||||
void
|
||||
ApplyLauncherShmemInit(void)
|
||||
static void
|
||||
ApplyLauncherShmemInit(void *arg)
|
||||
{
|
||||
bool found;
|
||||
int slot;
|
||||
|
||||
LogicalRepCtx = (LogicalRepCtxStruct *)
|
||||
ShmemInitStruct("Logical Replication Launcher Data",
|
||||
ApplyLauncherShmemSize(),
|
||||
&found);
|
||||
LogicalRepCtx->last_start_dsa = DSA_HANDLE_INVALID;
|
||||
LogicalRepCtx->last_start_dsh = DSHASH_HANDLE_INVALID;
|
||||
|
||||
if (!found)
|
||||
/* Initialize memory and spin locks for each worker slot. */
|
||||
for (slot = 0; slot < max_logical_replication_workers; slot++)
|
||||
{
|
||||
int slot;
|
||||
LogicalRepWorker *worker = &LogicalRepCtx->workers[slot];
|
||||
|
||||
memset(LogicalRepCtx, 0, ApplyLauncherShmemSize());
|
||||
|
||||
LogicalRepCtx->last_start_dsa = DSA_HANDLE_INVALID;
|
||||
LogicalRepCtx->last_start_dsh = DSHASH_HANDLE_INVALID;
|
||||
|
||||
/* Initialize memory and spin locks for each worker slot. */
|
||||
for (slot = 0; slot < max_logical_replication_workers; slot++)
|
||||
{
|
||||
LogicalRepWorker *worker = &LogicalRepCtx->workers[slot];
|
||||
|
||||
memset(worker, 0, sizeof(LogicalRepWorker));
|
||||
SpinLockInit(&worker->relmutex);
|
||||
}
|
||||
memset(worker, 0, sizeof(LogicalRepWorker));
|
||||
SpinLockInit(&worker->relmutex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@
|
|||
#include "storage/proc.h"
|
||||
#include "storage/procarray.h"
|
||||
#include "storage/procsignal.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/injection_point.h"
|
||||
|
||||
/*
|
||||
|
|
@ -98,6 +99,12 @@ typedef struct LogicalDecodingCtlData
|
|||
|
||||
static LogicalDecodingCtlData *LogicalDecodingCtl = NULL;
|
||||
|
||||
static void LogicalDecodingCtlShmemRequest(void *arg);
|
||||
|
||||
const ShmemCallbacks LogicalDecodingCtlShmemCallbacks = {
|
||||
.request_fn = LogicalDecodingCtlShmemRequest,
|
||||
};
|
||||
|
||||
/*
|
||||
* A process-local cache of LogicalDecodingCtl->xlog_logical_info. This is
|
||||
* initialized at process startup, and updated when processing the process
|
||||
|
|
@ -120,23 +127,13 @@ static void update_xlog_logical_info(void);
|
|||
static void abort_logical_decoding_activation(int code, Datum arg);
|
||||
static void write_logical_decoding_status_update_record(bool status);
|
||||
|
||||
Size
|
||||
LogicalDecodingCtlShmemSize(void)
|
||||
static void
|
||||
LogicalDecodingCtlShmemRequest(void *arg)
|
||||
{
|
||||
return sizeof(LogicalDecodingCtlData);
|
||||
}
|
||||
|
||||
void
|
||||
LogicalDecodingCtlShmemInit(void)
|
||||
{
|
||||
bool found;
|
||||
|
||||
LogicalDecodingCtl = ShmemInitStruct("Logical decoding control",
|
||||
LogicalDecodingCtlShmemSize(),
|
||||
&found);
|
||||
|
||||
if (!found)
|
||||
MemSet(LogicalDecodingCtl, 0, LogicalDecodingCtlShmemSize());
|
||||
ShmemRequestStruct(.name = "Logical decoding control",
|
||||
.size = sizeof(LogicalDecodingCtlData),
|
||||
.ptr = (void **) &LogicalDecodingCtl,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@
|
|||
#include "storage/fd.h"
|
||||
#include "storage/ipc.h"
|
||||
#include "storage/lmgr.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/fmgroids.h"
|
||||
#include "utils/guc.h"
|
||||
|
|
@ -176,6 +177,16 @@ ReplOriginXactState replorigin_xact_state = {
|
|||
*/
|
||||
static ReplicationState *replication_states;
|
||||
|
||||
static void ReplicationOriginShmemRequest(void *arg);
|
||||
static void ReplicationOriginShmemInit(void *arg);
|
||||
static void ReplicationOriginShmemAttach(void *arg);
|
||||
|
||||
const ShmemCallbacks ReplicationOriginShmemCallbacks = {
|
||||
.request_fn = ReplicationOriginShmemRequest,
|
||||
.init_fn = ReplicationOriginShmemInit,
|
||||
.attach_fn = ReplicationOriginShmemAttach,
|
||||
};
|
||||
|
||||
/*
|
||||
* Actual shared memory block (replication_states[] is now part of this).
|
||||
*/
|
||||
|
|
@ -539,52 +550,50 @@ replorigin_by_oid(ReplOriginId roident, bool missing_ok, char **roname)
|
|||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Size
|
||||
ReplicationOriginShmemSize(void)
|
||||
static void
|
||||
ReplicationOriginShmemRequest(void *arg)
|
||||
{
|
||||
Size size = 0;
|
||||
|
||||
if (max_active_replication_origins == 0)
|
||||
return size;
|
||||
return;
|
||||
|
||||
size = add_size(size, offsetof(ReplicationStateCtl, states));
|
||||
|
||||
size = add_size(size,
|
||||
mul_size(max_active_replication_origins, sizeof(ReplicationState)));
|
||||
return size;
|
||||
ShmemRequestStruct(.name = "ReplicationOriginState",
|
||||
.size = size,
|
||||
.ptr = (void **) &replication_states_ctl,
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
ReplicationOriginShmemInit(void)
|
||||
static void
|
||||
ReplicationOriginShmemInit(void *arg)
|
||||
{
|
||||
bool found;
|
||||
|
||||
if (max_active_replication_origins == 0)
|
||||
return;
|
||||
|
||||
replication_states_ctl = (ReplicationStateCtl *)
|
||||
ShmemInitStruct("ReplicationOriginState",
|
||||
ReplicationOriginShmemSize(),
|
||||
&found);
|
||||
replication_states = replication_states_ctl->states;
|
||||
|
||||
if (!found)
|
||||
replication_states_ctl->tranche_id = LWTRANCHE_REPLICATION_ORIGIN_STATE;
|
||||
|
||||
for (int i = 0; i < max_active_replication_origins; i++)
|
||||
{
|
||||
int i;
|
||||
|
||||
MemSet(replication_states_ctl, 0, ReplicationOriginShmemSize());
|
||||
|
||||
replication_states_ctl->tranche_id = LWTRANCHE_REPLICATION_ORIGIN_STATE;
|
||||
|
||||
for (i = 0; i < max_active_replication_origins; i++)
|
||||
{
|
||||
LWLockInitialize(&replication_states[i].lock,
|
||||
replication_states_ctl->tranche_id);
|
||||
ConditionVariableInit(&replication_states[i].origin_cv);
|
||||
}
|
||||
LWLockInitialize(&replication_states[i].lock,
|
||||
replication_states_ctl->tranche_id);
|
||||
ConditionVariableInit(&replication_states[i].origin_cv);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ReplicationOriginShmemAttach(void *arg)
|
||||
{
|
||||
if (max_active_replication_origins == 0)
|
||||
return;
|
||||
|
||||
replication_states = replication_states_ctl->states;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Perform a checkpoint of each replication origin's progress with respect to
|
||||
* the replayed remote_lsn. Make sure that all transactions we refer to in the
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@
|
|||
#include "storage/lmgr.h"
|
||||
#include "storage/proc.h"
|
||||
#include "storage/procarray.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "tcop/tcopprot.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/memutils.h"
|
||||
|
|
@ -118,6 +119,14 @@ typedef struct SlotSyncCtxStruct
|
|||
|
||||
static SlotSyncCtxStruct *SlotSyncCtx = NULL;
|
||||
|
||||
static void SlotSyncShmemRequest(void *arg);
|
||||
static void SlotSyncShmemInit(void *arg);
|
||||
|
||||
const ShmemCallbacks SlotSyncShmemCallbacks = {
|
||||
.request_fn = SlotSyncShmemRequest,
|
||||
.init_fn = SlotSyncShmemInit,
|
||||
};
|
||||
|
||||
/* GUC variable */
|
||||
bool sync_replication_slots = false;
|
||||
|
||||
|
|
@ -1828,32 +1837,26 @@ IsSyncingReplicationSlots(void)
|
|||
}
|
||||
|
||||
/*
|
||||
* Amount of shared memory required for slot synchronization.
|
||||
* Register shared memory space needed for slot synchronization.
|
||||
*/
|
||||
Size
|
||||
SlotSyncShmemSize(void)
|
||||
static void
|
||||
SlotSyncShmemRequest(void *arg)
|
||||
{
|
||||
return sizeof(SlotSyncCtxStruct);
|
||||
ShmemRequestStruct(.name = "Slot Sync Data",
|
||||
.size = sizeof(SlotSyncCtxStruct),
|
||||
.ptr = (void **) &SlotSyncCtx,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate and initialize the shared memory of slot synchronization.
|
||||
* Initialize shared memory for slot synchronization.
|
||||
*/
|
||||
void
|
||||
SlotSyncShmemInit(void)
|
||||
static void
|
||||
SlotSyncShmemInit(void *arg)
|
||||
{
|
||||
Size size = SlotSyncShmemSize();
|
||||
bool found;
|
||||
|
||||
SlotSyncCtx = (SlotSyncCtxStruct *)
|
||||
ShmemInitStruct("Slot Sync Data", size, &found);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
memset(SlotSyncCtx, 0, size);
|
||||
SlotSyncCtx->pid = InvalidPid;
|
||||
SpinLockInit(&SlotSyncCtx->mutex);
|
||||
}
|
||||
memset(SlotSyncCtx, 0, sizeof(SlotSyncCtxStruct));
|
||||
SlotSyncCtx->pid = InvalidPid;
|
||||
SpinLockInit(&SlotSyncCtx->mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@
|
|||
#include "storage/ipc.h"
|
||||
#include "storage/proc.h"
|
||||
#include "storage/procarray.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/guc_hooks.h"
|
||||
#include "utils/injection_point.h"
|
||||
|
|
@ -145,6 +146,14 @@ StaticAssertDecl(lengthof(SlotInvalidationCauses) == (RS_INVAL_MAX_CAUSES + 1),
|
|||
/* Control array for replication slot management */
|
||||
ReplicationSlotCtlData *ReplicationSlotCtl = NULL;
|
||||
|
||||
static void ReplicationSlotsShmemRequest(void *arg);
|
||||
static void ReplicationSlotsShmemInit(void *arg);
|
||||
|
||||
const ShmemCallbacks ReplicationSlotsShmemCallbacks = {
|
||||
.request_fn = ReplicationSlotsShmemRequest,
|
||||
.init_fn = ReplicationSlotsShmemInit,
|
||||
};
|
||||
|
||||
/* My backend's replication slot in the shared memory array */
|
||||
ReplicationSlot *MyReplicationSlot = NULL;
|
||||
|
||||
|
|
@ -183,56 +192,41 @@ static void CreateSlotOnDisk(ReplicationSlot *slot);
|
|||
static void SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel);
|
||||
|
||||
/*
|
||||
* Report shared-memory space needed by ReplicationSlotsShmemInit.
|
||||
* Register shared memory space needed for replication slots.
|
||||
*/
|
||||
Size
|
||||
ReplicationSlotsShmemSize(void)
|
||||
static void
|
||||
ReplicationSlotsShmemRequest(void *arg)
|
||||
{
|
||||
Size size = 0;
|
||||
|
||||
if (max_replication_slots == 0)
|
||||
return size;
|
||||
|
||||
size = offsetof(ReplicationSlotCtlData, replication_slots);
|
||||
size = add_size(size,
|
||||
mul_size(max_replication_slots, sizeof(ReplicationSlot)));
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate and initialize shared memory for replication slots.
|
||||
*/
|
||||
void
|
||||
ReplicationSlotsShmemInit(void)
|
||||
{
|
||||
bool found;
|
||||
Size size;
|
||||
|
||||
if (max_replication_slots == 0)
|
||||
return;
|
||||
|
||||
ReplicationSlotCtl = (ReplicationSlotCtlData *)
|
||||
ShmemInitStruct("ReplicationSlot Ctl", ReplicationSlotsShmemSize(),
|
||||
&found);
|
||||
size = offsetof(ReplicationSlotCtlData, replication_slots);
|
||||
size = add_size(size,
|
||||
mul_size(max_replication_slots, sizeof(ReplicationSlot)));
|
||||
ShmemRequestStruct(.name = "ReplicationSlot Ctl",
|
||||
.size = size,
|
||||
.ptr = (void **) &ReplicationSlotCtl,
|
||||
);
|
||||
}
|
||||
|
||||
if (!found)
|
||||
/*
|
||||
* Initialize shared memory for replication slots.
|
||||
*/
|
||||
static void
|
||||
ReplicationSlotsShmemInit(void *arg)
|
||||
{
|
||||
for (int i = 0; i < max_replication_slots; i++)
|
||||
{
|
||||
int i;
|
||||
ReplicationSlot *slot = &ReplicationSlotCtl->replication_slots[i];
|
||||
|
||||
/* First time through, so initialize */
|
||||
MemSet(ReplicationSlotCtl, 0, ReplicationSlotsShmemSize());
|
||||
|
||||
for (i = 0; i < max_replication_slots; i++)
|
||||
{
|
||||
ReplicationSlot *slot = &ReplicationSlotCtl->replication_slots[i];
|
||||
|
||||
/* everything else is zeroed by the memset above */
|
||||
slot->active_proc = INVALID_PROC_NUMBER;
|
||||
SpinLockInit(&slot->mutex);
|
||||
LWLockInitialize(&slot->io_in_progress_lock,
|
||||
LWTRANCHE_REPLICATION_SLOT_IO);
|
||||
ConditionVariableInit(&slot->active_cv);
|
||||
}
|
||||
/* everything else is zeroed by the memset above */
|
||||
slot->active_proc = INVALID_PROC_NUMBER;
|
||||
SpinLockInit(&slot->mutex);
|
||||
LWLockInitialize(&slot->io_in_progress_lock,
|
||||
LWTRANCHE_REPLICATION_SLOT_IO);
|
||||
ConditionVariableInit(&slot->active_cv);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,47 +29,46 @@
|
|||
#include "storage/pmsignal.h"
|
||||
#include "storage/proc.h"
|
||||
#include "storage/shmem.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/timestamp.h"
|
||||
#include "utils/wait_event.h"
|
||||
|
||||
WalRcvData *WalRcv = NULL;
|
||||
|
||||
static void WalRcvShmemRequest(void *arg);
|
||||
static void WalRcvShmemInit(void *arg);
|
||||
|
||||
const ShmemCallbacks WalRcvShmemCallbacks = {
|
||||
.request_fn = WalRcvShmemRequest,
|
||||
.init_fn = WalRcvShmemInit,
|
||||
};
|
||||
|
||||
/*
|
||||
* How long to wait for walreceiver to start up after requesting
|
||||
* postmaster to launch it. In seconds.
|
||||
*/
|
||||
#define WALRCV_STARTUP_TIMEOUT 10
|
||||
|
||||
/* Report shared memory space needed by WalRcvShmemInit */
|
||||
Size
|
||||
WalRcvShmemSize(void)
|
||||
/* Register shared memory space needed by walreceiver */
|
||||
static void
|
||||
WalRcvShmemRequest(void *arg)
|
||||
{
|
||||
Size size = 0;
|
||||
|
||||
size = add_size(size, sizeof(WalRcvData));
|
||||
|
||||
return size;
|
||||
ShmemRequestStruct(.name = "Wal Receiver Ctl",
|
||||
.size = sizeof(WalRcvData),
|
||||
.ptr = (void **) &WalRcv,
|
||||
);
|
||||
}
|
||||
|
||||
/* Allocate and initialize walreceiver-related shared memory */
|
||||
void
|
||||
WalRcvShmemInit(void)
|
||||
/* Initialize walreceiver-related shared memory */
|
||||
static void
|
||||
WalRcvShmemInit(void *arg)
|
||||
{
|
||||
bool found;
|
||||
|
||||
WalRcv = (WalRcvData *)
|
||||
ShmemInitStruct("Wal Receiver Ctl", WalRcvShmemSize(), &found);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
/* First time through, so initialize */
|
||||
MemSet(WalRcv, 0, WalRcvShmemSize());
|
||||
WalRcv->walRcvState = WALRCV_STOPPED;
|
||||
ConditionVariableInit(&WalRcv->walRcvStoppedCV);
|
||||
SpinLockInit(&WalRcv->mutex);
|
||||
pg_atomic_init_u64(&WalRcv->writtenUpto, 0);
|
||||
WalRcv->procno = INVALID_PROC_NUMBER;
|
||||
}
|
||||
MemSet(WalRcv, 0, sizeof(WalRcvData));
|
||||
WalRcv->walRcvState = WALRCV_STOPPED;
|
||||
ConditionVariableInit(&WalRcv->walRcvStoppedCV);
|
||||
SpinLockInit(&WalRcv->mutex);
|
||||
pg_atomic_init_u64(&WalRcv->writtenUpto, 0);
|
||||
WalRcv->procno = INVALID_PROC_NUMBER;
|
||||
}
|
||||
|
||||
/* Is walreceiver running (or starting up)? */
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@
|
|||
#include "storage/pmsignal.h"
|
||||
#include "storage/proc.h"
|
||||
#include "storage/procarray.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "tcop/dest.h"
|
||||
#include "tcop/tcopprot.h"
|
||||
#include "utils/acl.h"
|
||||
|
|
@ -117,6 +118,14 @@
|
|||
/* Array of WalSnds in shared memory */
|
||||
WalSndCtlData *WalSndCtl = NULL;
|
||||
|
||||
static void WalSndShmemRequest(void *arg);
|
||||
static void WalSndShmemInit(void *arg);
|
||||
|
||||
const ShmemCallbacks WalSndShmemCallbacks = {
|
||||
.request_fn = WalSndShmemRequest,
|
||||
.init_fn = WalSndShmemInit,
|
||||
};
|
||||
|
||||
/* My slot in the shared memory array */
|
||||
WalSnd *MyWalSnd = NULL;
|
||||
|
||||
|
|
@ -3765,47 +3774,37 @@ WalSndSignals(void)
|
|||
pqsignal(SIGCHLD, SIG_DFL);
|
||||
}
|
||||
|
||||
/* Report shared-memory space needed by WalSndShmemInit */
|
||||
Size
|
||||
WalSndShmemSize(void)
|
||||
/* Register shared-memory space needed by walsender */
|
||||
static void
|
||||
WalSndShmemRequest(void *arg)
|
||||
{
|
||||
Size size = 0;
|
||||
Size size;
|
||||
|
||||
size = offsetof(WalSndCtlData, walsnds);
|
||||
size = add_size(size, mul_size(max_wal_senders, sizeof(WalSnd)));
|
||||
|
||||
return size;
|
||||
ShmemRequestStruct(.name = "Wal Sender Ctl",
|
||||
.size = size,
|
||||
.ptr = (void **) &WalSndCtl,
|
||||
);
|
||||
}
|
||||
|
||||
/* Allocate and initialize walsender-related shared memory */
|
||||
void
|
||||
WalSndShmemInit(void)
|
||||
/* Initialize walsender-related shared memory */
|
||||
static void
|
||||
WalSndShmemInit(void *arg)
|
||||
{
|
||||
bool found;
|
||||
int i;
|
||||
for (int i = 0; i < NUM_SYNC_REP_WAIT_MODE; i++)
|
||||
dlist_init(&(WalSndCtl->SyncRepQueue[i]));
|
||||
|
||||
WalSndCtl = (WalSndCtlData *)
|
||||
ShmemInitStruct("Wal Sender Ctl", WalSndShmemSize(), &found);
|
||||
|
||||
if (!found)
|
||||
for (int i = 0; i < max_wal_senders; i++)
|
||||
{
|
||||
/* First time through, so initialize */
|
||||
MemSet(WalSndCtl, 0, WalSndShmemSize());
|
||||
WalSnd *walsnd = &WalSndCtl->walsnds[i];
|
||||
|
||||
for (i = 0; i < NUM_SYNC_REP_WAIT_MODE; i++)
|
||||
dlist_init(&(WalSndCtl->SyncRepQueue[i]));
|
||||
|
||||
for (i = 0; i < max_wal_senders; i++)
|
||||
{
|
||||
WalSnd *walsnd = &WalSndCtl->walsnds[i];
|
||||
|
||||
SpinLockInit(&walsnd->mutex);
|
||||
}
|
||||
|
||||
ConditionVariableInit(&WalSndCtl->wal_flush_cv);
|
||||
ConditionVariableInit(&WalSndCtl->wal_replay_cv);
|
||||
ConditionVariableInit(&WalSndCtl->wal_confirm_rcv_cv);
|
||||
SpinLockInit(&walsnd->mutex);
|
||||
}
|
||||
|
||||
ConditionVariableInit(&WalSndCtl->wal_flush_cv);
|
||||
ConditionVariableInit(&WalSndCtl->wal_replay_cv);
|
||||
ConditionVariableInit(&WalSndCtl->wal_confirm_rcv_cv);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -14,41 +14,16 @@
|
|||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include "access/clog.h"
|
||||
#include "access/commit_ts.h"
|
||||
#include "access/multixact.h"
|
||||
#include "access/nbtree.h"
|
||||
#include "access/subtrans.h"
|
||||
#include "access/syncscan.h"
|
||||
#include "access/twophase.h"
|
||||
#include "access/xlogprefetcher.h"
|
||||
#include "access/xlogrecovery.h"
|
||||
#include "access/xlogwait.h"
|
||||
#include "commands/async.h"
|
||||
#include "miscadmin.h"
|
||||
#include "pgstat.h"
|
||||
#include "postmaster/autovacuum.h"
|
||||
#include "postmaster/bgworker_internals.h"
|
||||
#include "postmaster/bgwriter.h"
|
||||
#include "postmaster/datachecksum_state.h"
|
||||
#include "postmaster/walsummarizer.h"
|
||||
#include "replication/logicallauncher.h"
|
||||
#include "replication/origin.h"
|
||||
#include "replication/slot.h"
|
||||
#include "replication/slotsync.h"
|
||||
#include "replication/walreceiver.h"
|
||||
#include "replication/walsender.h"
|
||||
#include "storage/aio_subsys.h"
|
||||
#include "storage/dsm.h"
|
||||
#include "storage/ipc.h"
|
||||
#include "storage/lock.h"
|
||||
#include "storage/pg_shmem.h"
|
||||
#include "storage/predicate.h"
|
||||
#include "storage/proc.h"
|
||||
#include "storage/shmem_internal.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/guc.h"
|
||||
#include "utils/injection_point.h"
|
||||
#include "utils/wait_event.h"
|
||||
|
||||
/* GUCs */
|
||||
int shared_memory_type = DEFAULT_SHARED_MEMORY_TYPE;
|
||||
|
|
@ -57,8 +32,6 @@ shmem_startup_hook_type shmem_startup_hook = NULL;
|
|||
|
||||
static Size total_addin_request = 0;
|
||||
|
||||
static void CreateOrAttachShmemStructs(void);
|
||||
|
||||
/*
|
||||
* RequestAddinShmemSpace
|
||||
* Request that extra shmem space be allocated for use by
|
||||
|
|
@ -97,33 +70,6 @@ CalculateShmemSize(void)
|
|||
size = 100000;
|
||||
size = add_size(size, ShmemGetRequestedSize());
|
||||
|
||||
/* legacy subsystems */
|
||||
size = add_size(size, LockManagerShmemSize());
|
||||
size = add_size(size, XLogPrefetchShmemSize());
|
||||
size = add_size(size, XLOGShmemSize());
|
||||
size = add_size(size, XLogRecoveryShmemSize());
|
||||
size = add_size(size, TwoPhaseShmemSize());
|
||||
size = add_size(size, BackgroundWorkerShmemSize());
|
||||
size = add_size(size, BackendStatusShmemSize());
|
||||
size = add_size(size, CheckpointerShmemSize());
|
||||
size = add_size(size, AutoVacuumShmemSize());
|
||||
size = add_size(size, ReplicationSlotsShmemSize());
|
||||
size = add_size(size, ReplicationOriginShmemSize());
|
||||
size = add_size(size, WalSndShmemSize());
|
||||
size = add_size(size, WalRcvShmemSize());
|
||||
size = add_size(size, WalSummarizerShmemSize());
|
||||
size = add_size(size, PgArchShmemSize());
|
||||
size = add_size(size, ApplyLauncherShmemSize());
|
||||
size = add_size(size, BTreeShmemSize());
|
||||
size = add_size(size, SyncScanShmemSize());
|
||||
size = add_size(size, StatsShmemSize());
|
||||
size = add_size(size, WaitEventCustomShmemSize());
|
||||
size = add_size(size, InjectionPointShmemSize());
|
||||
size = add_size(size, SlotSyncShmemSize());
|
||||
size = add_size(size, WaitLSNShmemSize());
|
||||
size = add_size(size, LogicalDecodingCtlShmemSize());
|
||||
size = add_size(size, DataChecksumsShmemSize());
|
||||
|
||||
/* include additional requested shmem from preload libraries */
|
||||
size = add_size(size, total_addin_request);
|
||||
|
||||
|
|
@ -157,7 +103,6 @@ AttachSharedMemoryStructs(void)
|
|||
|
||||
/* Establish pointers to all shared memory areas in this backend */
|
||||
ShmemAttachRequested();
|
||||
CreateOrAttachShmemStructs();
|
||||
|
||||
/*
|
||||
* Now give loadable modules a chance to set up their shmem allocations
|
||||
|
|
@ -204,9 +149,6 @@ CreateSharedMemoryAndSemaphores(void)
|
|||
/* Initialize all shmem areas */
|
||||
ShmemInitRequested();
|
||||
|
||||
/* Initialize legacy subsystems */
|
||||
CreateOrAttachShmemStructs();
|
||||
|
||||
/* Initialize dynamic shared memory facilities. */
|
||||
dsm_postmaster_startup(shim);
|
||||
|
||||
|
|
@ -237,70 +179,6 @@ RegisterBuiltinShmemCallbacks(void)
|
|||
#undef PG_SHMEM_SUBSYSTEM
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize various subsystems, setting up their data structures in
|
||||
* shared memory.
|
||||
*
|
||||
* This is called by the postmaster or by a standalone backend.
|
||||
* It is also called by a backend forked from the postmaster in the
|
||||
* EXEC_BACKEND case. In the latter case, the shared memory segment
|
||||
* already exists and has been physically attached to, but we have to
|
||||
* initialize pointers in local memory that reference the shared structures,
|
||||
* because we didn't inherit the correct pointer values from the postmaster
|
||||
* as we do in the fork() scenario. The easiest way to do that is to run
|
||||
* through the same code as before. (Note that the called routines mostly
|
||||
* check IsUnderPostmaster, rather than EXEC_BACKEND, to detect this case.
|
||||
* This is a bit code-wasteful and could be cleaned up.)
|
||||
*/
|
||||
static void
|
||||
CreateOrAttachShmemStructs(void)
|
||||
{
|
||||
/*
|
||||
* Set up xlog, clog, and buffers
|
||||
*/
|
||||
XLOGShmemInit();
|
||||
XLogPrefetchShmemInit();
|
||||
XLogRecoveryShmemInit();
|
||||
|
||||
/*
|
||||
* Set up lock manager
|
||||
*/
|
||||
LockManagerShmemInit();
|
||||
|
||||
/*
|
||||
* Set up process table
|
||||
*/
|
||||
BackendStatusShmemInit();
|
||||
TwoPhaseShmemInit();
|
||||
BackgroundWorkerShmemInit();
|
||||
|
||||
/*
|
||||
* Set up interprocess signaling mechanisms
|
||||
*/
|
||||
CheckpointerShmemInit();
|
||||
AutoVacuumShmemInit();
|
||||
ReplicationSlotsShmemInit();
|
||||
ReplicationOriginShmemInit();
|
||||
WalSndShmemInit();
|
||||
WalRcvShmemInit();
|
||||
WalSummarizerShmemInit();
|
||||
PgArchShmemInit();
|
||||
ApplyLauncherShmemInit();
|
||||
SlotSyncShmemInit();
|
||||
DataChecksumsShmemInit();
|
||||
|
||||
/*
|
||||
* Set up other modules that need some shared memory space
|
||||
*/
|
||||
BTreeShmemInit();
|
||||
SyncScanShmemInit();
|
||||
StatsShmemInit();
|
||||
WaitEventCustomShmemInit();
|
||||
InjectionPointShmemInit();
|
||||
WaitLSNShmemInit();
|
||||
LogicalDecodingCtlShmemInit();
|
||||
}
|
||||
|
||||
/*
|
||||
* InitializeShmemGUCs
|
||||
*
|
||||
|
|
|
|||
|
|
@ -43,8 +43,10 @@
|
|||
#include "storage/lmgr.h"
|
||||
#include "storage/proc.h"
|
||||
#include "storage/procarray.h"
|
||||
#include "storage/shmem.h"
|
||||
#include "storage/spin.h"
|
||||
#include "storage/standby.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/ps_status.h"
|
||||
#include "utils/resowner.h"
|
||||
|
|
@ -312,6 +314,14 @@ typedef struct
|
|||
|
||||
static volatile FastPathStrongRelationLockData *FastPathStrongRelationLocks;
|
||||
|
||||
static void LockManagerShmemRequest(void *arg);
|
||||
static void LockManagerShmemInit(void *arg);
|
||||
|
||||
const ShmemCallbacks LockManagerShmemCallbacks = {
|
||||
.request_fn = LockManagerShmemRequest,
|
||||
.init_fn = LockManagerShmemInit,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Pointers to hash tables containing lock state
|
||||
|
|
@ -432,21 +442,15 @@ static void GetSingleProcBlockerStatusData(PGPROC *blocked_proc,
|
|||
|
||||
|
||||
/*
|
||||
* Initialize the lock manager's shmem data structures.
|
||||
* Register the lock manager's shmem data structures.
|
||||
*
|
||||
* This is called from CreateSharedMemoryAndSemaphores(), which see for more
|
||||
* comments. In the normal postmaster case, the shared hash tables are
|
||||
* created here, and backends inherit pointers to them via fork(). In the
|
||||
* EXEC_BACKEND case, each backend re-executes this code to obtain pointers to
|
||||
* the already existing shared hash tables. In either case, each backend must
|
||||
* also call InitLockManagerAccess() to create the locallock hash table.
|
||||
* In addition to this, each backend must also call InitLockManagerAccess() to
|
||||
* create the locallock hash table.
|
||||
*/
|
||||
void
|
||||
LockManagerShmemInit(void)
|
||||
static void
|
||||
LockManagerShmemRequest(void *arg)
|
||||
{
|
||||
HASHCTL info;
|
||||
int64 max_table_size;
|
||||
bool found;
|
||||
|
||||
/*
|
||||
* Compute sizes for lock hashtables. Note that these calculations must
|
||||
|
|
@ -455,45 +459,41 @@ LockManagerShmemInit(void)
|
|||
max_table_size = NLOCKENTS();
|
||||
|
||||
/*
|
||||
* Allocate hash table for LOCK structs. This stores per-locked-object
|
||||
* Hash table for LOCK structs. This stores per-locked-object
|
||||
* information.
|
||||
*/
|
||||
info.keysize = sizeof(LOCKTAG);
|
||||
info.entrysize = sizeof(LOCK);
|
||||
info.num_partitions = NUM_LOCK_PARTITIONS;
|
||||
|
||||
LockMethodLockHash = ShmemInitHash("LOCK hash",
|
||||
max_table_size,
|
||||
&info,
|
||||
HASH_ELEM | HASH_BLOBS |
|
||||
HASH_PARTITION | HASH_FIXED_SIZE);
|
||||
ShmemRequestHash(.name = "LOCK hash",
|
||||
.nelems = max_table_size,
|
||||
.ptr = &LockMethodLockHash,
|
||||
.hash_info.keysize = sizeof(LOCKTAG),
|
||||
.hash_info.entrysize = sizeof(LOCK),
|
||||
.hash_info.num_partitions = NUM_LOCK_PARTITIONS,
|
||||
.hash_flags = HASH_ELEM | HASH_BLOBS | HASH_PARTITION,
|
||||
);
|
||||
|
||||
/* Assume an average of 2 holders per lock */
|
||||
max_table_size *= 2;
|
||||
|
||||
/*
|
||||
* Allocate hash table for PROCLOCK structs. This stores
|
||||
* per-lock-per-holder information.
|
||||
*/
|
||||
info.keysize = sizeof(PROCLOCKTAG);
|
||||
info.entrysize = sizeof(PROCLOCK);
|
||||
info.hash = proclock_hash;
|
||||
info.num_partitions = NUM_LOCK_PARTITIONS;
|
||||
ShmemRequestHash(.name = "PROCLOCK hash",
|
||||
.nelems = max_table_size,
|
||||
.ptr = &LockMethodProcLockHash,
|
||||
.hash_info.keysize = sizeof(PROCLOCKTAG),
|
||||
.hash_info.entrysize = sizeof(PROCLOCK),
|
||||
.hash_info.hash = proclock_hash,
|
||||
.hash_info.num_partitions = NUM_LOCK_PARTITIONS,
|
||||
.hash_flags = HASH_ELEM | HASH_FUNCTION | HASH_PARTITION,
|
||||
);
|
||||
|
||||
LockMethodProcLockHash = ShmemInitHash("PROCLOCK hash",
|
||||
max_table_size,
|
||||
&info,
|
||||
HASH_ELEM | HASH_FUNCTION |
|
||||
HASH_FIXED_SIZE | HASH_PARTITION);
|
||||
ShmemRequestStruct(.name = "Fast Path Strong Relation Lock Data",
|
||||
.size = sizeof(FastPathStrongRelationLockData),
|
||||
.ptr = (void **) (void *) &FastPathStrongRelationLocks,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate fast-path structures.
|
||||
*/
|
||||
FastPathStrongRelationLocks =
|
||||
ShmemInitStruct("Fast Path Strong Relation Lock Data",
|
||||
sizeof(FastPathStrongRelationLockData), &found);
|
||||
if (!found)
|
||||
SpinLockInit(&FastPathStrongRelationLocks->mutex);
|
||||
static void
|
||||
LockManagerShmemInit(void *arg)
|
||||
{
|
||||
SpinLockInit(&FastPathStrongRelationLocks->mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -3758,29 +3758,6 @@ PostPrepare_Locks(FullTransactionId fxid)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Estimate shared-memory space used for lock tables
|
||||
*/
|
||||
Size
|
||||
LockManagerShmemSize(void)
|
||||
{
|
||||
Size size = 0;
|
||||
long max_table_size;
|
||||
|
||||
/* lock hash table */
|
||||
max_table_size = NLOCKENTS();
|
||||
size = add_size(size, hash_estimate_size(max_table_size, sizeof(LOCK)));
|
||||
|
||||
/* proclock hash table */
|
||||
max_table_size *= 2;
|
||||
size = add_size(size, hash_estimate_size(max_table_size, sizeof(PROCLOCK)));
|
||||
|
||||
/* fast-path structures */
|
||||
size = add_size(size, sizeof(FastPathStrongRelationLockData));
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/*
|
||||
* GetLockStatusData - Return a summary of the lock manager's internal
|
||||
* status, for use in a user-level reporting function.
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
#include "storage/ipc.h"
|
||||
#include "storage/proc.h" /* for MyProc */
|
||||
#include "storage/procarray.h"
|
||||
#include "storage/shmem.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/ascii.h"
|
||||
#include "utils/guc.h" /* for application_name */
|
||||
#include "utils/memutils.h"
|
||||
|
|
@ -73,133 +75,97 @@ static void pgstat_beshutdown_hook(int code, Datum arg);
|
|||
static void pgstat_read_current_status(void);
|
||||
static void pgstat_setup_backend_status_context(void);
|
||||
|
||||
static void BackendStatusShmemRequest(void *arg);
|
||||
static void BackendStatusShmemInit(void *arg);
|
||||
static void BackendStatusShmemAttach(void *arg);
|
||||
|
||||
const ShmemCallbacks BackendStatusShmemCallbacks = {
|
||||
.request_fn = BackendStatusShmemRequest,
|
||||
.init_fn = BackendStatusShmemInit,
|
||||
.attach_fn = BackendStatusShmemAttach,
|
||||
};
|
||||
|
||||
/*
|
||||
* Report shared-memory space needed by BackendStatusShmemInit.
|
||||
* Register shared memory needs for backend status reporting.
|
||||
*/
|
||||
Size
|
||||
BackendStatusShmemSize(void)
|
||||
static void
|
||||
BackendStatusShmemRequest(void *arg)
|
||||
{
|
||||
Size size;
|
||||
ShmemRequestStruct(.name = "Backend Status Array",
|
||||
.size = mul_size(sizeof(PgBackendStatus), NumBackendStatSlots),
|
||||
.ptr = (void **) &BackendStatusArray,
|
||||
);
|
||||
|
||||
ShmemRequestStruct(.name = "Backend Application Name Buffer",
|
||||
.size = mul_size(NAMEDATALEN, NumBackendStatSlots),
|
||||
.ptr = (void **) &BackendAppnameBuffer,
|
||||
);
|
||||
|
||||
ShmemRequestStruct(.name = "Backend Client Host Name Buffer",
|
||||
.size = mul_size(NAMEDATALEN, NumBackendStatSlots),
|
||||
.ptr = (void **) &BackendClientHostnameBuffer,
|
||||
);
|
||||
|
||||
BackendActivityBufferSize = mul_size(pgstat_track_activity_query_size,
|
||||
NumBackendStatSlots);
|
||||
ShmemRequestStruct(.name = "Backend Activity Buffer",
|
||||
.size = BackendActivityBufferSize,
|
||||
.ptr = (void **) &BackendActivityBuffer
|
||||
);
|
||||
|
||||
/* BackendStatusArray: */
|
||||
size = mul_size(sizeof(PgBackendStatus), NumBackendStatSlots);
|
||||
/* BackendAppnameBuffer: */
|
||||
size = add_size(size,
|
||||
mul_size(NAMEDATALEN, NumBackendStatSlots));
|
||||
/* BackendClientHostnameBuffer: */
|
||||
size = add_size(size,
|
||||
mul_size(NAMEDATALEN, NumBackendStatSlots));
|
||||
/* BackendActivityBuffer: */
|
||||
size = add_size(size,
|
||||
mul_size(pgstat_track_activity_query_size, NumBackendStatSlots));
|
||||
#ifdef USE_SSL
|
||||
/* BackendSslStatusBuffer: */
|
||||
size = add_size(size,
|
||||
mul_size(sizeof(PgBackendSSLStatus), NumBackendStatSlots));
|
||||
ShmemRequestStruct(.name = "Backend SSL Status Buffer",
|
||||
.size = mul_size(sizeof(PgBackendSSLStatus), NumBackendStatSlots),
|
||||
.ptr = (void **) &BackendSslStatusBuffer,
|
||||
);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_GSS
|
||||
/* BackendGssStatusBuffer: */
|
||||
size = add_size(size,
|
||||
mul_size(sizeof(PgBackendGSSStatus), NumBackendStatSlots));
|
||||
ShmemRequestStruct(.name = "Backend GSS Status Buffer",
|
||||
.size = mul_size(sizeof(PgBackendGSSStatus), NumBackendStatSlots),
|
||||
.ptr = (void **) &BackendGssStatusBuffer,
|
||||
);
|
||||
#endif
|
||||
return size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the shared status array and several string buffers
|
||||
* during postmaster startup.
|
||||
*/
|
||||
void
|
||||
BackendStatusShmemInit(void)
|
||||
static void
|
||||
BackendStatusShmemInit(void *arg)
|
||||
{
|
||||
Size size;
|
||||
bool found;
|
||||
int i;
|
||||
char *buffer;
|
||||
|
||||
/* Create or attach to the shared array */
|
||||
size = mul_size(sizeof(PgBackendStatus), NumBackendStatSlots);
|
||||
BackendStatusArray = (PgBackendStatus *)
|
||||
ShmemInitStruct("Backend Status Array", size, &found);
|
||||
|
||||
if (!found)
|
||||
/* Initialize st_appname pointers. */
|
||||
buffer = BackendAppnameBuffer;
|
||||
for (i = 0; i < NumBackendStatSlots; i++)
|
||||
{
|
||||
/*
|
||||
* We're the first - initialize.
|
||||
*/
|
||||
MemSet(BackendStatusArray, 0, size);
|
||||
BackendStatusArray[i].st_appname = buffer;
|
||||
buffer += NAMEDATALEN;
|
||||
}
|
||||
|
||||
/* Create or attach to the shared appname buffer */
|
||||
size = mul_size(NAMEDATALEN, NumBackendStatSlots);
|
||||
BackendAppnameBuffer = (char *)
|
||||
ShmemInitStruct("Backend Application Name Buffer", size, &found);
|
||||
|
||||
if (!found)
|
||||
/* Initialize st_clienthostname pointers. */
|
||||
buffer = BackendClientHostnameBuffer;
|
||||
for (i = 0; i < NumBackendStatSlots; i++)
|
||||
{
|
||||
MemSet(BackendAppnameBuffer, 0, size);
|
||||
|
||||
/* Initialize st_appname pointers. */
|
||||
buffer = BackendAppnameBuffer;
|
||||
for (i = 0; i < NumBackendStatSlots; i++)
|
||||
{
|
||||
BackendStatusArray[i].st_appname = buffer;
|
||||
buffer += NAMEDATALEN;
|
||||
}
|
||||
BackendStatusArray[i].st_clienthostname = buffer;
|
||||
buffer += NAMEDATALEN;
|
||||
}
|
||||
|
||||
/* Create or attach to the shared client hostname buffer */
|
||||
size = mul_size(NAMEDATALEN, NumBackendStatSlots);
|
||||
BackendClientHostnameBuffer = (char *)
|
||||
ShmemInitStruct("Backend Client Host Name Buffer", size, &found);
|
||||
|
||||
if (!found)
|
||||
/* Initialize st_activity pointers. */
|
||||
buffer = BackendActivityBuffer;
|
||||
for (i = 0; i < NumBackendStatSlots; i++)
|
||||
{
|
||||
MemSet(BackendClientHostnameBuffer, 0, size);
|
||||
|
||||
/* Initialize st_clienthostname pointers. */
|
||||
buffer = BackendClientHostnameBuffer;
|
||||
for (i = 0; i < NumBackendStatSlots; i++)
|
||||
{
|
||||
BackendStatusArray[i].st_clienthostname = buffer;
|
||||
buffer += NAMEDATALEN;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create or attach to the shared activity buffer */
|
||||
BackendActivityBufferSize = mul_size(pgstat_track_activity_query_size,
|
||||
NumBackendStatSlots);
|
||||
BackendActivityBuffer = (char *)
|
||||
ShmemInitStruct("Backend Activity Buffer",
|
||||
BackendActivityBufferSize,
|
||||
&found);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
MemSet(BackendActivityBuffer, 0, BackendActivityBufferSize);
|
||||
|
||||
/* Initialize st_activity pointers. */
|
||||
buffer = BackendActivityBuffer;
|
||||
for (i = 0; i < NumBackendStatSlots; i++)
|
||||
{
|
||||
BackendStatusArray[i].st_activity_raw = buffer;
|
||||
buffer += pgstat_track_activity_query_size;
|
||||
}
|
||||
BackendStatusArray[i].st_activity_raw = buffer;
|
||||
buffer += pgstat_track_activity_query_size;
|
||||
}
|
||||
|
||||
#ifdef USE_SSL
|
||||
/* Create or attach to the shared SSL status buffer */
|
||||
size = mul_size(sizeof(PgBackendSSLStatus), NumBackendStatSlots);
|
||||
BackendSslStatusBuffer = (PgBackendSSLStatus *)
|
||||
ShmemInitStruct("Backend SSL Status Buffer", size, &found);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
PgBackendSSLStatus *ptr;
|
||||
|
||||
MemSet(BackendSslStatusBuffer, 0, size);
|
||||
|
||||
/* Initialize st_sslstatus pointers. */
|
||||
ptr = BackendSslStatusBuffer;
|
||||
for (i = 0; i < NumBackendStatSlots; i++)
|
||||
|
|
@ -211,17 +177,9 @@ BackendStatusShmemInit(void)
|
|||
#endif
|
||||
|
||||
#ifdef ENABLE_GSS
|
||||
/* Create or attach to the shared GSSAPI status buffer */
|
||||
size = mul_size(sizeof(PgBackendGSSStatus), NumBackendStatSlots);
|
||||
BackendGssStatusBuffer = (PgBackendGSSStatus *)
|
||||
ShmemInitStruct("Backend GSS Status Buffer", size, &found);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
PgBackendGSSStatus *ptr;
|
||||
|
||||
MemSet(BackendGssStatusBuffer, 0, size);
|
||||
|
||||
/* Initialize st_gssstatus pointers. */
|
||||
ptr = BackendGssStatusBuffer;
|
||||
for (i = 0; i < NumBackendStatSlots; i++)
|
||||
|
|
@ -233,6 +191,13 @@ BackendStatusShmemInit(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
BackendStatusShmemAttach(void *arg)
|
||||
{
|
||||
BackendActivityBufferSize = mul_size(pgstat_track_activity_query_size,
|
||||
NumBackendStatSlots);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize pgstats backend activity state, and set up our on-proc-exit
|
||||
* hook. Called from InitPostgres and AuxiliaryProcessMain. MyProcNumber must
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "pgstat.h"
|
||||
#include "storage/shmem.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/pgstat_internal.h"
|
||||
|
||||
|
|
@ -57,6 +58,13 @@ static void pgstat_release_matching_entry_refs(bool discard_pending, ReleaseMatc
|
|||
|
||||
static void pgstat_setup_memcxt(void);
|
||||
|
||||
static void StatsShmemRequest(void *arg);
|
||||
static void StatsShmemInit(void *arg);
|
||||
|
||||
const ShmemCallbacks StatsShmemCallbacks = {
|
||||
.request_fn = StatsShmemRequest,
|
||||
.init_fn = StatsShmemInit,
|
||||
};
|
||||
|
||||
/* parameter for the shared hash */
|
||||
static const dshash_parameters dsh_params = {
|
||||
|
|
@ -123,7 +131,7 @@ pgstat_dsa_init_size(void)
|
|||
/*
|
||||
* Compute shared memory space needed for cumulative statistics
|
||||
*/
|
||||
Size
|
||||
static Size
|
||||
StatsShmemSize(void)
|
||||
{
|
||||
Size sz;
|
||||
|
|
@ -149,102 +157,98 @@ StatsShmemSize(void)
|
|||
return sz;
|
||||
}
|
||||
|
||||
/*
|
||||
* Register shared memory area for cumulative statistics
|
||||
*/
|
||||
static void
|
||||
StatsShmemRequest(void *arg)
|
||||
{
|
||||
ShmemRequestStruct(.name = "Shared Memory Stats",
|
||||
.size = StatsShmemSize(),
|
||||
.ptr = (void **) &pgStatLocal.shmem,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize cumulative statistics system during startup
|
||||
*/
|
||||
void
|
||||
StatsShmemInit(void)
|
||||
static void
|
||||
StatsShmemInit(void *arg)
|
||||
{
|
||||
bool found;
|
||||
Size sz;
|
||||
dsa_area *dsa;
|
||||
dshash_table *dsh;
|
||||
PgStat_ShmemControl *ctl = pgStatLocal.shmem;
|
||||
char *p = (char *) ctl;
|
||||
|
||||
sz = StatsShmemSize();
|
||||
pgStatLocal.shmem = (PgStat_ShmemControl *)
|
||||
ShmemInitStruct("Shared Memory Stats", sz, &found);
|
||||
/* the allocation of pgStatLocal.shmem itself */
|
||||
p += MAXALIGN(sizeof(PgStat_ShmemControl));
|
||||
|
||||
if (!IsUnderPostmaster)
|
||||
/*
|
||||
* Create a small dsa allocation in plain shared memory. This is required
|
||||
* because postmaster cannot use dsm segments. It also provides a small
|
||||
* efficiency win.
|
||||
*/
|
||||
ctl->raw_dsa_area = p;
|
||||
dsa = dsa_create_in_place(ctl->raw_dsa_area,
|
||||
pgstat_dsa_init_size(),
|
||||
LWTRANCHE_PGSTATS_DSA, NULL);
|
||||
dsa_pin(dsa);
|
||||
|
||||
/*
|
||||
* To ensure dshash is created in "plain" shared memory, temporarily limit
|
||||
* size of dsa to the initial size of the dsa.
|
||||
*/
|
||||
dsa_set_size_limit(dsa, pgstat_dsa_init_size());
|
||||
|
||||
/*
|
||||
* With the limit in place, create the dshash table. XXX: It'd be nice if
|
||||
* there were dshash_create_in_place().
|
||||
*/
|
||||
dsh = dshash_create(dsa, &dsh_params, NULL);
|
||||
ctl->hash_handle = dshash_get_hash_table_handle(dsh);
|
||||
|
||||
/* lift limit set above */
|
||||
dsa_set_size_limit(dsa, -1);
|
||||
|
||||
/*
|
||||
* Postmaster will never access these again, thus free the local
|
||||
* dsa/dshash references.
|
||||
*/
|
||||
dshash_detach(dsh);
|
||||
dsa_detach(dsa);
|
||||
|
||||
pg_atomic_init_u64(&ctl->gc_request_count, 1);
|
||||
|
||||
/* Do the per-kind initialization */
|
||||
for (PgStat_Kind kind = PGSTAT_KIND_MIN; kind <= PGSTAT_KIND_MAX; kind++)
|
||||
{
|
||||
dsa_area *dsa;
|
||||
dshash_table *dsh;
|
||||
PgStat_ShmemControl *ctl = pgStatLocal.shmem;
|
||||
char *p = (char *) ctl;
|
||||
const PgStat_KindInfo *kind_info = pgstat_get_kind_info(kind);
|
||||
char *ptr;
|
||||
|
||||
Assert(!found);
|
||||
if (!kind_info)
|
||||
continue;
|
||||
|
||||
/* the allocation of pgStatLocal.shmem itself */
|
||||
p += MAXALIGN(sizeof(PgStat_ShmemControl));
|
||||
/* initialize entry count tracking */
|
||||
if (kind_info->track_entry_count)
|
||||
pg_atomic_init_u64(&ctl->entry_counts[kind - 1], 0);
|
||||
|
||||
/*
|
||||
* Create a small dsa allocation in plain shared memory. This is
|
||||
* required because postmaster cannot use dsm segments. It also
|
||||
* provides a small efficiency win.
|
||||
*/
|
||||
ctl->raw_dsa_area = p;
|
||||
dsa = dsa_create_in_place(ctl->raw_dsa_area,
|
||||
pgstat_dsa_init_size(),
|
||||
LWTRANCHE_PGSTATS_DSA, NULL);
|
||||
dsa_pin(dsa);
|
||||
|
||||
/*
|
||||
* To ensure dshash is created in "plain" shared memory, temporarily
|
||||
* limit size of dsa to the initial size of the dsa.
|
||||
*/
|
||||
dsa_set_size_limit(dsa, pgstat_dsa_init_size());
|
||||
|
||||
/*
|
||||
* With the limit in place, create the dshash table. XXX: It'd be nice
|
||||
* if there were dshash_create_in_place().
|
||||
*/
|
||||
dsh = dshash_create(dsa, &dsh_params, NULL);
|
||||
ctl->hash_handle = dshash_get_hash_table_handle(dsh);
|
||||
|
||||
/* lift limit set above */
|
||||
dsa_set_size_limit(dsa, -1);
|
||||
|
||||
/*
|
||||
* Postmaster will never access these again, thus free the local
|
||||
* dsa/dshash references.
|
||||
*/
|
||||
dshash_detach(dsh);
|
||||
dsa_detach(dsa);
|
||||
|
||||
pg_atomic_init_u64(&ctl->gc_request_count, 1);
|
||||
|
||||
/* Do the per-kind initialization */
|
||||
for (PgStat_Kind kind = PGSTAT_KIND_MIN; kind <= PGSTAT_KIND_MAX; kind++)
|
||||
/* initialize fixed-numbered stats */
|
||||
if (kind_info->fixed_amount)
|
||||
{
|
||||
const PgStat_KindInfo *kind_info = pgstat_get_kind_info(kind);
|
||||
char *ptr;
|
||||
|
||||
if (!kind_info)
|
||||
continue;
|
||||
|
||||
/* initialize entry count tracking */
|
||||
if (kind_info->track_entry_count)
|
||||
pg_atomic_init_u64(&ctl->entry_counts[kind - 1], 0);
|
||||
|
||||
/* initialize fixed-numbered stats */
|
||||
if (kind_info->fixed_amount)
|
||||
if (pgstat_is_kind_builtin(kind))
|
||||
ptr = ((char *) ctl) + kind_info->shared_ctl_off;
|
||||
else
|
||||
{
|
||||
if (pgstat_is_kind_builtin(kind))
|
||||
ptr = ((char *) ctl) + kind_info->shared_ctl_off;
|
||||
else
|
||||
{
|
||||
int idx = kind - PGSTAT_KIND_CUSTOM_MIN;
|
||||
int idx = kind - PGSTAT_KIND_CUSTOM_MIN;
|
||||
|
||||
Assert(kind_info->shared_size != 0);
|
||||
ctl->custom_data[idx] = ShmemAlloc(kind_info->shared_size);
|
||||
ptr = ctl->custom_data[idx];
|
||||
}
|
||||
|
||||
kind_info->init_shmem_cb(ptr);
|
||||
Assert(kind_info->shared_size != 0);
|
||||
ctl->custom_data[idx] = ShmemAlloc(kind_info->shared_size);
|
||||
ptr = ctl->custom_data[idx];
|
||||
}
|
||||
|
||||
kind_info->init_shmem_cb(ptr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert(found);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "storage/lmgr.h"
|
||||
#include "storage/lwlock.h"
|
||||
#include "storage/shmem.h"
|
||||
#include "storage/subsystems.h"
|
||||
#include "storage/spin.h"
|
||||
#include "utils/wait_event.h"
|
||||
|
||||
|
|
@ -95,59 +96,47 @@ static WaitEventCustomCounterData *WaitEventCustomCounter;
|
|||
static uint32 WaitEventCustomNew(uint32 classId, const char *wait_event_name);
|
||||
static const char *GetWaitEventCustomIdentifier(uint32 wait_event_info);
|
||||
|
||||
/*
|
||||
* Return the space for dynamic shared hash tables and dynamic allocation counter.
|
||||
*/
|
||||
Size
|
||||
WaitEventCustomShmemSize(void)
|
||||
{
|
||||
Size sz;
|
||||
static void WaitEventCustomShmemRequest(void *arg);
|
||||
static void WaitEventCustomShmemInit(void *arg);
|
||||
|
||||
sz = MAXALIGN(sizeof(WaitEventCustomCounterData));
|
||||
sz = add_size(sz, hash_estimate_size(WAIT_EVENT_CUSTOM_HASH_SIZE,
|
||||
sizeof(WaitEventCustomEntryByInfo)));
|
||||
sz = add_size(sz, hash_estimate_size(WAIT_EVENT_CUSTOM_HASH_SIZE,
|
||||
sizeof(WaitEventCustomEntryByName)));
|
||||
return sz;
|
||||
const ShmemCallbacks WaitEventCustomShmemCallbacks = {
|
||||
.request_fn = WaitEventCustomShmemRequest,
|
||||
.init_fn = WaitEventCustomShmemInit,
|
||||
};
|
||||
|
||||
/*
|
||||
* Register shmem space for dynamic shared hash and dynamic allocation counter.
|
||||
*/
|
||||
static void
|
||||
WaitEventCustomShmemRequest(void *arg)
|
||||
{
|
||||
ShmemRequestStruct(.name = "WaitEventCustomCounterData",
|
||||
.size = sizeof(WaitEventCustomCounterData),
|
||||
.ptr = (void **) &WaitEventCustomCounter,
|
||||
);
|
||||
ShmemRequestHash(.name = "WaitEventCustom hash by wait event information",
|
||||
.ptr = &WaitEventCustomHashByInfo,
|
||||
.nelems = WAIT_EVENT_CUSTOM_HASH_SIZE,
|
||||
.hash_info.keysize = sizeof(uint32),
|
||||
.hash_info.entrysize = sizeof(WaitEventCustomEntryByInfo),
|
||||
.hash_flags = HASH_ELEM | HASH_BLOBS,
|
||||
);
|
||||
ShmemRequestHash(.name = "WaitEventCustom hash by name",
|
||||
.ptr = &WaitEventCustomHashByName,
|
||||
.nelems = WAIT_EVENT_CUSTOM_HASH_SIZE,
|
||||
/* key is a NULL-terminated string */
|
||||
.hash_info.keysize = sizeof(char[NAMEDATALEN]),
|
||||
.hash_info.entrysize = sizeof(WaitEventCustomEntryByName),
|
||||
.hash_flags = HASH_ELEM | HASH_STRINGS,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate shmem space for dynamic shared hash and dynamic allocation counter.
|
||||
*/
|
||||
void
|
||||
WaitEventCustomShmemInit(void)
|
||||
static void
|
||||
WaitEventCustomShmemInit(void *arg)
|
||||
{
|
||||
bool found;
|
||||
HASHCTL info;
|
||||
|
||||
WaitEventCustomCounter = (WaitEventCustomCounterData *)
|
||||
ShmemInitStruct("WaitEventCustomCounterData",
|
||||
sizeof(WaitEventCustomCounterData), &found);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
/* initialize the allocation counter and its spinlock. */
|
||||
WaitEventCustomCounter->nextId = WAIT_EVENT_CUSTOM_INITIAL_ID;
|
||||
SpinLockInit(&WaitEventCustomCounter->mutex);
|
||||
}
|
||||
|
||||
/* initialize or attach the hash tables to store custom wait events */
|
||||
info.keysize = sizeof(uint32);
|
||||
info.entrysize = sizeof(WaitEventCustomEntryByInfo);
|
||||
WaitEventCustomHashByInfo =
|
||||
ShmemInitHash("WaitEventCustom hash by wait event information",
|
||||
WAIT_EVENT_CUSTOM_HASH_SIZE,
|
||||
&info,
|
||||
HASH_ELEM | HASH_BLOBS);
|
||||
|
||||
/* key is a NULL-terminated string */
|
||||
info.keysize = sizeof(char[NAMEDATALEN]);
|
||||
info.entrysize = sizeof(WaitEventCustomEntryByName);
|
||||
WaitEventCustomHashByName =
|
||||
ShmemInitHash("WaitEventCustom hash by name",
|
||||
WAIT_EVENT_CUSTOM_HASH_SIZE,
|
||||
&info,
|
||||
HASH_ELEM | HASH_STRINGS);
|
||||
/* initialize the allocation counter and its spinlock. */
|
||||
WaitEventCustomCounter->nextId = WAIT_EVENT_CUSTOM_INITIAL_ID;
|
||||
SpinLockInit(&WaitEventCustomCounter->mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include "storage/subsystems.h"
|
||||
#include "utils/injection_point.h"
|
||||
|
||||
#ifdef USE_INJECTION_POINTS
|
||||
|
|
@ -109,6 +110,11 @@ typedef struct InjectionPointCacheEntry
|
|||
|
||||
static HTAB *InjectionPointCache = NULL;
|
||||
|
||||
#ifdef USE_INJECTION_POINTS
|
||||
static void InjectionPointShmemRequest(void *arg);
|
||||
static void InjectionPointShmemInit(void *arg);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* injection_point_cache_add
|
||||
*
|
||||
|
|
@ -226,46 +232,35 @@ injection_point_cache_get(const char *name)
|
|||
}
|
||||
#endif /* USE_INJECTION_POINTS */
|
||||
|
||||
/*
|
||||
* Return the space for dynamic shared hash table.
|
||||
*/
|
||||
Size
|
||||
InjectionPointShmemSize(void)
|
||||
{
|
||||
const ShmemCallbacks InjectionPointShmemCallbacks = {
|
||||
#ifdef USE_INJECTION_POINTS
|
||||
Size sz = 0;
|
||||
|
||||
sz = add_size(sz, sizeof(InjectionPointsCtl));
|
||||
return sz;
|
||||
#else
|
||||
return 0;
|
||||
.request_fn = InjectionPointShmemRequest,
|
||||
.init_fn = InjectionPointShmemInit,
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Allocate shmem space for dynamic shared hash.
|
||||
* Reserve space for the dynamic shared hash table
|
||||
*/
|
||||
void
|
||||
InjectionPointShmemInit(void)
|
||||
{
|
||||
#ifdef USE_INJECTION_POINTS
|
||||
bool found;
|
||||
|
||||
ActiveInjectionPoints = ShmemInitStruct("InjectionPoint hash",
|
||||
sizeof(InjectionPointsCtl),
|
||||
&found);
|
||||
if (!IsUnderPostmaster)
|
||||
{
|
||||
Assert(!found);
|
||||
pg_atomic_init_u32(&ActiveInjectionPoints->max_inuse, 0);
|
||||
for (int i = 0; i < MAX_INJECTION_POINTS; i++)
|
||||
pg_atomic_init_u64(&ActiveInjectionPoints->entries[i].generation, 0);
|
||||
}
|
||||
else
|
||||
Assert(found);
|
||||
#endif
|
||||
static void
|
||||
InjectionPointShmemRequest(void *arg)
|
||||
{
|
||||
ShmemRequestStruct(.name = "InjectionPoint hash",
|
||||
.size = sizeof(InjectionPointsCtl),
|
||||
.ptr = (void **) &ActiveInjectionPoints,
|
||||
);
|
||||
}
|
||||
|
||||
static void
|
||||
InjectionPointShmemInit(void *arg)
|
||||
{
|
||||
pg_atomic_init_u32(&ActiveInjectionPoints->max_inuse, 0);
|
||||
for (int i = 0; i < MAX_INJECTION_POINTS; i++)
|
||||
pg_atomic_init_u64(&ActiveInjectionPoints->entries[i].generation, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Attach a new injection point.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1300,8 +1300,6 @@ extern BTCycleId _bt_vacuum_cycleid(Relation rel);
|
|||
extern BTCycleId _bt_start_vacuum(Relation rel);
|
||||
extern void _bt_end_vacuum(Relation rel);
|
||||
extern void _bt_end_vacuum_callback(int code, Datum arg);
|
||||
extern Size BTreeShmemSize(void);
|
||||
extern void BTreeShmemInit(void);
|
||||
extern bytea *btoptions(Datum reloptions, bool validate);
|
||||
extern bool btproperty(Oid index_oid, int attno,
|
||||
IndexAMProperty prop, const char *propname,
|
||||
|
|
|
|||
|
|
@ -24,7 +24,5 @@ extern PGDLLIMPORT bool trace_syncscan;
|
|||
|
||||
extern void ss_report_location(Relation rel, BlockNumber location);
|
||||
extern BlockNumber ss_get_location(Relation rel, BlockNumber relnblocks);
|
||||
extern void SyncScanShmemInit(void);
|
||||
extern Size SyncScanShmemSize(void);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -33,9 +33,6 @@ typedef struct GlobalTransactionData *GlobalTransaction;
|
|||
/* GUC variable */
|
||||
extern PGDLLIMPORT int max_prepared_xacts;
|
||||
|
||||
extern Size TwoPhaseShmemSize(void);
|
||||
extern void TwoPhaseShmemInit(void);
|
||||
|
||||
extern void AtAbort_Twophase(void);
|
||||
extern void PostPrepare_Twophase(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -259,8 +259,6 @@ extern void InitLocalDataChecksumState(void);
|
|||
extern void SetLocalDataChecksumState(uint32 data_checksum_version);
|
||||
extern bool GetDefaultCharSignedness(void);
|
||||
extern XLogRecPtr GetFakeLSNForUnloggedRel(void);
|
||||
extern Size XLOGShmemSize(void);
|
||||
extern void XLOGShmemInit(void);
|
||||
extern void BootStrapXLOG(uint32 data_checksum_version);
|
||||
extern void InitializeWalConsistencyChecking(void);
|
||||
extern void LocalProcessControlFile(bool reset);
|
||||
|
|
|
|||
|
|
@ -34,9 +34,6 @@ typedef struct XLogPrefetcher XLogPrefetcher;
|
|||
|
||||
extern void XLogPrefetchReconfigure(void);
|
||||
|
||||
extern size_t XLogPrefetchShmemSize(void);
|
||||
extern void XLogPrefetchShmemInit(void);
|
||||
|
||||
extern void XLogPrefetchResetStats(void);
|
||||
|
||||
extern XLogPrefetcher *XLogPrefetcherAllocate(XLogReaderState *reader);
|
||||
|
|
|
|||
|
|
@ -153,9 +153,6 @@ extern PGDLLIMPORT bool reachedConsistency;
|
|||
/* Are we currently in standby mode? */
|
||||
extern PGDLLIMPORT bool StandbyMode;
|
||||
|
||||
extern Size XLogRecoveryShmemSize(void);
|
||||
extern void XLogRecoveryShmemInit(void);
|
||||
|
||||
extern void InitWalRecovery(ControlFileData *ControlFile,
|
||||
bool *wasShutdown_ptr, bool *haveBackupLabel_ptr,
|
||||
bool *haveTblspcMap_ptr);
|
||||
|
|
|
|||
|
|
@ -100,8 +100,6 @@ typedef struct WaitLSNState
|
|||
|
||||
extern PGDLLIMPORT WaitLSNState *waitLSNState;
|
||||
|
||||
extern Size WaitLSNShmemSize(void);
|
||||
extern void WaitLSNShmemInit(void);
|
||||
extern XLogRecPtr GetCurrentLSNForWaitType(WaitLSNType lsnType);
|
||||
extern void WaitLSNWakeup(WaitLSNType lsnType, XLogRecPtr currentLSN);
|
||||
extern void WaitLSNCleanup(void);
|
||||
|
|
|
|||
|
|
@ -541,10 +541,6 @@ typedef struct PgStat_BackendPending
|
|||
* Functions in pgstat.c
|
||||
*/
|
||||
|
||||
/* functions called from postmaster */
|
||||
extern Size StatsShmemSize(void);
|
||||
extern void StatsShmemInit(void);
|
||||
|
||||
/* Functions called during server startup / shutdown */
|
||||
extern void pgstat_restore_stats(void);
|
||||
extern void pgstat_discard_stats(void);
|
||||
|
|
|
|||
|
|
@ -66,8 +66,4 @@ pg_noreturn extern void AutoVacWorkerMain(const void *startup_data, size_t start
|
|||
extern bool AutoVacuumRequestWork(AutoVacuumWorkItemType type,
|
||||
Oid relationId, BlockNumber blkno);
|
||||
|
||||
/* shared memory stuff */
|
||||
extern Size AutoVacuumShmemSize(void);
|
||||
extern void AutoVacuumShmemInit(void);
|
||||
|
||||
#endif /* AUTOVACUUM_H */
|
||||
|
|
|
|||
|
|
@ -41,8 +41,6 @@ typedef struct RegisteredBgWorker
|
|||
|
||||
extern PGDLLIMPORT dlist_head BackgroundWorkerList;
|
||||
|
||||
extern Size BackgroundWorkerShmemSize(void);
|
||||
extern void BackgroundWorkerShmemInit(void);
|
||||
extern void BackgroundWorkerStateChange(bool allow_new_workers);
|
||||
extern void ForgetBackgroundWorker(RegisteredBgWorker *rw);
|
||||
extern void ReportBackgroundWorkerPID(RegisteredBgWorker *rw);
|
||||
|
|
|
|||
|
|
@ -39,9 +39,6 @@ extern bool ForwardSyncRequest(const FileTag *ftag, SyncRequestType type);
|
|||
|
||||
extern void AbsorbSyncRequests(void);
|
||||
|
||||
extern Size CheckpointerShmemSize(void);
|
||||
extern void CheckpointerShmemInit(void);
|
||||
|
||||
extern bool FirstCallSinceLastCheckpoint(void);
|
||||
|
||||
#endif /* _BGWRITER_H */
|
||||
|
|
|
|||
|
|
@ -17,10 +17,6 @@
|
|||
|
||||
#include "storage/procsignal.h"
|
||||
|
||||
/* Shared memory */
|
||||
extern Size DataChecksumsShmemSize(void);
|
||||
extern void DataChecksumsShmemInit(void);
|
||||
|
||||
/* Possible operations the Datachecksumsworker can perform */
|
||||
typedef enum DataChecksumsWorkerOperation
|
||||
{
|
||||
|
|
|
|||
|
|
@ -26,8 +26,6 @@
|
|||
#define MAX_XFN_CHARS 40
|
||||
#define VALID_XFN_CHARS "0123456789ABCDEF.history.backup.partial"
|
||||
|
||||
extern Size PgArchShmemSize(void);
|
||||
extern void PgArchShmemInit(void);
|
||||
extern bool PgArchCanRestart(void);
|
||||
pg_noreturn extern void PgArchiverMain(const void *startup_data, size_t startup_data_len);
|
||||
extern void PgArchWakeup(void);
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@
|
|||
extern PGDLLIMPORT bool summarize_wal;
|
||||
extern PGDLLIMPORT int wal_summary_keep_time;
|
||||
|
||||
extern Size WalSummarizerShmemSize(void);
|
||||
extern void WalSummarizerShmemInit(void);
|
||||
pg_noreturn extern void WalSummarizerMain(const void *startup_data, size_t startup_data_len);
|
||||
|
||||
extern void GetWalSummarizerState(TimeLineID *summarized_tli,
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@
|
|||
#ifndef LOGICALCTL_H
|
||||
#define LOGICALCTL_H
|
||||
|
||||
extern Size LogicalDecodingCtlShmemSize(void);
|
||||
extern void LogicalDecodingCtlShmemInit(void);
|
||||
extern void StartupLogicalDecodingStatus(bool last_status);
|
||||
extern void InitializeProcessXLogLogicalInfo(void);
|
||||
extern bool ProcessBarrierUpdateXLogLogicalInfo(void);
|
||||
|
|
|
|||
|
|
@ -19,9 +19,6 @@ extern PGDLLIMPORT int max_parallel_apply_workers_per_subscription;
|
|||
extern void ApplyLauncherRegister(void);
|
||||
extern void ApplyLauncherMain(Datum main_arg);
|
||||
|
||||
extern Size ApplyLauncherShmemSize(void);
|
||||
extern void ApplyLauncherShmemInit(void);
|
||||
|
||||
extern void ApplyLauncherForgetWorkerStartTime(Oid subid);
|
||||
|
||||
extern void ApplyLauncherWakeupAtCommit(void);
|
||||
|
|
|
|||
|
|
@ -84,8 +84,4 @@ extern void replorigin_redo(XLogReaderState *record);
|
|||
extern void replorigin_desc(StringInfo buf, XLogReaderState *record);
|
||||
extern const char *replorigin_identify(uint8 info);
|
||||
|
||||
/* shared memory allocation */
|
||||
extern Size ReplicationOriginShmemSize(void);
|
||||
extern void ReplicationOriginShmemInit(void);
|
||||
|
||||
#endif /* PG_ORIGIN_H */
|
||||
|
|
|
|||
|
|
@ -327,10 +327,6 @@ extern PGDLLIMPORT int max_replication_slots;
|
|||
extern PGDLLIMPORT char *synchronized_standby_slots;
|
||||
extern PGDLLIMPORT int idle_replication_slot_timeout_secs;
|
||||
|
||||
/* shmem initialization functions */
|
||||
extern Size ReplicationSlotsShmemSize(void);
|
||||
extern void ReplicationSlotsShmemInit(void);
|
||||
|
||||
/* management of individual slots */
|
||||
extern void ReplicationSlotCreate(const char *name, bool db_specific,
|
||||
ReplicationSlotPersistency persistency,
|
||||
|
|
|
|||
|
|
@ -31,8 +31,6 @@ pg_noreturn extern void ReplSlotSyncWorkerMain(const void *startup_data, size_t
|
|||
extern void ShutDownSlotSync(void);
|
||||
extern bool SlotSyncWorkerCanRestart(void);
|
||||
extern bool IsSyncingReplicationSlots(void);
|
||||
extern Size SlotSyncShmemSize(void);
|
||||
extern void SlotSyncShmemInit(void);
|
||||
extern void SyncReplicationSlots(WalReceiverConn *wrconn);
|
||||
|
||||
#endif /* SLOTSYNC_H */
|
||||
|
|
|
|||
|
|
@ -491,8 +491,6 @@ pg_noreturn extern void WalReceiverMain(const void *startup_data, size_t startup
|
|||
extern void WalRcvRequestApplyReply(void);
|
||||
|
||||
/* prototypes for functions in walreceiverfuncs.c */
|
||||
extern Size WalRcvShmemSize(void);
|
||||
extern void WalRcvShmemInit(void);
|
||||
extern void ShutdownWalRcv(void);
|
||||
extern bool WalRcvStreaming(void);
|
||||
extern bool WalRcvRunning(void);
|
||||
|
|
|
|||
|
|
@ -41,8 +41,6 @@ extern void WalSndErrorCleanup(void);
|
|||
extern void PhysicalWakeupLogicalWalSnd(void);
|
||||
extern XLogRecPtr GetStandbyFlushRecPtr(TimeLineID *tli);
|
||||
extern void WalSndSignals(void);
|
||||
extern Size WalSndShmemSize(void);
|
||||
extern void WalSndShmemInit(void);
|
||||
extern void WalSndWakeup(bool physical, bool logical);
|
||||
extern void WalSndInitStopping(void);
|
||||
extern void WalSndWaitStopping(void);
|
||||
|
|
|
|||
|
|
@ -375,8 +375,6 @@ typedef enum
|
|||
/*
|
||||
* function prototypes
|
||||
*/
|
||||
extern void LockManagerShmemInit(void);
|
||||
extern Size LockManagerShmemSize(void);
|
||||
extern void InitLockManagerAccess(void);
|
||||
extern LockMethod GetLocksMethodTable(const LOCK *lock);
|
||||
extern LockMethod GetLockTagsMethodTable(const LOCKTAG *locktag);
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ PG_SHMEM_SUBSYSTEM(DSMRegistryShmemCallbacks)
|
|||
|
||||
/* xlog, clog, and buffers */
|
||||
PG_SHMEM_SUBSYSTEM(VarsupShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(XLOGShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(XLogPrefetchShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(XLogRecoveryShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(CLOGShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(CommitTsShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(SUBTRANSShmemCallbacks)
|
||||
|
|
@ -40,12 +43,18 @@ PG_SHMEM_SUBSYSTEM(BufferManagerShmemCallbacks)
|
|||
PG_SHMEM_SUBSYSTEM(StrategyCtlShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(BufTableShmemCallbacks)
|
||||
|
||||
/* lock manager */
|
||||
PG_SHMEM_SUBSYSTEM(LockManagerShmemCallbacks)
|
||||
|
||||
/* predicate lock manager */
|
||||
PG_SHMEM_SUBSYSTEM(PredicateLockShmemCallbacks)
|
||||
|
||||
/* process table */
|
||||
PG_SHMEM_SUBSYSTEM(ProcGlobalShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(ProcArrayShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(BackendStatusShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(TwoPhaseShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(BackgroundWorkerShmemCallbacks)
|
||||
|
||||
/* shared-inval messaging */
|
||||
PG_SHMEM_SUBSYSTEM(SharedInvalShmemCallbacks)
|
||||
|
|
@ -53,9 +62,27 @@ PG_SHMEM_SUBSYSTEM(SharedInvalShmemCallbacks)
|
|||
/* interprocess signaling mechanisms */
|
||||
PG_SHMEM_SUBSYSTEM(PMSignalShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(ProcSignalShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(CheckpointerShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(AutoVacuumShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(ReplicationSlotsShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(ReplicationOriginShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(WalSndShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(WalRcvShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(WalSummarizerShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(PgArchShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(ApplyLauncherShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(SlotSyncShmemCallbacks)
|
||||
|
||||
/* other modules that need some shared memory space */
|
||||
PG_SHMEM_SUBSYSTEM(BTreeShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(SyncScanShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(AsyncShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(StatsShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(WaitEventCustomShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(InjectionPointShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(WaitLSNShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(LogicalDecodingCtlShmemCallbacks)
|
||||
PG_SHMEM_SUBSYSTEM(DataChecksumsShmemCallbacks)
|
||||
|
||||
/* AIO subsystem. This delegates to the method-specific callbacks */
|
||||
PG_SHMEM_SUBSYSTEM(AioShmemCallbacks)
|
||||
|
|
|
|||
|
|
@ -298,14 +298,6 @@ extern PGDLLIMPORT int pgstat_track_activity_query_size;
|
|||
extern PGDLLIMPORT PgBackendStatus *MyBEEntry;
|
||||
|
||||
|
||||
/* ----------
|
||||
* Functions called from postmaster
|
||||
* ----------
|
||||
*/
|
||||
extern Size BackendStatusShmemSize(void);
|
||||
extern void BackendStatusShmemInit(void);
|
||||
|
||||
|
||||
/* ----------
|
||||
* Functions called from backends
|
||||
* ----------
|
||||
|
|
|
|||
|
|
@ -46,9 +46,6 @@ typedef void (*InjectionPointCallback) (const char *name,
|
|||
const void *private_data,
|
||||
void *arg);
|
||||
|
||||
extern Size InjectionPointShmemSize(void);
|
||||
extern void InjectionPointShmemInit(void);
|
||||
|
||||
extern void InjectionPointAttach(const char *name,
|
||||
const char *library,
|
||||
const char *function,
|
||||
|
|
|
|||
|
|
@ -42,8 +42,6 @@ extern PGDLLIMPORT uint32 *my_wait_event_info;
|
|||
extern uint32 WaitEventExtensionNew(const char *wait_event_name);
|
||||
extern uint32 WaitEventInjectionPointNew(const char *wait_event_name);
|
||||
|
||||
extern void WaitEventCustomShmemInit(void);
|
||||
extern Size WaitEventCustomShmemSize(void);
|
||||
extern char **GetWaitEventCustomNames(uint32 classId, int *nwaitevents);
|
||||
|
||||
/* ----------
|
||||
|
|
|
|||
|
|
@ -107,9 +107,13 @@ extern PGDLLEXPORT void injection_wait(const char *name,
|
|||
/* track if injection points attached in this process are linked to it */
|
||||
static bool injection_point_local = false;
|
||||
|
||||
/* Shared memory init callbacks */
|
||||
static shmem_request_hook_type prev_shmem_request_hook = NULL;
|
||||
static shmem_startup_hook_type prev_shmem_startup_hook = NULL;
|
||||
static void injection_shmem_request(void *arg);
|
||||
static void injection_shmem_init(void *arg);
|
||||
|
||||
static const ShmemCallbacks injection_shmem_callbacks = {
|
||||
.request_fn = injection_shmem_request,
|
||||
.init_fn = injection_shmem_init,
|
||||
};
|
||||
|
||||
/*
|
||||
* Routine for shared memory area initialization, used as a callback
|
||||
|
|
@ -126,44 +130,23 @@ injection_point_init_state(void *ptr, void *arg)
|
|||
ConditionVariableInit(&state->wait_point);
|
||||
}
|
||||
|
||||
/* Shared memory initialization when loading module */
|
||||
static void
|
||||
injection_shmem_request(void)
|
||||
injection_shmem_request(void *arg)
|
||||
{
|
||||
Size size;
|
||||
|
||||
if (prev_shmem_request_hook)
|
||||
prev_shmem_request_hook();
|
||||
|
||||
size = MAXALIGN(sizeof(InjectionPointSharedState));
|
||||
RequestAddinShmemSpace(size);
|
||||
ShmemRequestStruct(.name = "injection_points",
|
||||
.size = sizeof(InjectionPointSharedState),
|
||||
.ptr = (void **) &inj_state,
|
||||
);
|
||||
}
|
||||
|
||||
static void
|
||||
injection_shmem_startup(void)
|
||||
injection_shmem_init(void *arg)
|
||||
{
|
||||
bool found;
|
||||
|
||||
if (prev_shmem_startup_hook)
|
||||
prev_shmem_startup_hook();
|
||||
|
||||
/* Create or attach to the shared memory state */
|
||||
LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);
|
||||
|
||||
inj_state = ShmemInitStruct("injection_points",
|
||||
sizeof(InjectionPointSharedState),
|
||||
&found);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
/*
|
||||
* First time through, so initialize. This is shared with the dynamic
|
||||
* initialization using a DSM.
|
||||
*/
|
||||
injection_point_init_state(inj_state, NULL);
|
||||
}
|
||||
|
||||
LWLockRelease(AddinShmemInitLock);
|
||||
/*
|
||||
* First time through, so initialize. This is shared with the dynamic
|
||||
* initialization using a DSM.
|
||||
*/
|
||||
injection_point_init_state(inj_state, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -601,9 +584,5 @@ _PG_init(void)
|
|||
if (!process_shared_preload_libraries_in_progress)
|
||||
return;
|
||||
|
||||
/* Shared memory initialization */
|
||||
prev_shmem_request_hook = shmem_request_hook;
|
||||
shmem_request_hook = injection_shmem_request;
|
||||
prev_shmem_startup_hook = shmem_startup_hook;
|
||||
shmem_startup_hook = injection_shmem_startup;
|
||||
RegisterShmemCallbacks(&injection_shmem_callbacks);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@
|
|||
#include "storage/bufmgr.h"
|
||||
#include "storage/checksum.h"
|
||||
#include "storage/condition_variable.h"
|
||||
#include "storage/ipc.h"
|
||||
#include "storage/lwlock.h"
|
||||
#include "storage/proc.h"
|
||||
#include "storage/procnumber.h"
|
||||
|
|
@ -44,6 +43,7 @@
|
|||
PG_MODULE_MAGIC;
|
||||
|
||||
|
||||
/* In shared memory */
|
||||
typedef struct InjIoErrorState
|
||||
{
|
||||
ConditionVariable cv;
|
||||
|
|
@ -74,8 +74,15 @@ typedef struct BlocksReadStreamData
|
|||
static InjIoErrorState *inj_io_error_state;
|
||||
|
||||
/* Shared memory init callbacks */
|
||||
static shmem_request_hook_type prev_shmem_request_hook = NULL;
|
||||
static shmem_startup_hook_type prev_shmem_startup_hook = NULL;
|
||||
static void test_aio_shmem_request(void *arg);
|
||||
static void test_aio_shmem_init(void *arg);
|
||||
static void test_aio_shmem_attach(void *arg);
|
||||
|
||||
static const ShmemCallbacks inj_io_shmem_callbacks = {
|
||||
.request_fn = test_aio_shmem_request,
|
||||
.init_fn = test_aio_shmem_init,
|
||||
.attach_fn = test_aio_shmem_attach,
|
||||
};
|
||||
|
||||
|
||||
static PgAioHandle *last_handle;
|
||||
|
|
@ -83,70 +90,55 @@ static PgAioHandle *last_handle;
|
|||
|
||||
|
||||
static void
|
||||
test_aio_shmem_request(void)
|
||||
test_aio_shmem_request(void *arg)
|
||||
{
|
||||
if (prev_shmem_request_hook)
|
||||
prev_shmem_request_hook();
|
||||
|
||||
RequestAddinShmemSpace(sizeof(InjIoErrorState));
|
||||
ShmemRequestStruct(.name = "test_aio injection points",
|
||||
.size = sizeof(InjIoErrorState),
|
||||
.ptr = (void **) &inj_io_error_state,
|
||||
);
|
||||
}
|
||||
|
||||
static void
|
||||
test_aio_shmem_startup(void)
|
||||
test_aio_shmem_init(void *arg)
|
||||
{
|
||||
bool found;
|
||||
/* First time through, initialize */
|
||||
inj_io_error_state->enabled_short_read = false;
|
||||
inj_io_error_state->enabled_reopen = false;
|
||||
inj_io_error_state->enabled_completion_wait = false;
|
||||
|
||||
if (prev_shmem_startup_hook)
|
||||
prev_shmem_startup_hook();
|
||||
|
||||
/* Create or attach to the shared memory state */
|
||||
LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);
|
||||
|
||||
inj_io_error_state = ShmemInitStruct("injection_points",
|
||||
sizeof(InjIoErrorState),
|
||||
&found);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
/* First time through, initialize */
|
||||
inj_io_error_state->enabled_short_read = false;
|
||||
inj_io_error_state->enabled_reopen = false;
|
||||
inj_io_error_state->enabled_completion_wait = false;
|
||||
|
||||
ConditionVariableInit(&inj_io_error_state->cv);
|
||||
inj_io_error_state->completion_wait_event = WaitEventInjectionPointNew("completion_wait");
|
||||
ConditionVariableInit(&inj_io_error_state->cv);
|
||||
inj_io_error_state->completion_wait_event = WaitEventInjectionPointNew("completion_wait");
|
||||
|
||||
#ifdef USE_INJECTION_POINTS
|
||||
InjectionPointAttach("aio-process-completion-before-shared",
|
||||
"test_aio",
|
||||
"inj_io_completion_hook",
|
||||
NULL,
|
||||
0);
|
||||
InjectionPointLoad("aio-process-completion-before-shared");
|
||||
InjectionPointAttach("aio-process-completion-before-shared",
|
||||
"test_aio",
|
||||
"inj_io_completion_hook",
|
||||
NULL,
|
||||
0);
|
||||
InjectionPointLoad("aio-process-completion-before-shared");
|
||||
|
||||
InjectionPointAttach("aio-worker-after-reopen",
|
||||
"test_aio",
|
||||
"inj_io_reopen",
|
||||
NULL,
|
||||
0);
|
||||
InjectionPointLoad("aio-worker-after-reopen");
|
||||
InjectionPointAttach("aio-worker-after-reopen",
|
||||
"test_aio",
|
||||
"inj_io_reopen",
|
||||
NULL,
|
||||
0);
|
||||
InjectionPointLoad("aio-worker-after-reopen");
|
||||
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Pre-load the injection points now, so we can call them in a
|
||||
* critical section.
|
||||
*/
|
||||
}
|
||||
|
||||
static void
|
||||
test_aio_shmem_attach(void *arg)
|
||||
{
|
||||
/*
|
||||
* Pre-load the injection points now, so we can call them in a critical
|
||||
* section.
|
||||
*/
|
||||
#ifdef USE_INJECTION_POINTS
|
||||
InjectionPointLoad("aio-process-completion-before-shared");
|
||||
InjectionPointLoad("aio-worker-after-reopen");
|
||||
elog(LOG, "injection point loaded");
|
||||
InjectionPointLoad("aio-process-completion-before-shared");
|
||||
InjectionPointLoad("aio-worker-after-reopen");
|
||||
elog(LOG, "injection point loaded");
|
||||
#endif
|
||||
}
|
||||
|
||||
LWLockRelease(AddinShmemInitLock);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -155,10 +147,7 @@ _PG_init(void)
|
|||
if (!process_shared_preload_libraries_in_progress)
|
||||
return;
|
||||
|
||||
prev_shmem_request_hook = shmem_request_hook;
|
||||
shmem_request_hook = test_aio_shmem_request;
|
||||
prev_shmem_startup_hook = shmem_startup_hook;
|
||||
shmem_startup_hook = test_aio_shmem_startup;
|
||||
RegisterShmemCallbacks(&inj_io_shmem_callbacks);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue