mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-16 10:33:27 +08:00
Spread chunk indexes across tablespaces like chunks
Currently, chunk indexes are always created in the tablespace of the index on the main table (which could be none/default one), even if the chunks themselves are created in different tablespaces. This is problematic in a multi-disk setting where each disk is a separate tablespace where chunks are placed. The chunk indexes might exhaust the space on the common (often default tablespace) which might not have a lot of disk space. This also prohibits the database, including index storage to grow by adding new tablespaces. Instead, chunk indexes are now created in the "next" tablespace after that of their chunks to both spread indexes across tablespaces and avoid colocating indexes with their chunks (for I/O throughput reasons). To optionally avoid this spreading, one can pin chunk indexes to a specific tablespace by setting an explicit tablespace on a main table index.
This commit is contained in:
parent
e85721a8ed
commit
d135256ed7
@ -400,7 +400,7 @@ chunk_create_table(Chunk *chunk, Hypertable *ht)
|
||||
.type = T_CreateStmt,
|
||||
.relation = makeRangeVar(NameStr(chunk->fd.schema_name), NameStr(chunk->fd.table_name), 0),
|
||||
.inhRelations = list_make1(makeRangeVar(NameStr(ht->fd.schema_name), NameStr(ht->fd.table_name), 0)),
|
||||
.tablespacename = hypertable_select_tablespace(ht, chunk),
|
||||
.tablespacename = hypertable_select_tablespace_name(ht, chunk),
|
||||
.options = get_reloptions(ht->main_table_relid),
|
||||
};
|
||||
Oid uid,
|
||||
|
@ -195,6 +195,35 @@ chunk_adjust_attnos(IndexInfo *ii, Relation htrel, Relation idxrel, Relation chu
|
||||
chunk_adjust_expr_attnos(ii, htrel, idxrel, chunkrel);
|
||||
}
|
||||
|
||||
#define CHUNK_INDEX_TABLESPACE_OFFSET 1
|
||||
|
||||
|
||||
/*
|
||||
* Pick a chunk index's tablespace at an offset from the chunk's tablespace in
|
||||
* order to avoid colocating chunks and their indexes in the same tablespace.
|
||||
* This hopefully leads to more I/O parallelism.
|
||||
*/
|
||||
static Oid
|
||||
chunk_index_select_tablespace(Relation htrel, Relation chunkrel)
|
||||
{
|
||||
Cache *hcache = hypertable_cache_pin();
|
||||
Hypertable *ht = hypertable_cache_get_entry(hcache, htrel->rd_id);
|
||||
Tablespace *tspc;
|
||||
Oid tablespace_oid = InvalidOid;
|
||||
|
||||
Assert(ht != NULL);
|
||||
|
||||
tspc = hypertable_get_tablespace_at_offset_from(ht, chunkrel->rd_rel->reltablespace,
|
||||
CHUNK_INDEX_TABLESPACE_OFFSET);
|
||||
|
||||
if (NULL != tspc)
|
||||
tablespace_oid = tspc->tablespace_oid;
|
||||
|
||||
cache_release(hcache);
|
||||
|
||||
return tablespace_oid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a chunk index based on the configuration of the "parent" index.
|
||||
*/
|
||||
@ -213,6 +242,7 @@ chunk_relation_index_create(Relation htrel,
|
||||
Datum indclass;
|
||||
oidvector *indclassoid;
|
||||
List *colnames = create_index_colnames(template_indexrel);
|
||||
Oid tablespace = InvalidOid;
|
||||
|
||||
/*
|
||||
* Convert the IndexInfo's attnos to match the chunk instead of the
|
||||
@ -239,6 +269,15 @@ chunk_relation_index_create(Relation htrel,
|
||||
get_rel_name(RelationGetRelid(template_indexrel)),
|
||||
get_rel_namespace(RelationGetRelid(chunkrel)));
|
||||
|
||||
/*
|
||||
* Determine the index's tablespace. Use the main index's tablespace, or,
|
||||
* if not set, select one at an offset from the chunk's tablespace.
|
||||
*/
|
||||
if (OidIsValid(template_indexrel->rd_rel->reltablespace))
|
||||
tablespace = template_indexrel->rd_rel->reltablespace;
|
||||
else
|
||||
tablespace = chunk_index_select_tablespace(htrel, chunkrel);
|
||||
|
||||
chunk_indexrelid = index_create(chunkrel,
|
||||
indexname,
|
||||
InvalidOid,
|
||||
@ -246,7 +285,7 @@ chunk_relation_index_create(Relation htrel,
|
||||
indexinfo,
|
||||
colnames,
|
||||
template_indexrel->rd_rel->relam,
|
||||
template_indexrel->rd_rel->reltablespace,
|
||||
tablespace,
|
||||
template_indexrel->rd_indcollation,
|
||||
indclassoid->values,
|
||||
template_indexrel->rd_indoption,
|
||||
|
@ -282,7 +282,7 @@ hypertable_has_tablespace(Hypertable *ht, Oid tspc_oid)
|
||||
* chunks in the same closed (space) dimension. This ensures chunks in the same
|
||||
* "space" partition will live on the same disk.
|
||||
*/
|
||||
char *
|
||||
Tablespace *
|
||||
hypertable_select_tablespace(Hypertable *ht, Chunk *chunk)
|
||||
{
|
||||
Dimension *dim;
|
||||
@ -318,7 +318,39 @@ hypertable_select_tablespace(Hypertable *ht, Chunk *chunk)
|
||||
Assert(i >= 0);
|
||||
|
||||
/* Use the index of the slice to find the tablespace */
|
||||
return NameStr(tspcs->tablespaces[i % tspcs->num_tablespaces].fd.tablespace_name);
|
||||
return &tspcs->tablespaces[i % tspcs->num_tablespaces];
|
||||
}
|
||||
|
||||
char *
|
||||
hypertable_select_tablespace_name(Hypertable *ht, Chunk *chunk)
|
||||
{
|
||||
Tablespace *tspc = hypertable_select_tablespace(ht, chunk);
|
||||
|
||||
if (NULL == tspc)
|
||||
return NULL;
|
||||
|
||||
return NameStr(tspc->fd.tablespace_name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the tablespace at an offset from the given tablespace.
|
||||
*/
|
||||
Tablespace *
|
||||
hypertable_get_tablespace_at_offset_from(Hypertable *ht, Oid tablespace_oid, int16 offset)
|
||||
{
|
||||
Tablespaces *tspcs = tablespace_scan(ht->fd.id);
|
||||
int i = 0;
|
||||
|
||||
if (NULL == tspcs || tspcs->num_tablespaces == 0)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < tspcs->num_tablespaces; i++)
|
||||
{
|
||||
if (tablespace_oid == tspcs->tablespaces[i].tablespace_oid)
|
||||
return &tspcs->tablespaces[(i + offset) % tspcs->num_tablespaces];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline Oid
|
||||
|
@ -30,6 +30,8 @@ extern Chunk *hypertable_get_chunk(Hypertable *h, Point *point);
|
||||
extern Oid hypertable_relid(RangeVar *rv);
|
||||
extern bool is_hypertable(Oid relid);
|
||||
extern bool hypertable_has_tablespace(Hypertable *ht, Oid tspc_oid);
|
||||
extern char *hypertable_select_tablespace(Hypertable *ht, Chunk *chunk);
|
||||
extern Tablespace *hypertable_select_tablespace(Hypertable *ht, Chunk *chunk);
|
||||
extern char *hypertable_select_tablespace_name(Hypertable *ht, Chunk *chunk);
|
||||
extern Tablespace *hypertable_get_tablespace_at_offset_from(Hypertable *ht, Oid tablespace_oid, int16 offset);
|
||||
|
||||
#endif /* TIMESCALEDB_HYPERTABLE_H */
|
||||
|
@ -318,15 +318,15 @@ SET timezone = '+1';
|
||||
INSERT INTO PUBLIC.drop_chunk_test_ts VALUES(now()-INTERVAL '5 minutes', 1.0, 'dev1');
|
||||
INSERT INTO PUBLIC.drop_chunk_test_tstz VALUES(now()-INTERVAL '5 minutes', 1.0, 'dev1');
|
||||
SELECT * FROM test.show_subtables('drop_chunk_test_ts');
|
||||
Child
|
||||
-----------------------------------------
|
||||
_timescaledb_internal._hyper_4_19_chunk
|
||||
Child | Tablespace
|
||||
-----------------------------------------+------------
|
||||
_timescaledb_internal._hyper_4_19_chunk |
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM test.show_subtables('drop_chunk_test_tstz');
|
||||
Child
|
||||
-----------------------------------------
|
||||
_timescaledb_internal._hyper_5_20_chunk
|
||||
Child | Tablespace
|
||||
-----------------------------------------+------------
|
||||
_timescaledb_internal._hyper_5_20_chunk |
|
||||
(1 row)
|
||||
|
||||
BEGIN;
|
||||
@ -337,8 +337,8 @@ BEGIN;
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM test.show_subtables('drop_chunk_test_ts');
|
||||
Child
|
||||
-------
|
||||
Child | Tablespace
|
||||
-------+------------
|
||||
(0 rows)
|
||||
|
||||
SELECT drop_chunks(interval '1 minute', 'drop_chunk_test_tstz');
|
||||
@ -348,8 +348,8 @@ BEGIN;
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM test.show_subtables('drop_chunk_test_tstz');
|
||||
Child
|
||||
-------
|
||||
Child | Tablespace
|
||||
-------+------------
|
||||
(0 rows)
|
||||
|
||||
ROLLBACK;
|
||||
@ -361,8 +361,8 @@ BEGIN;
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM test.show_subtables('drop_chunk_test_ts');
|
||||
Child
|
||||
-------
|
||||
Child | Tablespace
|
||||
-------+------------
|
||||
(0 rows)
|
||||
|
||||
SELECT drop_chunks(now()-interval '1 minute', 'drop_chunk_test_tstz');
|
||||
@ -372,8 +372,8 @@ BEGIN;
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM test.show_subtables('drop_chunk_test_tstz');
|
||||
Child
|
||||
-------
|
||||
Child | Tablespace
|
||||
-------+------------
|
||||
(0 rows)
|
||||
|
||||
ROLLBACK;
|
||||
@ -405,8 +405,8 @@ BEGIN;
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM test.show_subtables('drop_chunk_test_date');
|
||||
Child
|
||||
-------
|
||||
Child | Tablespace
|
||||
-------+------------
|
||||
(0 rows)
|
||||
|
||||
ROLLBACK;
|
||||
@ -418,8 +418,8 @@ BEGIN;
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM test.show_subtables('drop_chunk_test_date');
|
||||
Child
|
||||
-------
|
||||
Child | Tablespace
|
||||
-------+------------
|
||||
(0 rows)
|
||||
|
||||
ROLLBACK;
|
||||
|
@ -398,7 +398,7 @@ SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk');
|
||||
----------------------------------------+-------------------------------------------------------------------+--------------------+--------+---------+-----------+-------------
|
||||
_timescaledb_internal._hyper_5_5_chunk | _timescaledb_internal._hyper_5_5_chunk_index_test_time_idx | {time,temp,device} | f | f | f | tablespace1
|
||||
_timescaledb_internal._hyper_5_5_chunk | _timescaledb_internal._hyper_5_5_chunk_index_test_time_device_idx | {time,temp,device} | f | f | f | tablespace2
|
||||
_timescaledb_internal._hyper_5_5_chunk | _timescaledb_internal._hyper_5_5_chunk_index_test_device_idx | {time,temp,device} | f | f | f |
|
||||
_timescaledb_internal._hyper_5_5_chunk | _timescaledb_internal._hyper_5_5_chunk_index_test_device_idx | {time,temp,device} | f | f | f | tablespace1
|
||||
(3 rows)
|
||||
|
||||
-- Creating a new index should propagate to existing chunks, including
|
||||
@ -418,7 +418,7 @@ SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk');
|
||||
----------------------------------------+-------------------------------------------------------------------+--------------------+--------+---------+-----------+-------------
|
||||
_timescaledb_internal._hyper_5_5_chunk | _timescaledb_internal._hyper_5_5_chunk_index_test_time_idx | {time,temp,device} | f | f | f | tablespace1
|
||||
_timescaledb_internal._hyper_5_5_chunk | _timescaledb_internal._hyper_5_5_chunk_index_test_time_device_idx | {time,temp,device} | f | f | f | tablespace2
|
||||
_timescaledb_internal._hyper_5_5_chunk | _timescaledb_internal._hyper_5_5_chunk_index_test_device_idx | {time,temp,device} | f | f | f |
|
||||
_timescaledb_internal._hyper_5_5_chunk | _timescaledb_internal._hyper_5_5_chunk_index_test_device_idx | {time,temp,device} | f | f | f | tablespace1
|
||||
_timescaledb_internal._hyper_5_5_chunk | _timescaledb_internal._hyper_5_5_chunk_time_temp_idx | {time,temp,device} | f | f | f | tablespace2
|
||||
(4 rows)
|
||||
|
||||
|
@ -21,13 +21,13 @@ SELECT * FROM test.show_columns('reindex_test');
|
||||
(2 rows)
|
||||
|
||||
SELECT * FROM test.show_subtables('reindex_test');
|
||||
Child
|
||||
----------------------------------------
|
||||
_timescaledb_internal._hyper_1_1_chunk
|
||||
_timescaledb_internal._hyper_1_2_chunk
|
||||
_timescaledb_internal._hyper_1_3_chunk
|
||||
_timescaledb_internal._hyper_1_4_chunk
|
||||
_timescaledb_internal._hyper_1_5_chunk
|
||||
Child | Tablespace
|
||||
----------------------------------------+------------
|
||||
_timescaledb_internal._hyper_1_1_chunk |
|
||||
_timescaledb_internal._hyper_1_2_chunk |
|
||||
_timescaledb_internal._hyper_1_3_chunk |
|
||||
_timescaledb_internal._hyper_1_4_chunk |
|
||||
_timescaledb_internal._hyper_1_5_chunk |
|
||||
(5 rows)
|
||||
|
||||
-- show reindexing
|
||||
|
@ -122,10 +122,10 @@ INSERT INTO "int_part" VALUES('2017-01-20T09:00:01', 1, 22.5);
|
||||
INSERT INTO "int_part" VALUES('2017-01-20T09:00:01', 2, 22.5);
|
||||
--check that there are two chunks
|
||||
SELECT * FROM test.show_subtables('int_part');
|
||||
Child
|
||||
----------------------------------------
|
||||
_timescaledb_internal._hyper_2_5_chunk
|
||||
_timescaledb_internal._hyper_2_6_chunk
|
||||
Child | Tablespace
|
||||
----------------------------------------+------------
|
||||
_timescaledb_internal._hyper_2_5_chunk |
|
||||
_timescaledb_internal._hyper_2_6_chunk |
|
||||
(2 rows)
|
||||
|
||||
SELECT * FROM "int_part" WHERE object_id = 1;
|
||||
|
@ -77,25 +77,33 @@ SELECT * FROM show_tablespaces('tspace_2dim');
|
||||
|
||||
--insert into another chunk
|
||||
INSERT INTO tspace_2dim VALUES ('2017-01-20T09:00:01', 24.3, 'brown');
|
||||
SELECT relname, spcname FROM pg_class c
|
||||
INNER JOIN pg_tablespace t ON (c.reltablespace = t.oid)
|
||||
INNER JOIN _timescaledb_catalog.chunk ch ON (ch.table_name = c.relname);
|
||||
relname | spcname
|
||||
------------------+-------------
|
||||
_hyper_1_1_chunk | tablespace1
|
||||
_hyper_1_2_chunk | tablespace2
|
||||
SELECT * FROM test.show_subtables('tspace_2dim');
|
||||
Child | Tablespace
|
||||
----------------------------------------+-------------
|
||||
_timescaledb_internal._hyper_1_1_chunk | tablespace1
|
||||
_timescaledb_internal._hyper_1_2_chunk | tablespace2
|
||||
(2 rows)
|
||||
|
||||
--indexes should inherit the tablespace of their chunk
|
||||
SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk');
|
||||
Table | Index | Columns | Unique | Primary | Exclusion | Tablespace
|
||||
----------------------------------------+--------------------------------------------------------------------+--------------------+--------+---------+-----------+-------------
|
||||
_timescaledb_internal._hyper_1_1_chunk | _timescaledb_internal._hyper_1_1_chunk_tspace_2dim_time_idx | {time,temp,device} | f | f | f | tablespace1
|
||||
_timescaledb_internal._hyper_1_1_chunk | _timescaledb_internal._hyper_1_1_chunk_tspace_2dim_device_time_idx | {time,temp,device} | f | f | f | tablespace1
|
||||
_timescaledb_internal._hyper_1_2_chunk | _timescaledb_internal._hyper_1_2_chunk_tspace_2dim_time_idx | {time,temp,device} | f | f | f | tablespace1
|
||||
_timescaledb_internal._hyper_1_2_chunk | _timescaledb_internal._hyper_1_2_chunk_tspace_2dim_device_time_idx | {time,temp,device} | f | f | f | tablespace1
|
||||
(4 rows)
|
||||
|
||||
--
|
||||
SET ROLE :ROLE_DEFAULT_PERM_USER_2;
|
||||
-- User doesn't have permission on tablespace1 --> error
|
||||
CREATE TABLE tspace_1dim(time timestamp, temp float, device text) TABLESPACE tablespace1;
|
||||
ERROR: permission denied for tablespace tablespace1
|
||||
CREATE TABLE tspace_1dim(time timestamp, temp float, device text);
|
||||
-- Grant permission to tablespace1
|
||||
SET ROLE :ROLE_DEFAULT_PERM_USER;
|
||||
GRANT CREATE ON TABLESPACE tablespace1 TO :ROLE_DEFAULT_PERM_USER_2;
|
||||
SET ROLE :ROLE_DEFAULT_PERM_USER_2;
|
||||
CREATE TABLE tspace_1dim(time timestamp, temp float, device text) TABLESPACE tablespace1;
|
||||
CREATE TABLE tspace_1dim(time timestamp, temp float, device text);
|
||||
ERROR: relation "tspace_1dim" already exists
|
||||
SELECT create_hypertable('tspace_1dim', 'time');
|
||||
NOTICE: Adding NOT NULL constraint to time column time (NULL time values not allowed)
|
||||
create_hypertable
|
||||
@ -103,6 +111,12 @@ NOTICE: Adding NOT NULL constraint to time column time (NULL time values not al
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT attach_tablespace('tablespace1', 'tspace_1dim');
|
||||
attach_tablespace
|
||||
-------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT attach_tablespace('tablespace2', 'tspace_1dim');
|
||||
attach_tablespace
|
||||
-------------------
|
||||
@ -120,17 +134,33 @@ SELECT * FROM _timescaledb_catalog.tablespace;
|
||||
|
||||
INSERT INTO tspace_1dim VALUES ('2017-01-20T09:00:01', 24.3, 'blue');
|
||||
INSERT INTO tspace_1dim VALUES ('2017-03-20T09:00:01', 24.3, 'brown');
|
||||
SELECT relname, spcname FROM pg_class c
|
||||
INNER JOIN pg_tablespace t ON (c.reltablespace = t.oid)
|
||||
INNER JOIN _timescaledb_catalog.chunk ch ON (ch.table_name = c.relname);
|
||||
relname | spcname
|
||||
------------------+-------------
|
||||
_hyper_1_1_chunk | tablespace1
|
||||
_hyper_1_2_chunk | tablespace2
|
||||
_hyper_2_3_chunk | tablespace1
|
||||
_hyper_2_4_chunk | tablespace2
|
||||
SELECT * FROM test.show_subtablesp('tspace_%');
|
||||
Parent | Child | Tablespace
|
||||
-------------+----------------------------------------+-------------
|
||||
tspace_2dim | _timescaledb_internal._hyper_1_1_chunk | tablespace1
|
||||
tspace_2dim | _timescaledb_internal._hyper_1_2_chunk | tablespace2
|
||||
tspace_1dim | _timescaledb_internal._hyper_2_3_chunk | tablespace1
|
||||
tspace_1dim | _timescaledb_internal._hyper_2_4_chunk | tablespace2
|
||||
(4 rows)
|
||||
|
||||
--indexes should inherit the tablespace of their chunk, unless the
|
||||
--parent index has a tablespace set, in which case the chunks'
|
||||
--corresponding indexes are pinned to the parent index's
|
||||
--tablespace. The parent index can have a tablespace set in two cases:
|
||||
--(1) if explicitly set in CREATE INDEX, or (2) if the main table was
|
||||
--created with a tablespace, because then default indexes will be
|
||||
--created in that tablespace too.
|
||||
SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk');
|
||||
Table | Index | Columns | Unique | Primary | Exclusion | Tablespace
|
||||
----------------------------------------+--------------------------------------------------------------------+--------------------+--------+---------+-----------+-------------
|
||||
_timescaledb_internal._hyper_1_1_chunk | _timescaledb_internal._hyper_1_1_chunk_tspace_2dim_time_idx | {time,temp,device} | f | f | f | tablespace1
|
||||
_timescaledb_internal._hyper_1_1_chunk | _timescaledb_internal._hyper_1_1_chunk_tspace_2dim_device_time_idx | {time,temp,device} | f | f | f | tablespace1
|
||||
_timescaledb_internal._hyper_1_2_chunk | _timescaledb_internal._hyper_1_2_chunk_tspace_2dim_time_idx | {time,temp,device} | f | f | f | tablespace1
|
||||
_timescaledb_internal._hyper_1_2_chunk | _timescaledb_internal._hyper_1_2_chunk_tspace_2dim_device_time_idx | {time,temp,device} | f | f | f | tablespace1
|
||||
_timescaledb_internal._hyper_2_3_chunk | _timescaledb_internal._hyper_2_3_chunk_tspace_1dim_time_idx | {time,temp,device} | f | f | f | tablespace2
|
||||
_timescaledb_internal._hyper_2_4_chunk | _timescaledb_internal._hyper_2_4_chunk_tspace_1dim_time_idx | {time,temp,device} | f | f | f | tablespace1
|
||||
(6 rows)
|
||||
|
||||
--detach tablespace1 from all tables. Due to lack of permissions,
|
||||
--should only detach from 'tspace_1dim' (1 tablespace)
|
||||
SELECT detach_tablespace('tablespace1');
|
||||
|
@ -45,12 +45,12 @@ SELECT * FROM _timescaledb_catalog.chunk;
|
||||
(4 rows)
|
||||
|
||||
SELECT * FROM test.show_subtables('"two_Partitions"');
|
||||
Child
|
||||
----------------------------------------
|
||||
_timescaledb_internal._hyper_1_1_chunk
|
||||
_timescaledb_internal._hyper_1_2_chunk
|
||||
_timescaledb_internal._hyper_1_3_chunk
|
||||
_timescaledb_internal._hyper_1_4_chunk
|
||||
Child | Tablespace
|
||||
----------------------------------------+------------
|
||||
_timescaledb_internal._hyper_1_1_chunk |
|
||||
_timescaledb_internal._hyper_1_2_chunk |
|
||||
_timescaledb_internal._hyper_1_3_chunk |
|
||||
_timescaledb_internal._hyper_1_4_chunk |
|
||||
(4 rows)
|
||||
|
||||
SELECT * FROM "two_Partitions";
|
||||
@ -85,8 +85,8 @@ SELECT * FROM _timescaledb_catalog.chunk;
|
||||
|
||||
-- should be empty
|
||||
SELECT * FROM test.show_subtables('"two_Partitions"');
|
||||
Child
|
||||
-------
|
||||
Child | Tablespace
|
||||
-------+------------
|
||||
(0 rows)
|
||||
|
||||
SELECT * FROM "two_Partitions";
|
||||
@ -140,8 +140,8 @@ WARNING: FIRING trigger when: BEFORE level: STATEMENT op: TRUNCATE cnt: <NULL>
|
||||
WARNING: FIRING trigger when: AFTER level: STATEMENT op: TRUNCATE cnt: <NULL> trigger_name _test_truncate_after
|
||||
-- should be empty
|
||||
SELECT * FROM test.show_subtables('"two_Partitions"');
|
||||
Child
|
||||
-------
|
||||
Child | Tablespace
|
||||
-------+------------
|
||||
(0 rows)
|
||||
|
||||
SELECT * FROM "two_Partitions";
|
||||
|
@ -57,22 +57,24 @@ SELECT * FROM show_tablespaces('tspace_2dim');
|
||||
--insert into another chunk
|
||||
INSERT INTO tspace_2dim VALUES ('2017-01-20T09:00:01', 24.3, 'brown');
|
||||
|
||||
SELECT relname, spcname FROM pg_class c
|
||||
INNER JOIN pg_tablespace t ON (c.reltablespace = t.oid)
|
||||
INNER JOIN _timescaledb_catalog.chunk ch ON (ch.table_name = c.relname);
|
||||
SELECT * FROM test.show_subtables('tspace_2dim');
|
||||
|
||||
--indexes should inherit the tablespace of their chunk
|
||||
SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk');
|
||||
|
||||
--
|
||||
SET ROLE :ROLE_DEFAULT_PERM_USER_2;
|
||||
-- User doesn't have permission on tablespace1 --> error
|
||||
CREATE TABLE tspace_1dim(time timestamp, temp float, device text) TABLESPACE tablespace1;
|
||||
CREATE TABLE tspace_1dim(time timestamp, temp float, device text);
|
||||
|
||||
-- Grant permission to tablespace1
|
||||
SET ROLE :ROLE_DEFAULT_PERM_USER;
|
||||
GRANT CREATE ON TABLESPACE tablespace1 TO :ROLE_DEFAULT_PERM_USER_2;
|
||||
SET ROLE :ROLE_DEFAULT_PERM_USER_2;
|
||||
CREATE TABLE tspace_1dim(time timestamp, temp float, device text) TABLESPACE tablespace1;
|
||||
CREATE TABLE tspace_1dim(time timestamp, temp float, device text);
|
||||
|
||||
SELECT create_hypertable('tspace_1dim', 'time');
|
||||
SELECT attach_tablespace('tablespace1', 'tspace_1dim');
|
||||
SELECT attach_tablespace('tablespace2', 'tspace_1dim');
|
||||
|
||||
SELECT * FROM _timescaledb_catalog.tablespace;
|
||||
@ -80,9 +82,15 @@ SELECT * FROM _timescaledb_catalog.tablespace;
|
||||
INSERT INTO tspace_1dim VALUES ('2017-01-20T09:00:01', 24.3, 'blue');
|
||||
INSERT INTO tspace_1dim VALUES ('2017-03-20T09:00:01', 24.3, 'brown');
|
||||
|
||||
SELECT relname, spcname FROM pg_class c
|
||||
INNER JOIN pg_tablespace t ON (c.reltablespace = t.oid)
|
||||
INNER JOIN _timescaledb_catalog.chunk ch ON (ch.table_name = c.relname);
|
||||
SELECT * FROM test.show_subtablesp('tspace_%');
|
||||
--indexes should inherit the tablespace of their chunk, unless the
|
||||
--parent index has a tablespace set, in which case the chunks'
|
||||
--corresponding indexes are pinned to the parent index's
|
||||
--tablespace. The parent index can have a tablespace set in two cases:
|
||||
--(1) if explicitly set in CREATE INDEX, or (2) if the main table was
|
||||
--created with a tablespace, because then default indexes will be
|
||||
--created in that tablespace too.
|
||||
SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk');
|
||||
|
||||
--detach tablespace1 from all tables. Due to lack of permissions,
|
||||
--should only detach from 'tspace_1dim' (1 tablespace)
|
||||
|
@ -198,19 +198,22 @@ END
|
||||
$BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION test.show_subtables(rel regclass)
|
||||
RETURNS TABLE("Child" regclass) LANGUAGE SQL STABLE AS
|
||||
RETURNS TABLE("Child" regclass,
|
||||
"Tablespace" name) LANGUAGE SQL STABLE AS
|
||||
$BODY$
|
||||
SELECT objid::regclass
|
||||
FROM pg_depend d
|
||||
SELECT objid::regclass, (SELECT t.spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace)
|
||||
FROM pg_depend d, pg_class c
|
||||
WHERE d.refobjid = rel
|
||||
AND d.deptype = 'n'
|
||||
AND d.classid = 'pg_class'::regclass
|
||||
AND d.objid = c.oid
|
||||
ORDER BY d.refobjid, d.objid;
|
||||
$BODY$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION test.show_subtablesp(pattern text)
|
||||
RETURNS TABLE("Parent" regclass,
|
||||
"Child" regclass) LANGUAGE PLPGSQL STABLE AS
|
||||
"Child" regclass,
|
||||
"Tablespace" name) LANGUAGE PLPGSQL STABLE AS
|
||||
$BODY$
|
||||
DECLARE
|
||||
schema_name name = split_part(pattern, '.', 1);
|
||||
@ -223,7 +226,8 @@ BEGIN
|
||||
|
||||
RETURN QUERY
|
||||
SELECT refobjid::regclass,
|
||||
objid::regclass
|
||||
objid::regclass,
|
||||
(SELECT t.spcname FROM pg_class cc, pg_tablespace t WHERE cc.oid = d.objid AND t.oid = cc.reltablespace)
|
||||
FROM pg_class c, pg_depend d
|
||||
WHERE format('%I.%I', c.relnamespace::regnamespace::name, c.relname) LIKE format('%I.%s', schema_name, table_name)
|
||||
AND d.refobjid = c.oid
|
||||
|
Loading…
x
Reference in New Issue
Block a user