On 15.01.2013 00:14, Heikki Linnakangas wrote:
On 14.01.2013 23:35, Tom Lane wrote:
Since commit 2065dd2834e832eb820f1fbcd16746d6af1f6037, there have been
a few buildfarm failures along the lines of
-- Commit table drop
COMMIT PREPARED 'regress-two';
! PANIC: failed to re-find shared proclock object
! PANIC: failed to re-find shared proclock object
! connection to server was lost
Evidently I bollixed something, but what? I've been unable to reproduce
this locally so far. Anybody see what's wrong?
I was able to reproduce this by setting max_locks_per_transaction and
max_connections to the minimum. My assumption is that there's something
wrong in the way hash_update_hash_key() handles collisions.
The problem seems to be when the the old and the key hash to the same
bucket. In that case, hash_update_hash_key() tries to link the entry to
itself. The attached patch fixes it for me.
- Heikki
*** a/src/backend/utils/hash/dynahash.c
--- b/src/backend/utils/hash/dynahash.c
***************
*** 1022,1027 **** hash_update_hash_key(HTAB *hashp,
--- 1022,1028 ----
uint32 newhashvalue;
Size keysize;
uint32 bucket;
+ uint32 newbucket;
long segment_num;
long segment_ndx;
HASHSEGMENT segp;
***************
*** 1078,1087 **** hash_update_hash_key(HTAB *hashp,
*/
newhashvalue = hashp->hash(newKeyPtr, hashp->keysize);
! bucket = calc_bucket(hctl, newhashvalue);
!
! segment_num = bucket >> hashp->sshift;
! segment_ndx = MOD(bucket, hashp->ssize);
segp = hashp->dir[segment_num];
--- 1079,1087 ----
*/
newhashvalue = hashp->hash(newKeyPtr, hashp->keysize);
! newbucket = calc_bucket(hctl, newhashvalue);
! segment_num = newbucket >> hashp->sshift;
! segment_ndx = MOD(newbucket, hashp->ssize);
segp = hashp->dir[segment_num];
***************
*** 1115,1126 **** hash_update_hash_key(HTAB *hashp,
currBucket = existingElement;
! /* OK to remove record from old hash bucket's chain. */
! *oldPrevPtr = currBucket->link;
! /* link into new hashbucket chain */
! *prevBucketPtr = currBucket;
! currBucket->link = NULL;
/* copy new key into record */
currBucket->hashvalue = newhashvalue;
--- 1115,1129 ----
currBucket = existingElement;
! if (bucket != newbucket)
! {
! /* OK to remove record from old hash bucket's chain. */
! *oldPrevPtr = currBucket->link;
! /* link into new hashbucket chain */
! *prevBucketPtr = currBucket;
! currBucket->link = NULL;
! }
/* copy new key into record */
currBucket->hashvalue = newhashvalue;
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers