NO WAIT ... - Mailing list pgsql-patches
From | Hans-Jürgen Schönig |
---|---|
Subject | NO WAIT ... |
Date | |
Msg-id | 40339D67.90208@cybertec.at Whole thread Raw |
Responses |
Re: NO WAIT ...
|
List | pgsql-patches |
hi everyone ... i have attached a patch implementing NO WAIT with the help of a GUC variable. documentation should be included as well. it works nicely for me. test=# begin; BEGIN test=# show wait_for_locks; wait_for_locks ---------------- row share (1 row) test=# lock table x in exclusive mode; LOCK TABLE test=# commit; COMMIT test=# begin; BEGIN test=# -- somebody else has locked the table ... test=# lock table x in exclusive mode; ERROR: LockAcquire failed [hs@fedora pgsql]$ difforig > nowait.patch ./doc/src/sgml/runtime.sgml ./src/backend/storage/lmgr/lock.c ./src/backend/utils/misc/guc.c ./src/backend/utils/misc/postgresql.conf.sample ./src/bin/psql/tab-complete.c ./src/include/storage/lock.h ./src/include/utils/guc.h i hope this patch is ok. if there are any modifications needed just drop me a line. maybe i will have some spare time to implement "SELECT FOR UPDATE NOWAIT" (SQL version). maybe this extension would make sense as well because many people porting from oracle to pg would like that. cheers, Hans -- Cybertec Geschwinde u Schoenig Schoengrabern 134, A-2020 Hollabrunn, Austria Tel: +43/2952/30706 or +43/664/233 90 75 www.cybertec.at, www.postgresql.at, kernel.cybertec.at *** ./doc/src/sgml/runtime.sgml.orig 2004-02-17 12:06:23.000000000 +0100 --- ./doc/src/sgml/runtime.sgml 2004-02-17 13:10:26.000000000 +0100 *************** *** 2555,2560 **** --- 2555,2578 ---- </listitem> </varlistentry> + <varlistentry> + <term><varname>wait_for_locks</varname> (<type>string</type>)</term> + <listitem> + <para> + By default an SQL statement has to wait until the desired locks for + processing the command can be acquired. In some cases this is not + the best thing to do. Therefore it is possible to tell PostgreSQL + which locks it is worth waiting for. The following kinds of locks / + settings are supported: all, access share, row share, row exclusive, + share update exclusive, share, share row exclusive, exclusive, + access exclusive. <quote>all</> is the default setting and means that + PostgreSQL will wait for all locks. If <quote>share</> is specified + PostgreSQL will not wait for locks which are higher or equal to a + share lock. + </para> + </listitem> + </varlistentry> + </variablelist> </sect2> *** ./src/backend/storage/lmgr/lock.c.orig 2004-02-17 09:45:04.000000000 +0100 --- ./src/backend/storage/lmgr/lock.c 2004-02-17 11:33:13.000000000 +0100 *************** *** 36,41 **** --- 36,42 ---- #include "access/xact.h" #include "miscadmin.h" #include "storage/proc.h" + #include "utils/guc.h" #include "utils/memutils.h" #include "utils/ps_status.h" *************** *** 435,440 **** --- 436,455 ---- locktag->objId.blkno, lock_mode_names[lockmode]); #endif + /* check if NO WAIT has been enabled + the basic strategy is very simple: if the user has selected "all" + PostgreSQL will act normally. However, if a certain lock level has + been defined PostgreSQL won't wait for locks which are higher than + the specified level */ + if (Wait_for_locks != 0) + { + /* now we have to adjust dontWait */ + if (lockmode >= Wait_for_locks) + { + dontWait = true; + } + } + /* ???????? This must be changed when short term locks will be used */ locktag->lockmethodid = lockmethodid; *** ./src/backend/utils/misc/guc.c.orig 2004-02-17 09:48:34.000000000 +0100 --- ./src/backend/utils/misc/guc.c 2004-02-17 14:42:10.000000000 +0100 *************** *** 47,52 **** --- 47,53 ---- #include "storage/fd.h" #include "storage/freespace.h" #include "storage/lock.h" + #include "storage/lmgr.h" #include "storage/proc.h" #include "tcop/tcopprot.h" #include "utils/array.h" *************** *** 85,90 **** --- 86,93 ---- static const char *assign_defaultxactisolevel(const char *newval, bool doit, GucSource source); + static const char *assign_wait_for_locks(const char *newval, + bool doit, GucSource source); static const char *assign_log_min_messages(const char *newval, bool doit, GucSource source); static const char *assign_client_min_messages(const char *newval, *************** *** 132,137 **** --- 135,141 ---- int client_min_messages = NOTICE; int log_min_duration_statement = -1; + int Wait_for_locks = 0; /* *************** *** 149,154 **** --- 153,159 ---- static char *client_encoding_string; static char *datestyle_string; static char *default_iso_level_string; + static char *wait_for_locks_string; static char *locale_collate; static char *locale_ctype; static char *regex_flavor_string; *************** *** 1515,1521 **** &default_iso_level_string, "read committed", assign_defaultxactisolevel, NULL }, ! { {"dynamic_library_path", PGC_SUSET, CLIENT_CONN_OTHER, gettext_noop("Sets the path for dynamically loadable modules."), --- 1520,1537 ---- &default_iso_level_string, "read committed", assign_defaultxactisolevel, NULL }, ! { ! {"wait_for_locks", PGC_USERSET, CLIENT_CONN_STATEMENT, ! gettext_noop("Tells PostgreSQL whether to wait for locks or not."), ! gettext_noop("Allowed settings: " ! "\"all\", \"access share\", \"row share\", " ! "\"row exclusive\", \"share update exclusive\", " ! "\"share\", \"share row exclusive\", " ! "\"exclusive\", \"access exclusive\".") ! }, ! &wait_for_locks_string, ! "all", assign_wait_for_locks, NULL ! }, { {"dynamic_library_path", PGC_SUSET, CLIENT_CONN_OTHER, gettext_noop("Sets the path for dynamically loadable modules."), *************** *** 4457,4462 **** --- 4473,4533 ---- #endif + /* in this function we will check if the string in the config-file + contains a correct lock level */ + static const char * + assign_wait_for_locks(const char *newval, bool doit, GucSource source) + { + if (strcasecmp(newval, "all") == 0) + { + if (doit) + Wait_for_locks = NoLock; + } + else if (strcasecmp(newval, "access share") == 0) + { + if (doit) + Wait_for_locks = AccessShareLock; + } + else if (strcasecmp(newval, "row share") == 0) + { + if (doit) + Wait_for_locks = RowShareLock; + } + else if (strcasecmp(newval, "row exclusive") == 0) + { + if (doit) + Wait_for_locks = RowExclusiveLock; + } + else if (strcasecmp(newval, "share update exclusive") == 0) + { + if (doit) + Wait_for_locks = ShareUpdateExclusiveLock; + } + else if (strcasecmp(newval, "share") == 0) + { + if (doit) + Wait_for_locks = ShareLock; + } + else if (strcasecmp(newval, "share row exclusive") == 0) + { + if (doit) + Wait_for_locks = ShareRowExclusiveLock; + } + else if (strcasecmp(newval, "exclusive") == 0) + { + if (doit) + Wait_for_locks = ExclusiveLock; + } + else if (strcasecmp(newval, "access exclusive") == 0) + { + if (doit) + Wait_for_locks = AccessExclusiveLock; + } + else + return NULL; + return newval; + } + static const char * assign_defaultxactisolevel(const char *newval, bool doit, GucSource source) { *** ./src/backend/utils/misc/postgresql.conf.sample.orig 2004-02-17 11:02:35.000000000 +0100 --- ./src/backend/utils/misc/postgresql.conf.sample 2004-02-17 13:38:14.000000000 +0100 *************** *** 248,253 **** --- 248,257 ---- # LOCK MANAGEMENT #--------------------------------------------------------------------------- + #wait_for_locks = 'all' # allowed settings: all, access share, + # row share, row exclusive, share update + # exclusive, share, share row exclusive, + # exclusive, access exclusive #deadlock_timeout = 1000 # in milliseconds #max_locks_per_transaction = 64 # min 10, ~260*max_connections bytes each *** ./src/bin/psql/tab-complete.c.orig 2004-02-17 11:51:19.000000000 +0100 --- ./src/bin/psql/tab-complete.c 2004-02-17 11:51:54.000000000 +0100 *************** *** 567,572 **** --- 567,573 ---- "unix_socket_directory", "unix_socket_group", "unix_socket_permissions", + "wait_for_locks", "wal_buffers", "wal_debug", "wal_sync_method", *** ./src/include/storage/lock.h.orig 2004-02-17 10:12:37.000000000 +0100 --- ./src/include/storage/lock.h 2004-02-17 10:16:51.000000000 +0100 *************** *** 32,37 **** --- 32,45 ---- extern int max_locks_per_xact; + + /* PostgreSQL supports NO WAIT via GUC variables + therefore we need information telling us whether we want to wait for locks or + not. In addition to that we want to tell the system for which locks we want + to wait */ + extern int Wait_for_locks; + + #ifdef LOCK_DEBUG extern int Trace_lock_oidmin; extern bool Trace_locks; *** ./src/include/utils/guc.h.orig 2004-02-17 10:35:02.000000000 +0100 --- ./src/include/utils/guc.h 2004-02-17 10:35:29.000000000 +0100 *************** *** 126,131 **** --- 126,132 ---- extern int log_min_messages; extern int client_min_messages; extern int log_min_duration_statement; + extern int Wait_for_locks; extern void SetConfigOption(const char *name, const char *value,
pgsql-patches by date: