⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 readme

📁 PostgreSQL7.4.6 for Linux
💻
字号:
$Header: /cvsroot/pgsql/src/backend/storage/buffer/README,v 1.4 2003/10/31 22:48:08 tgl Exp $Notes about shared buffer access rules--------------------------------------There are two separate access control mechanisms for shared disk buffers:reference counts (a/k/a pin counts) and buffer locks.  (Actually, there'sa third level of access control: one must hold the appropriate kind oflock on a relation before one can legally access any page belonging tothe relation.  Relation-level locks are not discussed here.)Pins: one must "hold a pin on" a buffer (increment its reference count)before being allowed to do anything at all with it.  An unpinned buffer issubject to being reclaimed and reused for a different page at any instant,so touching it is unsafe.  Typically a pin is acquired via ReadBuffer andreleased via WriteBuffer (if one modified the page) or ReleaseBuffer (if not).It is OK and indeed common for a single backend to pin a page more thanonce concurrently; the buffer manager handles this efficiently.  It isconsidered OK to hold a pin for long intervals --- for example, sequentialscans hold a pin on the current page until done processing all the tupleson the page, which could be quite a while if the scan is the outer scan ofa join.  Similarly, btree index scans hold a pin on the current index page.This is OK because normal operations never wait for a page's pin count todrop to zero.  (Anything that might need to do such a wait is insteadhandled by waiting to obtain the relation-level lock, which is why you'dbetter hold one first.)  Pins may not be held across transactionboundaries, however.Buffer locks: there are two kinds of buffer locks, shared and exclusive,which act just as you'd expect: multiple backends can hold shared locks onthe same buffer, but an exclusive lock prevents anyone else from holdingeither shared or exclusive lock.  (These can alternatively be called READand WRITE locks.)  These locks are intended to be short-term: they should notbe held for long.  Buffer locks are acquired and released by LockBuffer().It will *not* work for a single backend to try to acquire multiple locks onthe same buffer.  One must pin a buffer before trying to lock it.Buffer access rules:1. To scan a page for tuples, one must hold a pin and either shared orexclusive lock.  To examine the commit status (XIDs and status bits) ofa tuple in a shared buffer, one must likewise hold a pin and either sharedor exclusive lock.2. Once one has determined that a tuple is interesting (visible to thecurrent transaction) one may drop the buffer lock, yet continue to accessthe tuple's data for as long as one holds the buffer pin.  This is what istypically done by heap scans, since the tuple returned by heap_fetchcontains a pointer to tuple data in the shared buffer.  Therefore thetuple cannot go away while the pin is held (see rule #5).  Its state couldchange, but that is assumed not to matter after the initial determinationof visibility is made.3. To add a tuple or change the xmin/xmax fields of an existing tuple,one must hold a pin and an exclusive lock on the containing buffer.This ensures that no one else might see a partially-updated state of thetuple.4. It is considered OK to update tuple commit status bits (ie, OR thevalues HEAP_XMIN_COMMITTED, HEAP_XMIN_INVALID, HEAP_XMAX_COMMITTED, orHEAP_XMAX_INVALID into t_infomask) while holding only a shared lock andpin on a buffer.  This is OK because another backend looking at the tupleat about the same time would OR the same bits into the field, so thereis little or no risk of conflicting update; what's more, if there didmanage to be a conflict it would merely mean that one bit-update wouldbe lost and need to be done again later.  These four bits are only hints(they cache the results of transaction status lookups in pg_clog), so nogreat harm is done if they get reset to zero by conflicting updates.5. To physically remove a tuple or compact free space on a page, onemust hold a pin and an exclusive lock, *and* observe while holding theexclusive lock that the buffer's shared reference count is one (ie,no other backend holds a pin).  If these conditions are met then no otherbackend can perform a page scan until the exclusive lock is dropped, andno other backend can be holding a reference to an existing tuple that itmight expect to examine again.  Note that another backend might pin thebuffer (increment the refcount) while one is performing the cleanup, butit won't be able to actually examine the page until it acquires sharedor exclusive lock.VACUUM FULL ignores rule #5, because it instead acquires exclusive lock atthe relation level, which ensures indirectly that no one else is accessingpages of the relation at all.Plain (concurrent) VACUUM must respect rule #5 fully.  Obtaining thenecessary lock is done by the bufmgr routine LockBufferForCleanup().It first gets an exclusive lock and then checks to see if the shared pincount is currently 1.  If not, it releases the exclusive lock (but not thecaller's pin) and waits until signaled by another backend, whereupon ittries again.  The signal will occur when UnpinBuffer decrements the sharedpin count to 1.  As indicated above, this operation might have to wait agood while before it acquires lock, but that shouldn't matter much forconcurrent VACUUM.  The current implementation only supports a singlewaiter for pin-count-1 on any particular shared buffer.  This is enoughfor VACUUM's use, since we don't allow multiple VACUUMs concurrently on asingle relation anyway.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -