Reject incompatible options specified with VACUUM ONLY_DATABASE_STATS

From: Chao Li <li(dot)evan(dot)chao(at)gmail(dot)com>
To: PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Reject incompatible options specified with VACUUM ONLY_DATABASE_STATS
Date: 2026-10-22 06:23:52
Message-ID: 466138D9-580D-4C7B-B614-3382AB093533@gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

The VACUUM option ONLY_DATABASE_STATS can only be used with VERBOSE. Other options should be rejected, as the documentation describes:
```
<term><literal>ONLY_DATABASE_STATS</literal></term>
<listitem>
<para>
Specifies that <command>VACUUM</command> should do nothing except
update the database-wide statistics about oldest unfrozen XIDs.
When this option is specified,
the <replaceable class="parameter">table_and_columns</replaceable>
list must be empty, and no other option may be enabled
except <literal>VERBOSE</literal>.
</para>
```

When ONLY_DATABASE_STATS is enabled, no other option except VERBOSE may be enabled. But the current implementation does not check all options, for example:
```
evantest=# vacuum (ONLY_DATABASE_STATS, SKIP_LOCKED);
ERROR: ONLY_DATABASE_STATS cannot be specified with other VACUUM options
evantest=# vacuum (ONLY_DATABASE_STATS, PARALLEL 1);
VACUUM
```

With SKIP_LOCKED, the command fails as expected, while with PARALLEL 1 the command succeeds, which doesn't follow the doc and may confuse users.

In the fix, I considered whether rejection should be based on presence or value. VACUUM itself uses both approaches. When FULL rejects BUFFER_USAGE_LIMIT, the check is presence based:
```
evantest=# vacuum (FULL, BUFFER_USAGE_LIMIT 0);
ERROR: BUFFER_USAGE_LIMIT cannot be specified for VACUUM FULL
```

When FULL rejects PARALLEL, the check is value based:
```
evantest=# vacuum (FULL, PARALLEL 0);
VACUUM
evantest=# vacuum (FULL, PARALLEL 1);
ERROR: VACUUM FULL cannot be performed in parallel
```

I chose the presence based approach because in the PARALLEL case, the error specifically states that VACUUM FULL cannot be performed in parallel. In contrast, the ONLY_DATABASE_STATS error generically states that it cannot be specified with other VACUUM options, which is closer to when FULL rejects BUFFER_USAGE_LIMIT. Accordingly, I also updated the doc by replacing “enabled” with “specified".

See attached patch for the fix details.

Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/

Attachment Content-Type Size
v1-0001-Reject-incompatible-options-specified-with-VACUUM.patch application/octet-stream 9.6 KB

Browse pgsql-hackers by date

  From Date Subject
Next Message Hayato Kuroda (Fujitsu) 2026-10-22 06:52:59 RE: [PG19] Promotion hangs behind a backend blocked on a stuck client
Previous Message shveta malik 2026-10-22 06:23:51 Re: [PG19] Promotion hangs behind a backend blocked on a stuck client