* AbsorbSyncRequests * Retrieve queued sync requests and pass them to sync mechanism. * * This is exported because it must be called during CreateCheckPoint; * we have to be sure we have accepted all pending requests just before * we start fsync'ing. Since CreateCheckPoint sometimes runs in * non-checkpointer processes, do nothing if not checkpointer. */
| 1271 | * non-checkpointer processes, do nothing if not checkpointer. |
| 1272 | */ |
| 1273 | void |
| 1274 | AbsorbSyncRequests(void) |
| 1275 | { |
| 1276 | CheckpointerRequest *requests = NULL; |
| 1277 | CheckpointerRequest *request; |
| 1278 | int n; |
| 1279 | |
| 1280 | if (IsUnderPostmaster && !AmStartupProcess() && !AmCheckpointerProcess()) |
| 1281 | elog(ERROR, "AbsorbFsyncRequests() called in process %d (type %d)", |
| 1282 | MyProcPid, MyAuxProcType); |
| 1283 | |
| 1284 | LWLockAcquire(CheckpointerCommLock, LW_EXCLUSIVE); |
| 1285 | |
| 1286 | /* Transfer stats counts into pending pgstats message */ |
| 1287 | BgWriterStats.m_buf_written_backend += CheckpointerShmem->num_backend_writes; |
| 1288 | BgWriterStats.m_buf_fsync_backend += CheckpointerShmem->num_backend_fsync; |
| 1289 | |
| 1290 | CheckpointerShmem->num_backend_writes = 0; |
| 1291 | CheckpointerShmem->num_backend_fsync = 0; |
| 1292 | |
| 1293 | /* |
| 1294 | * We try to avoid holding the lock for a long time by copying the request |
| 1295 | * array, and processing the requests after releasing the lock. |
| 1296 | * |
| 1297 | * Once we have cleared the requests from shared memory, we have to PANIC |
| 1298 | * if we then fail to absorb them (eg, because our hashtable runs out of |
| 1299 | * memory). This is because the system cannot run safely if we are unable |
| 1300 | * to fsync what we have been told to fsync. Fortunately, the hashtable |
| 1301 | * is so small that the problem is quite unlikely to arise in practice. |
| 1302 | */ |
| 1303 | n = CheckpointerShmem->num_requests; |
| 1304 | if (n > 0) |
| 1305 | { |
| 1306 | requests = (CheckpointerRequest *) palloc(n * sizeof(CheckpointerRequest)); |
| 1307 | memcpy(requests, CheckpointerShmem->requests, n * sizeof(CheckpointerRequest)); |
| 1308 | } |
| 1309 | |
| 1310 | START_CRIT_SECTION(); |
| 1311 | |
| 1312 | CheckpointerShmem->num_requests = 0; |
| 1313 | |
| 1314 | LWLockRelease(CheckpointerCommLock); |
| 1315 | |
| 1316 | for (request = requests; n > 0; request++, n--) |
| 1317 | RememberSyncRequest(&request->ftag, request->type); |
| 1318 | |
| 1319 | END_CRIT_SECTION(); |
| 1320 | |
| 1321 | if (requests) |
| 1322 | pfree(requests); |
| 1323 | } |
| 1324 | |
| 1325 | /* |
| 1326 | * Update any shared memory configurations based on config parameters |
no test coverage detected