Fix memory corruption/crash in ANALYZE.
This fixes an embarrassing oversight I (Andres) made in 737a292b
,
namely missing two place where liverows/deadrows were used when
converting those variables to pointers, leading to incrementing the
pointer, rather than the value.
It's not that actually that easy to trigger a crash: One needs tuples
deleted by the current transaction, followed by a tuple deleted in
another session, all in one page. Which is presumably why this hasn't
been noticed before.
Reported-By: Steve Singer
Author: Steve Singer
Discussion: https://postgr.es/m/c7988239-d42c-ddc4-41db-171b23b35e4f@ssinger.info
This commit is contained in:
parent
8b21b416ed
commit
23224563d9
|
@ -1113,11 +1113,11 @@ heapam_scan_analyze_next_tuple(TableScanDesc scan, TransactionId OldestXmin,
|
||||||
* concurrent transaction never commits.
|
* concurrent transaction never commits.
|
||||||
*/
|
*/
|
||||||
if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetUpdateXid(targtuple->t_data)))
|
if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetUpdateXid(targtuple->t_data)))
|
||||||
deadrows += 1;
|
*deadrows += 1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sample_it = true;
|
sample_it = true;
|
||||||
liverows += 1;
|
*liverows += 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,18 @@ ANALYZE vaccluster;
|
||||||
ERROR: ANALYZE cannot be executed from VACUUM or ANALYZE
|
ERROR: ANALYZE cannot be executed from VACUUM or ANALYZE
|
||||||
CONTEXT: SQL function "do_analyze" statement 1
|
CONTEXT: SQL function "do_analyze" statement 1
|
||||||
SQL function "wrap_do_analyze" statement 1
|
SQL function "wrap_do_analyze" statement 1
|
||||||
|
-- Test ANALYZE in transaction, where the transaction surrounding
|
||||||
|
-- analyze performed modifications. This tests for the bug at
|
||||||
|
-- https://postgr.es/m/c7988239-d42c-ddc4-41db-171b23b35e4f%40ssinger.info
|
||||||
|
-- (which hopefully is unlikely to be reintroduced), but also seems
|
||||||
|
-- independently worthwhile to cover.
|
||||||
|
INSERT INTO vactst SELECT generate_series(1, 300);
|
||||||
|
DELETE FROM vactst WHERE i % 7 = 0; -- delete a few rows outside
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO vactst SELECT generate_series(301, 400);
|
||||||
|
DELETE FROM vactst WHERE i % 5 <> 0; -- delete a few rows inside
|
||||||
|
ANALYZE vactst;
|
||||||
|
COMMIT;
|
||||||
VACUUM FULL pg_am;
|
VACUUM FULL pg_am;
|
||||||
VACUUM FULL pg_class;
|
VACUUM FULL pg_class;
|
||||||
VACUUM FULL pg_database;
|
VACUUM FULL pg_database;
|
||||||
|
|
|
@ -54,6 +54,19 @@ CREATE INDEX ON vaccluster(wrap_do_analyze(i));
|
||||||
INSERT INTO vaccluster VALUES (1), (2);
|
INSERT INTO vaccluster VALUES (1), (2);
|
||||||
ANALYZE vaccluster;
|
ANALYZE vaccluster;
|
||||||
|
|
||||||
|
-- Test ANALYZE in transaction, where the transaction surrounding
|
||||||
|
-- analyze performed modifications. This tests for the bug at
|
||||||
|
-- https://postgr.es/m/c7988239-d42c-ddc4-41db-171b23b35e4f%40ssinger.info
|
||||||
|
-- (which hopefully is unlikely to be reintroduced), but also seems
|
||||||
|
-- independently worthwhile to cover.
|
||||||
|
INSERT INTO vactst SELECT generate_series(1, 300);
|
||||||
|
DELETE FROM vactst WHERE i % 7 = 0; -- delete a few rows outside
|
||||||
|
BEGIN;
|
||||||
|
INSERT INTO vactst SELECT generate_series(301, 400);
|
||||||
|
DELETE FROM vactst WHERE i % 5 <> 0; -- delete a few rows inside
|
||||||
|
ANALYZE vactst;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
VACUUM FULL pg_am;
|
VACUUM FULL pg_am;
|
||||||
VACUUM FULL pg_class;
|
VACUUM FULL pg_class;
|
||||||
VACUUM FULL pg_database;
|
VACUUM FULL pg_database;
|
||||||
|
|
Loading…
Reference in New Issue