postgresql/src/include
Alvaro Herrera c0bd128c81 Fix race when updating a tuple concurrently locked by another process
If a tuple is locked, and this lock is later upgraded either to an
update or to a stronger lock, and in the meantime some other process
tries to lock, update or delete the same tuple, it (the tuple) could end
up being updated twice, or having conflicting locks held.

The reason for this is that the second updater checks for a change in
Xmax value, or in the HEAP_XMAX_IS_MULTI infomask bit, after noticing
the first lock; and if there's a change, it restarts and re-evaluates
its ability to update the tuple.  But it neglected to check for changes
in lock strength or in lock-vs-update status when those two properties
stayed the same.  This would lead it to take the wrong decision and
continue with its own update, when in reality it shouldn't do so but
instead restart from the top.

This could lead to either an assertion failure much later (when a
multixact containing multiple updates is detected), or duplicate copies
of tuples.

To fix, make sure to compare the other relevant infomask bits alongside
the Xmax value and HEAP_XMAX_IS_MULTI bit, and restart from the top if
necessary.

Also, in the belt-and-suspenders spirit, add a check to
MultiXactCreateFromMembers that a multixact being created does not have
two or more members that are claimed to be updates.  This should protect
against other bugs that might cause similar bogus situations.

Backpatch to 9.3, where the possibility of multixacts containing updates
was introduced.  (In prior versions it was possible to have the tuple
lock upgraded from shared to exclusive, and an update would not restart
from the top; yet we're protected against a bug there because there's
always a sleep to wait for the locking transaction to complete before
continuing to do anything.  Really, the fact that tuple locks always
conflicted with concurrent updates is what protected against bugs here.)

Per report from Andrew Dunstan and Josh Berkus in thread at
http://www.postgresql.org/message-id/534C8B33.9050807@pgexperts.com

Bug analysis by Andres Freund.
2014-04-24 15:41:55 -03:00
..
access Fix race when updating a tuple concurrently locked by another process 2014-04-24 15:41:55 -03:00
bootstrap Update copyrights for 2013 2013-01-01 17:15:01 -05:00
catalog Fix incorrect pg_proc.proallargtypes entries for two built-in functions. 2014-04-23 21:21:08 -04:00
commands Avoid repeated name lookups during table and index DDL. 2014-02-17 09:33:32 -05:00
common pgindent run for release 9.3 2013-05-29 16:58:43 -04:00
datatype Update copyrights for 2013 2013-01-01 17:15:01 -05:00
executor Prevent leakage of SPI tuple tables during subtransaction abort. 2013-07-25 16:45:47 -04:00
foreign Improve updatability checking for views and foreign tables. 2013-06-12 17:53:33 -04:00
lib Reset the binary heap in MergeAppend rescans. 2013-08-30 19:15:32 -04:00
libpq Fix assorted issues in client host name lookup. 2014-04-02 17:11:27 -04:00
mb pgindent run for release 9.3 2013-05-29 16:58:43 -04:00
nodes Fix non-equivalence of VARIADIC and non-VARIADIC function call formats. 2014-04-03 22:02:27 -04:00
optimizer Compute correct em_nullable_relids in get_eclass_for_sort_expr(). 2013-11-15 16:46:21 -05:00
parser Avoid repeated name lookups during table and index DDL. 2014-02-17 09:33:32 -05:00
port Enable building with Visual Studion 2013. 2014-01-26 09:45:43 -05:00
portability Update copyrights for 2013 2013-01-01 17:15:01 -05:00
postmaster PGDLLIMPORT-ify MyBgworkerEntry. 2014-02-17 11:29:34 -05:00
regex Allow regex operations to be terminated early by query cancel requests. 2014-03-01 15:21:00 -05:00
replication pgindent run for release 9.3 2013-05-29 16:58:43 -04:00
rewrite Avoid getting more than AccessShareLock when deparsing a query. 2014-03-06 19:31:09 -05:00
snowball Update copyrights for 2013 2013-01-01 17:15:01 -05:00
storage Fix dangling smgr_owner pointer when a fake relcache entry is freed. 2014-03-07 13:29:24 +02:00
tcop Avoid repeated name lookups during table and index DDL. 2014-02-17 09:33:32 -05:00
tsearch Predict integer overflow to avoid buffer overruns. 2014-02-17 09:33:32 -05:00
utils Predict integer overflow to avoid buffer overruns. 2014-02-17 09:33:32 -05:00
.gitignore Autoconfiscate selection of 64-bit int type for 64-bit large object API. 2012-10-07 21:52:43 -04:00
c.h pgindent run for release 9.3 2013-05-29 16:58:43 -04:00
fmgr.h Prevent privilege escalation in explicit calls to PL validators. 2014-02-17 09:33:32 -05:00
funcapi.h Update copyrights for 2013 2013-01-01 17:15:01 -05:00
getaddrinfo.h Fix assorted issues in client host name lookup. 2014-04-02 17:11:27 -04:00
getopt_long.h Update copyrights for 2013 2013-01-01 17:15:01 -05:00
Makefile Install headers from the new src/include/common subdirectory. 2013-02-26 15:27:30 -05:00
miscadmin.h PGDLLIMPORT'ify DateStyle and IntervalStyle. 2014-02-16 12:37:10 -05:00
pg_config.h.in Improve handling of ereport(ERROR) and elog(ERROR). 2013-01-13 18:40:09 -05:00
pg_config.h.win32 Stamp 9.3.4. 2014-03-17 15:35:47 -04:00
pg_config_ext.h.in Autoconfiscate selection of 64-bit int type for 64-bit large object API. 2012-10-07 21:52:43 -04:00
pg_config_ext.h.win32 Autoconfiscate selection of 64-bit int type for 64-bit large object API. 2012-10-07 21:52:43 -04:00
pg_config_manual.h Update copyrights for 2013 2013-01-01 17:15:01 -05:00
pg_trace.h Update copyrights for 2013 2013-01-01 17:15:01 -05:00
pgstat.h Split pgstat file in smaller pieces 2013-02-18 18:12:52 -03:00
pgtar.h Move tar function headers to pgtar.h 2013-01-02 20:34:08 +01:00
pgtime.h Fix some odd behaviors when using a SQL-style simple GMT offset timezone. 2013-11-01 12:13:23 -04:00
port.h pgindent run for release 9.3 2013-05-29 16:58:43 -04:00
postgres.h pgindent run for release 9.3 2013-05-29 16:58:43 -04:00
postgres_ext.h Provide database object names as separate fields in error messages. 2013-01-29 17:08:26 -05:00
postgres_fe.h Create libpgcommon, and move pg_malloc et al to it 2013-02-12 11:21:05 -03:00
rusagestub.h Update copyrights for 2013 2013-01-01 17:15:01 -05:00
windowapi.h Update copyrights for 2013 2013-01-01 17:15:01 -05:00