Header And Logo

PostgreSQL
| 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

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


Variable Documentation

Definition at line 112 of file syncscan.c.