Header And Logo

| The world's most advanced open source database.

Data Structures | Defines | Typedefs | Functions | Variables

syncscan.c File Reference

#include "postgres.h"
#include "access/heapam.h"
#include "miscadmin.h"
#include "utils/rel.h"
Include dependency graph for syncscan.c:

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


#define SYNC_SCAN_NELEM   20
#define SYNC_SCAN_REPORT_INTERVAL   (128 * 1024 / BLCKSZ)
#define SizeOfScanLocations(N)   offsetof(ss_scan_locations_t, items[N])


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


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)


static ss_scan_locations_tscan_locations

Define Documentation

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

typedef struct ss_lru_item_t ss_lru_item_t

Function Documentation

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);

     * 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;

    if (trace_syncscan)
             "SYNC_SCAN: start \"%s\" (size %u) at %u",
             RelationGetRelationName(rel), relnblocks, startloc);

    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().

    if (trace_syncscan)
        if ((location % 1024) == 0)
                 "SYNC_SCAN: scanning \"%s\" at %u",
                 RelationGetRelationName(rel), location);

     * 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);
        else if (trace_syncscan)
                 "SYNC_SCAN: missed update for \"%s\" at %u",
                 RelationGetRelationName(rel), location);

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",

    if (!IsUnderPostmaster)
        /* Initialize shared memory area */

        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;

Size SyncScanShmemSize ( void   ) 

Definition at line 123 of file syncscan.c.

References SizeOfScanLocations, and SYNC_SCAN_NELEM.

Referenced by CreateSharedMemoryAndSemaphores().

Variable Documentation

Definition at line 112 of file syncscan.c.