From 47b5b7d55371de0451c369e83db8100fb0b2ae3c Mon Sep 17 00:00:00 2001 From: Joshua Lockerman Date: Wed, 9 Jan 2019 14:47:39 -0500 Subject: [PATCH] Log which chunks are dropped by background workers We don't want to do this silently, so that users are able to debug where their chunks went. --- sql/ddl_api.sql | 3 ++- sql/ddl_internal.sql | 8 -------- sql/updates/latest-dev.sql | 3 +++ src/chunk.c | 9 +++++++-- src/chunk.h | 2 +- test/expected/chunk_utils.out | 9 ++++++--- test/sql/chunk_utils.sql | 6 +++--- tsl/src/bgw_policy/job.c | 5 +++-- tsl/src/license.c | 4 +++- 9 files changed, 28 insertions(+), 21 deletions(-) diff --git a/sql/ddl_api.sql b/sql/ddl_api.sql index dff4ecc4d..3d640485f 100644 --- a/sql/ddl_api.sql +++ b/sql/ddl_api.sql @@ -74,7 +74,8 @@ CREATE OR REPLACE FUNCTION drop_chunks( table_name NAME = NULL, schema_name NAME = NULL, cascade BOOLEAN = FALSE, - newer_than "any" = NULL + newer_than "any" = NULL, + verbose BOOLEAN = FALSE ) RETURNS SETOF REGCLASS AS '@MODULE_PATHNAME@', 'ts_chunk_drop_chunks' LANGUAGE C STABLE PARALLEL SAFE; diff --git a/sql/ddl_internal.sql b/sql/ddl_internal.sql index 08d765b34..13fa2a7dc 100644 --- a/sql/ddl_internal.sql +++ b/sql/ddl_internal.sql @@ -3,14 +3,6 @@ -- This file is licensed under the Apache License, see LICENSE-APACHE -- at the top level directory of the TimescaleDB distribution. -CREATE OR REPLACE FUNCTION _timescaledb_internal.drop_chunks_impl( - hypertable REGCLASS = NULL, - older_than "any" = NULL, - newer_than "any" = NULL, - cascade BOOLEAN = FALSE -) RETURNS VOID AS '@MODULE_PATHNAME@', 'ts_chunk_drop_chunks' -LANGUAGE C STABLE PARALLEL SAFE; - --documentation of these function located in chunk_index.h CREATE OR REPLACE FUNCTION _timescaledb_internal.chunk_index_clone(chunk_index_oid OID) RETURNS OID AS '@MODULE_PATHNAME@', 'ts_chunk_index_clone' LANGUAGE C VOLATILE STRICT; diff --git a/sql/updates/latest-dev.sql b/sql/updates/latest-dev.sql index 98bb2eef7..e4715f4f8 100644 --- a/sql/updates/latest-dev.sql +++ b/sql/updates/latest-dev.sql @@ -29,3 +29,6 @@ CREATE TABLE IF NOT EXISTS _timescaledb_internal.bgw_policy_chunk_stats ( GRANT SELECT ON _timescaledb_config.bgw_policy_reorder TO PUBLIC; GRANT SELECT ON _timescaledb_config.bgw_policy_drop_chunks TO PUBLIC; GRANT SELECT ON _timescaledb_internal.bgw_policy_chunk_stats TO PUBLIC; + +DROP FUNCTION IF EXISTS _timescaledb_internal.drop_chunks_impl(REGCLASS, "any", "any", BOOLEAN); +DROP FUNCTION IF EXISTS drop_chunks("any", NAME, NAME, BOOLEAN, "any"); diff --git a/src/chunk.c b/src/chunk.c index 5b44e2cbe..92e798cb5 100644 --- a/src/chunk.c +++ b/src/chunk.c @@ -1839,7 +1839,7 @@ chunks_return_srf(FunctionCallInfo fcinfo) } void -ts_chunk_do_drop_chunks(Oid table_relid, Datum older_than_datum, Datum newer_than_datum, Oid older_than_type, Oid newer_than_type, bool cascade) +ts_chunk_do_drop_chunks(Oid table_relid, Datum older_than_datum, Datum newer_than_datum, Oid older_than_type, Oid newer_than_type, bool cascade, int32 log_level) { int i = 0; uint64 num_chunks = 0; @@ -1852,6 +1852,9 @@ ts_chunk_do_drop_chunks(Oid table_relid, Datum older_than_datum, Datum newer_tha .objectId = chunks[i]->table_id, }; + + elog(log_level, "dropping chunk %s.%s", chunks[i]->fd.schema_name.data, chunks[i]->fd.table_name.data); + /* Remove the chunk from the hypertable table */ ts_chunk_delete_by_relid(chunks[i]->table_id); @@ -1874,6 +1877,8 @@ ts_chunk_drop_chunks(PG_FUNCTION_ARGS) Oid older_than_type = PG_ARGISNULL(0) ? InvalidOid : get_fn_expr_argtype(fcinfo->flinfo, 0); Oid newer_than_type = PG_ARGISNULL(4) ? InvalidOid : get_fn_expr_argtype(fcinfo->flinfo, 4); bool cascade = PG_GETARG_BOOL(3); + bool verbose = PG_ARGISNULL(5) ? false : PG_GETARG_BOOL(5); + int elevel = verbose ? INFO : DEBUG2; if (PG_ARGISNULL(0) && PG_ARGISNULL(4)) ereport(ERROR, @@ -1941,7 +1946,7 @@ ts_chunk_drop_chunks(PG_FUNCTION_ARGS) { LockRelationOid(lfirst_oid(lf), AccessExclusiveLock); } - ts_chunk_do_drop_chunks(table_relid, older_than_datum, newer_than_datum, older_than_type, newer_than_type, cascade); + ts_chunk_do_drop_chunks(table_relid, older_than_datum, newer_than_datum, older_than_type, newer_than_type, cascade, elevel); } PG_RETURN_NULL(); diff --git a/src/chunk.h b/src/chunk.h index c26b76bdf..e18a82f10 100644 --- a/src/chunk.h +++ b/src/chunk.h @@ -86,7 +86,7 @@ extern bool ts_chunk_set_name(Chunk *chunk, const char *newname); extern bool ts_chunk_set_schema(Chunk *chunk, const char *newschema); extern List *ts_chunk_get_window(int32 dimension_id, int64 point, int count, MemoryContext mctx); extern void ts_chunks_rename_schema_name(char *old_schema, char *new_schema); -extern TSDLLEXPORT void ts_chunk_do_drop_chunks(Oid table_relid, Datum older_than_datum, Datum newer_than_datum, Oid older_than_type, Oid newer_than_type, bool cascade); +extern TSDLLEXPORT void ts_chunk_do_drop_chunks(Oid table_relid, Datum older_than_datum, Datum newer_than_datum, Oid older_than_type, Oid newer_than_type, bool cascade, int32 log_level); #define chunk_get_by_name(schema_name, table_name, num_constraints, fail_if_not_found) \ ts_chunk_get_by_name_with_memory_context(schema_name, table_name, num_constraints, \ diff --git a/test/expected/chunk_utils.out b/test/expected/chunk_utils.out index b0604d828..83fcb0dcb 100644 --- a/test/expected/chunk_utils.out +++ b/test/expected/chunk_utils.out @@ -13,7 +13,7 @@ $BODY$ d.interval_length IS NOT NULL $BODY$; -- Make sure drop_chunks when there are no tables succeeds -SELECT drop_chunks(INTERVAL '1 hour'); +SELECT drop_chunks(INTERVAL '1 hour', verbose => true); drop_chunks ------------- @@ -421,8 +421,10 @@ SELECT * FROM _timescaledb_catalog.dimension_slice; 24 | 3 | 6 | 7 (23 rows) -SELECT drop_chunks(2, CASCADE=>true); +SELECT drop_chunks(2, CASCADE=>true, verbose => true); +INFO: dropping chunk _timescaledb_internal._hyper_1_1_chunk NOTICE: drop cascades to view dependent_view +INFO: dropping chunk _timescaledb_internal._hyper_3_13_chunk drop_chunks ------------- @@ -709,7 +711,8 @@ WHERE h.schema_name = 'public' AND (h.table_name = 'drop_chunk_test1' OR h.table (8 rows) -- newer_than tests -SELECT drop_chunks(table_name=>'drop_chunk_test1', newer_than=>5); +SELECT drop_chunks(table_name=>'drop_chunk_test1', newer_than=>5, verbose => true); +INFO: dropping chunk _timescaledb_internal._hyper_1_5_chunk drop_chunks ------------- diff --git a/test/sql/chunk_utils.sql b/test/sql/chunk_utils.sql index fa095cc1c..336ad6ae5 100644 --- a/test/sql/chunk_utils.sql +++ b/test/sql/chunk_utils.sql @@ -15,7 +15,7 @@ $BODY$ $BODY$; -- Make sure drop_chunks when there are no tables succeeds -SELECT drop_chunks(INTERVAL '1 hour'); +SELECT drop_chunks(INTERVAL '1 hour', verbose => true); CREATE TABLE PUBLIC.drop_chunk_test1(time bigint, temp float8, device_id text); CREATE TABLE PUBLIC.drop_chunk_test2(time bigint, temp float8, device_id text); @@ -142,7 +142,7 @@ FULL OUTER JOIN _timescaledb_catalog.dimension_slice ds ON (ds.id = cc.dimension -- Only one dimension slice deleted SELECT * FROM _timescaledb_catalog.dimension_slice; -SELECT drop_chunks(2, CASCADE=>true); +SELECT drop_chunks(2, CASCADE=>true, verbose => true); SELECT c.table_name, cc.constraint_name, ds.id AS dimension_slice_id, ds.range_start, ds.range_end FROM _timescaledb_catalog.chunk c @@ -212,7 +212,7 @@ WHERE h.schema_name = 'public' AND (h.table_name = 'drop_chunk_test1' OR h.table \dt "_timescaledb_internal"._hyper* -- newer_than tests -SELECT drop_chunks(table_name=>'drop_chunk_test1', newer_than=>5); +SELECT drop_chunks(table_name=>'drop_chunk_test1', newer_than=>5, verbose => true); SELECT c.id AS chunk_id, c.hypertable_id, c.schema_name AS chunk_schema, c.table_name AS chunk_table, ds.range_start, ds.range_end FROM _timescaledb_catalog.chunk c diff --git a/tsl/src/bgw_policy/job.c b/tsl/src/bgw_policy/job.c index adaf5408b..de59d7e34 100644 --- a/tsl/src/bgw_policy/job.c +++ b/tsl/src/bgw_policy/job.c @@ -69,7 +69,7 @@ execute_reorder_policy(BgwJob *job, reorder_func reorder, bool fast_continue) BgwPolicyReorder *args; Hypertable *ht; Chunk *chunk; - int32 job_id = job->fd.id; + int32 job_id = job->fd.id; if (!IsTransactionOrTransactionBlock()) { @@ -141,7 +141,8 @@ execute_drop_chunks_policy(int32 job_id) errmsg("could not run drop_chunks policy #%d because no args in policy table", job_id))); - ts_chunk_do_drop_chunks(ts_hypertable_id_to_relid(args->fd.hypertable_id), IntervalPGetDatum(&args->fd.older_than), 0, INTERVALOID, InvalidOid, args->fd.cascade); + ts_chunk_do_drop_chunks(ts_hypertable_id_to_relid(args->fd.hypertable_id), IntervalPGetDatum(&args->fd.older_than), 0, INTERVALOID, InvalidOid, args->fd.cascade, LOG); + elog(LOG, "completed dropping chunks"); if (started) CommitTransactionCommand(); diff --git a/tsl/src/license.c b/tsl/src/license.c index 39d527677..9850a2919 100644 --- a/tsl/src/license.c +++ b/tsl/src/license.c @@ -181,6 +181,7 @@ static bool license_info_init_from_base64(char *license_key, LicenseInfo *out) { char *expanded = base64_decode(license_key); + if (expanded == NULL) return false; @@ -238,7 +239,8 @@ static TimestampTz json_get_end_time(Jsonb *license); static void license_info_init_from_jsonb(Jsonb *json_license, LicenseInfo *out) { - char *id_str = json_get_id(json_license); + char *id_str = json_get_id(json_license); + if (id_str == NULL) elog(ERROR, "missing id in license key"); StrNCpy(out->id, id_str, sizeof(out->id));