aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/analyze.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index 9498546f8c3..9581c2c0287 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -1124,20 +1124,35 @@ acquire_sample_rows(Relation onerel, int elevel,
case HEAPTUPLE_DELETE_IN_PROGRESS:
/*
- * We count delete-in-progress rows as still live, using
- * the same reasoning given above; but we don't bother to
- * include them in the sample.
+ * We count and sample delete-in-progress rows the same as
+ * live ones, so that the stats counters come out right if
+ * the deleting transaction commits after us, per the same
+ * reasoning given above.
*
* If the delete was done by our own transaction, however,
* we must count the row as dead to make
* pgstat_report_analyze's stats adjustments come out
* right. (Note: this works out properly when the row was
* both inserted and deleted in our xact.)
+ *
+ * The net effect of these choices is that we act as
+ * though an IN_PROGRESS transaction hasn't happened yet,
+ * except if it is our own transaction, which we assume
+ * has happened.
+ *
+ * This approach ensures that we behave sanely if we see
+ * both the pre-image and post-image rows for a row being
+ * updated by a concurrent transaction: we will sample the
+ * pre-image but not the post-image. We also get sane
+ * results if the concurrent transaction never commits.
*/
if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetUpdateXid(targtuple.t_data)))
deadrows += 1;
else
+ {
+ sample_it = true;
liverows += 1;
+ }
break;
default: