diff --git a/doc/src/sgml/mvcc.sgml b/doc/src/sgml/mvcc.sgml index 2eaf00803b16a3d05f5b0eca19bdd3117d8a6e0c..6d7013a46a2696c5baff7db068c868a8db7e6b6f 100644 --- a/doc/src/sgml/mvcc.sgml +++ b/doc/src/sgml/mvcc.sgml @@ -1,5 +1,5 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.15 2001/05/17 21:50:16 petere Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/mvcc.sgml,v 2.16 2001/07/09 22:18:33 tgl Exp $ --> <chapter id="mvcc"> @@ -441,6 +441,25 @@ ERROR: Can't serialize access due to concurrent update </listitem> </varlistentry> + <varlistentry> + <term> + ShareUpdateExclusiveLock + </term> + <listitem> + <para> + Acquired by <command>VACUUM</command> (without <option>FULL</option>) + and <command>LOCK TABLE</command> table + for <option>IN SHARE UPDATE EXCLUSIVE MODE</option> + statements. + </para> + + <para> + Conflicts with ShareUpdateExclusiveLock, ShareLock, + ShareRowExclusiveLock, ExclusiveLock and AccessExclusiveLock modes. + </para> + </listitem> + </varlistentry> + <varlistentry> <term> ShareLock @@ -454,7 +473,8 @@ ERROR: Can't serialize access due to concurrent update </para> <para> - Conflicts with RowExclusiveLock, ShareRowExclusiveLock, + Conflicts with RowExclusiveLock, ShareUpdateExclusiveLock, + ShareRowExclusiveLock, ExclusiveLock and AccessExclusiveLock modes. </para> </listitem> @@ -471,7 +491,8 @@ ERROR: Can't serialize access due to concurrent update </para> <para> - Conflicts with RowExclusiveLock, ShareLock, ShareRowExclusiveLock, + Conflicts with RowExclusiveLock, ShareUpdateExclusiveLock, + ShareLock, ShareRowExclusiveLock, ExclusiveLock and AccessExclusiveLock modes. </para> </listitem> @@ -488,7 +509,8 @@ ERROR: Can't serialize access due to concurrent update </para> <para> - Conflicts with RowShareLock, RowExclusiveLock, ShareLock, + Conflicts with RowShareLock, RowExclusiveLock, + ShareUpdateExclusiveLock, ShareLock, ShareRowExclusiveLock, ExclusiveLock and AccessExclusiveLock modes. </para> @@ -503,13 +525,13 @@ ERROR: Can't serialize access due to concurrent update <para> Acquired by <command>ALTER TABLE</command>, <command>DROP TABLE</command>, - <command>VACUUM</command> and <command>LOCK TABLE</command> + <command>VACUUM FULL</command> and <command>LOCK TABLE</command> statements. </para> <para> Conflicts with all modes (AccessShareLock, RowShareLock, - RowExclusiveLock, ShareLock, + RowExclusiveLock, ShareUpdateExclusiveLock, ShareLock, ShareRowExclusiveLock, ExclusiveLock and AccessExclusiveLock). </para> </listitem> diff --git a/doc/src/sgml/ref/lock.sgml b/doc/src/sgml/ref/lock.sgml index bffbb7c23d4551bfa268c5b62eb4d21849742cd8..d576890acb96797078a8e1b18b7080435eb14b42 100644 --- a/doc/src/sgml/ref/lock.sgml +++ b/doc/src/sgml/ref/lock.sgml @@ -1,5 +1,5 @@ <!-- -$Header: /cvsroot/pgsql/doc/src/sgml/ref/lock.sgml,v 1.23 2000/12/25 23:15:26 petere Exp $ +$Header: /cvsroot/pgsql/doc/src/sgml/ref/lock.sgml,v 1.24 2001/07/09 22:18:33 tgl Exp $ Postgres documentation --> @@ -20,12 +20,16 @@ Postgres documentation </refnamediv> <refsynopsisdiv> <refsynopsisdivinfo> - <date>1999-07-20</date> + <date>2001-07-09</date> </refsynopsisdivinfo> <synopsis> LOCK [ TABLE ] <replaceable class="PARAMETER">name</replaceable> -LOCK [ TABLE ] <replaceable class="PARAMETER">name</replaceable> IN [ ROW | ACCESS ] { SHARE | EXCLUSIVE } MODE -LOCK [ TABLE ] <replaceable class="PARAMETER">name</replaceable> IN SHARE ROW EXCLUSIVE MODE +LOCK [ TABLE ] <replaceable class="PARAMETER">name</replaceable> IN <replaceable class="PARAMETER">lockmode</replaceable> MODE + +where <replaceable class="PARAMETER">lockmode</replaceable> is one of: + + ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE | + SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE </synopsis> <refsect2 id="R2-SQL-LOCK-1"> @@ -33,7 +37,6 @@ LOCK [ TABLE ] <replaceable class="PARAMETER">name</replaceable> IN SHARE ROW EX <date>1999-06-09</date> </refsect2info> - <title> Inputs </title> @@ -62,7 +65,7 @@ LOCK [ TABLE ] <replaceable class="PARAMETER">name</replaceable> IN SHARE ROW EX This is the least restrictive lock mode. It conflicts only with ACCESS EXCLUSIVE mode. It is used to protect a table from being modified by concurrent <command>ALTER TABLE</command>, - <command>DROP TABLE</command> and <command>VACUUM</command> + <command>DROP TABLE</command> and <command>VACUUM FULL</command> commands. </para> </listitem> @@ -102,6 +105,25 @@ LOCK [ TABLE ] <replaceable class="PARAMETER">name</replaceable> IN SHARE ROW EX </listitem> </varlistentry> + <varlistentry> + <term>SHARE UPDATE EXCLUSIVE MODE</term> + <listitem> + <note> + <para> + Automatically acquired by <command>VACUUM</command> (without + <option>FULL</option>). + </para> + </note> + + <para> + Conflicts with SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, + EXCLUSIVE and + ACCESS EXCLUSIVE modes. This mode protects a table against + concurrent schema changes and VACUUMs. + </para> + </listitem> + </varlistentry> + <varlistentry> <term>SHARE MODE</term> <listitem> @@ -113,9 +135,10 @@ LOCK [ TABLE ] <replaceable class="PARAMETER">name</replaceable> IN SHARE ROW EX </note> <para> - Conflicts with ROW EXCLUSIVE, SHARE ROW EXCLUSIVE, EXCLUSIVE and + Conflicts with ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, + SHARE ROW EXCLUSIVE, EXCLUSIVE and ACCESS EXCLUSIVE modes. This mode protects a table against - concurrent updates. + concurrent data updates. </para> </listitem> </varlistentry> @@ -125,14 +148,14 @@ LOCK [ TABLE ] <replaceable class="PARAMETER">name</replaceable> IN SHARE ROW EX <listitem> <note> <para> - This is like EXCLUSIVE MODE, but allows SHARE ROW locks + This is like EXCLUSIVE MODE, but allows ROW SHARE locks by others. </para> </note> <para> - Conflicts with ROW EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, - EXCLUSIVE and ACCESS EXCLUSIVE modes. + Conflicts with ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, + SHARE ROW EXCLUSIVE, EXCLUSIVE and ACCESS EXCLUSIVE modes. </para> </listitem> </varlistentry> @@ -149,7 +172,8 @@ LOCK [ TABLE ] <replaceable class="PARAMETER">name</replaceable> IN SHARE ROW EX </note> <para> - Conflicts with ROW SHARE, ROW EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, + Conflicts with ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, + SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE and ACCESS EXCLUSIVE modes. </para> </listitem> @@ -161,9 +185,10 @@ LOCK [ TABLE ] <replaceable class="PARAMETER">name</replaceable> IN SHARE ROW EX <note> <para> Automatically acquired by <command>ALTER TABLE</command>, - <command>DROP TABLE</command>, <command>VACUUM</command> statements. - This is the most restrictive lock mode which conflicts with all other - lock modes and protects a locked table from any concurrent operations. + <command>DROP TABLE</command>, <command>VACUUM FULL</command> + statements. + This is the most restrictive lock mode which + protects a locked table from any concurrent operations. </para> </note> @@ -174,6 +199,10 @@ LOCK [ TABLE ] <replaceable class="PARAMETER">name</replaceable> IN SHARE ROW EX lock mode option). </para> </note> + + <para> + Conflicts with all lock modes. + </para> </listitem> </varlistentry> </variablelist> @@ -241,7 +270,11 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist. <term>EXCLUSIVE</term> <listitem> <para> - Exclusive lock that prevents other locks from being granted. + An exclusive lock prevents other locks of the same type from being + granted. (Note: ROW EXCLUSIVE mode does not follow this naming + convention perfectly, since it is shared at the level of the table; + it is exclusive only with respect to specific rows that are being + updated.) </para> </listitem> </varlistentry> @@ -250,7 +283,8 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist. <term>SHARE</term> <listitem> <para> - Allows others to share lock. Prevents EXCLUSIVE locks. + A shared lock allows others to also hold the same type of lock, + but prevents the corresponding EXCLUSIVE lock from being granted. </para> </listitem> </varlistentry> @@ -273,13 +307,6 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist. </listitem> </varlistentry> </variablelist> - - <note> - <para> - If EXCLUSIVE or SHARE are not specified, EXCLUSIVE is assumed. - Locks exist for the duration of the transaction. - </para> - </note> </para> <para> @@ -370,8 +397,8 @@ ERROR <replaceable class="PARAMETER">name</replaceable>: Table does not exist. </para> <para> - Except for ACCESS SHARE/EXCLUSIVE lock modes, all other - <productname>Postgres</productname> lock modes and the + Except for ACCESS SHARE, ACCESS EXCLUSIVE, and SHARE UPDATE EXCLUSIVE lock + modes, the <productname>Postgres</productname> lock modes and the <command>LOCK TABLE</command> syntax are compatible with those present in <productname>Oracle</productname>. </para> diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index cf518f3cadd691c7dd446af64747d98b81f94f39..7e6f782984e53657fe8af0b2c478e64f71639407 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.233 2001/06/30 22:03:25 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.234 2001/07/09 22:18:33 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -153,7 +153,7 @@ static void doNegateFloat(Value *v); %type <list> createdb_opt_list, createdb_opt_item %type <ival> opt_lock, lock_type -%type <boolean> opt_lmode, opt_force +%type <boolean> opt_force %type <ival> user_createdb_clause, user_createuser_clause %type <str> user_passwd_clause @@ -3277,18 +3277,18 @@ LockStmt: LOCK_P opt_table relation_name opt_lock } ; -opt_lock: IN lock_type MODE { $$ = $2; } +opt_lock: IN lock_type MODE { $$ = $2; } | /*EMPTY*/ { $$ = AccessExclusiveLock; } ; -lock_type: SHARE ROW EXCLUSIVE { $$ = ShareRowExclusiveLock; } - | ROW opt_lmode { $$ = ($2? RowShareLock: RowExclusiveLock); } - | ACCESS opt_lmode { $$ = ($2? AccessShareLock: AccessExclusiveLock); } - | opt_lmode { $$ = ($1? ShareLock: ExclusiveLock); } - ; - -opt_lmode: SHARE { $$ = TRUE; } - | EXCLUSIVE { $$ = FALSE; } +lock_type: ACCESS SHARE { $$ = AccessShareLock; } + | ROW SHARE { $$ = RowShareLock; } + | ROW EXCLUSIVE { $$ = RowExclusiveLock; } + | SHARE UPDATE EXCLUSIVE { $$ = ShareUpdateExclusiveLock; } + | SHARE { $$ = ShareLock; } + | SHARE ROW EXCLUSIVE { $$ = ShareRowExclusiveLock; } + | EXCLUSIVE { $$ = ExclusiveLock; } + | ACCESS EXCLUSIVE { $$ = AccessExclusiveLock; } ; diff --git a/src/backend/storage/lmgr/lmgr.c b/src/backend/storage/lmgr/lmgr.c index fa3812a87eb246b5d9f484e360b5969f8ba46c3b..10861348e800c986f97c2343157b4aa64d894816 100644 --- a/src/backend/storage/lmgr/lmgr.c +++ b/src/backend/storage/lmgr/lmgr.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lmgr.c,v 1.48 2001/06/22 00:04:59 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lmgr.c,v 1.49 2001/07/09 22:18:33 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -33,25 +33,35 @@ static LOCKMASK LockConflicts[] = { (1 << ExclusiveLock) | (1 << AccessExclusiveLock), /* RowExclusiveLock */ - (1 << ExclusiveLock) | (1 << ShareRowExclusiveLock) | (1 << ShareLock) | - (1 << AccessExclusiveLock), + (1 << ShareLock) | (1 << ShareRowExclusiveLock) | + (1 << ExclusiveLock) | (1 << AccessExclusiveLock), + + /* ShareUpdateExclusiveLock */ + (1 << ShareUpdateExclusiveLock) | + (1 << ShareLock) | (1 << ShareRowExclusiveLock) | + (1 << ExclusiveLock) | (1 << AccessExclusiveLock), /* ShareLock */ - (1 << ExclusiveLock) | (1 << ShareRowExclusiveLock) | - (1 << RowExclusiveLock) | (1 << AccessExclusiveLock), + (1 << RowExclusiveLock) | (1 << ShareUpdateExclusiveLock) | + (1 << ShareRowExclusiveLock) | + (1 << ExclusiveLock) | (1 << AccessExclusiveLock), /* ShareRowExclusiveLock */ - (1 << ExclusiveLock) | (1 << ShareRowExclusiveLock) | - (1 << ShareLock) | (1 << RowExclusiveLock) | (1 << AccessExclusiveLock), + (1 << RowExclusiveLock) | (1 << ShareUpdateExclusiveLock) | + (1 << ShareLock) | (1 << ShareRowExclusiveLock) | + (1 << ExclusiveLock) | (1 << AccessExclusiveLock), /* ExclusiveLock */ - (1 << ExclusiveLock) | (1 << ShareRowExclusiveLock) | (1 << ShareLock) | - (1 << RowExclusiveLock) | (1 << RowShareLock) | (1 << AccessExclusiveLock), + (1 << RowShareLock) | + (1 << RowExclusiveLock) | (1 << ShareUpdateExclusiveLock) | + (1 << ShareLock) | (1 << ShareRowExclusiveLock) | + (1 << ExclusiveLock) | (1 << AccessExclusiveLock), /* AccessExclusiveLock */ - (1 << ExclusiveLock) | (1 << ShareRowExclusiveLock) | (1 << ShareLock) | - (1 << RowExclusiveLock) | (1 << RowShareLock) | - (1 << AccessExclusiveLock) | (1 << AccessShareLock) + (1 << AccessShareLock) | (1 << RowShareLock) | + (1 << RowExclusiveLock) | (1 << ShareUpdateExclusiveLock) | + (1 << ShareLock) | (1 << ShareRowExclusiveLock) | + (1 << ExclusiveLock) | (1 << AccessExclusiveLock) }; @@ -63,14 +73,16 @@ static int LockPrios[] = { 2, /* RowExclusiveLock */ 3, - /* ShareLock */ + /* ShareUpdateExclusiveLock */ 4, - /* ShareRowExclusiveLock */ + /* ShareLock */ 5, - /* ExclusiveLock */ + /* ShareRowExclusiveLock */ 6, + /* ExclusiveLock */ + 7, /* AccessExclusiveLock */ - 7 + 8 }; LOCKMETHOD LockTableId = (LOCKMETHOD) NULL; diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 3eb010482749117420e9c0b758ec28dfc00a43c9..cff407a4a81db635baca8c32cda88325a1c7ad6a 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.90 2001/06/27 23:31:39 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.91 2001/07/09 22:18:33 tgl Exp $ * * NOTES * Outside modules can create a lock table and acquire/release @@ -58,6 +58,7 @@ static char *lock_mode_names[] = "AccessShareLock", "RowShareLock", "RowExclusiveLock", + "ShareUpdateExclusiveLock", "ShareLock", "ShareRowExclusiveLock", "ExclusiveLock", diff --git a/src/include/storage/lmgr.h b/src/include/storage/lmgr.h index c279ef63f2a0299a9d1eea2f21831ea1f544cfaa..1fb490e6d69fb49382a5d05626843b50d94c5332 100644 --- a/src/include/storage/lmgr.h +++ b/src/include/storage/lmgr.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: lmgr.h,v 1.31 2001/06/22 00:04:59 tgl Exp $ + * $Id: lmgr.h,v 1.32 2001/07/09 22:18:34 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -25,13 +25,14 @@ #define AccessShareLock 1 /* SELECT */ #define RowShareLock 2 /* SELECT FOR UPDATE */ #define RowExclusiveLock 3 /* INSERT, UPDATE, DELETE */ -#define ShareLock 4 /* CREATE INDEX */ -#define ShareRowExclusiveLock 5 /* like EXCLUSIVE MODE, allows - * SHARE ROW */ -#define ExclusiveLock 6 /* blocks ROW SHARE/SELECT...FOR +#define ShareUpdateExclusiveLock 4 /* VACUUM (non-FULL) */ +#define ShareLock 5 /* CREATE INDEX */ +#define ShareRowExclusiveLock 6 /* like EXCLUSIVE MODE, but allows + * ROW SHARE */ +#define ExclusiveLock 7 /* blocks ROW SHARE/SELECT...FOR * UPDATE */ -#define AccessExclusiveLock 7 /* ALTER TABLE, DROP TABLE, - * VACUUM, and unqualified LOCK +#define AccessExclusiveLock 8 /* ALTER TABLE, DROP TABLE, + * VACUUM FULL, and unqualified LOCK * TABLE */ /* diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h index 30a13649e43a48504bde9c16a230db35334ad890..1010e6760b3b83dabd45a96cd832a7f4d860dbeb 100644 --- a/src/include/storage/lock.h +++ b/src/include/storage/lock.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: lock.h,v 1.50 2001/06/27 23:31:39 tgl Exp $ + * $Id: lock.h,v 1.51 2001/07/09 22:18:34 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -49,7 +49,7 @@ typedef int LOCKMODE; typedef int LOCKMETHOD; /* MAX_LOCKMODES cannot be larger than the # of bits in LOCKMASK */ -#define MAX_LOCKMODES 8 +#define MAX_LOCKMODES 10 /* * MAX_LOCK_METHODS corresponds to the number of spin locks allocated in @@ -91,7 +91,7 @@ typedef int LOCKMETHOD; * * prio -- each lockmode has a priority, so, for example, waiting * writers can be given priority over readers (to avoid - * starvation). + * starvation). XXX this field is not actually used at present! * * masterlock -- synchronizes access to the table */ diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y index 2228c125d8a7aa8f02a7a91f6cd23032cb8851f6..e0626025d8f825355e00b213d06b9aae7a6967e1 100644 --- a/src/interfaces/ecpg/preproc/preproc.y +++ b/src/interfaces/ecpg/preproc/preproc.y @@ -326,7 +326,7 @@ make_name(void) %type <str> createdb_opt_list opt_encoding OptInherit Geometric %type <str> DropdbStmt ClusterStmt grantee RevokeStmt Bit bit %type <str> GrantStmt privileges operation_commalist operation PosAllConst -%type <str> opt_cursor opt_lmode ConstraintsSetStmt comment_tg AllConst +%type <str> opt_cursor ConstraintsSetStmt comment_tg AllConst %type <str> case_expr when_clause_list case_default case_arg when_clause %type <str> select_clause opt_select_limit select_limit_value ConstraintTimeSpec %type <str> select_offset_value ReindexStmt join_type opt_boolean @@ -2440,15 +2440,15 @@ opt_lock: IN lock_type MODE { $$ = cat_str(3, make_str("in"), $2, ma | /*EMPTY*/ { $$ = EMPTY;} ; -lock_type: SHARE ROW EXCLUSIVE { $$ = make_str("share row exclusive"); } - | ROW opt_lmode { $$ = cat2_str(make_str("row"), $2);} - | ACCESS opt_lmode { $$ = cat2_str(make_str("access"), $2);} - | opt_lmode { $$ = $1; } - ; - -opt_lmode: SHARE { $$ = make_str("share"); } - | EXCLUSIVE { $$ = make_str("exclusive"); } - ; +lock_type: ACCESS SHARE { $$ = make_str("access share"); } + | ROW SHARE { $$ = make_str("access share"); } + | ROW EXCLUSIVE { $$ = make_str("row exclusive"); } + | SHARE UPDATE EXCLUSIVE { $$ = make_str("share update exclusive"); } + | SHARE { $$ = make_str("share"); } + | SHARE ROW EXCLUSIVE { $$ = make_str("share row exclusive"); } + | EXCLUSIVE { $$ = make_str("exclusive"); } + | ACCESS EXCLUSIVE { $$ = make_str("access exclusive"); } + ; /***************************************************************************** *