Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1ivifV-0005zM-9q for pgsql-hackers@arkaria.postgresql.org; Sun, 26 Jan 2020 14:13:41 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1ivifR-0000Fw-W8 for pgsql-hackers@arkaria.postgresql.org; Sun, 26 Jan 2020 14:13:37 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1ivifR-0000Fp-Hq for pgsql-hackers@lists.postgresql.org; Sun, 26 Jan 2020 14:13:37 +0000 Received: from mail-yb1-xb30.google.com ([2607:f8b0:4864:20::b30]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1ivifN-00032f-8K for pgsql-hackers@postgresql.org; Sun, 26 Jan 2020 14:13:36 +0000 Received: by mail-yb1-xb30.google.com with SMTP id z125so1535055ybf.9 for ; Sun, 26 Jan 2020 06:13:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=telsasoft-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:mime-version:content-disposition :user-agent; bh=qHaLRXOJVSHrs3oFFSMTnfzQlNehKlFbkK/CGoN34tI=; b=Le7TM3CVNUeZvwG7WmJ40YD9L8nqEvK/pLiOYoDQ5RoHusCC/auJEfHKz2in9xRvtp WdbK+QXDfmUHE9urBrDwfyOnovMd1eedHxoqetreaTmm4CoiUHQ1avGm+Q5mBRSOfIcZ 18vB9XzBXD6Qr/rr1p2/mMFbOBWoXGtrdE+s/OILbnM8Zgk4/x26Zl82mjVp+5Y4CV0R nXXp0qeaLWrtusfEJLs1TtV+qiun1rLEQs70++JrW0G8AuLlUzSMKIpaiU03cNvQbDg9 NSrZHGRF61Z1lygNSaMpvC8tDecCpKYkK4t1UBOWRiXa1w/iZFSAOKmZY4O0VTI6VTX6 OxLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:mime-version :content-disposition:user-agent; bh=qHaLRXOJVSHrs3oFFSMTnfzQlNehKlFbkK/CGoN34tI=; b=Tg+4GBQCjsAYjYnE64VTqWa1M/MnUhGhlmABMjHWm9rXRF00RSK+CL8/KiIoo9qbIy JOuCGT6NuenfeRslTuqIY9lfQ2KWJnzA/9tQLAFYOoYPsqYL+wFLy9ULl8bH2/5DTBMC McX1l847HtCjSP5OMnLNz+DnuBWiZiEN02PcwRqGWoj4Eycmf7HunXp3oZobUlfp6070 pqncWb2feGKxS07xst05v3dvy5xYp+5LLSplCkrWLDGG1j39j2kxVqU/O5LhO41STAlt 8mMJv/vcl0QVkn/Gkj/of5aEO83eZHYQ0d07elGctQLLCuoEo4BN8EH9lJs8Ws3niDU9 b7Mw== X-Gm-Message-State: APjAAAWNHKNtkqq+NzSB4eKxHRXKV7cbw5w/+uw4C8R0uDW4cc7BAI0g +4/CuydnXTG+l6h/P4Jf8IhEAQ== X-Google-Smtp-Source: APXvYqwsWL5HlT0DLVgwHwVLJzCwSdV/SPGPwA3nBPa4ndr3FB5lH05HDFv9lXqyJZWQGC9PrM9BYg== X-Received: by 2002:a25:ac88:: with SMTP id x8mr9070577ybi.464.1580048010796; Sun, 26 Jan 2020 06:13:30 -0800 (PST) Received: from pryzbyj (charmander.telsasoft.com. [50.244.222.1]) by smtp.gmail.com with ESMTPSA id e21sm4999512ywa.94.2020.01.26.06.13.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 26 Jan 2020 06:13:29 -0800 (PST) Received: by pryzbyj (Postfix, from userid 1000) id 68D3F800831; Sun, 26 Jan 2020 08:13:28 -0600 (CST) Date: Sun, 26 Jan 2020 08:13:28 -0600 From: Justin Pryzby To: Jeff Janes Cc: pgsql-hackers@postgresql.org Subject: vacuum verbose: show pages marked allvisible/frozen/hintbits Message-ID: <20200126141328.GP13621@telsasoft.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="pP0ycGQONqsnqIMP" Content-Disposition: inline User-Agent: Mutt/1.5.24 (2015-08-30) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --pP0ycGQONqsnqIMP Content-Type: text/plain; charset=us-ascii Content-Disposition: inline I'm forking this thread since it's separate topic, and since keeping in a single branch hasn't made maintaining the patches any easier. https://www.postgresql.org/message-id/CAMkU%3D1xAyWnwnLGORBOD%3Dpyv%3DccEkDi%3DwKeyhwF%3DgtB7QxLBwQ%40mail.gmail.com On Sun, Dec 29, 2019 at 01:15:24PM -0500, Jeff Janes wrote: > Also, I'd appreciate a report on how many hint-bits were set, and how many > pages were marked all-visible and/or frozen. When I do a manual vacuum, it > is more often for those purposes than it is for removing removable rows > (which autovac generally does a good enough job of). The first patch seems simple enough but the 2nd could use critical review. --pP0ycGQONqsnqIMP Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v1-0001-Report-number-of-pages-marked-allvisible-frozen.patch" From 57eede7d1158904d6b66532c7d0ce6a59803210f Mon Sep 17 00:00:00 2001 From: Justin Pryzby Date: Sun, 29 Dec 2019 14:56:02 -0600 Subject: [PATCH v1 1/2] Report number of pages marked allvisible/frozen.. ..as requested by Jeff Janes --- src/backend/access/heap/vacuumlazy.c | 37 ++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 8ce5011..9975699 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -283,7 +283,9 @@ typedef struct LVRelStats double new_rel_tuples; /* new estimated total # of tuples */ double new_live_tuples; /* new estimated total # of live tuples */ double new_dead_tuples; /* new estimated total # of dead tuples */ - BlockNumber pages_removed; + BlockNumber pages_removed; /* Due to truncation */ + BlockNumber pages_allvisible; + BlockNumber pages_frozen; double tuples_deleted; BlockNumber nonempty_pages; /* actually, last nonempty page + 1 */ LVDeadTuples *dead_tuples; @@ -602,11 +604,13 @@ heap_vacuum_rel(Relation onerel, VacuumParams *params, get_namespace_name(RelationGetNamespace(onerel)), RelationGetRelationName(onerel), vacrelstats->num_index_scans); - appendStringInfo(&buf, _("pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen\n"), + appendStringInfo(&buf, _("pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen, %u marked all visible, %u marked frozen\n"), vacrelstats->pages_removed, vacrelstats->rel_pages, vacrelstats->pinskipped_pages, - vacrelstats->frozenskipped_pages); + vacrelstats->frozenskipped_pages, + vacrelstats->pages_allvisible, + vacrelstats->pages_frozen); appendStringInfo(&buf, _("tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable, oldest xmin: %u\n"), vacrelstats->tuples_deleted, @@ -751,6 +755,9 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, vacrelstats->scanned_pages = 0; vacrelstats->tupcount_pages = 0; vacrelstats->nonempty_pages = 0; + vacrelstats->pages_allvisible = 0; + vacrelstats->pages_frozen = 0; + vacrelstats->latestRemovedXid = InvalidTransactionId; /* @@ -1170,6 +1177,8 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, visibilitymap_set(onerel, blkno, buf, InvalidXLogRecPtr, vmbuffer, InvalidTransactionId, VISIBILITYMAP_ALL_VISIBLE | VISIBILITYMAP_ALL_FROZEN); + vacrelstats->pages_allvisible++; + vacrelstats->pages_frozen++; END_CRIT_SECTION(); } @@ -1501,8 +1510,12 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, { uint8 flags = VISIBILITYMAP_ALL_VISIBLE; - if (all_frozen) + if (all_frozen) { flags |= VISIBILITYMAP_ALL_FROZEN; + vacrelstats->pages_frozen++; + } + + vacrelstats->pages_allvisible++; /* * It should never be the case that the visibility map page is set @@ -1690,6 +1703,14 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, "%u pages are entirely empty.\n", empty_pages), empty_pages); + appendStringInfo(&buf, ngettext("Marked %u page all visible, ", + "Marked %u pages all visible, ", + vacrelstats->pages_allvisible), + vacrelstats->pages_allvisible); + appendStringInfo(&buf, ngettext("%u page frozen.\n", + "%u pages frozen.\n", + vacrelstats->pages_frozen), + vacrelstats->pages_frozen); appendStringInfo(&buf, _("%s."), pg_rusage_show(&ru0)); ereport(elevel, @@ -1912,10 +1933,14 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer, uint8 flags = 0; /* Set the VM all-frozen bit to flag, if needed */ - if ((vm_status & VISIBILITYMAP_ALL_VISIBLE) == 0) + if ((vm_status & VISIBILITYMAP_ALL_VISIBLE) == 0) { flags |= VISIBILITYMAP_ALL_VISIBLE; - if ((vm_status & VISIBILITYMAP_ALL_FROZEN) == 0 && all_frozen) + vacrelstats->pages_allvisible++; + } + if ((vm_status & VISIBILITYMAP_ALL_FROZEN) == 0 && all_frozen) { flags |= VISIBILITYMAP_ALL_FROZEN; + vacrelstats->pages_frozen++; + } Assert(BufferIsValid(*vmbuffer)); if (flags != 0) -- 2.7.4 --pP0ycGQONqsnqIMP Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v1-0002-Report-number-of-hint-bits-written.patch" From 494893c39711693e05e8b108ad863b7ee12d91d1 Mon Sep 17 00:00:00 2001 From: Justin Pryzby Date: Sun, 29 Dec 2019 16:02:50 -0600 Subject: [PATCH v1 2/2] Report number of hint bits written.. ..as requested by Jeff Janes --- src/backend/access/heap/vacuumlazy.c | 39 +++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 9975699..8cea0d6 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -287,6 +287,7 @@ typedef struct LVRelStats BlockNumber pages_allvisible; BlockNumber pages_frozen; double tuples_deleted; + double hintbit_tuples; BlockNumber nonempty_pages; /* actually, last nonempty page + 1 */ LVDeadTuples *dead_tuples; int num_index_scans; @@ -612,11 +613,12 @@ heap_vacuum_rel(Relation onerel, VacuumParams *params, vacrelstats->pages_allvisible, vacrelstats->pages_frozen); appendStringInfo(&buf, - _("tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable, oldest xmin: %u\n"), + _("tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable, oldest xmin: %u, wrote %.0f hint bits\n"), vacrelstats->tuples_deleted, vacrelstats->new_rel_tuples, vacrelstats->new_dead_tuples, - OldestXmin); + OldestXmin, + vacrelstats->hintbit_tuples); appendStringInfo(&buf, _("buffer usage: %d hits, %d misses, %d dirtied\n"), VacuumPageHit, @@ -1188,14 +1190,6 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, } /* - * Prune all HOT-update chains in this page. - * - * We count tuples removed by the pruning step as removed by VACUUM. - */ - tups_vacuumed += heap_page_prune(onerel, buf, OldestXmin, false, - &vacrelstats->latestRemovedXid); - - /* * Now scan the page to collect vacuumable items and check for tuples * requiring freezing. */ @@ -1215,6 +1209,8 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, offnum = OffsetNumberNext(offnum)) { ItemId itemid; + HTSV_Result satisfies; + int oldmask; itemid = PageGetItemId(page, offnum); @@ -1266,7 +1262,12 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, * cases impossible (e.g. in-progress insert from the same * transaction). */ - switch (HeapTupleSatisfiesVacuum(&tuple, OldestXmin, buf)) + oldmask = tuple.t_data->t_infomask; + satisfies = HeapTupleSatisfiesVacuum(&tuple, OldestXmin, buf); +#define HINT_FLAGS (HEAP_XMIN_COMMITTED|HEAP_XMIN_INVALID|HEAP_XMAX_COMMITTED|HEAP_XMAX_INVALID) + if ((oldmask&HINT_FLAGS) != (tuple.t_data->t_infomask&HINT_FLAGS)) + vacrelstats->hintbit_tuples++; + switch (satisfies) { case HEAPTUPLE_DEAD: @@ -1405,7 +1406,9 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, * Each non-removable tuple must be checked to see if it needs * freezing. Note we already have exclusive buffer lock. */ - if (heap_prepare_freeze_tuple(tuple.t_data, + // Avoid freezing HEAPTUPLE_DEAD, as required + if (satisfies!=HEAPTUPLE_DEAD && + heap_prepare_freeze_tuple(tuple.t_data, relfrozenxid, relminmxid, FreezeLimit, MultiXactCutoff, &frozen[nfrozen], @@ -1418,6 +1421,14 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, } /* scan along page */ /* + * Prune all HOT-update chains in this page. + * + * We count tuples removed by the pruning step as removed by VACUUM. + */ + tups_vacuumed += heap_page_prune(onerel, buf, OldestXmin, false, + &vacrelstats->latestRemovedXid); + + /* * If we froze any tuples, mark the buffer dirty, and write a WAL * record recording the changes. We must log the changes to be * crash-safe against future truncation of CLOG. @@ -1711,6 +1722,10 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, "%u pages frozen.\n", vacrelstats->pages_frozen), vacrelstats->pages_frozen); + appendStringInfo(&buf, ngettext("Wrote %.0f hint bit.\n", + "Wrote %.0f hint bits.\n", + vacrelstats->hintbit_tuples), + vacrelstats->hintbit_tuples); appendStringInfo(&buf, _("%s."), pg_rusage_show(&ru0)); ereport(elevel, -- 2.7.4 --pP0ycGQONqsnqIMP--