Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1uB08f-0057Bv-EI for pgsql-performance@arkaria.postgresql.org; Fri, 02 May 2025 23:49:53 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1uB08d-00CMkk-Cy for pgsql-performance@arkaria.postgresql.org; Fri, 02 May 2025 23:49:52 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1uB08d-00CMkW-1A for pgsql-performance@lists.postgresql.org; Fri, 02 May 2025 23:49:52 +0000 Received: from mail-lf1-x144.google.com ([2a00:1450:4864:20::144]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1uB08b-000lUO-2d for pgsql-performance@lists.postgresql.org; Fri, 02 May 2025 23:49:50 +0000 Received: by mail-lf1-x144.google.com with SMTP id 2adb3069b0e04-549967c72bcso2869637e87.3 for ; Fri, 02 May 2025 16:49:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1746229788; x=1746834588; darn=lists.postgresql.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=hKG3rEEp7ey1/DIX7Z4xm4O1XWyjrzd6oU9Y81JAsvw=; b=cN1l2ZsNIRU7eNymr96umAhQXuNlh44lh4X3xaiQHXUQwd8kI/27c9Ax+yt4cIqqNr RL87A32v6IuyBd9HcFyU3UfHRHZVRXZUeNsjc7vQnFEfmDMs0ErYpU3GyzqWYZ0oNokK S/7SoswwNWz9hIwSsebvsaXJdnZJ0wDeAK5HEOTeXUwoiv/X5wLRRrkmA00kYveiMlOy tHwIiDjFEPDvMJv0f3OXZ4zd7NUMPM+9zW1oDaUM0FC/CNfsBMQOESlhz38DOABSDy0O iFCjWXaQ+FoMW02a+XrovcmrP56k8t5r/0hc1DaZcv4uf0Dt7bgXdZEYdN6Drw+hmeC5 4Y0w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746229788; x=1746834588; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=hKG3rEEp7ey1/DIX7Z4xm4O1XWyjrzd6oU9Y81JAsvw=; b=U8W3u2WwFRpkbjL+FuI1izs8z4rtSTtFOZ5ChYn3jgsystUbnFZJk86A9c8Kb37zGQ WLUkumrBOeF4iBe8Pa3E316PguXvsVozN+FSYzLUZRKU7QAXwNo2KDUQUqS78iHtsuKD 0clN9gRhLnIBLrvshGfBXH41AFHL7mLfIjza3nvI6CAcRo8GQkG/0YFFjNtlmsYU4AkN Sjmyos9evOOQI/aKuhOYQ+mZ0A677kW9iRGbPZDwWPzI9b/VM+yGFp5iaoAgdutFuAkf UHB34WR6rK+ZTL1lHBnQeBWvgNAEDkNiUoFwdnMrX/k+RydA3zXSS4X7lhT2vu/0yX/k BMMQ== X-Gm-Message-State: AOJu0YweB+36SaJvpm6QXQC0pSZWTVu0taRiO/KremTiSiVbF/LnX6ln mwAaf2ZPssNqj8cK9t/cadX9sOTys22a8WOgUBK5gFP7nK/8f4rlDVXDXiX11hEWGFkJfhgAnEN Yxu6z08sqnS1Y1OA++BmJbJIpCEo= X-Gm-Gg: ASbGncvz42mfTrOx73OdUkETInSqCMDr+19WYxwosvUzYkPiPTCmSz+uZ3fJcD8kGJ0 Jdm7iPYqfWD53AyzoreNn+X7NymkdyW0JAGSK9fEM4ZaBVuoKe3fjQmYOSRF3oYs58St/bv1RI1 1RIEoCjBZ/8GEUMPCyaQ3yVQ== X-Google-Smtp-Source: AGHT+IFRgcjdVwtc8Ykzb1VqJ4hTVAac7sgLoocAab83D4SFzVzy6ouRmNYha2ry+YNqdgr63k5BH4r/OcrpLZHhdhA= X-Received: by 2002:a05:6512:2c86:b0:54c:a49:d3de with SMTP id 2adb3069b0e04-54eac1f0ab3mr1484632e87.10.1746229788079; Fri, 02 May 2025 16:49:48 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: John Naylor Date: Sat, 3 May 2025 06:49:37 +0700 X-Gm-Features: ATxdqUEVC-vEtjHOYvw2yiVWRK9hKmOlivawDXZLHRiX21n4cFz9_d6TszH3VTs Message-ID: Subject: Re: Vacuum Questions To: Leo Cc: pgsql-performance@lists.postgresql.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Fri, May 2, 2025 at 9:23=E2=80=AFPM Leo wrote: > I am purging old records from a table (500 million rows, but I am doing i= t in sets of 50,000,000 with a smaller loop of 100,000). That works just = fine. > > Because of the amount of data/rows deleted, I disabled the autovacuum for= this table (I want to have control over vacuum, autovacuum does not comple= te anyway due to the timeout, sizing, etc settings that I do not want to ch= ange system wide). I will put the autovacuum back once I am done of course= . > > The issue is when I start vacuuming. This table has 4 indexes and a PK t= hat I worry about. The PK takes about 30 minutes to vacuum and two of the = indexes take about an hour each. The problem comes in for the other 2 inde= xes - they take 12+ hours each to vacuum: Do you know offhand anything special about these two? Do they have a random key like UUID or a hash calculation? That can make index vacuuming slower, but 12x still seems abnormal to me. > I've increased max_parallel_maintenance_workers to 8 for the session and = it used parallel 4 (one for each index I assume) to handle it and the two i= ndexes were done in ~ an hour. Right, one worker scans one index, simultaneously with other workers. Here the leader process launched 4 workers and also vacuumed one index itself. > What I am trying to figure out is how to force the other two large indexe= s to be vacuumed in parallel - a few workers going against an index. It se= ems it is possible to do, the index size is large enough to kick in, but I = have not been able to figure it out yet. Most of the parameters are at def= ault values. It is not possible to run multiple workers on a single index. > I have a few other questions. Does vacuum time depend on the number of d= ead rows only and the size of the table, or does the entire storage allocat= ion (including dead tuples) also affect it? The vacuum time depends largely on 1) The number of heap (=3Dtable) and index pages that are written to by vacuum, since that correlates with WAL volume -- the DELETE query will affect how the partial deletes are spread across the table. You only want to delete records once for each page. 2) The number and size of the indexes, since they must be scanned in their entirety 3) The storage allocation -- What version is this and what is maintenance_work_mem set to? This affects how many times each index must be vacuumed. > Would it be more beneficial to drop the two large indexes, purge, vacuum,= and recreate the indexes after make more sense (I know it needs to be test= ed)? The reason I am doing it in stages is to make sure I have enough time= to vacuum, but maybe it would not take much longer to vacuum after the com= plete purge? Could you explain your operational constraints? In my experience, WAL volume has been a more pressing concern for clients in these cases than elapsed time, but your needs may vary. One possible concern is that the indexes that take a long time to vacuum may also take a long time to recreate. Aside from that, dropping and recreating indexes may be good way to speed this up, depending on how critical they are for queries. > Lastly, is it better to delete all the rows (500 mil) instead of doing it= in smaller batches, and vacuum only once? On PG16 and earlier, this would still require each index to be vacuumed 3 times due to memory allocation constraints, so would be similar to 3 batches. The drop/recreate strategy would still help in that case. > The current size of the table is about 1T and the indexes add another 1.5= T to it. > > Truncate is not an option as I am only deleting rows older than 6 months.= Client was not doing purging for years, but will do it after the clean up= . What percentage of the table does the 500 million deletes represent? If you're deleting the vast majority of the records and have the extra disk space to spare, you might consider VACUUM FULL after completing the deletes -- that would rewrite the table and recreate all indexes. That's not generally recommended, since that locks the table for the entire duration and has other disadvantages, but it is an option. For your follow-up question: > Also, is there a way to estimate the vacuum execution? Something like ex= plain plan - without actually vacuuming, just to see how it will perform it= - like a degree of parallelism? There is no way to ask the system to estimate the runtime or other resource usage. Also for future reference, please note that we discourage top-posting (quoting an entire message in a reply). -- John Naylor Amazon Web Services