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 1ukJTK-000rgr-S9 for pgsql-hackers@arkaria.postgresql.org; Fri, 08 Aug 2025 09:33:11 +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 1ukJTJ-00CISj-GB for pgsql-hackers@arkaria.postgresql.org; Fri, 08 Aug 2025 09:33:09 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1ukJTJ-00CISZ-34 for pgsql-hackers@lists.postgresql.org; Fri, 08 Aug 2025 09:33:09 +0000 Received: from mail-vk1-xa2c.google.com ([2607:f8b0:4864:20::a2c]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1ukJTG-001PyZ-2T for pgsql-hackers@postgresql.org; Fri, 08 Aug 2025 09:33:08 +0000 Received: by mail-vk1-xa2c.google.com with SMTP id 71dfb90a1353d-539345ebfc8so567128e0c.2 for ; Fri, 08 Aug 2025 02:33:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1754645585; x=1755250385; darn=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=PdF1pxKTF13UAo2LcoF41UcUjrSQLo1/iMFec3H7lJQ=; b=b4KMts2xr+k3TvIXornHu9WYzWof6M0eXuJ/HhJJvuDZqZ4y/DTKsO05RLV7RdorfA y4K+q/2BqYTUb17pu5/j1jQrQaN8e6OM4vZU6PgHDHQPOFgWGCpPwEgYLcsaxmH+fP2f iofb7eujhwEFR+37nb8WyaiCwBiLEYQXtIG48hzXsakVWQPg/ItyWCr0+6Hkbww9SaMm W1diDqVtWJSJA6JXxD7IUmHHWXQ4DrU0oDM82udTEmxR6lJ009/E30dpab7Xfrr4PYp1 ZZw/gfhL/8lXHcvnM3jQ1+A7PbPVOMrsDFmB9javGZ3J6zwS11VyT9nQmDLX2P2mlC5g L4Jg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754645585; x=1755250385; 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=PdF1pxKTF13UAo2LcoF41UcUjrSQLo1/iMFec3H7lJQ=; b=LqIpJe4JWZOWJbnu0gWmuxbB6X3oKRK8cqcuJdz8bU6ZN4qZQWgOAsgzm/eROLYlXC cOCNUds7juDpyCLfawfFIh99GNJW/+ufou7ACyUWygK8HRajZVXTEHcTqrAxp0uNXOkt dlOzAhfietxDcuI+OFmSSz+GOi1jJN/59r15D3hkZhpxzaAorU4le7zPdw3Da64eHnlC xDkbB5A5koXqInbcVbrfST0DpX5KPOuyPAgZO9rp1nQ8wQ/2DFUaZh9CwJmy0kqIcV9w RzmGzFp5J51KECxjmv4JV0n1jIlXKmhTYWjZjSSafUO3OjDG/K9wHcpP74fxAIjeDUpo E1Yw== X-Forwarded-Encrypted: i=1; AJvYcCWoo2vAa6ZIXxsNFJqV7TwVfemezQQp80FfE9uBBK+xIlplcDZGovbvmvbQXuvsNjANwL5v1eSk+yhkb3b0@postgresql.org X-Gm-Message-State: AOJu0YwT6Faeas8v6CcGAbChUbew6v0eoJ3iTdcWLYHeaSLruEDI+IPm TgSXARfJ3R1bDJnA7rE12LIRO7kLSdeS+cE7mWPZjNp5u2q5fjUASJXEnH+SBOkUoknfMiTqEoc YJBTZ3mPaOgMa30Gg7SHiD6XtOoLwI+M= X-Gm-Gg: ASbGncs8D9PTuzsMT93kLAN9QxHuegTicoFCPN1Y31mGSst1jKtDBpnCGycJt0Mv+CB iWiYO5AN2bPjc8ERiQCJ/3Y8uTIGachUSuIGkJBxw5jHPNX3lA+0zkN1PS86LaW4YjpYeVCpZD2 /v4UIM3xO4C4MK7Q6USQ2TgB3IJXXvSUWKI/XyH2LmkvZcGrHASaomVUN0XSxSpy1sNXpZWxN4L jMSWYw= X-Google-Smtp-Source: AGHT+IFW6OFn8dZLn6bW17F0/oO3Q7hefywmMZeYBw1abuf9GnfTGe63Q/geeh+YB0mvKSZDNg1wH0J80kYYzx5iQ8Q= X-Received: by 2002:a05:6122:a23:b0:534:7f57:8e25 with SMTP id 71dfb90a1353d-53a52d7133emr730617e0c.1.1754645584952; Fri, 08 Aug 2025 02:33:04 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Ashutosh Bapat Date: Fri, 8 Aug 2025 15:02:53 +0530 X-Gm-Features: Ac12FXwDjHh7Svo4U_vm-Ysxwsj2TqhSVuEbP02kAUc5mED9UDPWp5dLIGlCAZY Message-ID: Subject: Re: [Proposal] Expose internal MultiXact member count function for efficient monitoring To: Naga Appani Cc: Michael Paquier , Kirill Reshke , pgsql-hackers@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 Mon, Aug 4, 2025 at 11:46=E2=80=AFAM Naga Appani wro= te: > > In PG14+, the transaction wraparound is triggered if the size of the > > directory exceeds 10GB. This function does not help monitoring that > > condition. So a user will need to use du or pg_ls_multixactdir() > > anyway, which defeats the purpose of this function being more > > efficient than those methods. Am I correct? Can we also report the > > size of the directory in this function? > > Correct, that is the intent of the function. The members count > returned by this function already provides the necessary information > to determine the directory size, since each member entry has a fixed > size. The constants and formulas in [0] and discussed in [1] show that > each group stores four bytes of flags plus four TransactionIds (20 > bytes total), yielding 409 groups per 8=E2=80=AFKB page and a fixed > members=E2=80=91to=E2=80=91bytes ratio. This means ~2=E2=80=AFbillion mem= bers corresponds to > ~10=E2=80=AFGB (aggressive autovacuum threshold) and ~4=E2=80=AFbillion m= embers > corresponds to ~20=E2=80=AFGB (wraparound). Would it be better to do that math in the function and output the result? Users may not be able to read and understand the PostgreSQL code or pgsql-hackers threads Or the constants may change across versions. It will be more convenient for users if they get the output from the function itself. On Fri, Aug 8, 2025 at 6:05=E2=80=AFAM Michael Paquier wrote: > > ReadMultiXactCounts() is also incorrectly named with your proposal to > expose oldestMultiXactId in the information returned to the caller, > where the key point is to make sure that the information retrieved is > consistent across a single LWLock acquisition. So perhaps this should > be named GetMultiXactInformation() or something similar? +1 > > The top of ReadMultiXactCounts() (or whatever its new name) should > also document the information returned across a single call. It looks > inconsistent to return oldestMultiXactId if the oldestOffsetKnown is > false. What about oldestOffset itself? Should it be returned for > consistency with the counts and oldestMultiXactId? +1 Some more comments on the patch + multixacts is the number of multixact IDs assigned, + members is the number of multixact member entries crea= ted, + and oldest_multixact is the oldest MultiXact ID still in use. Now that the name of the function is changed, we need the names to indicate that they are counts e.g. num_mxids, num_members. + These values can be used to monitor multixact consumption and anticipate + autovacuum behavior. See + for further details on multixact wraparound. + + + + SELECT * FROM pg_get_multixact_stats(); + + multixacts | members | oldest_multixact +------------+-------------+------------------ + 182371396 | 2826221174 | 754321 + This file doesn't provide usage examples of other functions. This function doesn't seem to be an exception. I think we should mention that the statistics may get stale as soon as it's fetched, even with REPEATABLE READ isolation level. + linkend=3D"guc-autovacuum-multixact-freeze-max-age"/>. Also, if either + the storage occupied by multixact members exceeds about 10GB or the numbe= r + of members created exceeds approximately 2 billion entries, aggressive va= cuum In case each member starts consuming more or less space than it does today what would be the basis of triggering workaround? Space or number of members? I think we should mention only that. scans will occur more often for all tables, starting with those that - have the oldest multixact-age. Both of these kinds of aggressive + have the oldest multixact-age. Both of these kinds of aggressive scans will occur even if autovacuum is nominally disabled. The members stor= age - area can grow up to about 20GB before reaching wraparound. + area can grow up to about 20GB or approximately 4 billion entries before + reaching wraparound. Similar to above. + + + + The pg_get_multixact_stats() function provides a way + to monitor multixact allocation and usage patterns in real time. By expos= ing This is the right place to elaborate the usage of this function with an exa= mple. + counts of multixacts, member entries, and the oldest multixact ID, it hel= ps: + + + + Identify unusual multixact activity from concurrent row-level locks + or foreign key operations + + + + + Monitor progress toward wraparound thresholds that trigger aggressive + autovacuum (approximately 2 billion members or 10GB storage) + + + + + Verify whether autovacuum is effectively managing multixact cleanup + before reaching critical thresholds + + + + See for details. I think the second point here repeats what's already mentioned earlier. It will be good to elaborate each point with an example instead of just narration. +/* + * pg_get_multixact_stats + * + * SQL-callable function to retrieve MultiXact statistics. + * + * Returns a composite row containing: + * - total number of MultiXact IDs created since startup, + * - total number of MultiXact members created, ... since startup or the number of existing members? + * - the oldest existing MultiXact ID. + * + * This is primarily useful for monitoring MultiXact usage and ensuring + * appropriate wraparound protection. The last two lines are not required, I think. One of its usage is monitoring but users may find other usages. + +step commit1: COMMIT; +step commit2: COMMIT; +step check: + SELECT + multixacts, + members, + oldest_multixact + FROM pg_get_multixact_stats(); + +multixacts|members|oldest_multixact +----------+-------+---------------- + 1| 3| 1 +(1 row) Vacuum may clean the multixact between commit2 and check, in which case the result won't be stable. --=20 Best Wishes, Ashutosh Bapat