PostgreSQL Source Code git master
Loading...
Searching...
No Matches
datachecksum_state.h File Reference
Include dependency graph for datachecksum_state.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

bool AbsorbDataChecksumsBarrier (ProcSignalBarrierType barrier)
 
void EmitAndWaitDataChecksumsBarrier (uint32 state)
 
void DataChecksumsWorkerLauncherMain (Datum arg)
 
void DataChecksumsWorkerMain (Datum arg)
 

Function Documentation

◆ AbsorbDataChecksumsBarrier()

bool AbsorbDataChecksumsBarrier ( ProcSignalBarrierType  barrier)

Definition at line 468 of file datachecksum_state.c.

469{
471 int current = data_checksums;
472 bool found = false;
473
474 /*
475 * Translate the barrier condition to the target state, doing it here
476 * instead of in the procsignal code saves the latter from knowing about
477 * checksum states.
478 */
479 switch (barrier)
480 {
483 break;
486 break;
489 break;
492 break;
493 default:
494 elog(ERROR, "incorrect barrier \"%i\" received", barrier);
495 }
496
497 /*
498 * If the target state matches the current state then the barrier has been
499 * repeated.
500 */
501 if (current == target_state)
502 return true;
503
504 /*
505 * If the cluster is in recovery we skip the validation of current state
506 * since the replay is trusted.
507 */
508 if (RecoveryInProgress())
509 {
511 return true;
512 }
513
514 /*
515 * Find the barrier condition definition for the target state. Not finding
516 * a condition would be a grave programmer error as the states are a
517 * discrete set.
518 */
519 for (size_t i = 0; i < lengthof(checksum_barriers) && !found; i++)
520 {
521 if (checksum_barriers[i].from == current && checksum_barriers[i].to == target_state)
522 found = true;
523 }
524
525 /*
526 * If the relevant state criteria aren't satisfied, throw an error which
527 * will be caught by the procsignal machinery for a later retry.
528 */
529 if (!found)
532 errmsg("incorrect data checksum state %i for target state %i",
533 current, target_state));
534
536 return true;
537}
uint32_t uint32
Definition c.h:683
#define lengthof(array)
Definition c.h:932
@ PG_DATA_CHECKSUM_VERSION
Definition checksum.h:29
@ PG_DATA_CHECKSUM_INPROGRESS_OFF
Definition checksum.h:30
@ PG_DATA_CHECKSUM_INPROGRESS_ON
Definition checksum.h:31
@ PG_DATA_CHECKSUM_OFF
Definition checksum.h:28
static const ChecksumBarrierCondition checksum_barriers[9]
int errcode(int sqlerrcode)
Definition elog.c:875
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define ereport(elevel,...)
Definition elog.h:152
int i
Definition isn.c:77
static char * errmsg
static THREAD_BARRIER_T barrier
Definition pgbench.c:488
static int fb(int x)
@ PROCSIGNAL_BARRIER_CHECKSUM_INPROGRESS_OFF
Definition procsignal.h:55
@ PROCSIGNAL_BARRIER_CHECKSUM_INPROGRESS_ON
Definition procsignal.h:54
@ PROCSIGNAL_BARRIER_CHECKSUM_ON
Definition procsignal.h:56
@ PROCSIGNAL_BARRIER_CHECKSUM_OFF
Definition procsignal.h:53
bool RecoveryInProgress(void)
Definition xlog.c:6835
void SetLocalDataChecksumState(uint32 data_checksum_version)
Definition xlog.c:4969
int data_checksums
Definition xlog.c:683

References barrier, checksum_barriers, data_checksums, elog, ereport, errcode(), errmsg, ERROR, fb(), i, lengthof, PG_DATA_CHECKSUM_INPROGRESS_OFF, PG_DATA_CHECKSUM_INPROGRESS_ON, PG_DATA_CHECKSUM_OFF, PG_DATA_CHECKSUM_VERSION, PROCSIGNAL_BARRIER_CHECKSUM_INPROGRESS_OFF, PROCSIGNAL_BARRIER_CHECKSUM_INPROGRESS_ON, PROCSIGNAL_BARRIER_CHECKSUM_OFF, PROCSIGNAL_BARRIER_CHECKSUM_ON, RecoveryInProgress(), and SetLocalDataChecksumState().

Referenced by ProcessProcSignalBarrier().

◆ DataChecksumsWorkerLauncherMain()

void DataChecksumsWorkerLauncherMain ( Datum  arg)

Definition at line 1129 of file datachecksum_state.c.

1130{
1131
1133 errmsg("background worker \"datachecksums launcher\" started"));
1134
1139
1141
1144
1145 INJECTION_POINT("datachecksumsworker-launcher-delay", NULL);
1146
1148
1150 {
1151 ereport(LOG,
1152 errmsg("background worker \"datachecksums launcher\" already running, exiting"));
1153 /* Launcher was already running, let it finish */
1155 return;
1156 }
1157
1159 launcher_running = true;
1160
1161 /* Initialize a connection to shared catalogs only */
1163
1170
1171 /*
1172 * The target state can change while we are busy enabling/disabling
1173 * checksums, if the user calls pg_disable/enable_data_checksums() before
1174 * we are finished with the previous request. In that case, we will loop
1175 * back here, to process the new request.
1176 */
1177again:
1178
1180 InvalidOid);
1182
1184 {
1185 /*
1186 * If we are asked to enable checksums in a cluster which already has
1187 * checksums enabled, exit immediately as there is nothing more to do.
1188 */
1190 goto done;
1191
1192 ereport(LOG,
1193 errmsg("enabling data checksums requested, starting data checksum calculation"));
1194
1195 /*
1196 * Set the state to inprogress-on and wait on the procsignal barrier.
1197 */
1201
1202 /*
1203 * All backends are now in inprogress-on state and are writing data
1204 * checksums. Start processing all data at rest.
1205 */
1206 if (!ProcessAllDatabases())
1207 {
1208 /*
1209 * If the target state changed during processing then it's not a
1210 * failure, so restart processing instead.
1211 */
1213 if (abort_requested)
1214 goto done;
1215 ereport(ERROR,
1217 errmsg("unable to enable data checksums in cluster"));
1218 }
1219
1220 /*
1221 * Data checksums have been set on all pages, set the state to on in
1222 * order to instruct backends to validate checksums on reading.
1223 */
1225
1226 ereport(LOG,
1227 errmsg("data checksums are now enabled"));
1228 }
1229 else if (operation == DISABLE_DATACHECKSUMS)
1230 {
1231 ereport(LOG,
1232 errmsg("disabling data checksums requested"));
1233
1237 ereport(LOG,
1238 errmsg("data checksums are now disabled"));
1239 }
1240 else
1241 Assert(false);
1242
1243done:
1244
1245 /*
1246 * This state will only be displayed for a fleeting moment, but for the
1247 * sake of correctness it is still added before ending the command.
1248 */
1251
1252 /*
1253 * All done. But before we exit, check if the target state was changed
1254 * while we were running. In that case we will have to start all over
1255 * again.
1256 */
1259 {
1265 goto again;
1266 }
1267
1268 /* Shut down progress reporting as we are done */
1270
1271 launcher_running = false;
1274}
void pgstat_progress_start_command(ProgressCommandType cmdtype, Oid relid)
void pgstat_progress_update_param(int index, int64 val)
void pgstat_progress_end_command(void)
@ PROGRESS_COMMAND_DATACHECKSUMS
void BackgroundWorkerUnblockSignals(void)
Definition bgworker.c:949
void BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid, uint32 flags)
Definition bgworker.c:909
#define Assert(condition)
Definition c.h:1002
static DataChecksumsStateStruct * DataChecksumState
static volatile sig_atomic_t launcher_running
static volatile sig_atomic_t abort_requested
static DataChecksumsWorkerOperation operation
static void ResetDataChecksumsProgressCounters(void)
static void launcher_cancel_handler(SIGNAL_ARGS)
#define CHECK_FOR_LAUNCHER_ABORT_REQUEST()
static bool ProcessAllDatabases(void)
@ DISABLE_DATACHECKSUMS
@ ENABLE_DATACHECKSUMS
static void launcher_exit(int code, Datum arg)
#define LOG
Definition elog.h:32
#define DEBUG1
Definition elog.h:31
#define INJECTION_POINT(name, arg)
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition ipc.c:372
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition lwlock.c:1150
void LWLockRelease(LWLock *lock)
Definition lwlock.c:1767
@ LW_EXCLUSIVE
Definition lwlock.h:104
@ B_DATACHECKSUMSWORKER_LAUNCHER
Definition miscadmin.h:373
BackendType MyBackendType
Definition miscinit.c:65
#define die(msg)
#define pqsignal
Definition port.h:548
#define PG_SIG_IGN
Definition port.h:552
#define InvalidOid
void procsignal_sigusr1_handler(SIGNAL_ARGS)
Definition procsignal.c:696
#define PROGRESS_DATACHECKSUMS_PHASE_DONE
Definition progress.h:205
#define PROGRESS_DATACHECKSUMS_PHASE
Definition progress.h:192
#define PROGRESS_DATACHECKSUMS_PHASE_ENABLING
Definition progress.h:201
#define PROGRESS_DATACHECKSUMS_PHASE_DISABLING
Definition progress.h:202
void init_ps_display(const char *fixed_part)
Definition ps_status.c:286
DataChecksumsWorkerOperation launch_operation
DataChecksumsWorkerOperation operation
#define SIGUSR1
Definition win32_port.h:170
#define SIGUSR2
Definition win32_port.h:171
void SetDataChecksumsOff(void)
Definition xlog.c:4865
bool DataChecksumsNeedVerify(void)
Definition xlog.c:4732
void SetDataChecksumsOn(void)
Definition xlog.c:4801
void SetDataChecksumsOnInProgress(void)
Definition xlog.c:4748

References abort_requested, Assert, B_DATACHECKSUMSWORKER_LAUNCHER, BackgroundWorkerInitializeConnectionByOid(), BackgroundWorkerUnblockSignals(), CHECK_FOR_LAUNCHER_ABORT_REQUEST, DataChecksumsStateStruct::cost_delay, DataChecksumsStateStruct::cost_limit, DataChecksumsNeedVerify(), DataChecksumState, DEBUG1, die, DISABLE_DATACHECKSUMS, ENABLE_DATACHECKSUMS, ereport, errcode(), errmsg, ERROR, fb(), init_ps_display(), INJECTION_POINT, InvalidOid, DataChecksumsStateStruct::launch_cost_delay, DataChecksumsStateStruct::launch_cost_limit, DataChecksumsStateStruct::launch_operation, launcher_cancel_handler(), launcher_exit(), DataChecksumsStateStruct::launcher_running, launcher_running, LOG, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MyBackendType, on_shmem_exit(), DataChecksumsStateStruct::operation, operation, PG_SIG_IGN, pgstat_progress_end_command(), pgstat_progress_start_command(), pgstat_progress_update_param(), pqsignal, ProcessAllDatabases(), procsignal_sigusr1_handler(), PROGRESS_COMMAND_DATACHECKSUMS, PROGRESS_DATACHECKSUMS_PHASE, PROGRESS_DATACHECKSUMS_PHASE_DISABLING, PROGRESS_DATACHECKSUMS_PHASE_DONE, PROGRESS_DATACHECKSUMS_PHASE_ENABLING, ResetDataChecksumsProgressCounters(), SetDataChecksumsOff(), SetDataChecksumsOn(), SetDataChecksumsOnInProgress(), SIGUSR1, and SIGUSR2.

◆ DataChecksumsWorkerMain()

void DataChecksumsWorkerMain ( Datum  arg)

Definition at line 1580 of file datachecksum_state.c.

1581{
1582 Oid dboid;
1585 BufferAccessStrategy strategy;
1586 bool aborted = false;
1588 bool process_shared;
1589#ifdef USE_INJECTION_POINTS
1590 bool retried = false;
1591#endif
1592
1594
1596
1599
1601
1604
1607 {
1609 return;
1610 }
1613
1616
1617 /* worker will have a separate entry in pg_stat_progress_data_checksums */
1619 InvalidOid);
1621
1622 /*
1623 * Get a list of all temp tables present as we start in this database. We
1624 * need to wait until they are all gone before we exit. For the list of
1625 * relations to enable checksums in, check if shared catalogs have been
1626 * processed already.
1627 */
1631 {
1633 return;
1634 }
1636
1637 /*
1638 * Enable vacuum cost delay, if any. While this process isn't doing any
1639 * vacuuming, we are re-using the infrastructure that vacuum cost delay
1640 * provides rather than inventing something bespoke. This is an internal
1641 * implementation detail and care should be taken to avoid it bleeding
1642 * through to the user to avoid confusion.
1643 *
1644 * VacuumUpdateCosts() propagates the values to the variables actually
1645 * read by vacuum_delay_point().
1646 */
1652
1653 /*
1654 * Create and set the vacuum strategy as our buffer strategy.
1655 */
1656 strategy = GetAccessStrategy(BAS_VACUUM);
1657
1659
1660 /* Update the total number of relations to be processed in this DB. */
1661 {
1662 const int index[] = {
1665 };
1666
1667 int64 vals[2];
1668
1669 vals[0] = list_length(RelationList);
1670 vals[1] = 0;
1671
1673 }
1674
1675 /* Process the relations */
1676 rels_done = 0;
1677 foreach_oid(reloid, RelationList)
1678 {
1679 bool costs_updated = false;
1680
1681 if (!ProcessSingleRelationByOid(reloid, strategy))
1682 {
1683 aborted = true;
1684 break;
1685 }
1686
1688 ++rels_done);
1691
1692 if (abort_requested)
1693 break;
1694
1695 /*
1696 * Check if the cost settings changed during runtime and if so, update
1697 * to reflect the new values and signal that the access strategy needs
1698 * to be refreshed.
1699 */
1702 {
1704 break;
1705 }
1708 {
1709 costs_updated = true;
1713
1716 }
1717 else
1718 costs_updated = false;
1720
1721 if (costs_updated)
1722 {
1723 FreeAccessStrategy(strategy);
1724 strategy = GetAccessStrategy(BAS_VACUUM);
1725 }
1726 }
1727
1729 FreeAccessStrategy(strategy);
1730
1731 if (aborted || abort_requested)
1732 {
1738 errmsg("data checksum processing aborted in database OID %u",
1739 dboid));
1740 return;
1741 }
1742
1743 /* The worker is about to wait for temporary tables to go away. */
1746
1747 /*
1748 * Wait for all temp tables that existed when we started to go away. This
1749 * is necessary since we cannot "reach" them to enable checksums. Any temp
1750 * tables created after we started will already have checksums in them
1751 * (due to the "inprogress-on" state), so no need to wait for those.
1752 */
1753 for (;;)
1754 {
1756 int numleft;
1757 char activity[64];
1758
1759 CurrentTempTables = BuildRelationList(true, false);
1760 numleft = 0;
1762 {
1764 numleft++;
1765 }
1767
1768#ifdef USE_INJECTION_POINTS
1769 if (IS_INJECTION_POINT_ATTACHED("datachecksumsworker-fake-temptable-wait"))
1770 {
1771 /* Make sure to just cause one retry */
1772 if (!retried && numleft == 0)
1773 {
1774 numleft = 1;
1775 retried = true;
1776
1777 INJECTION_POINT_CACHED("datachecksumsworker-fake-temptable-wait", NULL);
1778 }
1779 }
1780#endif
1781
1782 if (numleft == 0)
1783 break;
1784
1785 /*
1786 * At least one temp table is left to wait for, indicate in pgstat
1787 * activity and progress reporting.
1788 */
1790 sizeof(activity),
1791 "Waiting for %d temp tables to be removed", numleft);
1793
1794 /* Retry every 3 seconds */
1798 3000,
1800
1803
1804 if (aborted || abort_requested)
1805 {
1810 ereport(LOG,
1811 errmsg("data checksum processing aborted in database OID %u",
1812 dboid));
1813 return;
1814 }
1815 }
1816
1818
1819 /* worker done */
1821
1826}
void VacuumUpdateCosts(void)
void pgstat_progress_update_multi_param(int nparam, const int *index, const int64 *val)
void pgstat_report_activity(BackendState state, const char *cmd_str)
@ STATE_RUNNING
#define BGWORKER_BYPASS_ALLOWCONN
Definition bgworker.h:166
@ BAS_VACUUM
Definition bufmgr.h:40
int64_t int64
Definition c.h:680
#define CHECK_FOR_WORKER_ABORT_REQUEST()
static bool ProcessSingleRelationByOid(Oid relationId, BufferAccessStrategy strategy)
@ DATACHECKSUMSWORKER_ABORTED
@ DATACHECKSUMSWORKER_SUCCESSFUL
static uint64 worker_invocation
static List * BuildRelationList(bool temp_relations, bool include_shared)
Datum arg
Definition elog.c:1323
BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype)
Definition freelist.c:426
void FreeAccessStrategy(BufferAccessStrategy strategy)
Definition freelist.c:608
int VacuumCostLimit
Definition globals.c:157
int VacuumCostBalance
Definition globals.c:160
struct Latch * MyLatch
Definition globals.c:65
double VacuumCostDelay
Definition globals.c:158
#define IS_INJECTION_POINT_ATTACHED(name)
#define INJECTION_POINT_CACHED(name, arg)
void ResetLatch(Latch *latch)
Definition latch.c:374
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition latch.c:172
void list_free(List *list)
Definition list.c:1546
bool list_member_oid(const List *list, Oid datum)
Definition list.c:722
@ LW_SHARED
Definition lwlock.h:105
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:125
@ B_DATACHECKSUMSWORKER_WORKER
Definition miscadmin.h:374
static int list_length(const List *l)
Definition pg_list.h:152
#define NIL
Definition pg_list.h:68
#define foreach_oid(var, lst)
Definition pg_list.h:503
#define snprintf
Definition port.h:261
static uint64 DatumGetUInt64(Datum X)
Definition postgres.h:436
unsigned int Oid
#define PROGRESS_DATACHECKSUMS_RELS_TOTAL
Definition progress.h:195
#define PROGRESS_DATACHECKSUMS_PHASE_WAITING_TEMPREL
Definition progress.h:203
#define PROGRESS_DATACHECKSUMS_RELS_DONE
Definition progress.h:196
DataChecksumsWorkerResult worker_result
Definition pg_list.h:54
Definition type.h:97
#define WL_TIMEOUT
#define WL_EXIT_ON_PM_DEATH
#define WL_LATCH_SET

References abort_requested, arg, B_DATACHECKSUMSWORKER_WORKER, BackgroundWorkerInitializeConnectionByOid(), BackgroundWorkerUnblockSignals(), BAS_VACUUM, BGWORKER_BYPASS_ALLOWCONN, BuildRelationList(), CHECK_FOR_INTERRUPTS, CHECK_FOR_WORKER_ABORT_REQUEST, DataChecksumsStateStruct::cost_delay, DataChecksumsStateStruct::cost_limit, DataChecksumsStateStruct::database_oid, DataChecksumState, DATACHECKSUMSWORKER_ABORTED, DATACHECKSUMSWORKER_SUCCESSFUL, DatumGetUInt64(), DEBUG1, die, ENABLE_DATACHECKSUMS, ereport, errmsg, fb(), foreach_oid, FreeAccessStrategy(), GetAccessStrategy(), init_ps_display(), INJECTION_POINT_CACHED, InvalidOid, IS_INJECTION_POINT_ATTACHED, DataChecksumsStateStruct::launch_cost_delay, DataChecksumsStateStruct::launch_cost_limit, list_free(), list_length(), list_member_oid(), LOG, LW_EXCLUSIVE, LW_SHARED, LWLockAcquire(), LWLockRelease(), MyBackendType, MyLatch, NIL, operation, pgstat_progress_end_command(), pgstat_progress_start_command(), pgstat_progress_update_multi_param(), pgstat_progress_update_param(), pgstat_report_activity(), pqsignal, DataChecksumsStateStruct::process_shared_catalogs, ProcessSingleRelationByOid(), procsignal_sigusr1_handler(), PROGRESS_COMMAND_DATACHECKSUMS, PROGRESS_DATACHECKSUMS_PHASE, PROGRESS_DATACHECKSUMS_PHASE_WAITING_TEMPREL, PROGRESS_DATACHECKSUMS_RELS_DONE, PROGRESS_DATACHECKSUMS_RELS_TOTAL, ResetDataChecksumsProgressCounters(), ResetLatch(), SIGUSR1, snprintf, STATE_RUNNING, VacuumCostBalance, VacuumCostDelay, VacuumCostLimit, VacuumUpdateCosts(), WaitLatch(), WL_EXIT_ON_PM_DEATH, WL_LATCH_SET, WL_TIMEOUT, DataChecksumsStateStruct::worker_invocation, worker_invocation, and DataChecksumsStateStruct::worker_result.

◆ EmitAndWaitDataChecksumsBarrier()

void EmitAndWaitDataChecksumsBarrier ( uint32  state)

Definition at line 427 of file datachecksum_state.c.

428{
430
431 switch (state)
432 {
436 break;
437
441 break;
442
446 break;
447
451 break;
452
453 default:
454 Assert(false);
455 }
456}
uint64_t uint64
Definition c.h:684
void WaitForProcSignalBarrier(uint64 generation)
Definition procsignal.c:436
uint64 EmitProcSignalBarrier(ProcSignalBarrierType type)
Definition procsignal.c:368

References Assert, barrier, EmitProcSignalBarrier(), PG_DATA_CHECKSUM_INPROGRESS_OFF, PG_DATA_CHECKSUM_INPROGRESS_ON, PG_DATA_CHECKSUM_OFF, PG_DATA_CHECKSUM_VERSION, PROCSIGNAL_BARRIER_CHECKSUM_INPROGRESS_OFF, PROCSIGNAL_BARRIER_CHECKSUM_INPROGRESS_ON, PROCSIGNAL_BARRIER_CHECKSUM_OFF, PROCSIGNAL_BARRIER_CHECKSUM_ON, and WaitForProcSignalBarrier().

Referenced by StartupXLOG(), xlog2_redo(), and xlog_redo().