mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-17 19:13:16 +08:00
Support tablespaces for continuous aggregates
Adding support for tablespaces when creating a continuous aggregate using `CREATE MATERIALIZED VIEW` and when altering a continuous aggregate using `ALTER MATERIALIZED VIEW`. Fixes #2122
This commit is contained in:
parent
4179f4f324
commit
d5a6a5b193
@ -2762,6 +2762,8 @@ process_altertable_start_matview(ProcessUtilityArgs *args)
|
||||
NameData view_schema;
|
||||
ContinuousAgg *cagg;
|
||||
ListCell *lc;
|
||||
Hypertable *ht;
|
||||
Cache *hcache;
|
||||
|
||||
if (!OidIsValid(view_relid))
|
||||
return DDL_CONTINUE;
|
||||
@ -2788,6 +2790,19 @@ process_altertable_start_matview(ProcessUtilityArgs *args)
|
||||
errmsg("expected set options to contain a list")));
|
||||
process_altercontinuousagg_set_with(cagg, view_relid, (List *) cmd->def);
|
||||
break;
|
||||
|
||||
case AT_SetTableSpace:
|
||||
hcache = ts_hypertable_cache_pin();
|
||||
ht = ts_hypertable_cache_get_entry_by_id(hcache, cagg->data.mat_hypertable_id);
|
||||
Assert(ht); /* Broken continuous aggregate */
|
||||
ts_hypertable_permissions_check_by_id(ht->fd.id);
|
||||
check_alter_table_allowed_on_ht_with_compression(ht, stmt);
|
||||
relation_not_only(stmt->relation);
|
||||
process_altertable_set_tablespace_end(ht, cmd);
|
||||
AlterTableInternal(ht->main_table_relid, list_make1(cmd), false);
|
||||
ts_cache_release(hcache);
|
||||
break;
|
||||
|
||||
default:
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
|
@ -203,6 +203,7 @@ static int32 mattablecolumninfo_create_materialization_table(MatTableColumnInfo
|
||||
int32 hypertable_id, RangeVar *mat_rel,
|
||||
CAggTimebucketInfo *origquery_tblinfo,
|
||||
bool create_addl_index,
|
||||
char *tablespacename,
|
||||
ObjectAddress *mataddress);
|
||||
static Query *mattablecolumninfo_get_partial_select_query(MatTableColumnInfo *matcolinfo,
|
||||
Query *userview_query);
|
||||
@ -460,7 +461,8 @@ static int32
|
||||
mattablecolumninfo_create_materialization_table(MatTableColumnInfo *matcolinfo, int32 hypertable_id,
|
||||
RangeVar *mat_rel,
|
||||
CAggTimebucketInfo *origquery_tblinfo,
|
||||
bool create_addl_index, ObjectAddress *mataddress)
|
||||
bool create_addl_index, char *const tablespacename,
|
||||
ObjectAddress *mataddress)
|
||||
{
|
||||
Oid uid, saved_uid;
|
||||
int sec_ctx;
|
||||
@ -484,7 +486,7 @@ mattablecolumninfo_create_materialization_table(MatTableColumnInfo *matcolinfo,
|
||||
create->constraints = NIL;
|
||||
create->options = NULL;
|
||||
create->oncommit = ONCOMMIT_NOOP;
|
||||
create->tablespacename = NULL;
|
||||
create->tablespacename = tablespacename;
|
||||
create->if_not_exists = false;
|
||||
|
||||
/* Create the materialization table. */
|
||||
@ -1662,8 +1664,8 @@ fixup_userview_query_tlist(Query *userquery, List *tlist_aliases)
|
||||
* )
|
||||
*/
|
||||
static void
|
||||
cagg_create(ViewStmt *stmt, Query *panquery, CAggTimebucketInfo *origquery_ht,
|
||||
WithClauseResult *with_clause_options)
|
||||
cagg_create(const CreateTableAsStmt *create_stmt, ViewStmt *stmt, Query *panquery,
|
||||
CAggTimebucketInfo *origquery_ht, WithClauseResult *with_clause_options)
|
||||
{
|
||||
ObjectAddress mataddress;
|
||||
char relnamebuf[NAMEDATALEN];
|
||||
@ -1721,6 +1723,7 @@ cagg_create(ViewStmt *stmt, Query *panquery, CAggTimebucketInfo *origquery_ht,
|
||||
mat_rel,
|
||||
origquery_ht,
|
||||
is_create_mattbl_index,
|
||||
create_stmt->into->tableSpaceName,
|
||||
&mataddress);
|
||||
/* Step 2: create view with select finalize from materialization
|
||||
* table
|
||||
@ -1819,7 +1822,7 @@ tsl_process_continuous_agg_viewstmt(Node *node, const char *query_string, void *
|
||||
}
|
||||
|
||||
timebucket_exprinfo = cagg_validate_query((Query *) stmt->into->viewQuery);
|
||||
cagg_create(&viewstmt, (Query *) stmt->query, &timebucket_exprinfo, with_clause_options);
|
||||
cagg_create(stmt, &viewstmt, (Query *) stmt->query, &timebucket_exprinfo, with_clause_options);
|
||||
|
||||
return DDL_DONE;
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ select table_name from create_hypertable('conditions', 'timec');
|
||||
|
||||
-- schema tests
|
||||
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||
CREATE TABLESPACE tablespace1 OWNER :ROLE_DEFAULT_PERM_USER LOCATION :TEST_TABLESPACE1_PATH;
|
||||
CREATE TABLESPACE tablespace2 OWNER :ROLE_DEFAULT_PERM_USER LOCATION :TEST_TABLESPACE2_PATH;
|
||||
CREATE SCHEMA rename_schema;
|
||||
GRANT ALL ON SCHEMA rename_schema TO :ROLE_DEFAULT_PERM_USER;
|
||||
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
|
||||
@ -876,3 +878,85 @@ DETAIL: Hypertable "_materialized_hypertable_11" is a materialized hypertable.
|
||||
HINT: Try the operation on the continuous aggregate instead.
|
||||
\set VERBOSITY terse
|
||||
\set ON_ERROR_STOP 1
|
||||
--------------------------------------------------------------------
|
||||
-- Check that we can create a materialized table in a tablespace. We
|
||||
-- create one with tablespace and one without and compare them.
|
||||
CREATE VIEW cagg_info AS
|
||||
WITH
|
||||
caggs AS (
|
||||
SELECT format('%s.%s', user_view_schema, user_view_name)::regclass AS user_view,
|
||||
format('%s.%s', ht.schema_name, ht.table_name)::regclass AS mat_relid
|
||||
FROM _timescaledb_catalog.hypertable ht,
|
||||
_timescaledb_catalog.continuous_agg cagg
|
||||
WHERE ht.id = cagg.mat_hypertable_id
|
||||
)
|
||||
SELECT user_view,
|
||||
relname AS mat_table,
|
||||
(SELECT spcname FROM pg_tablespace WHERE oid = reltablespace) AS tablespace
|
||||
FROM pg_class JOIN caggs ON pg_class.oid = caggs.mat_relid;
|
||||
CREATE VIEW chunk_info AS
|
||||
SELECT ht.schema_name, ht.table_name, relname AS chunk_name,
|
||||
(SELECT spcname FROM pg_tablespace WHERE oid = reltablespace) AS tablespace
|
||||
FROM pg_class c,
|
||||
_timescaledb_catalog.hypertable ht,
|
||||
_timescaledb_catalog.chunk ch
|
||||
WHERE ch.table_name = c.relname AND ht.id = ch.hypertable_id;
|
||||
CREATE TABLE whatever(time BIGINT NOT NULL, data INTEGER);
|
||||
SELECT hypertable_id AS whatever_nid
|
||||
FROM create_hypertable('whatever', 'time', chunk_time_interval => 10)
|
||||
\gset
|
||||
SELECT set_integer_now_func('whatever', 'integer_now_test');
|
||||
set_integer_now_func
|
||||
----------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
CREATE MATERIALIZED VIEW whatever_view_1
|
||||
WITH (timescaledb.continuous, timescaledb.materialized_only=true) AS
|
||||
SELECT time_bucket('2', time), COUNT(data)
|
||||
FROM whatever GROUP BY 1;
|
||||
CREATE MATERIALIZED VIEW whatever_view_2
|
||||
WITH (timescaledb.continuous, timescaledb.materialized_only=true)
|
||||
TABLESPACE tablespace1 AS
|
||||
SELECT time_bucket('2', time), COUNT(data)
|
||||
FROM whatever GROUP BY 1;
|
||||
INSERT INTO whatever SELECT i, i FROM generate_series(0, 29) AS i;
|
||||
REFRESH MATERIALIZED VIEW whatever_view_1;
|
||||
LOG: materializing continuous aggregate public.whatever_view_1: nothing to invalidate, new range up to 30
|
||||
REFRESH MATERIALIZED VIEW whatever_view_2;
|
||||
LOG: materializing continuous aggregate public.whatever_view_2: nothing to invalidate, new range up to 30
|
||||
SELECT user_view,
|
||||
mat_table,
|
||||
cagg_info.tablespace AS mat_tablespace,
|
||||
chunk_name,
|
||||
chunk_info.tablespace AS chunk_tablespace
|
||||
FROM cagg_info, chunk_info
|
||||
WHERE mat_table::text = table_name
|
||||
AND user_view::text LIKE 'whatever_view%';
|
||||
user_view | mat_table | mat_tablespace | chunk_name | chunk_tablespace
|
||||
-----------------+-----------------------------+----------------+--------------------+------------------
|
||||
whatever_view_1 | _materialized_hypertable_13 | | _hyper_13_24_chunk |
|
||||
whatever_view_2 | _materialized_hypertable_14 | tablespace1 | _hyper_14_25_chunk | tablespace1
|
||||
(2 rows)
|
||||
|
||||
ALTER MATERIALIZED VIEW whatever_view_1 SET TABLESPACE tablespace2;
|
||||
SELECT user_view,
|
||||
mat_table,
|
||||
cagg_info.tablespace AS mat_tablespace,
|
||||
chunk_name,
|
||||
chunk_info.tablespace AS chunk_tablespace
|
||||
FROM cagg_info, chunk_info
|
||||
WHERE mat_table::text = table_name
|
||||
AND user_view::text LIKE 'whatever_view%';
|
||||
user_view | mat_table | mat_tablespace | chunk_name | chunk_tablespace
|
||||
-----------------+-----------------------------+----------------+--------------------+------------------
|
||||
whatever_view_1 | _materialized_hypertable_13 | tablespace2 | _hyper_13_24_chunk | tablespace2
|
||||
whatever_view_2 | _materialized_hypertable_14 | tablespace1 | _hyper_14_25_chunk | tablespace1
|
||||
(2 rows)
|
||||
|
||||
DROP MATERIALIZED VIEW whatever_view_1;
|
||||
NOTICE: drop cascades to table _timescaledb_internal._hyper_13_24_chunk
|
||||
DROP MATERIALIZED VIEW whatever_view_2;
|
||||
NOTICE: drop cascades to table _timescaledb_internal._hyper_14_25_chunk
|
||||
DROP TABLESPACE tablespace1;
|
||||
DROP TABLESPACE tablespace2;
|
||||
|
@ -114,6 +114,7 @@ set(SOLO_TESTS
|
||||
compress_bgw_reorder_drop_chunks
|
||||
compression_ddl
|
||||
continuous_aggs_bgw
|
||||
continuous_aggs_ddl
|
||||
continuous_aggs_dump
|
||||
data_fetcher
|
||||
data_node
|
||||
|
@ -24,6 +24,8 @@ select table_name from create_hypertable('conditions', 'timec');
|
||||
-- schema tests
|
||||
|
||||
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||
CREATE TABLESPACE tablespace1 OWNER :ROLE_DEFAULT_PERM_USER LOCATION :TEST_TABLESPACE1_PATH;
|
||||
CREATE TABLESPACE tablespace2 OWNER :ROLE_DEFAULT_PERM_USER LOCATION :TEST_TABLESPACE2_PATH;
|
||||
|
||||
CREATE SCHEMA rename_schema;
|
||||
GRANT ALL ON SCHEMA rename_schema TO :ROLE_DEFAULT_PERM_USER;
|
||||
@ -478,3 +480,78 @@ WHERE hypertable_name = :'drop_chunks_mat_table_name' ORDER BY range_start_integ
|
||||
SELECT drop_chunks(:'drop_chunks_mat_tablen', older_than => 60);
|
||||
\set VERBOSITY terse
|
||||
\set ON_ERROR_STOP 1
|
||||
|
||||
--------------------------------------------------------------------
|
||||
-- Check that we can create a materialized table in a tablespace. We
|
||||
-- create one with tablespace and one without and compare them.
|
||||
|
||||
CREATE VIEW cagg_info AS
|
||||
WITH
|
||||
caggs AS (
|
||||
SELECT format('%s.%s', user_view_schema, user_view_name)::regclass AS user_view,
|
||||
format('%s.%s', ht.schema_name, ht.table_name)::regclass AS mat_relid
|
||||
FROM _timescaledb_catalog.hypertable ht,
|
||||
_timescaledb_catalog.continuous_agg cagg
|
||||
WHERE ht.id = cagg.mat_hypertable_id
|
||||
)
|
||||
SELECT user_view,
|
||||
relname AS mat_table,
|
||||
(SELECT spcname FROM pg_tablespace WHERE oid = reltablespace) AS tablespace
|
||||
FROM pg_class JOIN caggs ON pg_class.oid = caggs.mat_relid;
|
||||
|
||||
CREATE VIEW chunk_info AS
|
||||
SELECT ht.schema_name, ht.table_name, relname AS chunk_name,
|
||||
(SELECT spcname FROM pg_tablespace WHERE oid = reltablespace) AS tablespace
|
||||
FROM pg_class c,
|
||||
_timescaledb_catalog.hypertable ht,
|
||||
_timescaledb_catalog.chunk ch
|
||||
WHERE ch.table_name = c.relname AND ht.id = ch.hypertable_id;
|
||||
|
||||
CREATE TABLE whatever(time BIGINT NOT NULL, data INTEGER);
|
||||
|
||||
SELECT hypertable_id AS whatever_nid
|
||||
FROM create_hypertable('whatever', 'time', chunk_time_interval => 10)
|
||||
\gset
|
||||
|
||||
SELECT set_integer_now_func('whatever', 'integer_now_test');
|
||||
|
||||
CREATE MATERIALIZED VIEW whatever_view_1
|
||||
WITH (timescaledb.continuous, timescaledb.materialized_only=true) AS
|
||||
SELECT time_bucket('2', time), COUNT(data)
|
||||
FROM whatever GROUP BY 1;
|
||||
|
||||
CREATE MATERIALIZED VIEW whatever_view_2
|
||||
WITH (timescaledb.continuous, timescaledb.materialized_only=true)
|
||||
TABLESPACE tablespace1 AS
|
||||
SELECT time_bucket('2', time), COUNT(data)
|
||||
FROM whatever GROUP BY 1;
|
||||
|
||||
INSERT INTO whatever SELECT i, i FROM generate_series(0, 29) AS i;
|
||||
REFRESH MATERIALIZED VIEW whatever_view_1;
|
||||
REFRESH MATERIALIZED VIEW whatever_view_2;
|
||||
|
||||
SELECT user_view,
|
||||
mat_table,
|
||||
cagg_info.tablespace AS mat_tablespace,
|
||||
chunk_name,
|
||||
chunk_info.tablespace AS chunk_tablespace
|
||||
FROM cagg_info, chunk_info
|
||||
WHERE mat_table::text = table_name
|
||||
AND user_view::text LIKE 'whatever_view%';
|
||||
|
||||
ALTER MATERIALIZED VIEW whatever_view_1 SET TABLESPACE tablespace2;
|
||||
|
||||
SELECT user_view,
|
||||
mat_table,
|
||||
cagg_info.tablespace AS mat_tablespace,
|
||||
chunk_name,
|
||||
chunk_info.tablespace AS chunk_tablespace
|
||||
FROM cagg_info, chunk_info
|
||||
WHERE mat_table::text = table_name
|
||||
AND user_view::text LIKE 'whatever_view%';
|
||||
|
||||
DROP MATERIALIZED VIEW whatever_view_1;
|
||||
DROP MATERIALIZED VIEW whatever_view_2;
|
||||
|
||||
DROP TABLESPACE tablespace1;
|
||||
DROP TABLESPACE tablespace2;
|
||||
|
Loading…
x
Reference in New Issue
Block a user