From: | Amit Kapila <amit(dot)kapila16(at)gmail(dot)com> |
---|---|
To: | Mithun Cy <mithun(dot)cy(at)enterprisedb(dot)com> |
Cc: | Andres Freund <andres(at)anarazel(dot)de>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: POC: Cache data in GetSnapshotData() |
Date: | 2016-01-16 04:53:14 |
Message-ID: | CAA4eK1L8unie41+bJb91E65xc7-rstGz3RSkJCuj8JK2nt8SGA@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
On Fri, Jan 15, 2016 at 11:23 AM, Mithun Cy <mithun(dot)cy(at)enterprisedb(dot)com>
wrote:
> On Mon, Jan 4, 2016 at 2:28 PM, Andres Freund <andres(at)anarazel(dot)de> wrote:
>
> > I think at the very least the cache should be protected by a separate
> > lock, and that lock should be acquired with TryLock. I.e. the cache is
> > updated opportunistically. I'd go for an lwlock in the first iteration.
>
> I tried to implement a simple patch which protect the cache. Of all the
> backend which
> compute the snapshot(when cache is invalid) only one of them will write to
> cache.
> This is done with one atomic compare and swap operation.
>
> After above fix memory corruption is not visible. But I see some more
> failures at higher client sessions(128 it is easily reproducible).
>
> Errors are
> DETAIL: Key (bid)=(24) already exists.
> STATEMENT: UPDATE pgbench_branches SET bbalance = bbalance + $1 WHERE bid
> = $2;
> client 17 aborted in state 11: ERROR: duplicate key value violates unique
> constraint "pgbench_branches_pkey"
> DETAIL: Key (bid)=(24) already exists.
> client 26 aborted in state 11: ERROR: duplicate key value violates unique
> constraint "pgbench_branches_pkey"
> DETAIL: Key (bid)=(87) already exists.
> ERROR: duplicate key value violates unique constraint
> "pgbench_branches_pkey"
> DETAIL: Key (bid)=(113) already exists.
>
> After some analysis I think In GetSnapshotData() while computing snapshot.
> /*
> * We don't include our own XIDs (if any) in the snapshot,
> but we
> * must include them in xmin.
> */
> if (NormalTransactionIdPrecedes(xid, xmin))
> xmin = xid;
> *********** if (pgxact == MyPgXact) ******************
> continue;
>
> We do not add our own xid to xip array, I am wondering if other backend
> try to use
> the same snapshot will it be able to see changes made by me(current
> backend).
> I think since we compute a snapshot which will be used by other backends
> we need to
> add our xid to xip array to tell transaction is open.
>
I also think this observation of yours is right and currently that is
okay because we always first check TransactionIdIsCurrentTransactionId().
Refer comments on top of XidInMVCCSnapshot() [1]. However, I
am not sure if it is good idea to start including current backends xid
in snapshot, because that can lead to including its subxids as well
which can make snapshot size bigger for cases where current transaction
has many sub-transactions. One way could be that we store current
backends transaction and sub-transaction id's only for the saved
snapshot, does that sound reasonable to you?
Other than that, I think patch needs to clear saved snapshot for
Commit Prepared Transaction as well (refer function
FinishPreparedTransaction()).
! else if (!snapshot->takenDuringRecovery)
{
int *pgprocnos = arrayP->pgprocnos;
int numProcs;
+ const uint32 snapshot_cached= 0;
I don't think the const is required for above variable.
[1] -
Note: GetSnapshotData never stores either top xid or subxids of our own
backend into a snapshot, so these xids will not be reported as "running"
by this function. This is OK for current uses, because we always check
TransactionIdIsCurrentTransactionId first, except for known-committed
XIDs which could not be ours anyway.
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com
From | Date | Subject | |
---|---|---|---|
Next Message | Michael Paquier | 2016-01-16 06:02:50 | Re: [BUGS] about test_parser installation failure problem(PostgreSQL in 9.5.0)? |
Previous Message | Noah Misch | 2016-01-16 02:10:36 | Re: pgindent-polluted commits |