Re: [HACKERS] Concurrency control questions 6.3.2 vs. 6.4

From: Steve Frampton <frampton(at)mail(dot)flarc(dot)edu(dot)on(dot)ca>
To: PostgreSQL-development <hackers(at)postgreSQL(dot)org>
Subject: Re: [HACKERS] Concurrency control questions 6.3.2 vs. 6.4
Date: 1998-11-18 01:02:14
Message-ID: Pine.LNX.4.05.9811171905350.1859-100000@mail.flarc.edu.on.ca
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi everyone:

Thanks for the helpful responses. Are you folks getting sick of me yet?
I'm hoping somebody could help me understand a bit better the way locking
protocols are used in PostGreSQL 6.4, including how a query is parsed,
executed, etc.

I understand that there are two locks available: one for reads and one for
writes. They are called by RelationSetLockForRead() and
RelationSetLockForWrite(), respectively, which are both implemented in
backend/storage/lmgr.c.

These functions are called by the query parser, trigger handler, and
indexing subsystem. The query parser is responsible for parsing a given
expression in backend/parser/parse_expr.c and actually grabbing tuples in
backend/parser/parse_func.c which are passed as a heap array to the
backend which in turn passes the information to the client. Am I still
okay?

I'm interested in the locking protocols as used for query processing
so I guess I can ignore the trigger and indexing for now.

Locking is not accomplished with calls to the operating system but instead
is managed by the locking manager through a lock hash table which lives in
shared memory. The table contains information on locks such as the type of
lock (read/write), number of locks currently held, an array of bitmasks
showing lock conflicts, and lock priority level (used to prevent
starvation). In addition, each relation has its own data structure which
includes some locking information.

Here's where things get fuzzy -- there's a lot of code here so please be
patient with me if I really screwed up in my interpretation. :-)

When the RelationSetLockFor...() function is called, it ensures that the
relation and lock information for the relation are both valid. It then
calls MultiLockReln() with a pointer to the relation's lock information
and the appropriate lock type. MultiLockReln() initializes a lock tag
which is passed to MultiAcquire().

I'm a little vague on MultiAcquire(). It seems to search through the
lock hash table to see if a lock should be allowed? And if so it calls
LockAcquire(). But LockAcquire() itself checks for conflicts, sleeps if
one exists, or sets the appropriate lock, adding it to the lock table. So
I'm a bit confused here...

Unlocks are accomplished in much the same fashion.
RelationUnsetLockFor...() is called which in turn calls MultiRelease()
which searches the lock table using the same algorithm as in
MultiAcquire(). MultiRelease() calls LockRelease() which performs two
functions. First, it removes the lock information from the lock table.
Second, this function will awaken any transaction which had blocked
waiting for the same lock. This is done here because if it was not, a new
process could come along and request the lock causing a race condition.

So...did I even come *close* to understanding this behemoth? -_-;

Corrections would be appreciated. Sorry again to be such a pain.

--------------< LINUX: The choice of a GNU generation. >--------------
Steve Frampton <3srf(at)qlink(dot)queensu(dot)ca> http://qlink.queensu.ca/~3srf

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Oliver Elphick 1998-11-18 01:38:05 Re: [HACKERS] pg-dump bug (at 6.4)
Previous Message Tom Lane 1998-11-17 23:19:43 Re: [HACKERS] building 6.4 on sunos 4.1.4