Received: from localhost (unknown [200.46.204.183]) by developer.postgresql.org (Postfix) with ESMTP id 8A1F72E0039 for ; Tue, 10 Jun 2008 02:33:09 -0300 (ADT) Received: from developer.postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.183]) (amavisd-maia, port 10024) with ESMTP id 65521-07 for ; Tue, 10 Jun 2008 02:32:50 -0300 (ADT) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from yw-out-2324.google.com (yw-out-2324.google.com [74.125.46.29]) by developer.postgresql.org (Postfix) with ESMTP id 03DF72E0032 for ; Tue, 10 Jun 2008 02:32:49 -0300 (ADT) Received: by yw-out-2324.google.com with SMTP id 3so1392787ywj.73 for ; Mon, 09 Jun 2008 22:32:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from:to :subject:mime-version:content-type; bh=hAGCVCh2Q21onfaSgNVUookh2jppxgrjJyznoPuEacc=; b=OMn7StoCAdp3k+ch0cl66H5K+ixKnR8NVKcMetcbrYvrahylyifNrjQBcfs+dLHXbI ZE9fdN9cL0wMVrRrWiD/yFKJehPuiT9NnKk/8cu9fn+kE3onMX1Avh0KckWhwOgd/AkC JfJUaju7l5Tlxz8CNOh+sfrf6QJ+vXTDgEagI= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:to:subject:mime-version:content-type; b=NLmVAyesUPBIPY1Ke/FaC4RAC09op1V8FtSwuH6ngwkr7NUPPMCWcL6LahMYjlT+iY /J7EW9qBybm9e60ZB/gSIDYEBTucBoArft4vRWpmF7kmf6S8r0y2bXfR+CxpPZ0t/tuQ oT5dCPm1c7fNArckXxDgJzdvfZvHrTmfRl+EQ= Received: by 10.151.111.1 with SMTP id o1mr7735080ybm.189.1213075968760; Mon, 09 Jun 2008 22:32:48 -0700 (PDT) Received: by 10.151.84.7 with HTTP; Mon, 9 Jun 2008 22:32:48 -0700 (PDT) Message-ID: <2e78013d0806092232h6ca15ffejcbcd24e88401308f@mail.gmail.com> Date: Tue, 10 Jun 2008 11:02:48 +0530 From: "Pavan Deolasee" To: pgsql-patches Subject: VACUUM Improvements - WIP Patch MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_Part_27496_32134466.1213075968774" X-Virus-Scanned: Maia Mailguard 1.0.1 X-Archive-Number: 200806/60 X-Sequence-Number: 6546 ------=_Part_27496_32134466.1213075968774 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline Here is a WIP patch based on the discussions here: http://archives.postgresql.org/pgsql-hackers/2008-05/msg00863.php The attached WIP patch improves the LAZY VACUUM by limiting or avoiding the second heap scan. This not only saves considerable time in VACUUM, but also reduces the double-writes of vacuumed blocks. If the second heap scan is considerably limited, that should also save CPU usage and reduce WAL log writing. With HOT, the first heap scan prunes and defrags every page in the heap. That truncates all the dead tuples to their DEAD line pointers and releases all the free space in the page. The second scan only removes these DEAD line pointers and records the free space in the FSM. The free space in fact does not change from the first pass. But to do so, it again calls RepairPageFragmentation on each page, dirties the page and calls log_heap_clean() again on the page. This clearly looks like too much work for a small gain. As this patch stands, the first phase of vacuum prunes the heap pages as usual. But it marks the DEAD line pointers as DEAD_RECLAIMED to signal that the index pointers to these line pointers are being removed, if certain conditions are satisfied. Other backend when prunes a page, also reclaims DEAD_RECLAIMED line pointers by marking them UNUSED. We need some additional logic to do this in a safe way: - An additional boolean pg_class attribute (relvac_inprogress) is used to track the status of vacuum on a relation. If the attribute is true, either vacuum is in progress on the relation or the last vacuum did not complete successfully. When VACUUM starts, it sets relvac_inprogress to true. The transaction is committed and a new transaction is started so that all other backends can see the change. We also note down the transactions which may already have the table open. VACUUM then starts the first heap scan. It prunes the page, but it can start marking the DEAD line pointers as DEAD_RECLAIMED only after it knows that all other backends can see that VACUUM is in progress on the target relation. Otherwise there is a danger that backends might reclaim DEAD line pointers before their index pointers are removed and that would lead to index corruption. We do that by periodic conditional waits on the noted transactions ids. Once all old transactions are gone, VACUUM sets the second scan limit to the current block number and starts marking subsequent DEAD line pointers as DEAD_RECLAIMED. In most of the cases where the old transactions quickly go away, and for large tables, the second scan will be very limited. In the worst case, we might incur the overhead of conditional waits without any success. TODO: - We can potentially update FSM at the end of first pass. This is not a significant issue if the second scan is very limited. But if we do this, we need to handle the truncate case properly. - As the patch stands, we check of old transactions at every block iteration. This might not be acceptable for the cases where there are long running transactions. We probably need some exponential gap here. - As the patch stands, the heap_page_prune handles reclaiming the DEAD_RECLAIMED line pointers since it already has ability to WAL log similar changes. We don't do any extra work to trigger pruning though (except than setting page_prune_xid). May be we should trigger pruning if we got a line pointer bloat in a page too. Please let me know comments/suggestions and any other improvements. Thanks, Pavan -- Pavan Deolasee EnterpriseDB http://www.enterprisedb.com ------=_Part_27496_32134466.1213075968774 Content-Type: application/x-gzip; name=VACUUM_second_scan-v5.patch.gz Content-Transfer-Encoding: base64 X-Attachment-Id: f_fha22wpr0 Content-Disposition: attachment; filename=VACUUM_second_scan-v5.patch.gz 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 ------=_Part_27496_32134466.1213075968774--