Several objects have issues where you can drop them while a dependent is being created -- a good example is Domains (and types in general) -- but I'll hunt down others later (languages?). The solution (as Tom stated earlier) is to create a more generic lock tag.
1. Modify LOCKTAG to include 'classId'. Rename 'relId' to 'objId', and rename 'objId' to 'objsubId' -- very similar to dependency tracking. Expands locktag by sizeof(Oid), but also allows locking anything that we can attach a dependency to. If it wasn't for Page locks, objId could be a part of the union with xid. typedef struct LOCKTAG { Oid objId; Oid classId; Oid dbId; union { BlockNumber blkno; TransactionId xid; } objsubId; /* * offnum should be part of objId.tupleId above, but would increase * sizeof(LOCKTAG) and so moved here; currently used by userlocks * only. */ OffsetNumber offnum; uint16 lockmethod; /* needed by userlocks */ } LOCKTAG; 2. Modify current locks to set classId to RelOid_pg_class in most cases. Transaction locks will set classId to XactLockTableId and objId to InvalidOid. 3. Generate two new lock functions which allow locking of an arbitrary classId with the intent that they will be used to lock / unlock non-relation or transaction oriented locks (none of the current locks). The lock functions will only deal with 'AccessShare' and 'AccessExclusive' locks -- others will be rejected. 4. Lock problematic Type / Domain areas (classId RelOid_pg_type): ALTER TABLE .. [ ADD | ALTER | DROP ] COLUMN (AccessShareLock) CREATE TABLE -- one per column (AccessShareLock) SELECT -- one per column in query (AccessShareLock) DROP DOMAIN / DROP TYPE (AccessExclusive) ALTER DOMAIN (AccessExclusive) Since the below aren't visible, they don't require a lock: CREATE DOMAIN / CREATE TYPE (AccessExclusive) 5. Continue the process with schemas, languages, casts, etc. All of which can be dropped while another entity is being created that uses it. PSQL 1: CREATE SCHEMA sch; PSQL 1: BEGIN; CREATE TABLE sch.tab (col integer); PSQL 2: DROP SCHEMA sch; PSQL 1: COMMIT; -- Table tab is missing a schema entry. The above works with almost all database objects that are not relations (tables, views, indexes, sequences should be fine). Potential Problems: - This will add a huge number of 'AccessShare' locks, as every select will need to lock the types, casts, etc. involved. - You don't need to lock on pinned objects like the 'integer' type as it's guarenteed not be to dropped. If we create an ALTER TYPE command this changes. Do we kill a syscache lookup to prevent the lock -- probably not -- but it makes the above mentioned AccessShareLock count much larger. -- Rod Taylor <[EMAIL PROTECTED]> PGP Key: http://www.rbt.ca/rbtpub.asc
signature.asc
Description: This is a digitally signed message part