Re: Summary and Plan for Hot Standby - Mailing list pgsql-hackers
From | Heikki Linnakangas |
---|---|
Subject | Re: Summary and Plan for Hot Standby |
Date | |
Msg-id | 4B04FE33.6020704@enterprisedb.com Whole thread Raw |
In response to | Re: Summary and Plan for Hot Standby (Simon Riggs <simon@2ndQuadrant.com>) |
Responses |
Re: Summary and Plan for Hot Standby
Re: Summary and Plan for Hot Standby Re: Summary and Plan for Hot Standby |
List | pgsql-hackers |
Simon Riggs wrote: > Recovery does *not* take the same locks as the original statements on > the master took. For example, the WAL record for an INSERT just makes > its changes without acquiring locks. This is OK as long as we only allow > read-only users to acquire AccessShareLocks. If we allowed higher locks > we might need to do deadlock detection, which would add more complexity. But we *do* allow higher locks than AccessShareLocks, as Tatsuo-sans example shows. Is that a bug? > The above restrictions are limited to LOCKTAG_OBJECT so that advisory > locks work as advertised. So advisory locks can take both shared and > exclusive locks. This never conflicts with recovery because advisory > locks are not WAL logged. So we allow any lock on anything *except* LOCKTAG_OBJECT. That includes advisory locks, but also relation locks, tuple locks and page locks. Looking at the lock types in detail: LOCKTAG_RELATION Any lock level is allowed. We have other defenses against actually modifying a relation, but it feels a bit fragile and I got the impression from your comments that it's not intentional. LOCKTAG_RELATION_EXTEND Any lock level is allowed. Again, we have other defenses against modifying relations, but feels fragile. LOCKTAG_PAGE Any lock level is allowed. Page locks are only used when extending a hash index, so it seems irrelevant what we do. I think we should disallow page locks in standby altogether. LOCKTAG_TUPLE, Any lock level is allowed. Only used when locking a tuple for update. We forbid locking tuples by the general "is the transaction read-only?" check in executor, and if you manage to bypass that, you will fail to get an XID to set to xmax. Nevertheless, seems we shouldn't allow tuple locks. LOCKTAG_TRANSACTION, Any lock level is allowed. Acquired in AssignTransactionId, to allow others to wait for the transaction to finish. We don't allow AssignTransactionId() during recovery, but could someone want to wait for a transaction to finish? All the current callers of XactLockTableWait() seem to be from operations that are not allowed in recovery. Should we take a conservative stance and disallow taking transaction-locks? LOCKTAG_VIRTUALTRANSACTION Any lock level is allowed. Similar to transaction locks, but virtual transaction locks are held by read-only transactions as well. Also during recovery, and we rely on it in the code to wait for a conflicting transaction to finish. But we don't acquire locks to represent transactions in master. LOCKTAG_OBJECT, Anything higher than AccessShareLock is disallowed. Used by dependency walking in pg_depend.c. Also used as interlock between database start and DROP/CREATE DATABASE. At backend start, we normally take RowExclusiveLock on the database in postinit.c, but you had to modify to acquire AccessShareLock instead in standby mode. LOCKTAG_USERLOCK LOCKTAG_ADVISORY Any lock level is allowed. As documented, advisory locks are per-server, so a lock taken in master doesn't conflict with one taken in slave. In any case, all this really needs to be documented in a README or something. -- Heikki Linnakangas EnterpriseDB http://www.enterprisedb.com
pgsql-hackers by date: