Set status for backend in background jobs

The status of background workers is recorded in PostgreSQL using the
function `pgstat_record_activity` which allow the status of the
background worker to be inspected using the `status` field in
`pg_stat_activity`.  This is used by the TimescaleDB `job_stats` view
to show if a job is running, scheduled, or paused.

However, the activity was never recorded in the code and hence the
field was always NULL. Since this was the default for the `job_status`
field of `timescaledb_information.job_stats` it would always show as
`Scheduled`.

This commit fixes this by adding calls to `pgstat_record_activity` at
suitable locations.

Fixes #2831
This commit is contained in:
Mats Kindahl 2021-01-21 15:30:21 +01:00 committed by Mats Kindahl
parent e3c6725ad1
commit 954c775275
5 changed files with 48 additions and 0 deletions

View File

@ -429,6 +429,7 @@ ts_bgw_job_stat_mark_start(int32 bgw_job_id)
RowExclusiveLock))
bgw_job_stat_insert_relation(rel, bgw_job_id, true, DT_NOBEGIN);
table_close(rel, ShareRowExclusiveLock);
pgstat_report_activity(STATE_IDLE, NULL);
}
}
@ -446,6 +447,7 @@ ts_bgw_job_stat_mark_end(BgwJob *job, JobResult result)
&res,
RowExclusiveLock))
elog(ERROR, "unable to find job statistics for job %d", job->fd.id);
pgstat_report_activity(STATE_IDLE, NULL);
}
bool

View File

@ -734,6 +734,8 @@ ts_bgw_scheduler_process(int32 run_for_interval_ms,
TimestampTz start = ts_timer_get_current_timestamp();
TimestampTz quit_time = DT_NOEND;
pgstat_report_activity(STATE_RUNNING, NULL);
/* txn to read the list of jobs from the DB */
StartTransactionCommand();
scheduled_jobs = ts_update_scheduled_jobs_list(scheduled_jobs, scheduler_mctx);
@ -763,7 +765,9 @@ ts_bgw_scheduler_process(int32 run_for_interval_ms,
next_wakeup = least_timestamp(next_wakeup, earliest_wakeup_to_start_next_job());
next_wakeup = least_timestamp(next_wakeup, earliest_job_timeout());
pgstat_report_activity(STATE_IDLE, NULL);
ts_timer_wait(next_wakeup);
pgstat_report_activity(STATE_RUNNING, NULL);
CHECK_FOR_INTERRUPTS();

View File

@ -463,6 +463,7 @@ job_execute(BgwJob *job)
List *name;
FuncExpr *funcexpr;
MemoryContext parent_ctx = CurrentMemoryContext;
StringInfo query;
if (!IsTransactionOrTransactionBlock())
{
@ -504,6 +505,19 @@ job_execute(BgwJob *job)
InvalidOid,
COERCE_EXPLICIT_CALL);
/* Here we create a query string from the function/procedure name that we
* are calling. We do not update the status after the execution has
* finished since this is wrapped inside the code that starts and stops
* any job, not just custom jobs. We just provide more detailed
* information here that we are actually calling a specific custom
* function. */
query = makeStringInfo();
appendStringInfo(query,
"CALL %s.%s()",
quote_identifier(NameStr(job->fd.proc_schema)),
quote_identifier(NameStr(job->fd.proc_name)));
pgstat_report_activity(STATE_RUNNING, query->data);
switch (prokind)
{
case PROKIND_FUNCTION:

View File

@ -212,6 +212,26 @@ SELECT application_name FROM pg_stat_activity WHERE application_name LIKE 'User-
User-Defined Action [1001]
(1 row)
\x on
SELECT job_id, job_status FROM timescaledb_information.job_stats;
-[ RECORD 1 ]-------
job_id | 1001
job_status | Running
-- Showing non-volatile information from pg_stat_activity for
-- debugging purposes. Information schema above reads from this view.
SELECT datname, usename, application_name, state, query, wait_event_type, wait_event
FROM pg_stat_activity WHERE application_name LIKE 'User-Defined Action%';
-[ RECORD 1 ]----+------------------------------------
datname | db_bgw_db_scheduler
usename | default_perm_user
application_name | User-Defined Action [1001]
state | active
query | CALL public.ts_bgw_test_job_sleep()
wait_event_type | Timeout
wait_event | PgSleep
\x off
-- have to suppress notices here as delete_job will print pid of the running background worker processes
SET client_min_messages TO WARNING;
SELECT delete_job(:job_id);

View File

@ -150,6 +150,14 @@ SELECT ts_bgw_db_scheduler_test_run();
SELECT wait_for_logentry(:job_id);
SELECT application_name FROM pg_stat_activity WHERE application_name LIKE 'User-Defined Action%';
\x on
SELECT job_id, job_status FROM timescaledb_information.job_stats;
-- Showing non-volatile information from pg_stat_activity for
-- debugging purposes. Information schema above reads from this view.
SELECT datname, usename, application_name, state, query, wait_event_type, wait_event
FROM pg_stat_activity WHERE application_name LIKE 'User-Defined Action%';
\x off
-- have to suppress notices here as delete_job will print pid of the running background worker processes
SET client_min_messages TO WARNING;
SELECT delete_job(:job_id);