public inbox for [email protected]
help / color / mirror / Atom feedRe: example for xmltable with XMLNAMESPACES
68+ messages / 3 participants
[nested] [flat]
* Re: example for xmltable with XMLNAMESPACES
@ 2017-04-13 15:16 Alvaro Herrera <[email protected]>
0 siblings, 0 replies; 68+ messages in thread
From: Alvaro Herrera @ 2017-04-13 15:16 UTC (permalink / raw)
To: Arjen Nienhuis <[email protected]>; +Cc: pgsql-hackers
Arjen Nienhuis wrote:
> It wasn't completely clear for me how to use namespaces in xmltable().
> Maybe add this to the documentation. It shows the default namespace
> and quoting the namespace name.
Thanks, pushed.
--
Álvaro Herrera https://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
^ permalink raw reply [nested|flat] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ 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; 68+ 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] 68+ messages in thread
* Re: Estimating HugePages Requirements?
@ 2022-03-15 22:02 Magnus Hagander <[email protected]>
0 siblings, 0 replies; 68+ messages in thread
From: Magnus Hagander @ 2022-03-15 22:02 UTC (permalink / raw)
To: Michael Paquier <[email protected]>; +Cc: Nathan Bossart <[email protected]>; Bossart, Nathan <[email protected]>; Fujii Masao <[email protected]>; Justin Pryzby <[email protected]>; Andres Freund <[email protected]>; Mark Dilger <[email protected]>; Don Seiler <[email protected]>; pgsql-hackers
On Tue, Mar 15, 2022 at 3:41 AM Michael Paquier <[email protected]> wrote:
>
> On Mon, Mar 14, 2022 at 10:34:17AM -0700, Nathan Bossart wrote:
> > On Mon, Mar 14, 2022 at 04:26:43PM +0100, Magnus Hagander wrote:
> >> And in fact, the command documented on
> >> https://www.postgresql.org/docs/devel/kernel-resources.html doesn't
> >> actually produce the output that the docs show, it also shows the log
> >> line, in the default config? If we can't fix the extra logging we
> >> should at least have our docs represent reality -- maybe by adding a
> >> "2>/dev/null" entry? But it'd be better to have it not output that log
> >> in the first place...
> >
> > I attached a patch to adjust the documentation for now. This apparently
> > crossed my mind earlier [0], but I didn't follow through with it for some
> > reason.
>
> Another thing that we can add is -c log_min_messages=fatal, but my
> method is more complicated than a simple redirection, of course :)
Either does work, but yours has more characters :)
> >> (Of course what I'd really want is to be able to run it on a cluster
> >> that's running, but that was discussed downthread so I'm not bringing
> >> that one up for changes now)
> >
> > I think it is worth revisiting the extra logging and the ability to view
> > runtime-computed GUCs on a running server. Should this be an open item for
> > v15, or do you think it's alright to leave it for the v16 development
> > cycle?
>
> Well, this is a completely new problem as it opens the door of
> potential concurrent access issues with the data directory lock file
> while reading values from the control file. And that's not mandatory
> to be able to get those estimations without having to allocate a large
> chunk of memory, which was the primary goal discussed upthread as far
> as I recall. So I would leave that as an item to potentially tackle
> in future versions.
I think we're talking about two different things here.
I think the "avoid extra logging" would be worth seeing if we can
address for 15.
The "able to run on a live cluster" seems a lot bigger and more scary
and not 15 material.
--
Magnus Hagander
Me: https://www.hagander.net/
Work: https://www.redpill-linpro.com/
^ permalink raw reply [nested|flat] 68+ messages in thread
end of thread, other threads:[~2022-03-15 22:02 UTC | newest]
Thread overview: 68+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2017-04-13 15:16 Re: example for xmltable with XMLNAMESPACES Alvaro Herrera <[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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]>
2022-03-15 22:02 Re: Estimating HugePages Requirements? Magnus Hagander <[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