Issue in GIN fast-insert: XLogBeginInsert + Read/LockBuffer ordering
Matthias van de Meent <boekewurm+postgres@gmail.com>
From: Matthias van de Meent <boekewurm+postgres@gmail.com>
To: PostgreSQL Hackers <pgsql-hackers@postgresql.org>
Date: 2022-09-08T11:07:54Z
Lists: pgsql-hackers
Attachments
- v1-0001-Fix-GIN-fast-path-XLogBeginInsert-and-Read-LockBu.patch (application/octet-stream) patch v1-0001
Hi, In Neon, we've had to modify the GIN fast insertion path as attached, due to an unexpected XLOG insertion and buffer locking ordering issue. The xlog readme [0] mentions that the common order of operations is 1) pin and lock any buffers you need for the log record, then 2) start a critical section, then 3) call XLogBeginInsert. In Neon, we rely on this documented order of operations to expect to be able to WAL-log hint pages (freespace map, visibility map) when they are written to disk (e.g. cache eviction, checkpointer). In general, this works fine, except that in ginHeapTupleFastInsert we call XLogBeginInsert() before the last of the buffers for the eventual record was read, thus creating a path where eviction is possible in a `begininsert_called = true` context. That breaks our current code by being unable to evict (WAL-log) the dirtied hint pages. PFA a patch that rectifies this issue, by moving the XLogBeginInsert() down to where 1.) we have all relevant buffers pinned and locked, and 2.) we're in a critical section, making that part of the code consistent with the general scheme for XLog insertion. Kind regards, Matthias van de Meent [0] access/transam/README, section "Write-Ahead Log Coding", line 436-470
Commits
-
Fix ordering issue with WAL operations in GIN fast insert path
- b02fc7df193b 10.23 landed
- 341fba2a6291 11.18 landed
- 51c24d9e21d7 12.13 landed
- 594b97509e49 13.9 landed
- 5a30d43fa986 14.6 landed
- ca4070f2b4b1 15.1 landed
- 56b662523fd4 16.0 landed