diff --git a/contrib/pg_prewarm/autoprewarm.c b/contrib/pg_prewarm/autoprewarm.c index 51acc09aa7..9845aeb22a 100644 --- a/contrib/pg_prewarm/autoprewarm.c +++ b/contrib/pg_prewarm/autoprewarm.c @@ -5,22 +5,22 @@ * * DESCRIPTION * - * It is a bgworker which automatically records information about blocks - * which were present in buffer pool before server shutdown and then - * prewarm the buffer pool upon server restart with those blocks. + * It is a bgworker process that automatically records information about + * blocks which were present in buffer pool before server shutdown and then + * prewarms the buffer pool upon server restart with those blocks. * * How does it work? When the shared library "pg_prewarm" is preloaded, a * bgworker "autoprewarm" is launched immediately after the server has - * reached consistent state. The bgworker will start loading blocks - * recorded in the format BlockInfoRecord - * database,tablespace,filenode,forknum,blocknum in + * reached a consistent state. The bgworker will start loading blocks + * recorded in the format BlockInfoRecord consisting of + * database, tablespace, filenode, forknum, blocknum in * $PGDATA/AUTOPREWARM_FILE, until there is no free buffer left in the * buffer pool. This way we do not replace any new blocks which were * loaded either by the recovery process or the querying clients. * * Once the "autoprewarm" bgworker has completed its prewarm task, it will * start a new task to periodically dump the BlockInfoRecords related to - * blocks which are currently in shared buffer pool. Upon next server + * the blocks which are currently in shared buffer pool. On next server * restart, the bgworker will prewarm the buffer pool by loading those * blocks. The GUC pg_prewarm.dump_interval will control the dumping * activity of the bgworker. @@ -89,13 +89,13 @@ static void apw_sigterm_handler(SIGNAL_ARGS); static void apw_sighup_handler(SIGNAL_ARGS); static void apw_sigusr1_handler(SIGNAL_ARGS); -/* flags set by signal handlers */ +/* Flags set by signal handlers */ static volatile sig_atomic_t got_sigterm = false; static volatile sig_atomic_t got_sighup = false; /* * Signal handler for SIGTERM - * Set a flag to let the main loop to terminate, and set our latch to wake it + * Set a flag for the termination of main loop, and set our latch to wake it * up. */ static void @@ -113,7 +113,7 @@ apw_sigterm_handler(SIGNAL_ARGS) /* * Signal handler for SIGHUP - * Set a flag to tell the process to reread the config file, and set our + * Set a flag to notify the process to reread the config file, and set our * latch to wake it up. */ static void @@ -146,13 +146,11 @@ apw_sigusr1_handler(SIGNAL_ARGS) } /* ============================================================================ - * ============== types and variables used by autoprewarm ============= + * ============== Types and variables used by autoprewarm ============= * ============================================================================ */ -/* - * Metadata of each persistent block which is dumped and used to load. - */ +/* Metadata of each persistent block which is dumped and used for loading. */ typedef struct BlockInfoRecord { Oid database; @@ -160,20 +158,16 @@ typedef struct BlockInfoRecord Oid filenode; ForkNumber forknum; BlockNumber blocknum; -} BlockInfoRecord; +} BlockInfoRecord; -/* - * Tasks performed by autoprewarm workers. - */ +/* Tasks performed by autoprewarm workers.*/ typedef enum { TASK_PREWARM_BUFFERPOOL, /* prewarm the buffer pool. */ TASK_DUMP_BUFFERPOOL_INFO /* dump the buffer pool block info. */ -} AutoPrewarmTask; +} AutoPrewarmTask; -/* - * Shared state information about the running autoprewarm bgworker. - */ +/* Shared state information about running the autoprewarm bgworker. */ typedef struct AutoPrewarmSharedState { LWLock lock; /* mutual exclusion */ @@ -182,25 +176,25 @@ typedef struct AutoPrewarmSharedState bool skip_prewarm_on_restart; /* if set true, prewarm task * will not be done */ - /* following items are for communication with per-database worker */ + /* Following items are for communication with per-database worker */ dsm_handle block_info_handle; Oid database; int prewarm_start_idx; int prewarm_stop_idx; -} AutoPrewarmSharedState; +} AutoPrewarmSharedState; static AutoPrewarmSharedState *state = NULL; -/* GUC variable which control the dump activity of autoprewarm. */ +/* GUC variable that controls the dump activity of autoprewarm. */ static int dump_interval = 0; /* - * GUC variable which say whether autoprewarm worker has to be started when + * GUC variable to decide if autoprewarm worker has to be started when * preloaded. */ static bool autoprewarm = true; -/* compare member elements to check if they are not equal. */ +/* Compare member elements to check if they are not equal. */ #define cmp_member_elem(fld) \ do { \ if (a->fld < b->fld) \ @@ -228,7 +222,7 @@ blockinfo_cmp(const void *p, const void *q) } /* ============================================================================ - * ===================== prewarm part of autoprewarm ======================= + * ===================== Prewarm part of autoprewarm ======================= * ============================================================================ */ @@ -273,9 +267,9 @@ init_autoprewarm_state(void) /* * load_one_database - * Load block infos of one database by connecting to them. + * Load block info of one database after connecting to them. * - * Start of prewarm per-database worker. This will try to load blocks of one + * Start prewarm per-database worker, which will load blocks of one * database starting from block info position state->prewarm_start_idx to * state->prewarm_stop_idx. */ @@ -293,9 +287,7 @@ load_one_database(Datum main_arg) pqsignal(SIGTERM, apw_sigterm_handler); pqsignal(SIGHUP, apw_sighup_handler); - /* - * We're now ready to receive signals - */ + /* We're now ready to receive signals */ BackgroundWorkerUnblockSignals(); init_autoprewarm_state(); @@ -317,18 +309,18 @@ load_one_database(Datum main_arg) Buffer buf; /* - * Quit if we've reached records for another database. Unless the + * Quit if we've reached records of another database. Unless the * previous blocks were of global objects which were combined with - * next database's block infos. + * next database's block info. */ if (old_blk != NULL && old_blk->database != blk->database && old_blk->database != 0) break; /* - * When we reach a new relation, close the old one. Note, however, - * that the previous try_relation_open may have failed, in which case - * rel will be NULL. + * On reaching a new relation, close the old one. Note, that the + * previous try_relation_open may have failed, in which case rel will + * be NULL. */ if (old_blk != NULL && old_blk->filenode != blk->filenode && rel != NULL) @@ -339,8 +331,8 @@ load_one_database(Datum main_arg) } /* - * Try to open each new relation, but only once, when we first - * encounter it. If it's been dropped, skip the associated blocks. + * Each relation is open only once at it's first encounter. If it's + * been dropped, skip the associated blocks. */ if (old_blk == NULL || old_blk->filenode != blk->filenode) { @@ -362,7 +354,7 @@ load_one_database(Datum main_arg) continue; } - /* Once per fork, check for fork existence and size. */ + /* Check each fork for it's existence and size. */ if (old_blk == NULL || old_blk->filenode != blk->filenode || old_blk->forknum != blk->forknum) @@ -370,8 +362,8 @@ load_one_database(Datum main_arg) RelationOpenSmgr(rel); /* - * smgrexists is not safe for illegal forknum, so test before - * calling same. + * smgrexists is not safe for illegal forknum, hence check if the + * passed forknum is valid before using it in smgrexists. */ if (blk->forknum > InvalidForkNumber && blk->forknum <= MAX_FORKNUM && @@ -381,10 +373,10 @@ load_one_database(Datum main_arg) nblocks = 0; } - /* check if blocknum is valid and with in fork file size. */ + /* Check if blocknum is valid and within fork file size. */ if (blk->blocknum >= nblocks) { - /* move to next forknum. */ + /* Move to next forknum. */ ++pos; old_blk = blk; continue; @@ -402,7 +394,7 @@ load_one_database(Datum main_arg) dsm_detach(seg); - /* release lock on previous relation. */ + /* Release lock on previous relation. */ if (rel) { relation_close(rel, AccessShareLock); @@ -427,7 +419,7 @@ launch_and_wait_for_per_database_worker(void) (Datum) NULL, BGW_NEVER_RESTART, BGWORKER_BACKEND_DATABASE_CONNECTION); - /* set bgw_notify_pid so that we can use WaitForBackgroundWorkerShutdown */ + /* Set bgw_notify_pid so that we can use WaitForBackgroundWorkerShutdown */ worker.bgw_notify_pid = MyProcPid; if (!RegisterDynamicBackgroundWorker(&worker, &handle)) @@ -444,12 +436,12 @@ launch_and_wait_for_per_database_worker(void) /* * prewarm_buffer_pool - * The main routine which prewarm the buffer pool + * The main routine that prewarms the buffer pool. * - * The prewarm bgworker will first load all of the BlockInfoRecord's in - * $PGDATA/AUTOPREWARM_FILE to a dsm. And those BlockInfoRecords are further - * separated based on their database. And for each group of BlockInfoRecords a - * per-database worker will be launched to load corresponding blocks. Each of + * The prewarm bgworker will first load all of the BlockInfoRecords in + * $PGDATA/AUTOPREWARM_FILE to a dsm. Further, those BlockInfoRecords are + * separated based on their database. Finally, for each group of BlockInfoRecords a + * per-database worker will be launched to load corresponding blocks. Now, each of * those workers will be launched in sequential order only after the previous * one has finished its job. */ @@ -463,8 +455,8 @@ prewarm_buffer_pool(void) dsm_segment *seg; /* - * since there could be at max one worker who could do a prewarm no need - * to take lock before setting skip_prewarm_on_restart. + * Since there could be at max one worker who could do a prewarm, hence, + * acquiring locks is not required before setting skip_prewarm_on_restart. */ state->skip_prewarm_on_restart = true; @@ -509,7 +501,7 @@ prewarm_buffer_pool(void) for (i = 0; i < num_elements; i++) { - /* get next block. */ + /* Get next block. */ if (5 != fscanf(file, "%u,%u,%u,%u,%u\n", &blkinfo[i].database, &blkinfo[i].tablespace, &blkinfo[i].filenode, (uint32 *) &blkinfo[i].forknum, &blkinfo[i].blocknum)) @@ -523,7 +515,7 @@ prewarm_buffer_pool(void) i, num_elements); /* - * sort the block number to increase the chance of sequential reads during + * Sort the block number to increase the chance of sequential reads during * load. */ pg_qsort(blkinfo, num_elements, sizeof(BlockInfoRecord), blockinfo_cmp); @@ -531,14 +523,14 @@ prewarm_buffer_pool(void) state->block_info_handle = dsm_segment_handle(seg); state->prewarm_start_idx = state->prewarm_stop_idx = 0; - /* get next database's first block info's position. */ + /* Get the info position of the first block of the next database. */ while (state->prewarm_start_idx < num_elements) { uint32 i = state->prewarm_start_idx; Oid current_db = blkinfo[i].database; /* - * advance the prewarm_stop_idx to end of block infos of current + * Advance the prewarm_stop_idx to the end of block info of current * database. */ do @@ -549,7 +541,7 @@ prewarm_buffer_pool(void) /* * For block info of a global object whose database will be 0 * try to combine them with next non-zero database's block - * infos to load. + * info to load. */ if (current_db != InvalidOid) break; @@ -559,8 +551,8 @@ prewarm_buffer_pool(void) /* * If we are here with database as InvalidOid it means we only have - * block_infos belonging to global objects. As we do not have a valid - * database to connect we shall simply ignore them. + * block_info belonging to global objects. As we do not have a valid + * database to connect we shall ignore them. */ if (current_db == 0) break; @@ -571,8 +563,8 @@ prewarm_buffer_pool(void) Assert(state->prewarm_start_idx < state->prewarm_stop_idx); /* - * Register a per-database worker to load new database's block. And - * wait until they finish their job to launch next one. + * Register a per-database worker to load new database's block. Wait + * until they finish their job to launch next one. */ launch_and_wait_for_per_database_worker(); state->prewarm_start_idx = state->prewarm_stop_idx; @@ -588,21 +580,21 @@ prewarm_buffer_pool(void) } /* ============================================================================ - * ============= buffer pool info dump part of autoprewarm =============== + * ============= Buffer pool info dump part of autoprewarm =============== * ============================================================================ */ /* This sub-module is for periodically dumping buffer pool's block info into * a dump file AUTOPREWARM_FILE. - * Each entry of block info looks like this: - * database,tablespace,filenode,forknum,blocknum and we shall call it as - * BlockInfoRecord. Note we write in the text form so that the dump information - * is readable and if necessary can be carefully edited. + * Each entry of block info consists of following, + * database, tablespace, filenode, forknum, blocknum, and we will refer it as + * BlockInfoRecord. Note that this is in the text form so that the dump information + * is readable and can be edited, if required. */ /* * dump_now - * Dumps block infos in buffer pool + * Dumps block info in buffer pool. */ static uint32 dump_now(bool is_bgworker) @@ -643,9 +635,7 @@ dump_now(bool is_bgworker) { uint32 buf_state; - /* - * In case of a SIGHUP, just reload the configuration. - */ + /* In case of a SIGHUP, just reload the configuration. */ if (got_sighup) { got_sighup = false; @@ -661,7 +651,7 @@ dump_now(bool is_bgworker) bufHdr = GetBufferDescriptor(i); - /* lock each buffer header before inspecting. */ + /* Lock each buffer header before inspecting. */ buf_state = LockBufHdr(bufHdr); if (buf_state & BM_TAG_VALID) @@ -696,9 +686,7 @@ dump_now(bool is_bgworker) for (i = 0; i < num_blocks; i++) { - /* - * In case of a SIGHUP, just reload the configuration. - */ + /* In case of a SIGHUP, just reload the configuration. */ if (got_sighup) { got_sighup = false; @@ -738,7 +726,7 @@ dump_now(bool is_bgworker) pfree(block_info_array); /* - * rename transient_dump_file_path to AUTOPREWARM_FILE to make things + * Rename transient_dump_file_path to AUTOPREWARM_FILE to make things * permanent. */ ret = CloseTransientFile(fd); @@ -758,10 +746,9 @@ dump_now(bool is_bgworker) /* * dump_block_info_periodically - * Loop which periodically calls dump_now() + * Sub-routine to periodically call dump_now(). * - * At regular intervals, which is defined by GUC dump_interval, dump_now() will - * be called. + * Call dum_now() at regular intervals defined by GUC variable --dump_interval. */ void dump_block_info_periodically(void) @@ -776,7 +763,7 @@ dump_block_info_periodically(void) nap.tv_sec = AT_PWARM_DEFAULT_DUMP_INTERVAL; nap.tv_usec = 0; - /* Has been set not to dump. Nothing more to do. */ + /* If prewarm is set to off then nothing more to do. */ if (dump_interval == AT_PWARM_OFF) return; @@ -790,8 +777,8 @@ dump_block_info_periodically(void) { dump_now(true); if (got_sigterm) - return; /* got shutdown signal during or right after a - * dump. And, I think better to return now. */ + return; /* It is better to return when shutdown signal + * is receive during or right after a dump. */ last_dump_time = GetCurrentTimestamp(); nap.tv_sec = dump_interval; nap.tv_usec = 0; @@ -817,9 +804,7 @@ dump_block_info_periodically(void) if (rc & WL_POSTMASTER_DEATH) proc_exit(1); - /* - * In case of a SIGHUP, just reload the configuration. - */ + /* In case of a SIGHUP, just reload the configuration. */ if (got_sighup) { got_sighup = false; @@ -834,7 +819,7 @@ dump_block_info_periodically(void) /* * autoprewarm_main - * The main entry point of autoprewarm bgworker process + * The main entry point of autoprewarm bgworker process. */ void autoprewarm_main(Datum main_arg) @@ -846,7 +831,7 @@ autoprewarm_main(Datum main_arg) pqsignal(SIGHUP, apw_sighup_handler); pqsignal(SIGUSR1, apw_sigusr1_handler); - /* We're now ready to receive signals */ + /* We're now ready to receive signals. */ BackgroundWorkerUnblockSignals(); todo_task = DatumGetInt32(main_arg); @@ -859,7 +844,7 @@ autoprewarm_main(Datum main_arg) { LWLockRelease(&state->lock); ereport(LOG, - (errmsg("could not continue autoprewarm worker is already running under PID %d", + (errmsg("autoprewarm worker is already running under PID %d", state->bgworker_pid))); return; } @@ -873,7 +858,7 @@ autoprewarm_main(Datum main_arg) (errmsg("autoprewarm has started"))); /* - * **** perform autoprewarm's task **** + * **** Perform autoprewarm's task **** */ if (todo_task == TASK_PREWARM_BUFFERPOOL && !state->skip_prewarm_on_restart) @@ -886,13 +871,13 @@ autoprewarm_main(Datum main_arg) } /* ============================================================================ - * ============= extension's entry functions/utilities =================== + * ============= Extension's entry functions/utilities =================== * ============================================================================ */ /* * setup_autoprewarm - * A Common function to initialize BackgroundWorker structure + * A Common function to initialize BackgroundWorker structure. */ static void setup_autoprewarm(BackgroundWorker *autoprewarm, const char *worker_name, @@ -913,7 +898,7 @@ setup_autoprewarm(BackgroundWorker *autoprewarm, const char *worker_name, /* * _PG_init - * Extension's entry point + * Extension's entry point. */ void _PG_init(void) @@ -948,14 +933,14 @@ _PG_init(void) EmitWarningsOnPlaceholders("pg_prewarm"); - /* if not run as a preloaded library, nothing more to do here! */ + /* If not run as a preloaded library, nothing more to do here. */ if (!process_shared_preload_libraries_in_progress) return; - /* Request additional shared resources */ + /* Request additional shared resources. */ RequestAddinShmemSpace(MAXALIGN(sizeof(AutoPrewarmSharedState))); - /* Has been set not to start autoprewarm bgworker. Nothing more to do. */ + /* If autoprewarm bgworker is disabled then nothing more to do. */ if (!autoprewarm) return; @@ -967,7 +952,7 @@ _PG_init(void) /* * autoprewarm_dump_launcher - * Dynamically launch an autoprewarm dump worker + * Dynamically launch an autoprewarm dump worker. */ static pid_t autoprewarm_dump_launcher(void) @@ -980,7 +965,7 @@ autoprewarm_dump_launcher(void) setup_autoprewarm(&worker, "autoprewarm", "autoprewarm_main", Int32GetDatum(TASK_DUMP_BUFFERPOOL_INFO), 0, 0); - /* set bgw_notify_pid so that we can use WaitForBackgroundWorkerStartup */ + /* Set bgw_notify_pid so that we can use WaitForBackgroundWorkerStartup */ worker.bgw_notify_pid = MyProcPid; if (!RegisterDynamicBackgroundWorker(&worker, &handle)) @@ -1014,14 +999,14 @@ autoprewarm_dump_launcher(void) /* * launch_autoprewarm_dump - * The C-Language entry function to launch autoprewarm dump bgworker + * The C-Language entry function to launch autoprewarm dump bgworker. */ Datum launch_autoprewarm_dump(PG_FUNCTION_ARGS) { pid_t pid; - /* Has been set not to dump. Nothing more to do. */ + /* If dump_interval is disabled then nothing more to do. */ if (dump_interval == AT_PWARM_OFF) PG_RETURN_NULL(); @@ -1031,7 +1016,7 @@ launch_autoprewarm_dump(PG_FUNCTION_ARGS) /* * autoprewarm_dump_now - * The C-Language entry function to dump immediately + * The C-Language entry function to dump immediately. */ Datum autoprewarm_dump_now(PG_FUNCTION_ARGS)