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:
Erik Nordström 2018-01-15 11:48:41 +01:00 committed by Erik Nordström
parent e85721a8ed
commit d135256ed7
12 changed files with 193 additions and 78 deletions

View File

@ -400,7 +400,7 @@ chunk_create_table(Chunk *chunk, Hypertable *ht)
.type = T_CreateStmt, .type = T_CreateStmt,
.relation = makeRangeVar(NameStr(chunk->fd.schema_name), NameStr(chunk->fd.table_name), 0), .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)), .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), .options = get_reloptions(ht->main_table_relid),
}; };
Oid uid, Oid uid,

View File

@ -195,6 +195,35 @@ chunk_adjust_attnos(IndexInfo *ii, Relation htrel, Relation idxrel, Relation chu
chunk_adjust_expr_attnos(ii, htrel, idxrel, chunkrel); 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. * Create a chunk index based on the configuration of the "parent" index.
*/ */
@ -213,6 +242,7 @@ chunk_relation_index_create(Relation htrel,
Datum indclass; Datum indclass;
oidvector *indclassoid; oidvector *indclassoid;
List *colnames = create_index_colnames(template_indexrel); List *colnames = create_index_colnames(template_indexrel);
Oid tablespace = InvalidOid;
/* /*
* Convert the IndexInfo's attnos to match the chunk instead of the * 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_name(RelationGetRelid(template_indexrel)),
get_rel_namespace(RelationGetRelid(chunkrel))); 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, chunk_indexrelid = index_create(chunkrel,
indexname, indexname,
InvalidOid, InvalidOid,
@ -246,7 +285,7 @@ chunk_relation_index_create(Relation htrel,
indexinfo, indexinfo,
colnames, colnames,
template_indexrel->rd_rel->relam, template_indexrel->rd_rel->relam,
template_indexrel->rd_rel->reltablespace, tablespace,
template_indexrel->rd_indcollation, template_indexrel->rd_indcollation,
indclassoid->values, indclassoid->values,
template_indexrel->rd_indoption, template_indexrel->rd_indoption,

View File

@ -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 * chunks in the same closed (space) dimension. This ensures chunks in the same
* "space" partition will live on the same disk. * "space" partition will live on the same disk.
*/ */
char * Tablespace *
hypertable_select_tablespace(Hypertable *ht, Chunk *chunk) hypertable_select_tablespace(Hypertable *ht, Chunk *chunk)
{ {
Dimension *dim; Dimension *dim;
@ -318,7 +318,39 @@ hypertable_select_tablespace(Hypertable *ht, Chunk *chunk)
Assert(i >= 0); Assert(i >= 0);
/* Use the index of the slice to find the tablespace */ /* 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 static inline Oid

View File

@ -30,6 +30,8 @@ extern Chunk *hypertable_get_chunk(Hypertable *h, Point *point);
extern Oid hypertable_relid(RangeVar *rv); extern Oid hypertable_relid(RangeVar *rv);
extern bool is_hypertable(Oid relid); extern bool is_hypertable(Oid relid);
extern bool hypertable_has_tablespace(Hypertable *ht, Oid tspc_oid); 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 */ #endif /* TIMESCALEDB_HYPERTABLE_H */

View File

@ -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_ts VALUES(now()-INTERVAL '5 minutes', 1.0, 'dev1');
INSERT INTO PUBLIC.drop_chunk_test_tstz 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'); SELECT * FROM test.show_subtables('drop_chunk_test_ts');
Child Child | Tablespace
----------------------------------------- -----------------------------------------+------------
_timescaledb_internal._hyper_4_19_chunk _timescaledb_internal._hyper_4_19_chunk |
(1 row) (1 row)
SELECT * FROM test.show_subtables('drop_chunk_test_tstz'); SELECT * FROM test.show_subtables('drop_chunk_test_tstz');
Child Child | Tablespace
----------------------------------------- -----------------------------------------+------------
_timescaledb_internal._hyper_5_20_chunk _timescaledb_internal._hyper_5_20_chunk |
(1 row) (1 row)
BEGIN; BEGIN;
@ -337,8 +337,8 @@ BEGIN;
(1 row) (1 row)
SELECT * FROM test.show_subtables('drop_chunk_test_ts'); SELECT * FROM test.show_subtables('drop_chunk_test_ts');
Child Child | Tablespace
------- -------+------------
(0 rows) (0 rows)
SELECT drop_chunks(interval '1 minute', 'drop_chunk_test_tstz'); SELECT drop_chunks(interval '1 minute', 'drop_chunk_test_tstz');
@ -348,8 +348,8 @@ BEGIN;
(1 row) (1 row)
SELECT * FROM test.show_subtables('drop_chunk_test_tstz'); SELECT * FROM test.show_subtables('drop_chunk_test_tstz');
Child Child | Tablespace
------- -------+------------
(0 rows) (0 rows)
ROLLBACK; ROLLBACK;
@ -361,8 +361,8 @@ BEGIN;
(1 row) (1 row)
SELECT * FROM test.show_subtables('drop_chunk_test_ts'); SELECT * FROM test.show_subtables('drop_chunk_test_ts');
Child Child | Tablespace
------- -------+------------
(0 rows) (0 rows)
SELECT drop_chunks(now()-interval '1 minute', 'drop_chunk_test_tstz'); SELECT drop_chunks(now()-interval '1 minute', 'drop_chunk_test_tstz');
@ -372,8 +372,8 @@ BEGIN;
(1 row) (1 row)
SELECT * FROM test.show_subtables('drop_chunk_test_tstz'); SELECT * FROM test.show_subtables('drop_chunk_test_tstz');
Child Child | Tablespace
------- -------+------------
(0 rows) (0 rows)
ROLLBACK; ROLLBACK;
@ -405,8 +405,8 @@ BEGIN;
(1 row) (1 row)
SELECT * FROM test.show_subtables('drop_chunk_test_date'); SELECT * FROM test.show_subtables('drop_chunk_test_date');
Child Child | Tablespace
------- -------+------------
(0 rows) (0 rows)
ROLLBACK; ROLLBACK;
@ -418,8 +418,8 @@ BEGIN;
(1 row) (1 row)
SELECT * FROM test.show_subtables('drop_chunk_test_date'); SELECT * FROM test.show_subtables('drop_chunk_test_date');
Child Child | Tablespace
------- -------+------------
(0 rows) (0 rows)
ROLLBACK; ROLLBACK;

View File

@ -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_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_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) (3 rows)
-- Creating a new index should propagate to existing chunks, including -- 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_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_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 _timescaledb_internal._hyper_5_5_chunk | _timescaledb_internal._hyper_5_5_chunk_time_temp_idx | {time,temp,device} | f | f | f | tablespace2
(4 rows) (4 rows)

View File

@ -21,13 +21,13 @@ SELECT * FROM test.show_columns('reindex_test');
(2 rows) (2 rows)
SELECT * FROM test.show_subtables('reindex_test'); SELECT * FROM test.show_subtables('reindex_test');
Child Child | Tablespace
---------------------------------------- ----------------------------------------+------------
_timescaledb_internal._hyper_1_1_chunk _timescaledb_internal._hyper_1_1_chunk |
_timescaledb_internal._hyper_1_2_chunk _timescaledb_internal._hyper_1_2_chunk |
_timescaledb_internal._hyper_1_3_chunk _timescaledb_internal._hyper_1_3_chunk |
_timescaledb_internal._hyper_1_4_chunk _timescaledb_internal._hyper_1_4_chunk |
_timescaledb_internal._hyper_1_5_chunk _timescaledb_internal._hyper_1_5_chunk |
(5 rows) (5 rows)
-- show reindexing -- show reindexing

View File

@ -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); INSERT INTO "int_part" VALUES('2017-01-20T09:00:01', 2, 22.5);
--check that there are two chunks --check that there are two chunks
SELECT * FROM test.show_subtables('int_part'); SELECT * FROM test.show_subtables('int_part');
Child Child | Tablespace
---------------------------------------- ----------------------------------------+------------
_timescaledb_internal._hyper_2_5_chunk _timescaledb_internal._hyper_2_5_chunk |
_timescaledb_internal._hyper_2_6_chunk _timescaledb_internal._hyper_2_6_chunk |
(2 rows) (2 rows)
SELECT * FROM "int_part" WHERE object_id = 1; SELECT * FROM "int_part" WHERE object_id = 1;

View File

@ -77,25 +77,33 @@ SELECT * FROM show_tablespaces('tspace_2dim');
--insert into another chunk --insert into another chunk
INSERT INTO tspace_2dim VALUES ('2017-01-20T09:00:01', 24.3, 'brown'); INSERT INTO tspace_2dim VALUES ('2017-01-20T09:00:01', 24.3, 'brown');
SELECT relname, spcname FROM pg_class c SELECT * FROM test.show_subtables('tspace_2dim');
INNER JOIN pg_tablespace t ON (c.reltablespace = t.oid) Child | Tablespace
INNER JOIN _timescaledb_catalog.chunk ch ON (ch.table_name = c.relname); ----------------------------------------+-------------
relname | spcname _timescaledb_internal._hyper_1_1_chunk | tablespace1
------------------+------------- _timescaledb_internal._hyper_1_2_chunk | tablespace2
_hyper_1_1_chunk | tablespace1
_hyper_1_2_chunk | tablespace2
(2 rows) (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; SET ROLE :ROLE_DEFAULT_PERM_USER_2;
-- User doesn't have permission on tablespace1 --> error -- 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);
ERROR: permission denied for tablespace tablespace1
-- Grant permission to tablespace1 -- Grant permission to tablespace1
SET ROLE :ROLE_DEFAULT_PERM_USER; SET ROLE :ROLE_DEFAULT_PERM_USER;
GRANT CREATE ON TABLESPACE tablespace1 TO :ROLE_DEFAULT_PERM_USER_2; GRANT CREATE ON TABLESPACE tablespace1 TO :ROLE_DEFAULT_PERM_USER_2;
SET ROLE :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'); SELECT create_hypertable('tspace_1dim', 'time');
NOTICE: Adding NOT NULL constraint to time column time (NULL time values not allowed) NOTICE: Adding NOT NULL constraint to time column time (NULL time values not allowed)
create_hypertable create_hypertable
@ -103,6 +111,12 @@ NOTICE: Adding NOT NULL constraint to time column time (NULL time values not al
(1 row) (1 row)
SELECT attach_tablespace('tablespace1', 'tspace_1dim');
attach_tablespace
-------------------
(1 row)
SELECT attach_tablespace('tablespace2', 'tspace_1dim'); SELECT attach_tablespace('tablespace2', 'tspace_1dim');
attach_tablespace 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-01-20T09:00:01', 24.3, 'blue');
INSERT INTO tspace_1dim VALUES ('2017-03-20T09:00:01', 24.3, 'brown'); INSERT INTO tspace_1dim VALUES ('2017-03-20T09:00:01', 24.3, 'brown');
SELECT relname, spcname FROM pg_class c SELECT * FROM test.show_subtablesp('tspace_%');
INNER JOIN pg_tablespace t ON (c.reltablespace = t.oid) Parent | Child | Tablespace
INNER JOIN _timescaledb_catalog.chunk ch ON (ch.table_name = c.relname); -------------+----------------------------------------+-------------
relname | spcname tspace_2dim | _timescaledb_internal._hyper_1_1_chunk | tablespace1
------------------+------------- tspace_2dim | _timescaledb_internal._hyper_1_2_chunk | tablespace2
_hyper_1_1_chunk | tablespace1 tspace_1dim | _timescaledb_internal._hyper_2_3_chunk | tablespace1
_hyper_1_2_chunk | tablespace2 tspace_1dim | _timescaledb_internal._hyper_2_4_chunk | tablespace2
_hyper_2_3_chunk | tablespace1
_hyper_2_4_chunk | tablespace2
(4 rows) (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, --detach tablespace1 from all tables. Due to lack of permissions,
--should only detach from 'tspace_1dim' (1 tablespace) --should only detach from 'tspace_1dim' (1 tablespace)
SELECT detach_tablespace('tablespace1'); SELECT detach_tablespace('tablespace1');

View File

@ -45,12 +45,12 @@ SELECT * FROM _timescaledb_catalog.chunk;
(4 rows) (4 rows)
SELECT * FROM test.show_subtables('"two_Partitions"'); SELECT * FROM test.show_subtables('"two_Partitions"');
Child Child | Tablespace
---------------------------------------- ----------------------------------------+------------
_timescaledb_internal._hyper_1_1_chunk _timescaledb_internal._hyper_1_1_chunk |
_timescaledb_internal._hyper_1_2_chunk _timescaledb_internal._hyper_1_2_chunk |
_timescaledb_internal._hyper_1_3_chunk _timescaledb_internal._hyper_1_3_chunk |
_timescaledb_internal._hyper_1_4_chunk _timescaledb_internal._hyper_1_4_chunk |
(4 rows) (4 rows)
SELECT * FROM "two_Partitions"; SELECT * FROM "two_Partitions";
@ -85,8 +85,8 @@ SELECT * FROM _timescaledb_catalog.chunk;
-- should be empty -- should be empty
SELECT * FROM test.show_subtables('"two_Partitions"'); SELECT * FROM test.show_subtables('"two_Partitions"');
Child Child | Tablespace
------- -------+------------
(0 rows) (0 rows)
SELECT * FROM "two_Partitions"; 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 WARNING: FIRING trigger when: AFTER level: STATEMENT op: TRUNCATE cnt: <NULL> trigger_name _test_truncate_after
-- should be empty -- should be empty
SELECT * FROM test.show_subtables('"two_Partitions"'); SELECT * FROM test.show_subtables('"two_Partitions"');
Child Child | Tablespace
------- -------+------------
(0 rows) (0 rows)
SELECT * FROM "two_Partitions"; SELECT * FROM "two_Partitions";

View File

@ -57,22 +57,24 @@ SELECT * FROM show_tablespaces('tspace_2dim');
--insert into another chunk --insert into another chunk
INSERT INTO tspace_2dim VALUES ('2017-01-20T09:00:01', 24.3, 'brown'); INSERT INTO tspace_2dim VALUES ('2017-01-20T09:00:01', 24.3, 'brown');
SELECT relname, spcname FROM pg_class c SELECT * FROM test.show_subtables('tspace_2dim');
INNER JOIN pg_tablespace t ON (c.reltablespace = t.oid)
INNER JOIN _timescaledb_catalog.chunk ch ON (ch.table_name = c.relname); --indexes should inherit the tablespace of their chunk
SELECT * FROM test.show_indexesp('_timescaledb_internal._hyper%_chunk');
-- --
SET ROLE :ROLE_DEFAULT_PERM_USER_2; SET ROLE :ROLE_DEFAULT_PERM_USER_2;
-- User doesn't have permission on tablespace1 --> error -- 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 -- Grant permission to tablespace1
SET ROLE :ROLE_DEFAULT_PERM_USER; SET ROLE :ROLE_DEFAULT_PERM_USER;
GRANT CREATE ON TABLESPACE tablespace1 TO :ROLE_DEFAULT_PERM_USER_2; GRANT CREATE ON TABLESPACE tablespace1 TO :ROLE_DEFAULT_PERM_USER_2;
SET ROLE :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 create_hypertable('tspace_1dim', 'time');
SELECT attach_tablespace('tablespace1', 'tspace_1dim');
SELECT attach_tablespace('tablespace2', 'tspace_1dim'); SELECT attach_tablespace('tablespace2', 'tspace_1dim');
SELECT * FROM _timescaledb_catalog.tablespace; 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-01-20T09:00:01', 24.3, 'blue');
INSERT INTO tspace_1dim VALUES ('2017-03-20T09:00:01', 24.3, 'brown'); INSERT INTO tspace_1dim VALUES ('2017-03-20T09:00:01', 24.3, 'brown');
SELECT relname, spcname FROM pg_class c SELECT * FROM test.show_subtablesp('tspace_%');
INNER JOIN pg_tablespace t ON (c.reltablespace = t.oid) --indexes should inherit the tablespace of their chunk, unless the
INNER JOIN _timescaledb_catalog.chunk ch ON (ch.table_name = c.relname); --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, --detach tablespace1 from all tables. Due to lack of permissions,
--should only detach from 'tspace_1dim' (1 tablespace) --should only detach from 'tspace_1dim' (1 tablespace)

View File

@ -198,19 +198,22 @@ END
$BODY$; $BODY$;
CREATE OR REPLACE FUNCTION test.show_subtables(rel regclass) 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$ $BODY$
SELECT objid::regclass SELECT objid::regclass, (SELECT t.spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace)
FROM pg_depend d FROM pg_depend d, pg_class c
WHERE d.refobjid = rel WHERE d.refobjid = rel
AND d.deptype = 'n' AND d.deptype = 'n'
AND d.classid = 'pg_class'::regclass AND d.classid = 'pg_class'::regclass
AND d.objid = c.oid
ORDER BY d.refobjid, d.objid; ORDER BY d.refobjid, d.objid;
$BODY$; $BODY$;
CREATE OR REPLACE FUNCTION test.show_subtablesp(pattern text) CREATE OR REPLACE FUNCTION test.show_subtablesp(pattern text)
RETURNS TABLE("Parent" regclass, RETURNS TABLE("Parent" regclass,
"Child" regclass) LANGUAGE PLPGSQL STABLE AS "Child" regclass,
"Tablespace" name) LANGUAGE PLPGSQL STABLE AS
$BODY$ $BODY$
DECLARE DECLARE
schema_name name = split_part(pattern, '.', 1); schema_name name = split_part(pattern, '.', 1);
@ -223,7 +226,8 @@ BEGIN
RETURN QUERY RETURN QUERY
SELECT refobjid::regclass, 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 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) WHERE format('%I.%I', c.relnamespace::regnamespace::name, c.relname) LIKE format('%I.%s', schema_name, table_name)
AND d.refobjid = c.oid AND d.refobjid = c.oid