Re: Static snapshot data

From: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
To: Manfred Koizar <mkoi-pg(at)aon(dot)at>
Cc: pgsql-patches(at)postgresql(dot)org
Subject: Re: Static snapshot data
Date: 2003-06-12 01:42:28
Message-ID: 200306120142.h5C1gSr22110@candle.pha.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers pgsql-patches


Patch applied. Thanks.

---------------------------------------------------------------------------

Manfred Koizar wrote:
> Up to now, SerializableSnapshot and QuerySnapshot are malloc'ed and
> free'd for every transaction or statement, respectively. This patch
> puts these data structures into static memory, thus saving a few CPU
> cycles and two malloc calls per transaction or (in isolation level
> READ COMMITTED) per query.
>
> Servus
> Manfred

> diff -ruN ../base/src/backend/storage/ipc/sinval.c src/backend/storage/ipc/sinval.c
> --- ../base/src/backend/storage/ipc/sinval.c 2003-04-04 15:45:37.000000000 +0200
> +++ src/backend/storage/ipc/sinval.c 2003-05-08 21:39:15.000000000 +0200
> @@ -305,9 +305,8 @@
> *----------
> */
> Snapshot
> -GetSnapshotData(bool serializable)
> +GetSnapshotData(Snapshot snapshot, bool serializable)
> {
> - Snapshot snapshot = (Snapshot) malloc(sizeof(SnapshotData));
> SISeg *segP = shmInvalBuffer;
> ProcState *stateP = segP->procState;
> TransactionId xmin;
> @@ -316,18 +315,29 @@
> int index;
> int count = 0;
>
> - if (snapshot == NULL)
> - elog(ERROR, "Memory exhausted in GetSnapshotData");
> + Assert(snapshot != NULL);
>
> /*
> * Allocating space for MaxBackends xids is usually overkill;
> * lastBackend would be sufficient. But it seems better to do the
> * malloc while not holding the lock, so we can't look at lastBackend.
> + *
> + * if (snapshot->xip != NULL)
> + * no need to free and reallocate xip;
> + *
> + * We can reuse the old xip array, because MaxBackends does not change
> + * at runtime.
> */
> - snapshot->xip = (TransactionId *)
> - malloc(MaxBackends * sizeof(TransactionId));
> if (snapshot->xip == NULL)
> - elog(ERROR, "Memory exhausted in GetSnapshotData");
> + {
> + /*
> + * First call for this snapshot
> + */
> + snapshot->xip = (TransactionId *)
> + malloc(MaxBackends * sizeof(TransactionId));
> + if (snapshot->xip == NULL)
> + elog(ERROR, "Memory exhausted in GetSnapshotData");
> + }
>
> globalxmin = xmin = GetCurrentTransactionId();
>
> diff -ruN ../base/src/backend/utils/time/tqual.c src/backend/utils/time/tqual.c
> --- ../base/src/backend/utils/time/tqual.c 2003-04-04 15:45:45.000000000 +0200
> +++ src/backend/utils/time/tqual.c 2003-05-08 21:45:55.000000000 +0200
> @@ -30,6 +30,8 @@
> static SnapshotData SnapshotDirtyData;
> Snapshot SnapshotDirty = &SnapshotDirtyData;
>
> +static SnapshotData QuerySnapshotData;
> +static SnapshotData SerializableSnapshotData;
> Snapshot QuerySnapshot = NULL;
> Snapshot SerializableSnapshot = NULL;
>
> @@ -941,23 +943,16 @@
> /* 1st call in xaction? */
> if (SerializableSnapshot == NULL)
> {
> - SerializableSnapshot = GetSnapshotData(true);
> + SerializableSnapshot = GetSnapshotData(&SerializableSnapshotData, true);
> QuerySnapshot = SerializableSnapshot;
> Assert(QuerySnapshot != NULL);
> return;
> }
>
> - if (QuerySnapshot != SerializableSnapshot)
> - {
> - free(QuerySnapshot->xip);
> - free(QuerySnapshot);
> - QuerySnapshot = NULL;
> - }
> -
> if (XactIsoLevel == XACT_SERIALIZABLE)
> QuerySnapshot = SerializableSnapshot;
> else
> - QuerySnapshot = GetSnapshotData(false);
> + QuerySnapshot = GetSnapshotData(&QuerySnapshotData, false);
>
> Assert(QuerySnapshot != NULL);
> }
> @@ -1003,19 +998,11 @@
> void
> FreeXactSnapshot(void)
> {
> - if (QuerySnapshot != NULL && QuerySnapshot != SerializableSnapshot)
> - {
> - free(QuerySnapshot->xip);
> - free(QuerySnapshot);
> - }
> -
> + /*
> + * We do not free(QuerySnapshot->xip);
> + * or free(SerializableSnapshot->xip);
> + * they will be reused soon
> + */
> QuerySnapshot = NULL;
> -
> - if (SerializableSnapshot != NULL)
> - {
> - free(SerializableSnapshot->xip);
> - free(SerializableSnapshot);
> - }
> -
> SerializableSnapshot = NULL;
> }
> diff -ruN ../base/src/include/utils/tqual.h src/include/utils/tqual.h
> --- ../base/src/include/utils/tqual.h 2003-04-04 15:45:50.000000000 +0200
> +++ src/include/utils/tqual.h 2003-05-08 21:40:04.000000000 +0200
> @@ -113,7 +113,7 @@
> extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTupleHeader tuple,
> TransactionId OldestXmin);
>
> -extern Snapshot GetSnapshotData(bool serializable);
> +extern Snapshot GetSnapshotData(Snapshot snapshot, bool serializable);
> extern void SetQuerySnapshot(void);
> extern Snapshot CopyQuerySnapshot(void);
> extern void FreeXactSnapshot(void);

>
> ---------------------------(end of broadcast)---------------------------
> TIP 1: subscribe and unsubscribe commands go to majordomo(at)postgresql(dot)org

--
Bruce Momjian | http://candle.pha.pa.us
pgman(at)candle(dot)pha(dot)pa(dot)us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Bruce Momjian 2003-06-12 02:02:44 Re: Linux startup script
Previous Message Alvaro Herrera 2003-06-11 23:42:56 Re: Pre-allocation of shared memory ...

Browse pgsql-patches by date

  From Date Subject
Next Message Bruce Momjian 2003-06-12 02:02:36 Re: Start-scripts linux
Previous Message Rod Taylor 2003-06-12 01:41:46 Doc updates (minor)