Re: DataChecksumsStateStruct cost_delay fields and locking

From: Daniel Gustafsson <daniel(at)yesql(dot)se>
To: Heikki Linnakangas <hlinnaka(at)iki(dot)fi>
Cc: PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: DataChecksumsStateStruct cost_delay fields and locking
Date: 2026-06-17 13:04:59
Message-ID: 45CC0DA8-22D1-46E4-B093-AF3280E2852B@yesql.se
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

> On 17 Jun 2026, at 09:42, Heikki Linnakangas <hlinnaka(at)iki(dot)fi> wrote:
>
> Hi,
>
> The comment in the DataChecksumsStateStruct says:
>
>> /*
>> * These fields indicate the target state that the launcher is currently
>> * working towards. They can be different from the corresponding launch_*
>> * fields, if a new pg_enable/disable_data_checksums() call was made while
>> * the launcher/worker was already running.
>> *
>> * The below members are set when the launcher starts, and are only
>> * accessed read-only by the single worker. Thus, we can access these
>> * without a lock. If multiple workers, or dynamic cost parameters, are
>> * supported at some point then this would need to be revisited.
>> */
>> DataChecksumsWorkerOperation operation;
>> int cost_delay;
>> int cost_limit;
>
> The "only accessed read-only by the single worker" part isn't true, because DataChecksumsWorkerMain() does this:
>
>> /*
>> * Check if the cost settings changed during runtime and if so, update
>> * to reflect the new values and signal that the access strategy needs
>> * to be refreshed.
>> */
>> LWLockAcquire(DataChecksumsWorkerLock, LW_EXCLUSIVE);
>> if ((DataChecksumState->launch_cost_delay != DataChecksumState->cost_delay)
>> || (DataChecksumState->launch_cost_limit != DataChecksumState->cost_limit))
>> {
>> costs_updated = true;
>> VacuumCostDelay = DataChecksumState->launch_cost_delay;
>> VacuumCostLimit = DataChecksumState->launch_cost_limit;
>> VacuumUpdateCosts();
>> DataChecksumState->cost_delay = DataChecksumState->launch_cost_delay;
>> DataChecksumState->cost_limit = DataChecksumState->launch_cost_limit;
>> }
>> else
>> costs_updated = false;
>> LWLockRelease(DataChecksumsWorkerLock);
>
> So contrary to the comment, the cost_delay fields are updated by the worker.

Ugh, that comment was missed when I added the ability to update the cost params
during runtime.

> Some other observations:
>
> - at the beginning of DataChecksumsWorkerMain(), it reads DataChecksumState->cost_delay and cost_limit without holding the lock, and also DataChecksumState->process_shared_catalogs. I think that's OK, but I would just add locking to it, to remove all doubt.

Agreed, it should be wrapped in a lock even if it's (currently) safe.

> - the comment says "These fields indicate the target state that the launcher is currently working towards". It took me a moment to understand what the means. At first, I thought that it means that it's the target state of the launcher, but not necessarily what it's currently using. That's wrong. Those are in fact the values that the *worker* is *currently* using. launch_cost_delay/limit are the "target" values, which will eventually be copied into the current cost_delay/limit values. Perhaps change "... launcher is currently working towards" into "... worker is currently running with" or something like that.

Yes, that sentence was clearly a pretty strong wordsoup. Thanks for pointing
it out.

All comments addressed in the attached.

--
Daniel Gustafsson

Attachment Content-Type Size
0001-Fix-comments-on-data-checksum-cost-settings.patch application/octet-stream 3.7 KB

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Tatsuo Ishii 2026-06-17 13:13:27 Re: Row pattern recognition
Previous Message vignesh C 2026-06-17 13:03:52 Re: Proposal: Conflict log history table for Logical Replication