#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.