mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-17 11:03:36 +08:00
Add next_start option to alter_job_schedule
Add the option to set the next start time on a job in the alter job schedule function. This also adds the ability to pause jobs by setting next_start to 'infinity' Also fix the enterprise licence check to only activate for enterprise jobs.
This commit is contained in:
parent
01f2bbaf5a
commit
2209133781
@ -45,7 +45,9 @@ CREATE OR REPLACE FUNCTION alter_job_schedule(
|
|||||||
max_runtime INTERVAL = NULL,
|
max_runtime INTERVAL = NULL,
|
||||||
max_retries INTEGER = NULL,
|
max_retries INTEGER = NULL,
|
||||||
retry_period INTERVAL = NULL,
|
retry_period INTERVAL = NULL,
|
||||||
if_exists BOOL = FALSE)
|
if_exists BOOL = FALSE,
|
||||||
RETURNS TABLE (job_id INTEGER, schedule_interval INTERVAL, max_runtime INTERVAL, max_retries INTEGER, retry_period INTERVAL)
|
next_start TIMESTAMPTZ = NULL
|
||||||
|
)
|
||||||
|
RETURNS TABLE (job_id INTEGER, schedule_interval INTERVAL, max_runtime INTERVAL, max_retries INTEGER, retry_period INTERVAL, next_start TIMESTAMPTZ)
|
||||||
AS '@MODULE_PATHNAME@', 'ts_alter_job_schedule'
|
AS '@MODULE_PATHNAME@', 'ts_alter_job_schedule'
|
||||||
LANGUAGE C VOLATILE;
|
LANGUAGE C VOLATILE;
|
||||||
|
@ -58,3 +58,5 @@ INSERT INTO _timescaledb_config.bgw_policy_drop_chunks
|
|||||||
SELECT pg_catalog.pg_extension_config_dump('_timescaledb_config.bgw_policy_drop_chunks', '');
|
SELECT pg_catalog.pg_extension_config_dump('_timescaledb_config.bgw_policy_drop_chunks', '');
|
||||||
DROP TABLE _timescaledb_config.bgw_policy_drop_chunks_tmp;
|
DROP TABLE _timescaledb_config.bgw_policy_drop_chunks_tmp;
|
||||||
GRANT SELECT ON _timescaledb_config.bgw_policy_drop_chunks TO PUBLIC;
|
GRANT SELECT ON _timescaledb_config.bgw_policy_drop_chunks TO PUBLIC;
|
||||||
|
|
||||||
|
DROP FUNCTION IF EXISTS alter_job_schedule(INTEGER, INTERVAL, INTERVAL, INTEGER, INTERVAL, BOOL);
|
||||||
|
@ -771,7 +771,10 @@ bgw_job_tuple_update_by_id(TupleInfo *ti, void *const data)
|
|||||||
DirectFunctionCall2(timestamptz_pl_interval,
|
DirectFunctionCall2(timestamptz_pl_interval,
|
||||||
TimestampTzGetDatum(stat->fd.last_finish),
|
TimestampTzGetDatum(stat->fd.last_finish),
|
||||||
IntervalPGetDatum(&updated_job->fd.schedule_interval)));
|
IntervalPGetDatum(&updated_job->fd.schedule_interval)));
|
||||||
ts_bgw_job_stat_update_next_start(updated_job, next_start);
|
/* allow DT_NOBEGIN for next_start here through allow_unset=true in the case that
|
||||||
|
* last_finish is DT_NOBEGIN,
|
||||||
|
* This means the value is counted as unset which is what we want */
|
||||||
|
ts_bgw_job_stat_update_next_start(updated_job, next_start, true);
|
||||||
}
|
}
|
||||||
fd->schedule_interval = updated_job->fd.schedule_interval;
|
fd->schedule_interval = updated_job->fd.schedule_interval;
|
||||||
}
|
}
|
||||||
|
@ -296,7 +296,8 @@ bgw_job_stat_tuple_set_next_start(TupleInfo *ti, void *const data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
bgw_job_stat_insert_mark_start_relation(Relation rel, int32 bgw_job_id)
|
bgw_job_stat_insert_relation(Relation rel, int32 bgw_job_id, bool mark_start,
|
||||||
|
TimestampTz next_start)
|
||||||
{
|
{
|
||||||
TupleDesc desc = RelationGetDescr(rel);
|
TupleDesc desc = RelationGetDescr(rel);
|
||||||
Datum values[Natts_bgw_job_stat];
|
Datum values[Natts_bgw_job_stat];
|
||||||
@ -307,21 +308,35 @@ bgw_job_stat_insert_mark_start_relation(Relation rel, int32 bgw_job_id)
|
|||||||
};
|
};
|
||||||
|
|
||||||
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_job_id)] = Int32GetDatum(bgw_job_id);
|
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_job_id)] = Int32GetDatum(bgw_job_id);
|
||||||
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_last_start)] =
|
if (mark_start)
|
||||||
TimestampGetDatum(ts_timer_get_current_timestamp());
|
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_last_start)] =
|
||||||
|
TimestampGetDatum(ts_timer_get_current_timestamp());
|
||||||
|
else
|
||||||
|
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_last_start)] =
|
||||||
|
TimestampGetDatum(DT_NOBEGIN);
|
||||||
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_last_finish)] = TimestampGetDatum(DT_NOBEGIN);
|
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_last_finish)] = TimestampGetDatum(DT_NOBEGIN);
|
||||||
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_next_start)] = TimestampGetDatum(DT_NOBEGIN);
|
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_next_start)] = TimestampGetDatum(next_start);
|
||||||
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_total_runs)] = Int64GetDatum(1);
|
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_total_runs)] =
|
||||||
|
Int64GetDatum((mark_start ? 1 : 0));
|
||||||
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_total_duration)] =
|
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_total_duration)] =
|
||||||
IntervalPGetDatum(&zero_ival);
|
IntervalPGetDatum(&zero_ival);
|
||||||
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_total_success)] = Int64GetDatum(0);
|
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_total_success)] = Int64GetDatum(0);
|
||||||
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_total_failures)] = Int64GetDatum(0);
|
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_total_failures)] = Int64GetDatum(0);
|
||||||
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_consecutive_failures)] = Int32GetDatum(0);
|
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_consecutive_failures)] = Int32GetDatum(0);
|
||||||
|
|
||||||
/* This is udone by any of the end marks */
|
if (mark_start)
|
||||||
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_last_run_success)] = BoolGetDatum(false);
|
{
|
||||||
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_total_crashes)] = Int64GetDatum(1);
|
/* This is udone by any of the end marks */
|
||||||
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_consecutive_crashes)] = Int32GetDatum(1);
|
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_last_run_success)] = BoolGetDatum(false);
|
||||||
|
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_total_crashes)] = Int64GetDatum(1);
|
||||||
|
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_consecutive_crashes)] = Int32GetDatum(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_last_run_success)] = BoolGetDatum(true);
|
||||||
|
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_total_crashes)] = Int64GetDatum(0);
|
||||||
|
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_consecutive_crashes)] = Int32GetDatum(0);
|
||||||
|
}
|
||||||
|
|
||||||
ts_catalog_database_info_become_owner(ts_catalog_database_info_get(), &sec_ctx);
|
ts_catalog_database_info_become_owner(ts_catalog_database_info_get(), &sec_ctx);
|
||||||
ts_catalog_insert_values(rel, desc, values, nulls);
|
ts_catalog_insert_values(rel, desc, values, nulls);
|
||||||
@ -330,29 +345,27 @@ bgw_job_stat_insert_mark_start_relation(Relation rel, int32 bgw_job_id)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
bgw_job_stat_insert_mark_start(int32 bgw_job_id)
|
|
||||||
{
|
|
||||||
Catalog *catalog = ts_catalog_get();
|
|
||||||
Relation rel;
|
|
||||||
bool result;
|
|
||||||
|
|
||||||
rel = heap_open(catalog_get_table_id(catalog, BGW_JOB_STAT), RowExclusiveLock);
|
|
||||||
result = bgw_job_stat_insert_mark_start_relation(rel, bgw_job_id);
|
|
||||||
heap_close(rel, RowExclusiveLock);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ts_bgw_job_stat_mark_start(int32 bgw_job_id)
|
ts_bgw_job_stat_mark_start(int32 bgw_job_id)
|
||||||
{
|
{
|
||||||
|
/* Use double-check locking */
|
||||||
if (!bgw_job_stat_scan_job_id(bgw_job_id,
|
if (!bgw_job_stat_scan_job_id(bgw_job_id,
|
||||||
bgw_job_stat_tuple_mark_start,
|
bgw_job_stat_tuple_mark_start,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
RowExclusiveLock))
|
RowExclusiveLock))
|
||||||
bgw_job_stat_insert_mark_start(bgw_job_id);
|
{
|
||||||
|
Relation rel =
|
||||||
|
heap_open(catalog_get_table_id(ts_catalog_get(), BGW_JOB_STAT), ShareRowExclusiveLock);
|
||||||
|
/* Recheck while having a self-exclusive lock */
|
||||||
|
if (!bgw_job_stat_scan_job_id(bgw_job_id,
|
||||||
|
bgw_job_stat_tuple_mark_start,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
RowExclusiveLock))
|
||||||
|
bgw_job_stat_insert_relation(rel, bgw_job_id, true, DT_NOBEGIN);
|
||||||
|
heap_close(rel, ShareRowExclusiveLock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -394,11 +407,11 @@ ts_bgw_job_stat_set_next_start(BgwJob *job, TimestampTz next_start)
|
|||||||
|
|
||||||
/* update next_start if job stat exists */
|
/* update next_start if job stat exists */
|
||||||
TSDLLEXPORT bool
|
TSDLLEXPORT bool
|
||||||
ts_bgw_job_stat_update_next_start(BgwJob *job, TimestampTz next_start)
|
ts_bgw_job_stat_update_next_start(BgwJob *job, TimestampTz next_start, bool allow_unset)
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
/* Cannot use DT_NOBEGIN as that's the value used to indicate "not set" */
|
/* Cannot use DT_NOBEGIN as that's the value used to indicate "not set" */
|
||||||
if (next_start == DT_NOBEGIN)
|
if (!allow_unset && next_start == DT_NOBEGIN)
|
||||||
elog(ERROR, "cannot set next start to -infinity");
|
elog(ERROR, "cannot set next start to -infinity");
|
||||||
|
|
||||||
found = bgw_job_stat_scan_job_id(job->fd.id,
|
found = bgw_job_stat_scan_job_id(job->fd.id,
|
||||||
@ -409,6 +422,33 @@ ts_bgw_job_stat_update_next_start(BgwJob *job, TimestampTz next_start)
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TSDLLEXPORT void
|
||||||
|
ts_bgw_job_stat_upsert_next_start(int32 bgw_job_id, TimestampTz next_start)
|
||||||
|
{
|
||||||
|
/* Cannot use DT_NOBEGIN as that's the value used to indicate "not set" */
|
||||||
|
if (next_start == DT_NOBEGIN)
|
||||||
|
elog(ERROR, "cannot set next start to -infinity");
|
||||||
|
|
||||||
|
/* Use double-check locking */
|
||||||
|
if (!bgw_job_stat_scan_job_id(bgw_job_id,
|
||||||
|
bgw_job_stat_tuple_set_next_start,
|
||||||
|
NULL,
|
||||||
|
&next_start,
|
||||||
|
RowExclusiveLock))
|
||||||
|
{
|
||||||
|
Relation rel =
|
||||||
|
heap_open(catalog_get_table_id(ts_catalog_get(), BGW_JOB_STAT), ShareRowExclusiveLock);
|
||||||
|
/* Recheck while having a self-exclusive lock */
|
||||||
|
if (!bgw_job_stat_scan_job_id(bgw_job_id,
|
||||||
|
bgw_job_stat_tuple_set_next_start,
|
||||||
|
NULL,
|
||||||
|
&next_start,
|
||||||
|
RowExclusiveLock))
|
||||||
|
bgw_job_stat_insert_relation(rel, bgw_job_id, true, next_start);
|
||||||
|
heap_close(rel, ShareRowExclusiveLock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ts_bgw_job_stat_should_execute(BgwJobStat *jobstat, BgwJob *job)
|
ts_bgw_job_stat_should_execute(BgwJobStat *jobstat, BgwJob *job)
|
||||||
{
|
{
|
||||||
|
@ -27,7 +27,10 @@ extern void ts_bgw_job_stat_mark_end(BgwJob *job, JobResult result);
|
|||||||
extern bool ts_bgw_job_stat_end_was_marked(BgwJobStat *jobstat);
|
extern bool ts_bgw_job_stat_end_was_marked(BgwJobStat *jobstat);
|
||||||
|
|
||||||
extern TSDLLEXPORT void ts_bgw_job_stat_set_next_start(BgwJob *job, TimestampTz next_start);
|
extern TSDLLEXPORT void ts_bgw_job_stat_set_next_start(BgwJob *job, TimestampTz next_start);
|
||||||
extern TSDLLEXPORT bool ts_bgw_job_stat_update_next_start(BgwJob *job, TimestampTz next_start);
|
extern TSDLLEXPORT bool ts_bgw_job_stat_update_next_start(BgwJob *job, TimestampTz next_start,
|
||||||
|
bool allow_unset);
|
||||||
|
|
||||||
|
extern TSDLLEXPORT void ts_bgw_job_stat_upsert_next_start(int32 bgw_job_id, TimestampTz next_start);
|
||||||
|
|
||||||
extern bool ts_bgw_job_stat_should_execute(BgwJobStat *jobstat, BgwJob *job);
|
extern bool ts_bgw_job_stat_should_execute(BgwJobStat *jobstat, BgwJob *job);
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
#include "drop_chunks_api.h"
|
#include "drop_chunks_api.h"
|
||||||
#include "interval.h"
|
#include "interval.h"
|
||||||
|
|
||||||
#define ALTER_JOB_SCHEDULE_NUM_COLS 5
|
#define ALTER_JOB_SCHEDULE_NUM_COLS 6
|
||||||
#define REORDER_SKIP_RECENT_DIM_SLICES_N 3
|
#define REORDER_SKIP_RECENT_DIM_SLICES_N 3
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -289,17 +289,16 @@ Datum
|
|||||||
bgw_policy_alter_job_schedule(PG_FUNCTION_ARGS)
|
bgw_policy_alter_job_schedule(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
BgwJob *job;
|
BgwJob *job;
|
||||||
|
BgwJobStat *stat;
|
||||||
TupleDesc tupdesc;
|
TupleDesc tupdesc;
|
||||||
Datum values[ALTER_JOB_SCHEDULE_NUM_COLS];
|
Datum values[ALTER_JOB_SCHEDULE_NUM_COLS];
|
||||||
bool nulls[ALTER_JOB_SCHEDULE_NUM_COLS] = { false };
|
bool nulls[ALTER_JOB_SCHEDULE_NUM_COLS] = { false };
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
|
TimestampTz next_start;
|
||||||
|
|
||||||
int job_id = PG_GETARG_INT32(0);
|
int job_id = PG_GETARG_INT32(0);
|
||||||
bool if_exists = PG_GETARG_BOOL(5);
|
bool if_exists = PG_GETARG_BOOL(5);
|
||||||
|
|
||||||
license_enforce_enterprise_enabled();
|
|
||||||
license_print_expiration_warning_if_needed();
|
|
||||||
|
|
||||||
/* First get the job */
|
/* First get the job */
|
||||||
job = ts_bgw_job_find(job_id, CurrentMemoryContext, false);
|
job = ts_bgw_job_find(job_id, CurrentMemoryContext, false);
|
||||||
|
|
||||||
@ -318,6 +317,10 @@ bgw_policy_alter_job_schedule(PG_FUNCTION_ARGS)
|
|||||||
errmsg("cannot alter policy schedule, policy #%d not found", job_id)));
|
errmsg("cannot alter policy schedule, policy #%d not found", job_id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bgw_policy_job_requires_enterprise_license(job))
|
||||||
|
license_enforce_enterprise_enabled();
|
||||||
|
license_print_expiration_warning_if_needed();
|
||||||
|
|
||||||
ts_bgw_job_permission_check(job);
|
ts_bgw_job_permission_check(job);
|
||||||
|
|
||||||
if (!PG_ARGISNULL(1))
|
if (!PG_ARGISNULL(1))
|
||||||
@ -331,6 +334,9 @@ bgw_policy_alter_job_schedule(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
ts_bgw_job_update_by_id(job_id, job);
|
ts_bgw_job_update_by_id(job_id, job);
|
||||||
|
|
||||||
|
if (!PG_ARGISNULL(6))
|
||||||
|
ts_bgw_job_stat_upsert_next_start(job_id, PG_GETARG_TIMESTAMPTZ(6));
|
||||||
|
|
||||||
/* Now look up the job and return it */
|
/* Now look up the job and return it */
|
||||||
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
|
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
@ -338,12 +344,19 @@ bgw_policy_alter_job_schedule(PG_FUNCTION_ARGS)
|
|||||||
errmsg("function returning record called in context "
|
errmsg("function returning record called in context "
|
||||||
"that cannot accept type record")));
|
"that cannot accept type record")));
|
||||||
|
|
||||||
|
stat = ts_bgw_job_stat_find(job_id);
|
||||||
|
if (stat != NULL)
|
||||||
|
next_start = stat->fd.next_start;
|
||||||
|
else
|
||||||
|
next_start = DT_NOBEGIN;
|
||||||
|
|
||||||
tupdesc = BlessTupleDesc(tupdesc);
|
tupdesc = BlessTupleDesc(tupdesc);
|
||||||
values[0] = Int32GetDatum(job->fd.id);
|
values[0] = Int32GetDatum(job->fd.id);
|
||||||
values[1] = IntervalPGetDatum(&job->fd.schedule_interval);
|
values[1] = IntervalPGetDatum(&job->fd.schedule_interval);
|
||||||
values[2] = IntervalPGetDatum(&job->fd.max_runtime);
|
values[2] = IntervalPGetDatum(&job->fd.max_runtime);
|
||||||
values[3] = Int32GetDatum(job->fd.max_retries);
|
values[3] = Int32GetDatum(job->fd.max_retries);
|
||||||
values[4] = IntervalPGetDatum(&job->fd.retry_period);
|
values[4] = IntervalPGetDatum(&job->fd.retry_period);
|
||||||
|
values[5] = TimestampTzGetDatum(next_start);
|
||||||
|
|
||||||
tuple = heap_form_tuple(tupdesc, values, nulls);
|
tuple = heap_form_tuple(tupdesc, values, nulls);
|
||||||
return HeapTupleGetDatum(tuple);
|
return HeapTupleGetDatum(tuple);
|
||||||
|
@ -440,9 +440,9 @@ SELECT json_object_field(get_telemetry_report(always_display_report := true)::js
|
|||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT alter_job_schedule(:drop_chunks_job_id, schedule_interval => INTERVAL '1 second');
|
SELECT alter_job_schedule(:drop_chunks_job_id, schedule_interval => INTERVAL '1 second');
|
||||||
alter_job_schedule
|
alter_job_schedule
|
||||||
---------------------------------------------
|
-------------------------------------------------------
|
||||||
(1001,"@ 1 sec","@ 5 mins",-1,"@ 12 hours")
|
(1001,"@ 1 sec","@ 5 mins",-1,"@ 12 hours",-infinity)
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
select * from _timescaledb_config.bgw_policy_drop_chunks where job_id=:drop_chunks_job_id;
|
select * from _timescaledb_config.bgw_policy_drop_chunks where job_id=:drop_chunks_job_id;
|
||||||
|
@ -285,6 +285,28 @@ WHERE job_id=:job_id;
|
|||||||
1000 | @ 1 min | 3
|
1000 | @ 1 min | 3
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
--change next run to be after 30s instead
|
||||||
|
SELECT (next_start - '30s'::interval) AS "NEW_NEXT_START"
|
||||||
|
FROM _timescaledb_internal.bgw_job_stat
|
||||||
|
WHERE job_id=:job_id \gset
|
||||||
|
SELECT alter_job_schedule(:job_id, next_start => :'NEW_NEXT_START');
|
||||||
|
alter_job_schedule
|
||||||
|
--------------------------------------------------------------------
|
||||||
|
(1000,"@ 1 min","@ 0",-1,"@ 1 min","Sat Jan 01 04:02:30 2000 PST")
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT ts_bgw_params_reset_time((extract(epoch from interval '12 hour')::bigint * 1000000)+(extract(epoch from interval '2 minute 30 seconds')::bigint * 1000000), true);
|
||||||
|
ts_bgw_params_reset_time
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT wait_for_job_to_run(:job_id, 4);
|
||||||
|
wait_for_job_to_run
|
||||||
|
---------------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
--advance clock to quit scheduler
|
--advance clock to quit scheduler
|
||||||
SELECT ts_bgw_params_reset_time(extract(epoch from interval '25 hour')::bigint * 1000000, true);
|
SELECT ts_bgw_params_reset_time(extract(epoch from interval '25 hour')::bigint * 1000000, true);
|
||||||
ts_bgw_params_reset_time
|
ts_bgw_params_reset_time
|
||||||
|
@ -776,73 +776,152 @@ select add_reorder_policy('test_table', 'test_table_time_idx') as job_id \gset
|
|||||||
|
|
||||||
-- No change
|
-- No change
|
||||||
select * from alter_job_schedule(:job_id);
|
select * from alter_job_schedule(:job_id);
|
||||||
job_id | schedule_interval | max_runtime | max_retries | retry_period
|
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
|
||||||
--------+-------------------+-------------+-------------+--------------
|
--------+-------------------+-------------+-------------+--------------+------------
|
||||||
1014 | @ 84 hours | @ 0 | -1 | @ 1 day
|
1014 | @ 84 hours | @ 0 | -1 | @ 1 day | -infinity
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- Changes expected
|
-- Changes expected
|
||||||
select * from alter_job_schedule(:job_id, INTERVAL '3 years', INTERVAL '5 min', 5, INTERVAL '123 sec');
|
select * from alter_job_schedule(:job_id, INTERVAL '3 years', INTERVAL '5 min', 5, INTERVAL '123 sec');
|
||||||
job_id | schedule_interval | max_runtime | max_retries | retry_period
|
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
|
||||||
--------+-------------------+-------------+-------------+-----------------
|
--------+-------------------+-------------+-------------+-----------------+------------
|
||||||
1014 | @ 3 years | @ 5 mins | 5 | @ 2 mins 3 secs
|
1014 | @ 3 years | @ 5 mins | 5 | @ 2 mins 3 secs | -infinity
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
select * from alter_job_schedule(:job_id, INTERVAL '123 years');
|
select * from alter_job_schedule(:job_id, INTERVAL '123 years');
|
||||||
job_id | schedule_interval | max_runtime | max_retries | retry_period
|
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
|
||||||
--------+-------------------+-------------+-------------+-----------------
|
--------+-------------------+-------------+-------------+-----------------+------------
|
||||||
1014 | @ 123 years | @ 5 mins | 5 | @ 2 mins 3 secs
|
1014 | @ 123 years | @ 5 mins | 5 | @ 2 mins 3 secs | -infinity
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
select * from alter_job_schedule(:job_id, retry_period => INTERVAL '33 hours');
|
select * from alter_job_schedule(:job_id, retry_period => INTERVAL '33 hours');
|
||||||
job_id | schedule_interval | max_runtime | max_retries | retry_period
|
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
|
||||||
--------+-------------------+-------------+-------------+--------------
|
--------+-------------------+-------------+-------------+--------------+------------
|
||||||
1014 | @ 123 years | @ 5 mins | 5 | @ 33 hours
|
1014 | @ 123 years | @ 5 mins | 5 | @ 33 hours | -infinity
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
select * from alter_job_schedule(:job_id, max_runtime => INTERVAL '456 sec');
|
select * from alter_job_schedule(:job_id, max_runtime => INTERVAL '456 sec');
|
||||||
job_id | schedule_interval | max_runtime | max_retries | retry_period
|
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
|
||||||
--------+-------------------+------------------+-------------+--------------
|
--------+-------------------+------------------+-------------+--------------+------------
|
||||||
1014 | @ 123 years | @ 7 mins 36 secs | 5 | @ 33 hours
|
1014 | @ 123 years | @ 7 mins 36 secs | 5 | @ 33 hours | -infinity
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
select * from alter_job_schedule(:job_id, max_retries => 0);
|
select * from alter_job_schedule(:job_id, max_retries => 0);
|
||||||
job_id | schedule_interval | max_runtime | max_retries | retry_period
|
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
|
||||||
--------+-------------------+------------------+-------------+--------------
|
--------+-------------------+------------------+-------------+--------------+------------
|
||||||
1014 | @ 123 years | @ 7 mins 36 secs | 0 | @ 33 hours
|
1014 | @ 123 years | @ 7 mins 36 secs | 0 | @ 33 hours | -infinity
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
select * from alter_job_schedule(:job_id, max_retries => -1);
|
select * from alter_job_schedule(:job_id, max_retries => -1);
|
||||||
job_id | schedule_interval | max_runtime | max_retries | retry_period
|
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
|
||||||
--------+-------------------+------------------+-------------+--------------
|
--------+-------------------+------------------+-------------+--------------+------------
|
||||||
1014 | @ 123 years | @ 7 mins 36 secs | -1 | @ 33 hours
|
1014 | @ 123 years | @ 7 mins 36 secs | -1 | @ 33 hours | -infinity
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
select * from alter_job_schedule(:job_id, max_retries => 20);
|
select * from alter_job_schedule(:job_id, max_retries => 20);
|
||||||
job_id | schedule_interval | max_runtime | max_retries | retry_period
|
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
|
||||||
--------+-------------------+------------------+-------------+--------------
|
--------+-------------------+------------------+-------------+--------------+------------
|
||||||
1014 | @ 123 years | @ 7 mins 36 secs | 20 | @ 33 hours
|
1014 | @ 123 years | @ 7 mins 36 secs | 20 | @ 33 hours | -infinity
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- No change
|
-- No change
|
||||||
select * from alter_job_schedule(:job_id, max_runtime => NULL);
|
select * from alter_job_schedule(:job_id, max_runtime => NULL);
|
||||||
job_id | schedule_interval | max_runtime | max_retries | retry_period
|
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
|
||||||
--------+-------------------+------------------+-------------+--------------
|
--------+-------------------+------------------+-------------+--------------+------------
|
||||||
1014 | @ 123 years | @ 7 mins 36 secs | 20 | @ 33 hours
|
1014 | @ 123 years | @ 7 mins 36 secs | 20 | @ 33 hours | -infinity
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
select * from alter_job_schedule(:job_id, max_retries => NULL);
|
select * from alter_job_schedule(:job_id, max_retries => NULL);
|
||||||
job_id | schedule_interval | max_runtime | max_retries | retry_period
|
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
|
||||||
--------+-------------------+------------------+-------------+--------------
|
--------+-------------------+------------------+-------------+--------------+------------
|
||||||
1014 | @ 123 years | @ 7 mins 36 secs | 20 | @ 33 hours
|
1014 | @ 123 years | @ 7 mins 36 secs | 20 | @ 33 hours | -infinity
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
--change schedule_interval when bgw_job_stat does not exist
|
||||||
|
select * from alter_job_schedule(:job_id, schedule_interval=>'1 min');
|
||||||
|
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
|
||||||
|
--------+-------------------+------------------+-------------+--------------+------------
|
||||||
|
1014 | @ 1 min | @ 7 mins 36 secs | 20 | @ 33 hours | -infinity
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select count(*) = 0 from _timescaledb_internal.bgw_job_stat where job_id = :job_id;
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
--set next_start when bgw_job_stat does not exist
|
||||||
|
select * from alter_job_schedule(:job_id, next_start=>'2001-01-01 01:01:01');
|
||||||
|
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
|
||||||
|
--------+-------------------+------------------+-------------+--------------+------------------------------
|
||||||
|
1014 | @ 1 min | @ 7 mins 36 secs | 20 | @ 33 hours | Mon Jan 01 01:01:01 2001 PST
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
--change schedule_interval when no last_finish set
|
||||||
|
select * from alter_job_schedule(:job_id, schedule_interval=>'10 min');
|
||||||
|
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
|
||||||
|
--------+-------------------+------------------+-------------+--------------+------------
|
||||||
|
1014 | @ 10 mins | @ 7 mins 36 secs | 20 | @ 33 hours | -infinity
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
--next_start overrides any schedule_interval changes
|
||||||
|
select * from alter_job_schedule(:job_id, schedule_interval=>'20 min', next_start=>'2002-01-01 01:01:01');
|
||||||
|
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
|
||||||
|
--------+-------------------+------------------+-------------+--------------+------------------------------
|
||||||
|
1014 | @ 20 mins | @ 7 mins 36 secs | 20 | @ 33 hours | Tue Jan 01 01:01:01 2002 PST
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
--set the last_finish manually
|
||||||
|
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||||
|
UPDATE _timescaledb_internal.bgw_job_stat SET last_finish = '2003-01-01:01:01:01' WHERE job_id = :job_id;
|
||||||
|
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
|
||||||
|
--not changing the interval doesn't change the next_start
|
||||||
|
select * from alter_job_schedule(:job_id, schedule_interval=>'20 min');
|
||||||
|
WARNING: Timescale License expired
|
||||||
|
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
|
||||||
|
--------+-------------------+------------------+-------------+--------------+------------------------------
|
||||||
|
1014 | @ 20 mins | @ 7 mins 36 secs | 20 | @ 33 hours | Tue Jan 01 01:01:01 2002 PST
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
--changing the interval changes next_start
|
||||||
|
select * from alter_job_schedule(:job_id, schedule_interval=>'30 min');
|
||||||
|
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
|
||||||
|
--------+-------------------+------------------+-------------+--------------+------------------------------
|
||||||
|
1014 | @ 30 mins | @ 7 mins 36 secs | 20 | @ 33 hours | Wed Jan 01 01:31:01 2003 PST
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
--explicit next start overrides.
|
||||||
|
select * from alter_job_schedule(:job_id, schedule_interval=>'40 min', next_start=>'2004-01-01 01:01:01');
|
||||||
|
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
|
||||||
|
--------+-------------------+------------------+-------------+--------------+------------------------------
|
||||||
|
1014 | @ 40 mins | @ 7 mins 36 secs | 20 | @ 33 hours | Thu Jan 01 01:01:01 2004 PST
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
--test pausing
|
||||||
|
select * from alter_job_schedule(:job_id, next_start=>'infinity');
|
||||||
|
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
|
||||||
|
--------+-------------------+------------------+-------------+--------------+------------
|
||||||
|
1014 | @ 40 mins | @ 7 mins 36 secs | 20 | @ 33 hours | infinity
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
--test that you can use now() to unpause
|
||||||
|
select next_start = now() from alter_job_schedule(:job_id, next_start=>now());
|
||||||
|
?column?
|
||||||
|
----------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\set ON_ERROR_STOP 0
|
||||||
|
-- negative infinity disallowed (used as special value)
|
||||||
|
select * from alter_job_schedule(:job_id, next_start=>'-infinity');
|
||||||
|
ERROR: cannot set next start to -infinity
|
||||||
|
\set ON_ERROR_STOP 1
|
||||||
-- Check if_exists boolean works correctly
|
-- Check if_exists boolean works correctly
|
||||||
select * from alter_job_schedule(1234, if_exists => TRUE);
|
select * from alter_job_schedule(1234, if_exists => TRUE);
|
||||||
NOTICE: cannot alter policy schedule, policy #1234 not found, skipping
|
NOTICE: cannot alter policy schedule, policy #1234 not found, skipping
|
||||||
job_id | schedule_interval | max_runtime | max_retries | retry_period
|
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
|
||||||
--------+-------------------+-------------+-------------+--------------
|
--------+-------------------+-------------+-------------+--------------+------------
|
||||||
| | | |
|
| | | | |
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
\set ON_ERROR_STOP 0
|
\set ON_ERROR_STOP 0
|
||||||
@ -868,7 +947,7 @@ ERROR: cannot execute an enterprise function with an invalid enterprise license
|
|||||||
select remove_drop_chunks_policy('test_table');
|
select remove_drop_chunks_policy('test_table');
|
||||||
ERROR: cannot execute an enterprise function with an invalid enterprise license
|
ERROR: cannot execute an enterprise function with an invalid enterprise license
|
||||||
select alter_job_schedule(12345);
|
select alter_job_schedule(12345);
|
||||||
ERROR: cannot execute an enterprise function with an invalid enterprise license
|
ERROR: cannot alter policy schedule, policy #12345 not found
|
||||||
\set ON_ERROR_STOP 1
|
\set ON_ERROR_STOP 1
|
||||||
\c :TEST_DBNAME :ROLE_SUPERUSER
|
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||||
select add_reorder_policy('test_table', 'test_table_time_idx') as reorder_job_id \gset
|
select add_reorder_policy('test_table', 'test_table_time_idx') as reorder_job_id \gset
|
||||||
|
@ -196,6 +196,15 @@ SELECT job_id, next_start-last_finish as until_next, total_runs
|
|||||||
FROM _timescaledb_internal.bgw_job_stat
|
FROM _timescaledb_internal.bgw_job_stat
|
||||||
WHERE job_id=:job_id;
|
WHERE job_id=:job_id;
|
||||||
|
|
||||||
|
--change next run to be after 30s instead
|
||||||
|
SELECT (next_start - '30s'::interval) AS "NEW_NEXT_START"
|
||||||
|
FROM _timescaledb_internal.bgw_job_stat
|
||||||
|
WHERE job_id=:job_id \gset
|
||||||
|
SELECT alter_job_schedule(:job_id, next_start => :'NEW_NEXT_START');
|
||||||
|
|
||||||
|
SELECT ts_bgw_params_reset_time((extract(epoch from interval '12 hour')::bigint * 1000000)+(extract(epoch from interval '2 minute 30 seconds')::bigint * 1000000), true);
|
||||||
|
SELECT wait_for_job_to_run(:job_id, 4);
|
||||||
|
|
||||||
--advance clock to quit scheduler
|
--advance clock to quit scheduler
|
||||||
SELECT ts_bgw_params_reset_time(extract(epoch from interval '25 hour')::bigint * 1000000, true);
|
SELECT ts_bgw_params_reset_time(extract(epoch from interval '25 hour')::bigint * 1000000, true);
|
||||||
select ts_bgw_db_scheduler_test_wait_for_scheduler_finish();
|
select ts_bgw_db_scheduler_test_wait_for_scheduler_finish();
|
||||||
|
@ -309,6 +309,37 @@ select * from alter_job_schedule(:job_id, max_retries => 20);
|
|||||||
select * from alter_job_schedule(:job_id, max_runtime => NULL);
|
select * from alter_job_schedule(:job_id, max_runtime => NULL);
|
||||||
select * from alter_job_schedule(:job_id, max_retries => NULL);
|
select * from alter_job_schedule(:job_id, max_retries => NULL);
|
||||||
|
|
||||||
|
--change schedule_interval when bgw_job_stat does not exist
|
||||||
|
select * from alter_job_schedule(:job_id, schedule_interval=>'1 min');
|
||||||
|
select count(*) = 0 from _timescaledb_internal.bgw_job_stat where job_id = :job_id;
|
||||||
|
--set next_start when bgw_job_stat does not exist
|
||||||
|
select * from alter_job_schedule(:job_id, next_start=>'2001-01-01 01:01:01');
|
||||||
|
--change schedule_interval when no last_finish set
|
||||||
|
select * from alter_job_schedule(:job_id, schedule_interval=>'10 min');
|
||||||
|
--next_start overrides any schedule_interval changes
|
||||||
|
select * from alter_job_schedule(:job_id, schedule_interval=>'20 min', next_start=>'2002-01-01 01:01:01');
|
||||||
|
|
||||||
|
--set the last_finish manually
|
||||||
|
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||||
|
UPDATE _timescaledb_internal.bgw_job_stat SET last_finish = '2003-01-01:01:01:01' WHERE job_id = :job_id;
|
||||||
|
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
|
||||||
|
|
||||||
|
--not changing the interval doesn't change the next_start
|
||||||
|
select * from alter_job_schedule(:job_id, schedule_interval=>'20 min');
|
||||||
|
--changing the interval changes next_start
|
||||||
|
select * from alter_job_schedule(:job_id, schedule_interval=>'30 min');
|
||||||
|
--explicit next start overrides.
|
||||||
|
select * from alter_job_schedule(:job_id, schedule_interval=>'40 min', next_start=>'2004-01-01 01:01:01');
|
||||||
|
--test pausing
|
||||||
|
select * from alter_job_schedule(:job_id, next_start=>'infinity');
|
||||||
|
--test that you can use now() to unpause
|
||||||
|
select next_start = now() from alter_job_schedule(:job_id, next_start=>now());
|
||||||
|
|
||||||
|
\set ON_ERROR_STOP 0
|
||||||
|
-- negative infinity disallowed (used as special value)
|
||||||
|
select * from alter_job_schedule(:job_id, next_start=>'-infinity');
|
||||||
|
\set ON_ERROR_STOP 1
|
||||||
|
|
||||||
-- Check if_exists boolean works correctly
|
-- Check if_exists boolean works correctly
|
||||||
select * from alter_job_schedule(1234, if_exists => TRUE);
|
select * from alter_job_schedule(1234, if_exists => TRUE);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user