PostgreSQL Source Code: src/backend/postmaster/checkpointer.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
38
41
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107typedef struct
108{
112
113typedef struct
114{
116
118
121 int ckpt_failed;
122
123 int ckpt_flags;
124
127
132
134
135
136#define WRITES_PER_ABSORB 1000
137
138
139
140
144
145
146
147
150
151
155
158
159
160
167
168
170
171
172
173
174
175
176
177
178void
180{
181 sigjmp_buf local_sigjmp_buf;
183
184 Assert(startup_data_len == 0);
185
188
190
191
192
193
194
195
196
197
198
201 pqsignal(SIGTERM, SIG_IGN);
202
207
208
209
210
212
213
214
215
217
218
219
220
221
222
223
224
225
226
227
228
230
231
232
233
234
235
236
238 "Checkpointer",
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260 if (sigsetjmp(local_sigjmp_buf, 1) != 0)
261 {
262
264
265
267
268
270
271
272
273
274
275
276
287
288
290 {
295
297
299 }
300
301
302
303
304
307
308
310
311
313
314
315
316
317
318
320 }
321
322
324
325
326
327
328 sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
329
330
331
332
333
335
336
337
338
339
341
342
343
344
345
346 for (;;)
347 {
348 bool do_checkpoint = false;
349 int flags = 0;
351 int elapsed_secs;
352 int cur_timeout;
353 bool chkpt_or_rstpt_requested = false;
354 bool chkpt_or_rstpt_timed = false;
355
356
358
359
360
361
363
366 break;
367
368
369
370
371
372
374 {
375 do_checkpoint = true;
376 chkpt_or_rstpt_requested = true;
377 }
378
379
380
381
382
383
384
388 {
389 if (!do_checkpoint)
390 chkpt_or_rstpt_timed = true;
391 do_checkpoint = true;
393 }
394
395
396
397
398 if (do_checkpoint)
399 {
400 bool ckpt_performed = false;
401 bool do_restartpoint;
402
403
405
406
407
408
409
410
416
418
419
420
421
422
424 do_restartpoint = false;
425
426 if (chkpt_or_rstpt_timed)
427 {
428 chkpt_or_rstpt_timed = false;
429 if (do_restartpoint)
431 else
433 }
434
435 if (chkpt_or_rstpt_requested)
436 {
437 chkpt_or_rstpt_requested = false;
438 if (do_restartpoint)
440 else
442 }
443
444
445
446
447
448
449
450
451 if (!do_restartpoint &&
455 (errmsg_plural("checkpoints are occurring too frequently (%d second apart)",
456 "checkpoints are occurring too frequently (%d seconds apart)",
457 elapsed_secs,
458 elapsed_secs),
459 errhint("Consider increasing the configuration parameter \"%s\".", "max_wal_size")));
460
461
462
463
464
466 if (do_restartpoint)
468 else
472
473
474
475
476 if (!do_restartpoint)
478 else
480
481
482
483
484
485
486
488
489
490
491
495
497
498 if (!do_restartpoint)
499 {
500
501
502
503
504
506
507 if (ckpt_performed)
509 }
510 else
511 {
512 if (ckpt_performed)
513 {
514
515
516
517
519
521 }
522 else
523 {
524
525
526
527
528
529
530
532 }
533 }
534
536
537
538
539
540
543 break;
544 }
545
546
548
549
552
553
554
555
556
558 continue;
559
560
561
562
563
567 continue;
570 {
573 continue;
575 }
576
579 cur_timeout * 1000L ,
580 WAIT_EVENT_CHECKPOINTER_MAIN);
581 }
582
583
584
585
586
588
590 {
591
592
593
594
595
596
597
602
603
604
605
608 }
609
610
611
612
613
614
615 for (;;)
616 {
617
619
621
623 break;
624
627 0,
628 WAIT_EVENT_CHECKPOINTER_SHUTDOWN);
629 }
630
631
633}
634
635
636
637
638static void
640{
643
645 {
648
649
650
651
652
653
654
655
656
657
658
659
661 }
662
663
666}
667
668
669
670
671
672
673
674
675
676
677
678
679
680static void
682{
686
688 return;
689
691
692
694 return;
695
696
697
698
699
701
703
704
706 {
707
708
709
710
711
713 {
715
716
718
719
720
721
722
724 elog(DEBUG1, "write-ahead log switch forced (\"archive_timeout\"=%d)",
726 }
727
728
729
730
731
733 }
734}
735
736
737
738
739
740
741static bool
743{
745
746
747
748
749
751 return true;
752 return false;
753}
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768void
770{
772
773
775 return;
776
777
778
779
780
786 {
788 {
791
793 }
794
797
799
800
802
803
804
805
806
807
808
810 100,
811 WAIT_EVENT_CHECKPOINT_WRITE_DELAY);
813 }
814 else if (--absorb_counter <= 0)
815 {
816
817
818
819
820
823 }
824
825
828}
829
830
831
832
833
834
835
836
837
838static bool
840{
842 struct timeval now;
843 double elapsed_xlogs,
845
847
848
850
851
852
853
854
855
856
858 return false;
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
882 else
886
887 if (progress < elapsed_xlogs)
888 {
890 return false;
891 }
892
893
894
895
899
901 {
903 return false;
904 }
905
906
907 return true;
908}
909
910
911
912
913
914
915
916
917static void
919{
922}
923
924
925
926
927
928
929
930
931
932
933
936{
938
939
940
941
942
945
946 return size;
947}
948
949
950
951
952
953void
955{
957 bool found;
958
961 size,
962 &found);
963
964 if (!found)
965 {
966
967
968
969
970
976 }
977}
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996void
998{
999 int ntries;
1000 int old_failed,
1001 old_started;
1002
1003
1004
1005
1007 {
1008
1009
1010
1011
1013
1014
1016
1017 return;
1018 }
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1030
1034
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047#define MAX_SIGNAL_TRIES 600
1048 for (ntries = 0;; ntries++)
1049 {
1052
1054 {
1056 {
1058 "could not notify checkpoint: checkpointer is not running");
1059 break;
1060 }
1061 }
1062 else
1063 {
1065
1066 break;
1067 }
1068
1070 pg_usleep(100000L);
1071 }
1072
1073
1074
1075
1076
1078 {
1079 int new_started,
1080 new_failed;
1081
1082
1084 for (;;)
1085 {
1089
1090 if (new_started != old_started)
1091 break;
1092
1094 WAIT_EVENT_CHECKPOINT_START);
1095 }
1097
1098
1099
1100
1102 for (;;)
1103 {
1104 int new_done;
1105
1110
1111 if (new_done - new_started >= 0)
1112 break;
1113
1115 WAIT_EVENT_CHECKPOINT_DONE);
1116 }
1118
1119 if (new_failed != old_failed)
1121 (errmsg("checkpoint request failed"),
1122 errhint("Consult recent messages in the server log for details.")));
1123 }
1124}
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146bool
1148{
1150 bool too_full;
1151
1153 return false;
1154
1156 elog(ERROR, "ForwardSyncRequest must not be called in checkpointer");
1157
1159
1160
1161
1162
1163
1164
1168 {
1170 return false;
1171 }
1172
1173
1175 request->ftag = *ftag;
1177
1178
1181
1183
1184
1185 if (too_full)
1186 {
1189
1192 }
1193
1194 return true;
1195}
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213static bool
1215{
1216 struct CheckpointerSlotMapping
1217 {
1219 int slot;
1220 };
1221
1222 int n,
1223 preserve_count;
1224 int num_skipped = 0;
1227 bool *skip_slot;
1228
1229
1231
1232
1234 return false;
1235
1236
1238
1239
1241 ctl.entrysize = sizeof(struct CheckpointerSlotMapping);
1243
1244 htab = hash_create("CompactCheckpointerRequestQueue",
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1262 {
1264 struct CheckpointerSlotMapping *slotmap;
1265 bool found;
1266
1267
1268
1269
1270
1271
1272
1273
1276 if (found)
1277 {
1278
1279 skip_slot[slotmap->slot] = true;
1280 num_skipped++;
1281 }
1282
1283 slotmap->slot = n;
1284 }
1285
1286
1288
1289
1290 if (!num_skipped)
1291 {
1292 pfree(skip_slot);
1293 return false;
1294 }
1295
1296
1297 preserve_count = 0;
1299 {
1300 if (skip_slot[n])
1301 continue;
1303 }
1305 (errmsg_internal("compacted fsync request queue from %d entries to %d entries",
1308
1309
1310 pfree(skip_slot);
1311 return true;
1312}
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323void
1325{
1328 int n;
1329
1331 return;
1332
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1346 if (n > 0)
1347 {
1350 }
1351
1353
1355
1357
1358 for (request = requests; n > 0; request++, n--)
1360
1362
1363 if (requests)
1364 pfree(requests);
1365}
1366
1367
1368
1369
1370static void
1372{
1373
1375
1376
1377
1378
1379
1381
1382 elog(DEBUG2, "checkpointer updated shared memory configuration values");
1383}
1384
1385
1386
1387
1388
1389bool
1391{
1392 static int ckpt_done = 0;
1393 int new_done;
1394 bool FirstCall = false;
1395
1399
1400 if (new_done != ckpt_done)
1401 FirstCall = true;
1402
1403 ckpt_done = new_done;
1404
1405 return FirstCall;
1406}
void pgaio_error_cleanup(void)
void AuxiliaryProcessMainCommon(void)
Datum now(PG_FUNCTION_ARGS)
void AtEOXact_Buffers(bool isCommit)
#define FLEXIBLE_ARRAY_MEMBER
#define MemSet(start, val, len)
static void UpdateSharedMemoryConfig(void)
static XLogRecPtr ckpt_start_recptr
static bool ImmediateCheckpointRequested(void)
static bool IsCheckpointOnSchedule(double progress)
bool ForwardSyncRequest(const FileTag *ftag, SyncRequestType type)
static void ReqShutdownXLOG(SIGNAL_ARGS)
static void CheckArchiveTimeout(void)
static double ckpt_cached_elapsed
void CheckpointerMain(const void *startup_data, size_t startup_data_len)
static bool CompactCheckpointerRequestQueue(void)
static void ProcessCheckpointerInterrupts(void)
static volatile sig_atomic_t ShutdownXLOGPending
void AbsorbSyncRequests(void)
#define WRITES_PER_ABSORB
double CheckPointCompletionTarget
static pg_time_t last_xlog_switch_time
void CheckpointerShmemInit(void)
bool FirstCallSinceLastCheckpoint(void)
static CheckpointerShmemStruct * CheckpointerShmem
void RequestCheckpoint(int flags)
static pg_time_t last_checkpoint_time
void CheckpointWriteDelay(int flags, double progress)
static pg_time_t ckpt_start_time
Size CheckpointerShmemSize(void)
bool ConditionVariableCancelSleep(void)
void ConditionVariableBroadcast(ConditionVariable *cv)
void ConditionVariablePrepareToSleep(ConditionVariable *cv)
void ConditionVariableInit(ConditionVariable *cv)
void ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info)
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
void AtEOXact_HashTables(bool isCommit)
void hash_destroy(HTAB *hashp)
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
int errmsg_internal(const char *fmt,...)
void EmitErrorReport(void)
ErrorContextCallback * error_context_stack
void FlushErrorState(void)
int errhint(const char *fmt,...)
int errmsg(const char *fmt,...)
sigjmp_buf * PG_exception_stack
#define ereport(elevel,...)
static double elapsed_time(instr_time *starttime)
void AtEOXact_Files(bool isCommit)
volatile sig_atomic_t LogMemoryContextPending
volatile sig_atomic_t ProcSignalBarrierPending
volatile uint32 CritSectionCount
bool IsPostmasterEnvironment
void ProcessConfigFile(GucContext context)
Assert(PointerIsAligned(start, uint64))
void SignalHandlerForShutdownRequest(SIGNAL_ARGS)
volatile sig_atomic_t ShutdownRequestPending
volatile sig_atomic_t ConfigReloadPending
void SignalHandlerForConfigReload(SIGNAL_ARGS)
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
void SetLatch(Latch *latch)
void ResetLatch(Latch *latch)
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
bool LWLockHeldByMe(LWLock *lock)
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
void LWLockRelease(LWLock *lock)
void LWLockReleaseAll(void)
void MemoryContextReset(MemoryContext context)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext TopMemoryContext
MemoryContext CurrentMemoryContext
void ProcessLogMemoryContextInterrupt(void)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define AmCheckpointerProcess()
#define RESUME_INTERRUPTS()
#define START_CRIT_SECTION()
#define CHECK_FOR_INTERRUPTS()
#define HOLD_INTERRUPTS()
#define END_CRIT_SECTION()
BackendType MyBackendType
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
void pgstat_before_server_shutdown(int code, Datum arg)
void pgstat_report_checkpointer(void)
PgStat_CheckpointerStats PendingCheckpointerStats
void pgstat_report_wal(bool force)
void SendPostmasterSignal(PMSignalReason reason)
@ PMSIGNAL_XLOG_IS_SHUTDOWN
#define GetPGProcByNumber(n)
#define INVALID_PROC_NUMBER
void ProcessProcSignalBarrier(void)
void procsignal_sigusr1_handler(SIGNAL_ARGS)
void ReleaseAuxProcessResources(bool isCommit)
Size add_size(Size s1, Size s2)
Size mul_size(Size s1, Size s2)
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
void pg_usleep(long microsec)
void smgrdestroyall(void)
#define SpinLockInit(lock)
#define SpinLockRelease(lock)
#define SpinLockAcquire(lock)
ConditionVariable done_cv
ConditionVariable start_cv
CheckpointerRequest requests[FLEXIBLE_ARRAY_MEMBER]
ProcNumber checkpointerProc
PgStat_Counter restartpoints_requested
PgStat_Counter num_requested
PgStat_Counter num_performed
PgStat_Counter restartpoints_timed
PgStat_Counter restartpoints_performed
void RememberSyncRequest(const FileTag *ftag, SyncRequestType type)
void SyncRepUpdateSyncStandbysDefined(void)
static void pgstat_report_wait_end(void)
#define WL_EXIT_ON_PM_DEATH
int gettimeofday(struct timeval *tp, void *tzp)
void UpdateFullPageWrites(void)
bool RecoveryInProgress(void)
XLogRecPtr RequestXLogSwitch(bool mark_unimportant)
bool CreateRestartPoint(int flags)
XLogRecPtr GetInsertRecPtr(void)
void ShutdownXLOG(int code, Datum arg)
pg_time_t GetLastSegSwitchData(XLogRecPtr *lastSwitchLSN)
XLogRecPtr GetLastImportantRecPtr(void)
bool CreateCheckPoint(int flags)
#define CHECKPOINT_CAUSE_XLOG
#define CHECKPOINT_END_OF_RECOVERY
#define CHECKPOINT_CAUSE_TIME
#define CHECKPOINT_REQUESTED
#define CHECKPOINT_IMMEDIATE
#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)
XLogRecPtr GetXLogReplayRecPtr(TimeLineID *replayTLI)