public inbox for [email protected]help / color / mirror / Atom feed
[PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. 67+ messages / 2 participants [nested] [flat]
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 7 ++++--- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6441e8baf0 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -146,9 +146,10 @@ The following infomask bits are applicable: FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit. - HEAP_KEYS_UPDATED - This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + This bit lives in t_infomask2. If set, indicates that the operation(s) done + by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE + that modifies the columns of the key, or a DELETE. It's set regardless of + whether the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --0ntfKIWw70PvrIHh-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/hio.c | 8 +++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --CE+1k2dSO48ffgeK-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 5 +++-- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6d357565a8 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -147,8 +147,9 @@ The following infomask bits are applicable: - HEAP_KEYS_UPDATED This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + this tuple and changed the key values, or it deleted the tuple. It can also + be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether + the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --+HP7ph2BbKc20aGI-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 7 ++++--- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6441e8baf0 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -146,9 +146,10 @@ The following infomask bits are applicable: FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit. - HEAP_KEYS_UPDATED - This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + This bit lives in t_infomask2. If set, indicates that the operation(s) done + by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE + that modifies the columns of the key, or a DELETE. It's set regardless of + whether the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --0ntfKIWw70PvrIHh-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/hio.c | 8 +++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --CE+1k2dSO48ffgeK-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 5 +++-- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6d357565a8 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -147,8 +147,9 @@ The following infomask bits are applicable: - HEAP_KEYS_UPDATED This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + this tuple and changed the key values, or it deleted the tuple. It can also + be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether + the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --+HP7ph2BbKc20aGI-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 7 ++++--- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6441e8baf0 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -146,9 +146,10 @@ The following infomask bits are applicable: FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit. - HEAP_KEYS_UPDATED - This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + This bit lives in t_infomask2. If set, indicates that the operation(s) done + by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE + that modifies the columns of the key, or a DELETE. It's set regardless of + whether the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --0ntfKIWw70PvrIHh-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/hio.c | 8 +++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --CE+1k2dSO48ffgeK-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 5 +++-- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6d357565a8 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -147,8 +147,9 @@ The following infomask bits are applicable: - HEAP_KEYS_UPDATED This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + this tuple and changed the key values, or it deleted the tuple. It can also + be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether + the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --+HP7ph2BbKc20aGI-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 7 ++++--- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6441e8baf0 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -146,9 +146,10 @@ The following infomask bits are applicable: FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit. - HEAP_KEYS_UPDATED - This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + This bit lives in t_infomask2. If set, indicates that the operation(s) done + by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE + that modifies the columns of the key, or a DELETE. It's set regardless of + whether the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --0ntfKIWw70PvrIHh-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/hio.c | 8 +++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --CE+1k2dSO48ffgeK-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 5 +++-- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6d357565a8 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -147,8 +147,9 @@ The following infomask bits are applicable: - HEAP_KEYS_UPDATED This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + this tuple and changed the key values, or it deleted the tuple. It can also + be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether + the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --+HP7ph2BbKc20aGI-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 7 ++++--- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6441e8baf0 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -146,9 +146,10 @@ The following infomask bits are applicable: FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit. - HEAP_KEYS_UPDATED - This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + This bit lives in t_infomask2. If set, indicates that the operation(s) done + by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE + that modifies the columns of the key, or a DELETE. It's set regardless of + whether the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --0ntfKIWw70PvrIHh-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/hio.c | 8 +++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --CE+1k2dSO48ffgeK-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 5 +++-- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6d357565a8 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -147,8 +147,9 @@ The following infomask bits are applicable: - HEAP_KEYS_UPDATED This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + this tuple and changed the key values, or it deleted the tuple. It can also + be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether + the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --+HP7ph2BbKc20aGI-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 7 ++++--- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6441e8baf0 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -146,9 +146,10 @@ The following infomask bits are applicable: FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit. - HEAP_KEYS_UPDATED - This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + This bit lives in t_infomask2. If set, indicates that the operation(s) done + by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE + that modifies the columns of the key, or a DELETE. It's set regardless of + whether the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --0ntfKIWw70PvrIHh-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/hio.c | 8 +++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --CE+1k2dSO48ffgeK-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 5 +++-- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6d357565a8 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -147,8 +147,9 @@ The following infomask bits are applicable: - HEAP_KEYS_UPDATED This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + this tuple and changed the key values, or it deleted the tuple. It can also + be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether + the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --+HP7ph2BbKc20aGI-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 7 ++++--- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6441e8baf0 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -146,9 +146,10 @@ The following infomask bits are applicable: FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit. - HEAP_KEYS_UPDATED - This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + This bit lives in t_infomask2. If set, indicates that the operation(s) done + by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE + that modifies the columns of the key, or a DELETE. It's set regardless of + whether the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --0ntfKIWw70PvrIHh-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/hio.c | 8 +++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --CE+1k2dSO48ffgeK-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 5 +++-- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6d357565a8 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -147,8 +147,9 @@ The following infomask bits are applicable: - HEAP_KEYS_UPDATED This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + this tuple and changed the key values, or it deleted the tuple. It can also + be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether + the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --+HP7ph2BbKc20aGI-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 7 ++++--- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6441e8baf0 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -146,9 +146,10 @@ The following infomask bits are applicable: FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit. - HEAP_KEYS_UPDATED - This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + This bit lives in t_infomask2. If set, indicates that the operation(s) done + by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE + that modifies the columns of the key, or a DELETE. It's set regardless of + whether the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --0ntfKIWw70PvrIHh-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/hio.c | 8 +++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --CE+1k2dSO48ffgeK-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 5 +++-- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6d357565a8 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -147,8 +147,9 @@ The following infomask bits are applicable: - HEAP_KEYS_UPDATED This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + this tuple and changed the key values, or it deleted the tuple. It can also + be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether + the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --+HP7ph2BbKc20aGI-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 7 ++++--- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6441e8baf0 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -146,9 +146,10 @@ The following infomask bits are applicable: FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit. - HEAP_KEYS_UPDATED - This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + This bit lives in t_infomask2. If set, indicates that the operation(s) done + by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE + that modifies the columns of the key, or a DELETE. It's set regardless of + whether the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --0ntfKIWw70PvrIHh-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/hio.c | 8 +++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --CE+1k2dSO48ffgeK-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 5 +++-- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6d357565a8 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -147,8 +147,9 @@ The following infomask bits are applicable: - HEAP_KEYS_UPDATED This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + this tuple and changed the key values, or it deleted the tuple. It can also + be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether + the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --+HP7ph2BbKc20aGI-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 7 ++++--- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6441e8baf0 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -146,9 +146,10 @@ The following infomask bits are applicable: FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit. - HEAP_KEYS_UPDATED - This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + This bit lives in t_infomask2. If set, indicates that the operation(s) done + by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE + that modifies the columns of the key, or a DELETE. It's set regardless of + whether the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --0ntfKIWw70PvrIHh-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/hio.c | 8 +++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --CE+1k2dSO48ffgeK-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 5 +++-- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6d357565a8 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -147,8 +147,9 @@ The following infomask bits are applicable: - HEAP_KEYS_UPDATED This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + this tuple and changed the key values, or it deleted the tuple. It can also + be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether + the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --+HP7ph2BbKc20aGI-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 7 ++++--- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6441e8baf0 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -146,9 +146,10 @@ The following infomask bits are applicable: FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit. - HEAP_KEYS_UPDATED - This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + This bit lives in t_infomask2. If set, indicates that the operation(s) done + by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE + that modifies the columns of the key, or a DELETE. It's set regardless of + whether the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --0ntfKIWw70PvrIHh-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/hio.c | 8 +++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --CE+1k2dSO48ffgeK-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 5 +++-- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6d357565a8 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -147,8 +147,9 @@ The following infomask bits are applicable: - HEAP_KEYS_UPDATED This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + this tuple and changed the key values, or it deleted the tuple. It can also + be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether + the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --+HP7ph2BbKc20aGI-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 7 ++++--- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6441e8baf0 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -146,9 +146,10 @@ The following infomask bits are applicable: FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit. - HEAP_KEYS_UPDATED - This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + This bit lives in t_infomask2. If set, indicates that the operation(s) done + by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE + that modifies the columns of the key, or a DELETE. It's set regardless of + whether the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --0ntfKIWw70PvrIHh-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/hio.c | 8 +++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --CE+1k2dSO48ffgeK-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 5 +++-- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6d357565a8 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -147,8 +147,9 @@ The following infomask bits are applicable: - HEAP_KEYS_UPDATED This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + this tuple and changed the key values, or it deleted the tuple. It can also + be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether + the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --+HP7ph2BbKc20aGI-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 7 ++++--- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6441e8baf0 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -146,9 +146,10 @@ The following infomask bits are applicable: FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit. - HEAP_KEYS_UPDATED - This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + This bit lives in t_infomask2. If set, indicates that the operation(s) done + by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE + that modifies the columns of the key, or a DELETE. It's set regardless of + whether the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --0ntfKIWw70PvrIHh-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/hio.c | 8 +++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --CE+1k2dSO48ffgeK-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 5 +++-- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6d357565a8 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -147,8 +147,9 @@ The following infomask bits are applicable: - HEAP_KEYS_UPDATED This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + this tuple and changed the key values, or it deleted the tuple. It can also + be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether + the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --+HP7ph2BbKc20aGI-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 7 ++++--- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6441e8baf0 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -146,9 +146,10 @@ The following infomask bits are applicable: FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit. - HEAP_KEYS_UPDATED - This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + This bit lives in t_infomask2. If set, indicates that the operation(s) done + by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE + that modifies the columns of the key, or a DELETE. It's set regardless of + whether the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --0ntfKIWw70PvrIHh-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/hio.c | 8 +++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --CE+1k2dSO48ffgeK-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 5 +++-- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6d357565a8 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -147,8 +147,9 @@ The following infomask bits are applicable: - HEAP_KEYS_UPDATED This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + this tuple and changed the key values, or it deleted the tuple. It can also + be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether + the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --+HP7ph2BbKc20aGI-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 7 ++++--- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6441e8baf0 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -146,9 +146,10 @@ The following infomask bits are applicable: FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit. - HEAP_KEYS_UPDATED - This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + This bit lives in t_infomask2. If set, indicates that the operation(s) done + by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE + that modifies the columns of the key, or a DELETE. It's set regardless of + whether the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --0ntfKIWw70PvrIHh-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/hio.c | 8 +++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --CE+1k2dSO48ffgeK-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 5 +++-- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6d357565a8 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -147,8 +147,9 @@ The following infomask bits are applicable: - HEAP_KEYS_UPDATED This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + this tuple and changed the key values, or it deleted the tuple. It can also + be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether + the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --+HP7ph2BbKc20aGI-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 7 ++++--- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6441e8baf0 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -146,9 +146,10 @@ The following infomask bits are applicable: FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit. - HEAP_KEYS_UPDATED - This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + This bit lives in t_infomask2. If set, indicates that the operation(s) done + by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE + that modifies the columns of the key, or a DELETE. It's set regardless of + whether the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --0ntfKIWw70PvrIHh-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/hio.c | 8 +++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --CE+1k2dSO48ffgeK-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 5 +++-- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6d357565a8 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -147,8 +147,9 @@ The following infomask bits are applicable: - HEAP_KEYS_UPDATED This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + this tuple and changed the key values, or it deleted the tuple. It can also + be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether + the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --+HP7ph2BbKc20aGI-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 7 ++++--- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6441e8baf0 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -146,9 +146,10 @@ The following infomask bits are applicable: FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit. - HEAP_KEYS_UPDATED - This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + This bit lives in t_infomask2. If set, indicates that the operation(s) done + by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE + that modifies the columns of the key, or a DELETE. It's set regardless of + whether the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --0ntfKIWw70PvrIHh-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/hio.c | 8 +++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --CE+1k2dSO48ffgeK-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 5 +++-- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6d357565a8 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -147,8 +147,9 @@ The following infomask bits are applicable: - HEAP_KEYS_UPDATED This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + this tuple and changed the key values, or it deleted the tuple. It can also + be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether + the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --+HP7ph2BbKc20aGI-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 7 ++++--- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6441e8baf0 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -146,9 +146,10 @@ The following infomask bits are applicable: FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit. - HEAP_KEYS_UPDATED - This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + This bit lives in t_infomask2. If set, indicates that the operation(s) done + by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE + that modifies the columns of the key, or a DELETE. It's set regardless of + whether the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --0ntfKIWw70PvrIHh-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/hio.c | 8 +++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --CE+1k2dSO48ffgeK-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 5 +++-- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6d357565a8 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -147,8 +147,9 @@ The following infomask bits are applicable: - HEAP_KEYS_UPDATED This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + this tuple and changed the key values, or it deleted the tuple. It can also + be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether + the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --+HP7ph2BbKc20aGI-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 7 ++++--- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6441e8baf0 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -146,9 +146,10 @@ The following infomask bits are applicable: FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit. - HEAP_KEYS_UPDATED - This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + This bit lives in t_infomask2. If set, indicates that the operation(s) done + by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE + that modifies the columns of the key, or a DELETE. It's set regardless of + whether the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --0ntfKIWw70PvrIHh-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/hio.c | 8 +++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --CE+1k2dSO48ffgeK-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 5 +++-- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6d357565a8 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -147,8 +147,9 @@ The following infomask bits are applicable: - HEAP_KEYS_UPDATED This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + this tuple and changed the key values, or it deleted the tuple. It can also + be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether + the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --+HP7ph2BbKc20aGI-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 7 ++++--- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6441e8baf0 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -146,9 +146,10 @@ The following infomask bits are applicable: FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit. - HEAP_KEYS_UPDATED - This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + This bit lives in t_infomask2. If set, indicates that the operation(s) done + by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE + that modifies the columns of the key, or a DELETE. It's set regardless of + whether the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --0ntfKIWw70PvrIHh-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/hio.c | 8 +++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --CE+1k2dSO48ffgeK-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 5 +++-- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6d357565a8 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -147,8 +147,9 @@ The following infomask bits are applicable: - HEAP_KEYS_UPDATED This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + this tuple and changed the key values, or it deleted the tuple. It can also + be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether + the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --+HP7ph2BbKc20aGI-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 7 ++++--- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6441e8baf0 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -146,9 +146,10 @@ The following infomask bits are applicable: FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit. - HEAP_KEYS_UPDATED - This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + This bit lives in t_infomask2. If set, indicates that the operation(s) done + by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE + that modifies the columns of the key, or a DELETE. It's set regardless of + whether the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --0ntfKIWw70PvrIHh-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/hio.c | 8 +++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --CE+1k2dSO48ffgeK-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 5 +++-- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6d357565a8 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -147,8 +147,9 @@ The following infomask bits are applicable: - HEAP_KEYS_UPDATED This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + this tuple and changed the key values, or it deleted the tuple. It can also + be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether + the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --+HP7ph2BbKc20aGI-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 7 ++++--- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6441e8baf0 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -146,9 +146,10 @@ The following infomask bits are applicable: FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit. - HEAP_KEYS_UPDATED - This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + This bit lives in t_infomask2. If set, indicates that the operation(s) done + by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE + that modifies the columns of the key, or a DELETE. It's set regardless of + whether the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --0ntfKIWw70PvrIHh-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/hio.c | 8 +++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --CE+1k2dSO48ffgeK-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. @ 2021-01-21 16:06 Julien Rouhaud <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: Julien Rouhaud @ 2021-01-21 16:06 UTC (permalink / raw) This combination of hint bits was previously detected as a form of corruption, but it can be obtained with some mix of SELECT ... FOR UPDATE and UPDATE queries. Discussion: https://postgr.es/m/20210124061758.GA11756@nol --- contrib/amcheck/t/001_verify_heapam.pl | 14 +++++++++++++- contrib/amcheck/verify_heapam.c | 7 ------- src/backend/access/heap/README.tuplock | 5 +++-- src/backend/access/heap/hio.c | 8 +++----- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index a2f65b826d..6050feb712 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 79; +use Test::More tests => 80; my ($node, $result); @@ -47,6 +47,9 @@ detects_heap_corruption( # fresh_test_table('test'); $node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption( + "verify_heapam('test')", + "all-frozen not corrupted table"); corrupt_first_page('test'); detects_heap_corruption("verify_heapam('test')", "all-frozen corrupted table"); @@ -92,6 +95,15 @@ sub fresh_test_table ALTER TABLE $relname ALTER b SET STORAGE external; INSERT INTO $relname (a, b) (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; )); } diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 88ab32490c..49f5ca0ef2 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -608,13 +608,6 @@ check_tuple_header_and_visibilty(HeapTupleHeader tuphdr, HeapCheckContext *ctx) ctx->tuphdr->t_hoff, ctx->lp_len)); header_garbled = true; } - if ((ctx->tuphdr->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (ctx->tuphdr->t_infomask2 & HEAP_KEYS_UPDATED)) - { - report_corruption(ctx, - pstrdup("tuple is marked as only locked, but also claims key columns were updated")); - header_garbled = true; - } if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdc..6d357565a8 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -147,8 +147,9 @@ The following infomask bits are applicable: - HEAP_KEYS_UPDATED This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + this tuple and changed the key values, or it deleted the tuple. It can also + be set in combination of HEAP_XMAX_LOCK_ONLY. It's set regardless of whether + the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index fb7ad0bab4..75223c9bea 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -49,12 +49,10 @@ RelationPutHeapTuple(Relation relation, /* * Do not allow tuples with invalid combinations of hint bits to be placed - * on a page. These combinations are detected as corruption by the - * contrib/amcheck logic, so if you disable one or both of these - * assertions, make corresponding changes there. + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. */ - Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_LOCK_ONLY) && - (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED))); Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); -- 2.20.1 --+HP7ph2BbKc20aGI-- ^ permalink raw reply [nested|flat] 67+ messages in thread
* Re: Revise the Asserts added to bimapset manipulation functions @ 2023-12-29 09:22 David Rowley <[email protected]> 0 siblings, 0 replies; 67+ messages in thread From: David Rowley @ 2023-12-29 09:22 UTC (permalink / raw) To: Richard Guo <[email protected]>; +Cc: pgsql-hackers On Fri, 29 Dec 2023 at 21:07, Richard Guo <[email protected]> wrote: > It seems to me that the former scenario also makes sense in some cases. > For instance, let's say there are two pointers in two structs, s1->p and > s2->p, both referencing the same bitmapset. If we modify the bitmapset > via s1->p (even if no reallocation could occur), s2 would see different > content via its pointer 'p'. That statement simply isn't true. If there's no reallocation then both pointers point to the same memory and, therefore have the same content, not different content. In the absence of a reallocation, then the only time s1->p and s2->p could differ is if s1->p became an empty set as a result of the modification. > Sometimes this is just wrong and could > cause problems. If we can force a reallocation for every modification > of the bitmapset, it'd be much easier to find such bugs. Whether it's intended or unintended, at least it's consistent, therefore isn't going to behave differently if the number of bitmapwords in the set changes. All REALLOCATE_BITMAPSETS does for bms_int_members(), bms_join() and bms_del_members() is change one consistent behaviour (we never reallocate) into some other consistent behaviour (we always reallocate). If we make REALLOCATE_BITMAPSETS work how I propose in my patch then the reallocation is just limited to cases where the set *could* be repalloced by a modification. That change gives us consistent behaviour as the set is *always* reallocated when it *could* be reallocated. Making it consistent to me, seems good as a debug option. Swapping one consistent behaviour for another (as you propose) seems pointless and more likely to force us to change code that works perfectly fine today. In any case, the comments in bms_int_members(), bms_join() and bms_del_members() are now only true when REALLOCATE_BITMAPSETS is not defined. Are you proposing we leave those comments outdated? or do you propose that we mention that the left inputs are not recycled when building with REALLOCATE_BITMAPSETS? In my view, neither of these is acceptable as often the primary reason to use something like bms_int_members() over bms_intersect() is exactly because the left input is recycled. I don't want people to have to start contorting code because bms_int_members()'s left input recycling cannot be relied on. David ^ permalink raw reply [nested|flat] 67+ messages in thread
end of thread, other threads:[~2023-12-29 09:22 UTC | newest] Thread overview: 67+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH 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 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 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 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 v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH 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 v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH 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 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 v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH 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 v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH v3] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH v2] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH v1] Allow HEAP_XMAX_LOCK_ONLY and HEAP_KEYS_UPDATED combination. Julien Rouhaud <[email protected]> 2021-01-21 16:06 [PATCH 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 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]> 2023-12-29 09:22 Re: Revise the Asserts added to bimapset manipulation functions David Rowley <[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