#include "postgres.h"#include "access/heapam.h"#include "miscadmin.h"#include "utils/rel.h"
Go to the source code of this file.
Data Structures | |
| struct | ss_scan_location_t |
| struct | ss_lru_item_t |
| struct | ss_scan_locations_t |
Defines | |
| #define | SYNC_SCAN_NELEM 20 |
| #define | SYNC_SCAN_REPORT_INTERVAL (128 * 1024 / BLCKSZ) |
| #define | SizeOfScanLocations(N) offsetof(ss_scan_locations_t, items[N]) |
Typedefs | |
| typedef struct ss_scan_location_t | ss_scan_location_t |
| typedef struct ss_lru_item_t | ss_lru_item_t |
| typedef struct ss_scan_locations_t | ss_scan_locations_t |
Functions | |
| static BlockNumber | ss_search (RelFileNode relfilenode, BlockNumber location, bool set) |
| Size | SyncScanShmemSize (void) |
| void | SyncScanShmemInit (void) |
| BlockNumber | ss_get_location (Relation rel, BlockNumber relnblocks) |
| void | ss_report_location (Relation rel, BlockNumber location) |
Variables | |
| static ss_scan_locations_t * | scan_locations |
| #define SizeOfScanLocations | ( | N | ) | offsetof(ss_scan_locations_t, items[N]) |
Definition at line 109 of file syncscan.c.
Referenced by SyncScanShmemInit(), and SyncScanShmemSize().
| #define SYNC_SCAN_NELEM 20 |
Definition at line 69 of file syncscan.c.
Referenced by SyncScanShmemInit(), and SyncScanShmemSize().
| #define SYNC_SCAN_REPORT_INTERVAL (128 * 1024 / BLCKSZ) |
Definition at line 81 of file syncscan.c.
Referenced by ss_report_location().
| typedef struct ss_lru_item_t ss_lru_item_t |
| typedef struct ss_scan_location_t ss_scan_location_t |
| typedef struct ss_scan_locations_t ss_scan_locations_t |
| BlockNumber ss_get_location | ( | Relation | rel, | |
| BlockNumber | relnblocks | |||
| ) |
Definition at line 250 of file syncscan.c.
References elog, LOG, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), RelationData::rd_node, RelationGetRelationName, ss_search(), and SyncScanLock.
Referenced by initscan().
{
BlockNumber startloc;
LWLockAcquire(SyncScanLock, LW_EXCLUSIVE);
startloc = ss_search(rel->rd_node, 0, false);
LWLockRelease(SyncScanLock);
/*
* If the location is not a valid block number for this scan, start at 0.
*
* This can happen if for instance a VACUUM truncated the table since the
* location was saved.
*/
if (startloc >= relnblocks)
startloc = 0;
#ifdef TRACE_SYNCSCAN
if (trace_syncscan)
elog(LOG,
"SYNC_SCAN: start \"%s\" (size %u) at %u",
RelationGetRelationName(rel), relnblocks, startloc);
#endif
return startloc;
}
| void ss_report_location | ( | Relation | rel, | |
| BlockNumber | location | |||
| ) |
Definition at line 285 of file syncscan.c.
References elog, LOG, LW_EXCLUSIVE, LWLockConditionalAcquire(), LWLockRelease(), RelationData::rd_node, RelationGetRelationName, ss_search(), SYNC_SCAN_REPORT_INTERVAL, and SyncScanLock.
Referenced by heapgettup(), and heapgettup_pagemode().
{
#ifdef TRACE_SYNCSCAN
if (trace_syncscan)
{
if ((location % 1024) == 0)
elog(LOG,
"SYNC_SCAN: scanning \"%s\" at %u",
RelationGetRelationName(rel), location);
}
#endif
/*
* To reduce lock contention, only report scan progress every N pages. For
* the same reason, don't block if the lock isn't immediately available.
* Missing a few updates isn't critical, it just means that a new scan
* that wants to join the pack will start a little bit behind the head of
* the scan. Hopefully the pages are still in OS cache and the scan
* catches up quickly.
*/
if ((location % SYNC_SCAN_REPORT_INTERVAL) == 0)
{
if (LWLockConditionalAcquire(SyncScanLock, LW_EXCLUSIVE))
{
(void) ss_search(rel->rd_node, location, true);
LWLockRelease(SyncScanLock);
}
#ifdef TRACE_SYNCSCAN
else if (trace_syncscan)
elog(LOG,
"SYNC_SCAN: missed update for \"%s\" at %u",
RelationGetRelationName(rel), location);
#endif
}
}
| static BlockNumber ss_search | ( | RelFileNode | relfilenode, | |
| BlockNumber | location, | |||
| bool | set | |||
| ) | [static] |
Definition at line 188 of file syncscan.c.
References ss_scan_locations_t::head, ss_scan_location_t::location, ss_lru_item_t::location, ss_lru_item_t::next, NULL, ss_lru_item_t::prev, ss_scan_location_t::relfilenode, RelFileNodeEquals, and ss_scan_locations_t::tail.
Referenced by ss_get_location(), and ss_report_location().
{
ss_lru_item_t *item;
item = scan_locations->head;
for (;;)
{
bool match;
match = RelFileNodeEquals(item->location.relfilenode, relfilenode);
if (match || item->next == NULL)
{
/*
* If we reached the end of list and no match was found, take over
* the last entry
*/
if (!match)
{
item->location.relfilenode = relfilenode;
item->location.location = location;
}
else if (set)
item->location.location = location;
/* Move the entry to the front of the LRU list */
if (item != scan_locations->head)
{
/* unlink */
if (item == scan_locations->tail)
scan_locations->tail = item->prev;
item->prev->next = item->next;
if (item->next)
item->next->prev = item->prev;
/* link */
item->prev = NULL;
item->next = scan_locations->head;
scan_locations->head->prev = item;
scan_locations->head = item;
}
return item->location.location;
}
item = item->next;
}
/* not reached */
}
| void SyncScanShmemInit | ( | void | ) |
Definition at line 132 of file syncscan.c.
References Assert, RelFileNode::dbNode, ss_scan_locations_t::head, i, IsUnderPostmaster, ss_scan_locations_t::items, ss_scan_location_t::location, ss_lru_item_t::location, ss_lru_item_t::next, ss_lru_item_t::prev, ss_scan_location_t::relfilenode, RelFileNode::relNode, ShmemInitStruct(), SizeOfScanLocations, RelFileNode::spcNode, SYNC_SCAN_NELEM, and ss_scan_locations_t::tail.
Referenced by CreateSharedMemoryAndSemaphores().
{
int i;
bool found;
scan_locations = (ss_scan_locations_t *)
ShmemInitStruct("Sync Scan Locations List",
SizeOfScanLocations(SYNC_SCAN_NELEM),
&found);
if (!IsUnderPostmaster)
{
/* Initialize shared memory area */
Assert(!found);
scan_locations->head = &scan_locations->items[0];
scan_locations->tail = &scan_locations->items[SYNC_SCAN_NELEM - 1];
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.relfilenode.spcNode = InvalidOid;
item->location.relfilenode.dbNode = InvalidOid;
item->location.relfilenode.relNode = InvalidOid;
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;
}
}
else
Assert(found);
}
| Size SyncScanShmemSize | ( | void | ) |
Definition at line 123 of file syncscan.c.
References SizeOfScanLocations, and SYNC_SCAN_NELEM.
Referenced by CreateSharedMemoryAndSemaphores().
{
return SizeOfScanLocations(SYNC_SCAN_NELEM);
}
ss_scan_locations_t* scan_locations [static] |
Definition at line 112 of file syncscan.c.
1.7.1