PostgreSQL Source Code: src/backend/storage/sync/sync.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
16
18#include <fcntl.h>
20
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
55
56typedef struct
57{
62
63typedef struct
64{
69
73
76
77
78#define FSYNCS_PER_ABSORB 10
79#define UNLINKS_PER_ABSORB 10
80
81
82
83
85{
89 const FileTag *candidate);
91
92
93
94
96
101 },
102
105 },
106
109 },
110
113 },
114
117 }
118};
119
120
121
122
123void
125{
126
127
128
129
130
132 {
134
135
136
137
138
139
140
141
142
143
145 "Pending ops context",
148
153 100L,
154 &hash_ctl,
157 }
158}
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176void
178{
179
180
181
182
183
184
185
186
188
189
190
191
192
194}
195
196
197
198
199
200
201void
203{
204 int absorb_counter;
206
209 {
212
213
215 continue;
216
217
218
219
220
221
222
223
224
225
227 break;
228
229
231 path) < 0)
232 {
233
234
235
236
237
238
239
240 if (errno != ENOENT)
243 errmsg("could not remove file \"%s\": %m", path)));
244 }
245
246
248
249
250
251
252
253
254 if (--absorb_counter <= 0)
255 {
258 }
259 }
260
261
262
263
264
265
266 if (lc == NULL)
267 {
270 }
271 else
272 {
274
275 for (int i = 0; i < ntodelete; i++)
277
279 }
280}
281
282
283
284
285void
287{
288 static bool sync_in_progress = false;
289
292 int absorb_counter;
293
294
295 int processed = 0;
297 sync_end,
298 sync_diff;
301 uint64 total_elapsed = 0;
302
303
304
305
306
308 elog(ERROR, "cannot sync without a pendingOps table");
309
310
311
312
313
314
315
316
317
318
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345 if (sync_in_progress)
346 {
347
350 {
352 }
353 }
354
355
357
358
359 sync_in_progress = true;
360
361
365 {
366 int failures;
367
368
369
370
371
372
374 continue;
375
376
378
379
380
381
382
383
385 {
386
387
388
389
390
391
392
393 if (--absorb_counter <= 0)
394 {
397 }
398
399
400
401
402
403
404
405
406
407
408
409
410 for (failures = 0; !entry->canceled; failures++)
411 {
413
416 path) == 0)
417 {
418
420 sync_diff = sync_end;
425 total_elapsed += elapsed;
426 processed++;
427
429 elog(DEBUG1, "checkpoint sync: number=%d file=%s time=%.3f ms",
430 processed,
431 path,
432 (double) elapsed / 1000);
433
434 break;
435 }
436
437
438
439
440
441
442
446 errmsg("could not fsync file \"%s\": %m",
447 path)));
448 else
451 errmsg_internal("could not fsync file \"%s\" but retrying: %m",
452 path)));
453
454
455
456
457
460 }
461 }
462
463
465 elog(ERROR, "pendingOps corrupted");
466 }
467
468
472
473
474 sync_in_progress = false;
475}
476
477
478
479
480
481
482
483
484
485
486void
488{
490
492 {
494
495
497 ftag,
499 NULL);
500 if (entry != NULL)
502 }
504 {
508
509
512 {
516 }
517
518
520 {
522
526 }
527 }
529 {
530
533
535 entry->tag = *ftag;
538
540
542 }
543 else
544 {
545
548 bool found;
549
551
553 ftag,
555 &found);
556
557 if (!found || entry->canceled)
558 {
561 }
562
563
564
565
566
567
568
570 }
571}
572
573
574
575
576
577
578
579bool
581 bool retryOnError)
582{
583 bool ret;
584
586 {
587
589 return true;
590 }
591
592 for (;;)
593 {
594
595
596
597
598
599
600
601
602
603
604
606
607
608
609
610
611 if (ret || (!ret && !retryOnError))
612 break;
613
615 WAIT_EVENT_REGISTER_SYNC_REQUEST);
616 }
617
618 return ret;
619}
bool ForwardSyncRequest(const FileTag *ftag, SyncRequestType type)
void AbsorbSyncRequests(void)
int clogsyncfiletag(const FileTag *ftag, char *path)
int committssyncfiletag(const FileTag *ftag, char *path)
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
void * hash_seq_search(HASH_SEQ_STATUS *status)
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
int errmsg_internal(const char *fmt,...)
int errcode_for_file_access(void)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
int data_sync_elevel(int elevel)
#define FILE_POSSIBLY_DELETED(err)
Assert(PointerIsAligned(start, uint64))
#define INSTR_TIME_SET_CURRENT(t)
#define INSTR_TIME_SUBTRACT(x, y)
#define INSTR_TIME_GET_MICROSEC(t)
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
List * lappend(List *list, void *datum)
List * list_delete_first_n(List *list, int n)
void list_free_deep(List *list)
void pfree(void *pointer)
MemoryContext TopMemoryContext
void MemoryContextAllowInCriticalSection(MemoryContext context, bool allow)
bool mdfiletagmatches(const FileTag *ftag, const FileTag *candidate)
int mdunlinkfiletag(const FileTag *ftag, char *path)
int mdsyncfiletag(const FileTag *ftag, char *path)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define AmCheckpointerProcess()
int multixactoffsetssyncfiletag(const FileTag *ftag, char *path)
int multixactmemberssyncfiletag(const FileTag *ftag, char *path)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
static void * list_nth(const List *list, int n)
static int list_cell_number(const List *l, const ListCell *c)
static chr * longest(struct vars *v, struct dfa *d, chr *start, chr *stop, int *hitstopp)
uint64 ckpt_agg_sync_time
int(* sync_syncfiletag)(const FileTag *ftag, char *path)
bool(* sync_filetagmatches)(const FileTag *ftag, const FileTag *candidate)
int(* sync_unlinkfiletag)(const FileTag *ftag, char *path)
void ProcessSyncRequests(void)
static CycleCtr checkpoint_cycle_ctr
void SyncPreCheckpoint(void)
static List * pendingUnlinks
#define UNLINKS_PER_ABSORB
static const SyncOps syncsw[]
static MemoryContext pendingOpsCxt
void RememberSyncRequest(const FileTag *ftag, SyncRequestType type)
static CycleCtr sync_cycle_ctr
#define FSYNCS_PER_ABSORB
void SyncPostCheckpoint(void)
bool RegisterSyncRequest(const FileTag *ftag, SyncRequestType type, bool retryOnError)
@ SYNC_HANDLER_MULTIXACT_MEMBER
@ SYNC_HANDLER_MULTIXACT_OFFSET
#define WL_EXIT_ON_PM_DEATH
CheckpointStatsData CheckpointStats