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:
Matvey Arye 2019-10-11 11:08:57 -04:00 committed by Matvey Arye
parent 01f2bbaf5a
commit 2209133781
11 changed files with 275 additions and 71 deletions

View File

@ -45,7 +45,9 @@ CREATE OR REPLACE FUNCTION alter_job_schedule(
max_runtime INTERVAL = NULL,
max_retries INTEGER = NULL,
retry_period INTERVAL = NULL,
if_exists BOOL = FALSE)
RETURNS TABLE (job_id INTEGER, schedule_interval INTERVAL, max_runtime INTERVAL, max_retries INTEGER, retry_period INTERVAL)
if_exists BOOL = FALSE,
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'
LANGUAGE C VOLATILE;

View File

@ -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', '');
DROP TABLE _timescaledb_config.bgw_policy_drop_chunks_tmp;
GRANT SELECT ON _timescaledb_config.bgw_policy_drop_chunks TO PUBLIC;
DROP FUNCTION IF EXISTS alter_job_schedule(INTEGER, INTERVAL, INTERVAL, INTEGER, INTERVAL, BOOL);

View File

@ -771,7 +771,10 @@ bgw_job_tuple_update_by_id(TupleInfo *ti, void *const data)
DirectFunctionCall2(timestamptz_pl_interval,
TimestampTzGetDatum(stat->fd.last_finish),
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;
}

View File

@ -296,7 +296,8 @@ bgw_job_stat_tuple_set_next_start(TupleInfo *ti, void *const data)
}
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);
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_last_start)] =
TimestampGetDatum(ts_timer_get_current_timestamp());
if (mark_start)
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_next_start)] = TimestampGetDatum(DT_NOBEGIN);
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_total_runs)] = Int64GetDatum(1);
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_next_start)] = TimestampGetDatum(next_start);
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_total_runs)] =
Int64GetDatum((mark_start ? 1 : 0));
values[AttrNumberGetAttrOffset(Anum_bgw_job_stat_total_duration)] =
IntervalPGetDatum(&zero_ival);
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_consecutive_failures)] = Int32GetDatum(0);
/* This is udone by any of the end marks */
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);
if (mark_start)
{
/* This is udone by any of the end marks */
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_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;
}
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
ts_bgw_job_stat_mark_start(int32 bgw_job_id)
{
/* Use double-check locking */
if (!bgw_job_stat_scan_job_id(bgw_job_id,
bgw_job_stat_tuple_mark_start,
NULL,
NULL,
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
@ -394,11 +407,11 @@ ts_bgw_job_stat_set_next_start(BgwJob *job, TimestampTz next_start)
/* update next_start if job stat exists */
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;
/* 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");
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;
}
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
ts_bgw_job_stat_should_execute(BgwJobStat *jobstat, BgwJob *job)
{

View File

@ -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 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);

View File

@ -36,7 +36,7 @@
#include "drop_chunks_api.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
static void
@ -289,17 +289,16 @@ Datum
bgw_policy_alter_job_schedule(PG_FUNCTION_ARGS)
{
BgwJob *job;
BgwJobStat *stat;
TupleDesc tupdesc;
Datum values[ALTER_JOB_SCHEDULE_NUM_COLS];
bool nulls[ALTER_JOB_SCHEDULE_NUM_COLS] = { false };
HeapTuple tuple;
TimestampTz next_start;
int job_id = PG_GETARG_INT32(0);
bool if_exists = PG_GETARG_BOOL(5);
license_enforce_enterprise_enabled();
license_print_expiration_warning_if_needed();
/* First get the job */
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)));
}
if (bgw_policy_job_requires_enterprise_license(job))
license_enforce_enterprise_enabled();
license_print_expiration_warning_if_needed();
ts_bgw_job_permission_check(job);
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);
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 */
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
ereport(ERROR,
@ -338,12 +344,19 @@ bgw_policy_alter_job_schedule(PG_FUNCTION_ARGS)
errmsg("function returning record called in context "
"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);
values[0] = Int32GetDatum(job->fd.id);
values[1] = IntervalPGetDatum(&job->fd.schedule_interval);
values[2] = IntervalPGetDatum(&job->fd.max_runtime);
values[3] = Int32GetDatum(job->fd.max_retries);
values[4] = IntervalPGetDatum(&job->fd.retry_period);
values[5] = TimestampTzGetDatum(next_start);
tuple = heap_form_tuple(tupdesc, values, nulls);
return HeapTupleGetDatum(tuple);

View File

@ -440,9 +440,9 @@ SELECT json_object_field(get_telemetry_report(always_display_report := true)::js
(1 row)
SELECT alter_job_schedule(:drop_chunks_job_id, schedule_interval => INTERVAL '1 second');
alter_job_schedule
---------------------------------------------
(1001,"@ 1 sec","@ 5 mins",-1,"@ 12 hours")
alter_job_schedule
-------------------------------------------------------
(1001,"@ 1 sec","@ 5 mins",-1,"@ 12 hours",-infinity)
(1 row)
select * from _timescaledb_config.bgw_policy_drop_chunks where job_id=:drop_chunks_job_id;

View File

@ -285,6 +285,28 @@ WHERE job_id=:job_id;
1000 | @ 1 min | 3
(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
SELECT ts_bgw_params_reset_time(extract(epoch from interval '25 hour')::bigint * 1000000, true);
ts_bgw_params_reset_time

View File

@ -776,73 +776,152 @@ select add_reorder_policy('test_table', 'test_table_time_idx') as job_id \gset
-- No change
select * from alter_job_schedule(:job_id);
job_id | schedule_interval | max_runtime | max_retries | retry_period
--------+-------------------+-------------+-------------+--------------
1014 | @ 84 hours | @ 0 | -1 | @ 1 day
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
--------+-------------------+-------------+-------------+--------------+------------
1014 | @ 84 hours | @ 0 | -1 | @ 1 day | -infinity
(1 row)
-- Changes expected
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
--------+-------------------+-------------+-------------+-----------------
1014 | @ 3 years | @ 5 mins | 5 | @ 2 mins 3 secs
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
--------+-------------------+-------------+-------------+-----------------+------------
1014 | @ 3 years | @ 5 mins | 5 | @ 2 mins 3 secs | -infinity
(1 row)
select * from alter_job_schedule(:job_id, INTERVAL '123 years');
job_id | schedule_interval | max_runtime | max_retries | retry_period
--------+-------------------+-------------+-------------+-----------------
1014 | @ 123 years | @ 5 mins | 5 | @ 2 mins 3 secs
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
--------+-------------------+-------------+-------------+-----------------+------------
1014 | @ 123 years | @ 5 mins | 5 | @ 2 mins 3 secs | -infinity
(1 row)
select * from alter_job_schedule(:job_id, retry_period => INTERVAL '33 hours');
job_id | schedule_interval | max_runtime | max_retries | retry_period
--------+-------------------+-------------+-------------+--------------
1014 | @ 123 years | @ 5 mins | 5 | @ 33 hours
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
--------+-------------------+-------------+-------------+--------------+------------
1014 | @ 123 years | @ 5 mins | 5 | @ 33 hours | -infinity
(1 row)
select * from alter_job_schedule(:job_id, max_runtime => INTERVAL '456 sec');
job_id | schedule_interval | max_runtime | max_retries | retry_period
--------+-------------------+------------------+-------------+--------------
1014 | @ 123 years | @ 7 mins 36 secs | 5 | @ 33 hours
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
--------+-------------------+------------------+-------------+--------------+------------
1014 | @ 123 years | @ 7 mins 36 secs | 5 | @ 33 hours | -infinity
(1 row)
select * from alter_job_schedule(:job_id, max_retries => 0);
job_id | schedule_interval | max_runtime | max_retries | retry_period
--------+-------------------+------------------+-------------+--------------
1014 | @ 123 years | @ 7 mins 36 secs | 0 | @ 33 hours
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
--------+-------------------+------------------+-------------+--------------+------------
1014 | @ 123 years | @ 7 mins 36 secs | 0 | @ 33 hours | -infinity
(1 row)
select * from alter_job_schedule(:job_id, max_retries => -1);
job_id | schedule_interval | max_runtime | max_retries | retry_period
--------+-------------------+------------------+-------------+--------------
1014 | @ 123 years | @ 7 mins 36 secs | -1 | @ 33 hours
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
--------+-------------------+------------------+-------------+--------------+------------
1014 | @ 123 years | @ 7 mins 36 secs | -1 | @ 33 hours | -infinity
(1 row)
select * from alter_job_schedule(:job_id, max_retries => 20);
job_id | schedule_interval | max_runtime | max_retries | retry_period
--------+-------------------+------------------+-------------+--------------
1014 | @ 123 years | @ 7 mins 36 secs | 20 | @ 33 hours
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
--------+-------------------+------------------+-------------+--------------+------------
1014 | @ 123 years | @ 7 mins 36 secs | 20 | @ 33 hours | -infinity
(1 row)
-- No change
select * from alter_job_schedule(:job_id, max_runtime => NULL);
job_id | schedule_interval | max_runtime | max_retries | retry_period
--------+-------------------+------------------+-------------+--------------
1014 | @ 123 years | @ 7 mins 36 secs | 20 | @ 33 hours
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
--------+-------------------+------------------+-------------+--------------+------------
1014 | @ 123 years | @ 7 mins 36 secs | 20 | @ 33 hours | -infinity
(1 row)
select * from alter_job_schedule(:job_id, max_retries => NULL);
job_id | schedule_interval | max_runtime | max_retries | retry_period
--------+-------------------+------------------+-------------+--------------
1014 | @ 123 years | @ 7 mins 36 secs | 20 | @ 33 hours
job_id | schedule_interval | max_runtime | max_retries | retry_period | next_start
--------+-------------------+------------------+-------------+--------------+------------
1014 | @ 123 years | @ 7 mins 36 secs | 20 | @ 33 hours | -infinity
(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
select * from alter_job_schedule(1234, if_exists => TRUE);
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)
\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');
ERROR: cannot execute an enterprise function with an invalid enterprise license
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
\c :TEST_DBNAME :ROLE_SUPERUSER
select add_reorder_policy('test_table', 'test_table_time_idx') as reorder_job_id \gset

View File

@ -196,6 +196,15 @@ SELECT job_id, next_start-last_finish as until_next, total_runs
FROM _timescaledb_internal.bgw_job_stat
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
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();

View File

@ -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_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
select * from alter_job_schedule(1234, if_exists => TRUE);