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

117 slock_t ckpt_lck;

118

120 int ckpt_done;

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)