Re: fixing old_snapshot_threshold's time->xid mapping - Mailing list pgsql-hackers
From | Dilip Kumar |
---|---|
Subject | Re: fixing old_snapshot_threshold's time->xid mapping |
Date | |
Msg-id | CAFiTN-ubxCSS+3XHJWG9hFvRf2Ev1KPhnDe-kBnmor_DWz18mQ@mail.gmail.com Whole thread Raw |
In response to | fixing old_snapshot_threshold's time->xid mapping (Robert Haas <robertmhaas@gmail.com>) |
Responses |
Re: fixing old_snapshot_threshold's time->xid mapping
|
List | pgsql-hackers |
On Thu, Apr 16, 2020 at 10:12 PM Robert Haas <robertmhaas@gmail.com> wrote: > > Hi, > > I'm starting a new thread for this, because the recent discussion of > problems with old_snapshot_threshold[1] touched on a lot of separate > issues, and I think it will be too confusing if we discuss all of them > on one thread. Attached are three patches. > > 0001 makes oldSnapshotControl "extern" rather than "static" and > exposes the struct definition via a header. > > 0002 adds a contrib module called old_snapshot which makes it possible > to examine the time->XID mapping via SQL. As Andres said, the comments > are not really adequate in the existing code, and the code itself is > buggy, so it was a little hard to be sure that I was understanding the > intended meaning of the different fields correctly. However, I gave it > a shot. > > 0003 attempts to fix bugs in MaintainOldSnapshotTimeMapping() so that > it produces a sensible mapping. I encountered and tried to fix two > issues here: > > First, as previously discussed, the branch that advances the mapping > should not categorically do "oldSnapshotControl->head_timestamp = ts;" > assuming that the head_timestamp is supposed to be the timestamp for > the oldest bucket rather than the newest one. Rather, there are three > cases: (1) resetting the mapping resets head_timestamp, (2) extending > the mapping by an entry without dropping an entry leaves > head_timestamp alone, and (3) overwriting the previous head with a new > entry advances head_timestamp by 1 minute. > > Second, the calculation of the number of entries by which the mapping > should advance is incorrect. It thinks that it should advance by the > number of minutes between the current head_timestamp and the incoming > timestamp. That would be correct if head_timestamp were the most > recent entry in the mapping, but it's actually the oldest. As a > result, without this fix, every time we move into a new minute, we > advance the mapping much further than we actually should. Instead of > advancing by 1, we advance by the number of entries that already exist > in the mapping - which means we now have entries that correspond to > times which are in the future, and don't advance the mapping again > until those future timestamps are in the past. > > With these fixes, I seem to get reasonably sensible mappings, at least > in light testing. I tried running this in one window with \watch 10: > > select *, age(newest_xmin), clock_timestamp() from > pg_old_snapshot_time_mapping(); > > And in another window I ran: > > pgbench -T 300 -R 10 > > And the age does in fact advance by ~600 transactions per minute. I have started reviewing these patches. I think, the fixes looks right to me. + LWLockAcquire(OldSnapshotTimeMapLock, LW_SHARED); + mapping->head_offset = oldSnapshotControl->head_offset; + mapping->head_timestamp = oldSnapshotControl->head_timestamp; + mapping->count_used = oldSnapshotControl->count_used; + for (int i = 0; i < OLD_SNAPSHOT_TIME_MAP_ENTRIES; ++i) + mapping->xid_by_minute[i] = oldSnapshotControl->xid_by_minute[i]; + LWLockRelease(OldSnapshotTimeMapLock); I think memcpy would be a better choice instead of looping it for all the entries, since we are doing this under a lock? -- Regards, Dilip Kumar EnterpriseDB: http://www.enterprisedb.com
pgsql-hackers by date: