Skip to content

Commit 8deb6b3

Browse files
committed
Reinstate HEAP_XMAX_LOCK_ONLY|HEAP_KEYS_UPDATED as allowed
Commit 866e24d added an assert that HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED cannot appear together, on the faulty assumption that the latter necessarily referred to an update and not a tuple lock; but that's wrong, because SELECT FOR UPDATE can use precisely that combination, as evidenced by the amcheck test case added here. Remove the Assert(), and also patch amcheck's verify_heapam.c to not complain if the combination is found. Also, out of overabundance of caution, update (across all branches) README.tuplock to be more explicit about this. Author: Julien Rouhaud <rjuju123@gmail.com> Reviewed-by: Mahendra Singh Thalor <mahi6run@gmail.com> Reviewed-by: Dilip Kumar <dilipbalaut@gmail.com> Discussion: https://postgr.es/m/20210124061758.GA11756@nol
1 parent 3db05e7 commit 8deb6b3

File tree

4 files changed

+20
-16
lines changed

4 files changed

+20
-16
lines changed

contrib/amcheck/t/001_verify_heapam.pl

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use PostgresNode;
55
use TestLib;
66

7-
use Test::More tests => 79;
7+
use Test::More tests => 80;
88

99
my ($node, $result);
1010

@@ -47,6 +47,9 @@
4747
#
4848
fresh_test_table('test');
4949
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
50+
detects_no_corruption(
51+
"verify_heapam('test')",
52+
"all-frozen not corrupted table");
5053
corrupt_first_page('test');
5154
detects_heap_corruption("verify_heapam('test')",
5255
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
9295
ALTER TABLE $relname ALTER b SET STORAGE external;
9396
INSERT INTO $relname (a, b)
9497
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
98+
BEGIN;
99+
SAVEPOINT s1;
100+
SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
101+
UPDATE $relname SET b = b WHERE a = 42;
102+
RELEASE s1;
103+
SAVEPOINT s1;
104+
SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
105+
UPDATE $relname SET b = b WHERE a = 42;
106+
COMMIT;
95107
));
96108
}
97109

contrib/amcheck/verify_heapam.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
608608
ctx->tuphdr->t_hoff, ctx->lp_len));
609609
header_garbled = true;
610610
}
611-
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
612-
(ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
613-
{
614-
report_corruption(ctx,
615-
pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
616-
header_garbled = true;
617-
}
618611

619612
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
620613
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))

src/backend/access/heap/README.tuplock

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,10 @@ The following infomask bits are applicable:
146146
FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit.
147147

148148
- HEAP_KEYS_UPDATED
149-
This bit lives in t_infomask2. If set, indicates that the XMAX updated
150-
this tuple and changed the key values, or it deleted the tuple.
151-
It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
149+
This bit lives in t_infomask2. If set, indicates that the operation(s) done
150+
by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE
151+
that modifies the columns of the key, or a DELETE. It's set regardless of
152+
whether the XMAX is a TransactionId or a MultiXactId.
152153

153154
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
154155
is set.

src/backend/access/heap/hio.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
4949

5050
/*
5151
* Do not allow tuples with invalid combinations of hint bits to be placed
52-
* on a page. These combinations are detected as corruption by the
53-
* contrib/amcheck logic, so if you disable one or both of these
54-
* assertions, make corresponding changes there.
52+
* on a page. This combination is detected as corruption by the
53+
* contrib/amcheck logic, so if you disable this assertion, make
54+
* corresponding changes there.
5555
*/
56-
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
57-
(tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
5856
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
5957
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
6058

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy