public inbox for [email protected]
help / color / mirror / Atom feed[PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
67+ messages / 2 participants
[nested] [flat]
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 5 +++--
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6d357565a8 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -147,8 +147,9 @@ The following infomask bits are applicable:
- HEAP_KEYS_UPDATED
This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ this tuple and changed the key values, or it deleted the tuple. It can also
+ be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether
+ the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--+HP7ph2BbKc20aGI--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/hio.c | 8 +++-----
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--CE+1k2dSO48ffgeK--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 7 ++++---
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6441e8baf0 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -146,9 +146,10 @@ The following infomask bits are applicable:
FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit.
- HEAP_KEYS_UPDATED
- This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ This bit lives in t_infomask2. If set, indicates that the operation(s) done
+ by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE
+ that modifies the columns of the key, or a DELETE. It's set regardless of
+ whether the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--0ntfKIWw70PvrIHh--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/hio.c | 8 +++-----
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--CE+1k2dSO48ffgeK--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/hio.c | 8 +++-----
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--CE+1k2dSO48ffgeK--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 7 ++++---
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6441e8baf0 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -146,9 +146,10 @@ The following infomask bits are applicable:
FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit.
- HEAP_KEYS_UPDATED
- This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ This bit lives in t_infomask2. If set, indicates that the operation(s) done
+ by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE
+ that modifies the columns of the key, or a DELETE. It's set regardless of
+ whether the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--0ntfKIWw70PvrIHh--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 7 ++++---
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6441e8baf0 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -146,9 +146,10 @@ The following infomask bits are applicable:
FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit.
- HEAP_KEYS_UPDATED
- This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ This bit lives in t_infomask2. If set, indicates that the operation(s) done
+ by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE
+ that modifies the columns of the key, or a DELETE. It's set regardless of
+ whether the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--0ntfKIWw70PvrIHh--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 5 +++--
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6d357565a8 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -147,8 +147,9 @@ The following infomask bits are applicable:
- HEAP_KEYS_UPDATED
This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ this tuple and changed the key values, or it deleted the tuple. It can also
+ be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether
+ the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--+HP7ph2BbKc20aGI--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/hio.c | 8 +++-----
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--CE+1k2dSO48ffgeK--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 7 ++++---
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6441e8baf0 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -146,9 +146,10 @@ The following infomask bits are applicable:
FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit.
- HEAP_KEYS_UPDATED
- This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ This bit lives in t_infomask2. If set, indicates that the operation(s) done
+ by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE
+ that modifies the columns of the key, or a DELETE. It's set regardless of
+ whether the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--0ntfKIWw70PvrIHh--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 7 ++++---
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6441e8baf0 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -146,9 +146,10 @@ The following infomask bits are applicable:
FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit.
- HEAP_KEYS_UPDATED
- This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ This bit lives in t_infomask2. If set, indicates that the operation(s) done
+ by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE
+ that modifies the columns of the key, or a DELETE. It's set regardless of
+ whether the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--0ntfKIWw70PvrIHh--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 5 +++--
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6d357565a8 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -147,8 +147,9 @@ The following infomask bits are applicable:
- HEAP_KEYS_UPDATED
This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ this tuple and changed the key values, or it deleted the tuple. It can also
+ be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether
+ the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--+HP7ph2BbKc20aGI--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 5 +++--
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6d357565a8 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -147,8 +147,9 @@ The following infomask bits are applicable:
- HEAP_KEYS_UPDATED
This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ this tuple and changed the key values, or it deleted the tuple. It can also
+ be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether
+ the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--+HP7ph2BbKc20aGI--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 7 ++++---
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6441e8baf0 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -146,9 +146,10 @@ The following infomask bits are applicable:
FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit.
- HEAP_KEYS_UPDATED
- This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ This bit lives in t_infomask2. If set, indicates that the operation(s) done
+ by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE
+ that modifies the columns of the key, or a DELETE. It's set regardless of
+ whether the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--0ntfKIWw70PvrIHh--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 7 ++++---
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6441e8baf0 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -146,9 +146,10 @@ The following infomask bits are applicable:
FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit.
- HEAP_KEYS_UPDATED
- This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ This bit lives in t_infomask2. If set, indicates that the operation(s) done
+ by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE
+ that modifies the columns of the key, or a DELETE. It's set regardless of
+ whether the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--0ntfKIWw70PvrIHh--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/hio.c | 8 +++-----
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--CE+1k2dSO48ffgeK--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/hio.c | 8 +++-----
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--CE+1k2dSO48ffgeK--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/hio.c | 8 +++-----
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--CE+1k2dSO48ffgeK--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/hio.c | 8 +++-----
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--CE+1k2dSO48ffgeK--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 7 ++++---
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6441e8baf0 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -146,9 +146,10 @@ The following infomask bits are applicable:
FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit.
- HEAP_KEYS_UPDATED
- This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ This bit lives in t_infomask2. If set, indicates that the operation(s) done
+ by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE
+ that modifies the columns of the key, or a DELETE. It's set regardless of
+ whether the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--0ntfKIWw70PvrIHh--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 7 ++++---
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6441e8baf0 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -146,9 +146,10 @@ The following infomask bits are applicable:
FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit.
- HEAP_KEYS_UPDATED
- This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ This bit lives in t_infomask2. If set, indicates that the operation(s) done
+ by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE
+ that modifies the columns of the key, or a DELETE. It's set regardless of
+ whether the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--0ntfKIWw70PvrIHh--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 5 +++--
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6d357565a8 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -147,8 +147,9 @@ The following infomask bits are applicable:
- HEAP_KEYS_UPDATED
This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ this tuple and changed the key values, or it deleted the tuple. It can also
+ be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether
+ the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--+HP7ph2BbKc20aGI--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 7 ++++---
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6441e8baf0 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -146,9 +146,10 @@ The following infomask bits are applicable:
FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit.
- HEAP_KEYS_UPDATED
- This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ This bit lives in t_infomask2. If set, indicates that the operation(s) done
+ by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE
+ that modifies the columns of the key, or a DELETE. It's set regardless of
+ whether the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--0ntfKIWw70PvrIHh--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/hio.c | 8 +++-----
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--CE+1k2dSO48ffgeK--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/hio.c | 8 +++-----
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--CE+1k2dSO48ffgeK--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 5 +++--
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6d357565a8 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -147,8 +147,9 @@ The following infomask bits are applicable:
- HEAP_KEYS_UPDATED
This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ this tuple and changed the key values, or it deleted the tuple. It can also
+ be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether
+ the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--+HP7ph2BbKc20aGI--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 5 +++--
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6d357565a8 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -147,8 +147,9 @@ The following infomask bits are applicable:
- HEAP_KEYS_UPDATED
This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ this tuple and changed the key values, or it deleted the tuple. It can also
+ be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether
+ the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--+HP7ph2BbKc20aGI--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 7 ++++---
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6441e8baf0 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -146,9 +146,10 @@ The following infomask bits are applicable:
FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit.
- HEAP_KEYS_UPDATED
- This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ This bit lives in t_infomask2. If set, indicates that the operation(s) done
+ by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE
+ that modifies the columns of the key, or a DELETE. It's set regardless of
+ whether the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--0ntfKIWw70PvrIHh--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/hio.c | 8 +++-----
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--CE+1k2dSO48ffgeK--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 5 +++--
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6d357565a8 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -147,8 +147,9 @@ The following infomask bits are applicable:
- HEAP_KEYS_UPDATED
This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ this tuple and changed the key values, or it deleted the tuple. It can also
+ be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether
+ the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--+HP7ph2BbKc20aGI--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 5 +++--
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6d357565a8 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -147,8 +147,9 @@ The following infomask bits are applicable:
- HEAP_KEYS_UPDATED
This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ this tuple and changed the key values, or it deleted the tuple. It can also
+ be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether
+ the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--+HP7ph2BbKc20aGI--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 7 ++++---
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6441e8baf0 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -146,9 +146,10 @@ The following infomask bits are applicable:
FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit.
- HEAP_KEYS_UPDATED
- This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ This bit lives in t_infomask2. If set, indicates that the operation(s) done
+ by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE
+ that modifies the columns of the key, or a DELETE. It's set regardless of
+ whether the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--0ntfKIWw70PvrIHh--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/hio.c | 8 +++-----
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--CE+1k2dSO48ffgeK--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 5 +++--
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6d357565a8 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -147,8 +147,9 @@ The following infomask bits are applicable:
- HEAP_KEYS_UPDATED
This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ this tuple and changed the key values, or it deleted the tuple. It can also
+ be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether
+ the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--+HP7ph2BbKc20aGI--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 5 +++--
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6d357565a8 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -147,8 +147,9 @@ The following infomask bits are applicable:
- HEAP_KEYS_UPDATED
This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ this tuple and changed the key values, or it deleted the tuple. It can also
+ be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether
+ the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--+HP7ph2BbKc20aGI--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 7 ++++---
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6441e8baf0 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -146,9 +146,10 @@ The following infomask bits are applicable:
FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit.
- HEAP_KEYS_UPDATED
- This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ This bit lives in t_infomask2. If set, indicates that the operation(s) done
+ by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE
+ that modifies the columns of the key, or a DELETE. It's set regardless of
+ whether the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--0ntfKIWw70PvrIHh--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/hio.c | 8 +++-----
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--CE+1k2dSO48ffgeK--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/hio.c | 8 +++-----
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--CE+1k2dSO48ffgeK--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 5 +++--
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6d357565a8 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -147,8 +147,9 @@ The following infomask bits are applicable:
- HEAP_KEYS_UPDATED
This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ this tuple and changed the key values, or it deleted the tuple. It can also
+ be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether
+ the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--+HP7ph2BbKc20aGI--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 7 ++++---
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6441e8baf0 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -146,9 +146,10 @@ The following infomask bits are applicable:
FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit.
- HEAP_KEYS_UPDATED
- This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ This bit lives in t_infomask2. If set, indicates that the operation(s) done
+ by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE
+ that modifies the columns of the key, or a DELETE. It's set regardless of
+ whether the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--0ntfKIWw70PvrIHh--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/hio.c | 8 +++-----
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--CE+1k2dSO48ffgeK--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 7 ++++---
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6441e8baf0 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -146,9 +146,10 @@ The following infomask bits are applicable:
FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit.
- HEAP_KEYS_UPDATED
- This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ This bit lives in t_infomask2. If set, indicates that the operation(s) done
+ by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE
+ that modifies the columns of the key, or a DELETE. It's set regardless of
+ whether the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--0ntfKIWw70PvrIHh--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 5 +++--
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6d357565a8 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -147,8 +147,9 @@ The following infomask bits are applicable:
- HEAP_KEYS_UPDATED
This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ this tuple and changed the key values, or it deleted the tuple. It can also
+ be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether
+ the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--+HP7ph2BbKc20aGI--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/hio.c | 8 +++-----
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--CE+1k2dSO48ffgeK--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 5 +++--
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6d357565a8 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -147,8 +147,9 @@ The following infomask bits are applicable:
- HEAP_KEYS_UPDATED
This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ this tuple and changed the key values, or it deleted the tuple. It can also
+ be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether
+ the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--+HP7ph2BbKc20aGI--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 5 +++--
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6d357565a8 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -147,8 +147,9 @@ The following infomask bits are applicable:
- HEAP_KEYS_UPDATED
This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ this tuple and changed the key values, or it deleted the tuple. It can also
+ be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether
+ the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--+HP7ph2BbKc20aGI--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 7 ++++---
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6441e8baf0 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -146,9 +146,10 @@ The following infomask bits are applicable:
FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit.
- HEAP_KEYS_UPDATED
- This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ This bit lives in t_infomask2. If set, indicates that the operation(s) done
+ by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE
+ that modifies the columns of the key, or a DELETE. It's set regardless of
+ whether the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--0ntfKIWw70PvrIHh--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 7 ++++---
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6441e8baf0 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -146,9 +146,10 @@ The following infomask bits are applicable:
FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit.
- HEAP_KEYS_UPDATED
- This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ This bit lives in t_infomask2. If set, indicates that the operation(s) done
+ by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE
+ that modifies the columns of the key, or a DELETE. It's set regardless of
+ whether the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--0ntfKIWw70PvrIHh--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 5 +++--
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6d357565a8 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -147,8 +147,9 @@ The following infomask bits are applicable:
- HEAP_KEYS_UPDATED
This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ this tuple and changed the key values, or it deleted the tuple. It can also
+ be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether
+ the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--+HP7ph2BbKc20aGI--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/hio.c | 8 +++-----
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--CE+1k2dSO48ffgeK--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/hio.c | 8 +++-----
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--CE+1k2dSO48ffgeK--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 7 ++++---
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6441e8baf0 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -146,9 +146,10 @@ The following infomask bits are applicable:
FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit.
- HEAP_KEYS_UPDATED
- This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ This bit lives in t_infomask2. If set, indicates that the operation(s) done
+ by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE
+ that modifies the columns of the key, or a DELETE. It's set regardless of
+ whether the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--0ntfKIWw70PvrIHh--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/hio.c | 8 +++-----
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--CE+1k2dSO48ffgeK--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/hio.c | 8 +++-----
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--CE+1k2dSO48ffgeK--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 5 +++--
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6d357565a8 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -147,8 +147,9 @@ The following infomask bits are applicable:
- HEAP_KEYS_UPDATED
This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ this tuple and changed the key values, or it deleted the tuple. It can also
+ be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether
+ the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--+HP7ph2BbKc20aGI--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 5 +++--
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6d357565a8 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -147,8 +147,9 @@ The following infomask bits are applicable:
- HEAP_KEYS_UPDATED
This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ this tuple and changed the key values, or it deleted the tuple. It can also
+ be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether
+ the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--+HP7ph2BbKc20aGI--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 5 +++--
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6d357565a8 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -147,8 +147,9 @@ The following infomask bits are applicable:
- HEAP_KEYS_UPDATED
This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ this tuple and changed the key values, or it deleted the tuple. It can also
+ be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether
+ the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--+HP7ph2BbKc20aGI--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/hio.c | 8 +++-----
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--CE+1k2dSO48ffgeK--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/hio.c | 8 +++-----
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--CE+1k2dSO48ffgeK--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 7 ++++---
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6441e8baf0 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -146,9 +146,10 @@ The following infomask bits are applicable:
FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit.
- HEAP_KEYS_UPDATED
- This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ This bit lives in t_infomask2. If set, indicates that the operation(s) done
+ by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE
+ that modifies the columns of the key, or a DELETE. It's set regardless of
+ whether the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--0ntfKIWw70PvrIHh--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 5 +++--
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6d357565a8 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -147,8 +147,9 @@ The following infomask bits are applicable:
- HEAP_KEYS_UPDATED
This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ this tuple and changed the key values, or it deleted the tuple. It can also
+ be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether
+ the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--+HP7ph2BbKc20aGI--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 7 ++++---
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6441e8baf0 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -146,9 +146,10 @@ The following infomask bits are applicable:
FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit.
- HEAP_KEYS_UPDATED
- This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ This bit lives in t_infomask2. If set, indicates that the operation(s) done
+ by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE
+ that modifies the columns of the key, or a DELETE. It's set regardless of
+ whether the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--0ntfKIWw70PvrIHh--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 7 ++++---
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6441e8baf0 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -146,9 +146,10 @@ The following infomask bits are applicable:
FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit.
- HEAP_KEYS_UPDATED
- This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ This bit lives in t_infomask2. If set, indicates that the operation(s) done
+ by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE
+ that modifies the columns of the key, or a DELETE. It's set regardless of
+ whether the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--0ntfKIWw70PvrIHh--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 7 ++++---
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6441e8baf0 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -146,9 +146,10 @@ The following infomask bits are applicable:
FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit.
- HEAP_KEYS_UPDATED
- This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ This bit lives in t_infomask2. If set, indicates that the operation(s) done
+ by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE
+ that modifies the columns of the key, or a DELETE. It's set regardless of
+ whether the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--0ntfKIWw70PvrIHh--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 5 +++--
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6d357565a8 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -147,8 +147,9 @@ The following infomask bits are applicable:
- HEAP_KEYS_UPDATED
This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ this tuple and changed the key values, or it deleted the tuple. It can also
+ be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether
+ the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--+HP7ph2BbKc20aGI--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination.
@ 2021-01-21 16:06 Julien Rouhaud <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw)
This combination of hint bits was previously detected as a form of corruption,
but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE
queries.
Discussion: https://postgr.es/m/20210124061758.GA11756@nol
---
contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++-
contrib/amcheck/verify_heapam.c | 7 -------
src/backend/access/heap/README.tuplock | 5 +++--
src/backend/access/heap/hio.c | 8 +++-----
4 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl
index a2f65b826d..6050feb712 100644
--- a/contrib/amcheck/t/001_verify_heapam.pl
+++ b/contrib/amcheck/t/001_verify_heapam.pl
@@ -4,7 +4,7 @@ use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 79;
+use Test::More tests => 80;
my ($node, $result);
@@ -47,6 +47,9 @@ detects_heap_corruption(
#
fresh_test_table('test');
$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test));
+detects_no_corruption(
+ "verify_heapam('test')",
+ "all-frozen not corrupted table");
corrupt_first_page('test');
detects_heap_corruption("verify_heapam('test')",
"all-frozen corrupted table");
@@ -92,6 +95,15 @@ sub fresh_test_table
ALTER TABLE $relname ALTER b SET STORAGE external;
INSERT INTO $relname (a, b)
(SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs);
+ BEGIN;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ RELEASE s1;
+ SAVEPOINT s1;
+ SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE;
+ UPDATE $relname SET b = b WHERE a = 42;
+ COMMIT;
));
}
diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c
index 88ab32490c..49f5ca0ef2 100644
--- a/contrib/amcheck/verify_heapam.c
+++ b/contrib/amcheck/verify_heapam.c
@@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx)
ctx->tuphdr->t_hoff, ctx->lp_len));
header_garbled = true;
}
- if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED))
- {
- report_corruption(ctx,
- pstrdup("tuple is marked as only locked, but also claims key columns were updated"));
- header_garbled = true;
- }
if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) &&
(ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI))
diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock
index d03ddf6cdc..6d357565a8 100644
--- a/src/backend/access/heap/README.tuplock
+++ b/src/backend/access/heap/README.tuplock
@@ -147,8 +147,9 @@ The following infomask bits are applicable:
- HEAP_KEYS_UPDATED
This bit lives in t_infomask2. If set, indicates that the XMAX updated
- this tuple and changed the key values, or it deleted the tuple.
- It's set regardless of whether the XMAX is a TransactionId or a MultiXactId.
+ this tuple and changed the key values, or it deleted the tuple. It can also
+ be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether
+ the XMAX is a TransactionId or a MultiXactId.
We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit
is set.
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index fb7ad0bab4..75223c9bea 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation,
/*
* Do not allow tuples with invalid combinations of hint bits to be placed
- * on a page. These combinations are detected as corruption by the
- * contrib/amcheck logic, so if you disable one or both of these
- * assertions, make corresponding changes there.
+ * on a page. This combination is detected as corruption by the
+ * contrib/amcheck logic, so if you disable this assertion, make
+ * corresponding changes there.
*/
- Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) &&
- (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)));
Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) &&
(tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI)));
--
2.20.1
--+HP7ph2BbKc20aGI--
^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH] Slight improvement of worker_spi.c example
@ 2023-05-12 15:39 Aleksander Alekseev <[email protected]>
0 siblings, 0 replies; 67+ messages in thread
From: Aleksander Alekseev @ 2023-05-12 15:39 UTC (permalink / raw)
To: PostgreSQL Hackers <[email protected]>
Hi,
Currently the example uses the following order of calls:
StartTransactionCommand();
SPI_connect();
PushActiveSnapshot(...);
...
SPI_finish();
PopActiveSnapshot();
CommitTransactionCommand();
This could be somewhat misleading. Typically one expects something to be freed
in a reverse order compared to initialization. This creates a false impression
that PushActiveSnapshot(...) _should_ be called after SPI_connect().
The patch changes the order to:
StartTransactionCommand();
PushActiveSnapshot(...);
SPI_connect();
...
SPI_finish();
PopActiveSnapshot();
CommitTransactionCommand();
... and also clarifies that the order of PushActiveSnapshot(...) and
SPI_connect() is not important.
--
Best regards,
Aleksander Alekseev
Attachments:
[application/x-patch] v1-0001-Slight-improvement-of-worker_spi.c-example.patch (2.6K, ../../CAJ7c6TMOhWmP92_fFss-cvNnsxdj5_TSdtmiE3AJOv6yGotoFQ@mail.gmail.com/2-v1-0001-Slight-improvement-of-worker_spi.c-example.patch)
download | inline diff:
From 9f20a508c3b52d94455d67e3bdf7872787c63255 Mon Sep 17 00:00:00 2001
From: Aleksander Alekseev <[email protected]>
Date: Fri, 12 May 2023 17:15:04 +0300
Subject: [PATCH v1] Slight improvement of worker_spi.c example
Previously the example used the following order of calls:
StartTransactionCommand();
SPI_connect();
PushActiveSnapshot(...);
...
SPI_finish();
PopActiveSnapshot();
CommitTransactionCommand();
This could be somewhat misleading. Typically one expects something to be freed
in a reverse order comparing to initialization. This creates a false impression
that PushActiveSnapshot(...) _should_ be called after SPI_connect().
The patch changes the order to:
StartTransactionCommand();
PushActiveSnapshot(...);
SPI_connect();
...
SPI_finish();
PopActiveSnapshot();
CommitTransactionCommand();
... and also clarifies that the order of PushActiveSnapshot(...) and
SPI_connect() is not important.
Aleksander Alekseev, reviewed by TODO FIXME
Discussion: TODO FIXME
---
src/test/modules/worker_spi/worker_spi.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/test/modules/worker_spi/worker_spi.c b/src/test/modules/worker_spi/worker_spi.c
index ad491d7722..8045bb3546 100644
--- a/src/test/modules/worker_spi/worker_spi.c
+++ b/src/test/modules/worker_spi/worker_spi.c
@@ -74,8 +74,8 @@ initialize_worker_spi(worktable *table)
SetCurrentStatementStartTimestamp();
StartTransactionCommand();
- SPI_connect();
PushActiveSnapshot(GetTransactionSnapshot());
+ SPI_connect();
pgstat_report_activity(STATE_RUNNING, "initializing worker_spi schema");
/* XXX could we use CREATE SCHEMA IF NOT EXISTS? */
@@ -222,17 +222,19 @@ worker_spi_main(Datum main_arg)
* preceded by SetCurrentStatementStartTimestamp(), so that statement
* start time is always up to date.
*
- * The SPI_connect() call lets us run queries through the SPI manager,
- * and the PushActiveSnapshot() call creates an "active" snapshot
+ * The PushActiveSnapshot() call creates an "active" snapshot,
* which is necessary for queries to have MVCC data to work on.
+ * The SPI_connect() call lets us run queries through the SPI manager.
+ * The order of PushActiveSnapshot() and SPI_connect() is not really
+ * important.
*
* The pgstat_report_activity() call makes our activity visible
* through the pgstat views.
*/
SetCurrentStatementStartTimestamp();
StartTransactionCommand();
- SPI_connect();
PushActiveSnapshot(GetTransactionSnapshot());
+ SPI_connect();
debug_query_string = buf.data;
pgstat_report_activity(STATE_RUNNING, buf.data);
--
2.40.1
^ permalink raw reply [nested|flat] 67+ messages in thread
end of thread, other threads:[~2023-05-12 15:39 UTC | newest]
Thread overview: 67+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2023-05-12 15:39 [PATCH] Slight improvement of worker_spi.c example Aleksander Alekseev <[email protected]>
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox