Re: [HACKERS] Concurrency control questions 6.3.2 vs. 6.4 - Mailing list pgsql-hackers
From | Steve Frampton |
---|---|
Subject | Re: [HACKERS] Concurrency control questions 6.3.2 vs. 6.4 |
Date | |
Msg-id | Pine.LNX.4.05.9811171905350.1859-100000@mail.flarc.edu.on.ca Whole thread Raw |
In response to | Concurrency control questions 6.3.2 vs. 6.4 (Steve Frampton <frampton@mail.flarc.edu.on.ca>) |
Responses |
Re: [HACKERS] Concurrency control questions 6.3.2 vs. 6.4
|
List | 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@qlink.queensu.ca> http://qlink.queensu.ca/~3srf
pgsql-hackers by date: