From a48970af13c1c78cd8dad2473ad5f480bfb81961 Mon Sep 17 00:00:00 2001 From: Onder Kalaci Date: Fri, 12 Dec 2014 14:42:49 +0200 Subject: [PATCH 1/5] Shards backed by foreign tables marked correctly in the metadata Before this fix, when a foreign table is distributed by "master_create_worker_shards", "storage" field in the "pgs_distribution_metadata.shard" was set to 't'. After the fix, it is set to 'f'. Note that 'f' denotes foreign table, 't' denotes table. --- create_shards.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/create_shards.c b/create_shards.c index 9bc9393..ed14f1b 100644 --- a/create_shards.c +++ b/create_shards.c @@ -30,6 +30,7 @@ #include "access/attnum.h" #include "catalog/namespace.h" +#include "catalog/pg_class.h" #include "lib/stringinfo.h" #include "nodes/pg_list.h" #include "nodes/primnodes.h" @@ -107,6 +108,7 @@ master_create_worker_shards(PG_FUNCTION_ARGS) int32 replicationFactor = PG_GETARG_INT32(2); Oid distributedTableId = ResolveRelationId(tableNameText); + char relationKind = get_rel_relkind(distributedTableId); int32 shardIndex = 0; List *workerNodeList = NIL; List *ddlCommandList = NIL; @@ -114,6 +116,7 @@ master_create_worker_shards(PG_FUNCTION_ARGS) uint32 placementAttemptCount = 0; uint32 hashTokenIncrement = 0; List *existingShardList = NIL; + char shardStorageType = '\0'; /* make sure table is hash partitioned */ CheckHashPartitionedTable(distributedTableId); @@ -170,6 +173,16 @@ master_create_worker_shards(PG_FUNCTION_ARGS) placementAttemptCount++; } + /* set shard storage type according to relation type */ + if (relationKind == RELKIND_FOREIGN_TABLE) + { + shardStorageType = SHARD_STORAGE_FOREIGN; + } + else + { + shardStorageType = SHARD_STORAGE_TABLE; + } + for (shardIndex = 0; shardIndex < shardCount; shardIndex++) { uint64 shardId = NextSequenceId(SHARD_ID_SEQUENCE_NAME); @@ -234,7 +247,7 @@ master_create_worker_shards(PG_FUNCTION_ARGS) /* insert the shard metadata row along with its min/max values */ minHashTokenText = IntegerToText(shardMinHashToken); maxHashTokenText = IntegerToText(shardMaxHashToken); - InsertShardRow(distributedTableId, shardId, SHARD_STORAGE_TABLE, + InsertShardRow(distributedTableId, shardId, shardStorageType, minHashTokenText, maxHashTokenText); } From 4919b0971df648c5b4a7632bce6830ec96f7d2fb Mon Sep 17 00:00:00 2001 From: Onder Kalaci Date: Thu, 18 Dec 2014 18:13:36 +0200 Subject: [PATCH 2/5] Improvements on style This commit aims to improve coding style to fit our coding conventions. --- create_shards.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/create_shards.c b/create_shards.c index ed14f1b..bdaf981 100644 --- a/create_shards.c +++ b/create_shards.c @@ -108,7 +108,7 @@ master_create_worker_shards(PG_FUNCTION_ARGS) int32 replicationFactor = PG_GETARG_INT32(2); Oid distributedTableId = ResolveRelationId(tableNameText); - char relationKind = get_rel_relkind(distributedTableId); + char relationKind = '\0'; int32 shardIndex = 0; List *workerNodeList = NIL; List *ddlCommandList = NIL; @@ -174,6 +174,7 @@ master_create_worker_shards(PG_FUNCTION_ARGS) } /* set shard storage type according to relation type */ + relationKind = get_rel_relkind(distributedTableId); if (relationKind == RELKIND_FOREIGN_TABLE) { shardStorageType = SHARD_STORAGE_FOREIGN; From 81b8381f84ed6a1365b062c280c8d47e7a31ebaf Mon Sep 17 00:00:00 2001 From: Onder Kalaci Date: Mon, 29 Dec 2014 15:43:27 +0200 Subject: [PATCH 3/5] Improvements on Style This commit makes small changes for improving code style. --- create_shards.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/create_shards.c b/create_shards.c index bdaf981..210020d 100644 --- a/create_shards.c +++ b/create_shards.c @@ -108,7 +108,8 @@ master_create_worker_shards(PG_FUNCTION_ARGS) int32 replicationFactor = PG_GETARG_INT32(2); Oid distributedTableId = ResolveRelationId(tableNameText); - char relationKind = '\0'; + char relationKind = get_rel_relkind(distributedTableId); + char shardStorageType = '\0'; int32 shardIndex = 0; List *workerNodeList = NIL; List *ddlCommandList = NIL; @@ -116,7 +117,6 @@ master_create_worker_shards(PG_FUNCTION_ARGS) uint32 placementAttemptCount = 0; uint32 hashTokenIncrement = 0; List *existingShardList = NIL; - char shardStorageType = '\0'; /* make sure table is hash partitioned */ CheckHashPartitionedTable(distributedTableId); @@ -174,7 +174,6 @@ master_create_worker_shards(PG_FUNCTION_ARGS) } /* set shard storage type according to relation type */ - relationKind = get_rel_relkind(distributedTableId); if (relationKind == RELKIND_FOREIGN_TABLE) { shardStorageType = SHARD_STORAGE_FOREIGN; From 1b2f37ca2b0a14bb79dfb5e2b994457919f544fa Mon Sep 17 00:00:00 2001 From: Onder Kalaci Date: Fri, 2 Jan 2015 17:59:58 +0200 Subject: [PATCH 4/5] Regression tests for foreign tables This is initial commit to add regression tests for foreign tables in pg_shard. --- expected/create_shards.out.tmpl | 111 +++++++++++++++++++++++++------- sql/create_shards.sql.tmpl | 28 +++++++- 2 files changed, 112 insertions(+), 27 deletions(-) diff --git a/expected/create_shards.out.tmpl b/expected/create_shards.out.tmpl index 6bf6dba..68addc4 100644 --- a/expected/create_shards.out.tmpl +++ b/expected/create_shards.out.tmpl @@ -58,27 +58,27 @@ DETAIL: Replication factor: 3 exceeds worker node count: 2 -- use a replication factor higher than healthy node count -- this will create a shard on the healthy node but fail right after SELECT master_create_worker_shards('table_to_distribute', 16, 2); -WARNING: Connection failed to adeadhost:$PGPORT -WARNING: could not create shard on "adeadhost:$PGPORT" +WARNING: Connection failed to adeadhost:5432 +WARNING: could not create shard on "adeadhost:5432" ERROR: could only create 1 of 2 of required shard replicas -- finally, create shards and inspect metadata SELECT master_create_worker_shards('table_to_distribute', 16, 1); -WARNING: Connection failed to adeadhost:$PGPORT -WARNING: could not create shard on "adeadhost:$PGPORT" -WARNING: Connection failed to adeadhost:$PGPORT -WARNING: could not create shard on "adeadhost:$PGPORT" -WARNING: Connection failed to adeadhost:$PGPORT -WARNING: could not create shard on "adeadhost:$PGPORT" -WARNING: Connection failed to adeadhost:$PGPORT -WARNING: could not create shard on "adeadhost:$PGPORT" -WARNING: Connection failed to adeadhost:$PGPORT -WARNING: could not create shard on "adeadhost:$PGPORT" -WARNING: Connection failed to adeadhost:$PGPORT -WARNING: could not create shard on "adeadhost:$PGPORT" -WARNING: Connection failed to adeadhost:$PGPORT -WARNING: could not create shard on "adeadhost:$PGPORT" -WARNING: Connection failed to adeadhost:$PGPORT -WARNING: could not create shard on "adeadhost:$PGPORT" +WARNING: Connection failed to adeadhost:5432 +WARNING: could not create shard on "adeadhost:5432" +WARNING: Connection failed to adeadhost:5432 +WARNING: could not create shard on "adeadhost:5432" +WARNING: Connection failed to adeadhost:5432 +WARNING: could not create shard on "adeadhost:5432" +WARNING: Connection failed to adeadhost:5432 +WARNING: could not create shard on "adeadhost:5432" +WARNING: Connection failed to adeadhost:5432 +WARNING: could not create shard on "adeadhost:5432" +WARNING: Connection failed to adeadhost:5432 +WARNING: could not create shard on "adeadhost:5432" +WARNING: Connection failed to adeadhost:5432 +WARNING: could not create shard on "adeadhost:5432" +WARNING: Connection failed to adeadhost:5432 +WARNING: could not create shard on "adeadhost:5432" master_create_worker_shards ----------------------------- @@ -108,12 +108,16 @@ SELECT storage, min_value, max_value FROM pgs_distribution_metadata.shard t | 805306357 | 1073741811 (16 rows) -SELECT DISTINCT ON (node_name, node_port) node_name, node_port - FROM pgs_distribution_metadata.shard_placement, pgs_distribution_metadata.shard - WHERE shard_placement.shard_id = shard.id; - node_name | node_port ------------+----------- - localhost | $PGPORT +-- all shards should be on a single node +WITH unique_nodes AS ( + SELECT DISTINCT ON (node_name, node_port) node_name, node_port + FROM pgs_distribution_metadata.shard_placement, pgs_distribution_metadata.shard + WHERE shard_placement.shard_id = shard.id + ) +SELECT COUNT(*) FROM unique_nodes; + count +------- + 1 (1 row) SELECT COUNT(*) FROM pg_class WHERE relname LIKE 'table_to_distribute%' AND relkind = 'r'; @@ -151,3 +155,62 @@ SELECT COUNT(*) FROM pg_class WHERE relname LIKE 'throwaway%' AND relkind = 'r'; 0 (1 row) +\set VERBOSITY terse +-- test foreign table creation +CREATE FOREIGN TABLE foreign_table_to_distribute +( + name text, + id bigint +) +SERVER fake_fdw_server; +SELECT master_create_distributed_table('foreign_table_to_distribute', 'id'); + master_create_distributed_table +--------------------------------- + +(1 row) + +SELECT master_create_worker_shards('foreign_table_to_distribute', 16, 1); +WARNING: Connection failed to adeadhost:5432 +WARNING: could not create shard on "adeadhost:5432" +WARNING: Connection failed to adeadhost:5432 +WARNING: could not create shard on "adeadhost:5432" +WARNING: Connection failed to adeadhost:5432 +WARNING: could not create shard on "adeadhost:5432" +WARNING: Connection failed to adeadhost:5432 +WARNING: could not create shard on "adeadhost:5432" +WARNING: Connection failed to adeadhost:5432 +WARNING: could not create shard on "adeadhost:5432" +WARNING: Connection failed to adeadhost:5432 +WARNING: could not create shard on "adeadhost:5432" +WARNING: Connection failed to adeadhost:5432 +WARNING: could not create shard on "adeadhost:5432" +WARNING: Connection failed to adeadhost:5432 +WARNING: could not create shard on "adeadhost:5432" + master_create_worker_shards +----------------------------- + +(1 row) + +SELECT storage, min_value, max_value FROM pgs_distribution_metadata.shard + WHERE relation_id = 'foreign_table_to_distribute'::regclass + ORDER BY (min_value COLLATE "C") ASC; + storage | min_value | max_value +---------+-------------+------------- + f | -1073741828 | -805306374 + f | -1342177283 | -1073741829 + f | -1610612738 | -1342177284 + f | -1879048193 | -1610612739 + f | -2147483648 | -1879048194 + f | -268435463 | -9 + f | -536870918 | -268435464 + f | -8 | 268435446 + f | -805306373 | -536870919 + f | 1073741812 | 1342177266 + f | 1342177267 | 1610612721 + f | 1610612722 | 1879048176 + f | 1879048177 | 2147483647 + f | 268435447 | 536870901 + f | 536870902 | 805306356 + f | 805306357 | 1073741811 +(16 rows) + diff --git a/sql/create_shards.sql.tmpl b/sql/create_shards.sql.tmpl index 0631278..7074e11 100644 --- a/sql/create_shards.sql.tmpl +++ b/sql/create_shards.sql.tmpl @@ -59,9 +59,13 @@ SELECT storage, min_value, max_value FROM pgs_distribution_metadata.shard WHERE relation_id = 'table_to_distribute'::regclass ORDER BY (min_value COLLATE "C") ASC; -SELECT DISTINCT ON (node_name, node_port) node_name, node_port - FROM pgs_distribution_metadata.shard_placement, pgs_distribution_metadata.shard - WHERE shard_placement.shard_id = shard.id; +-- all shards should be on a single node +WITH unique_nodes AS ( + SELECT DISTINCT ON (node_name, node_port) node_name, node_port + FROM pgs_distribution_metadata.shard_placement, pgs_distribution_metadata.shard + WHERE shard_placement.shard_id = shard.id + ) +SELECT COUNT(*) FROM unique_nodes; SELECT COUNT(*) FROM pg_class WHERE relname LIKE 'table_to_distribute%' AND relkind = 'r'; @@ -75,3 +79,21 @@ SELECT sort_names('sumedh', 'jason', 'ozgun'); SELECT create_table_then_fail('localhost', $PGPORT); SELECT COUNT(*) FROM pg_class WHERE relname LIKE 'throwaway%' AND relkind = 'r'; + +\set VERBOSITY terse + +-- test foreign table creation +CREATE FOREIGN TABLE foreign_table_to_distribute +( + name text, + id bigint +) +SERVER fake_fdw_server; + +SELECT master_create_distributed_table('foreign_table_to_distribute', 'id'); + +SELECT master_create_worker_shards('foreign_table_to_distribute', 16, 1); + +SELECT storage, min_value, max_value FROM pgs_distribution_metadata.shard + WHERE relation_id = 'foreign_table_to_distribute'::regclass + ORDER BY (min_value COLLATE "C") ASC; \ No newline at end of file From b659a6559d7695c93eca0c6b06fcff6b94377819 Mon Sep 17 00:00:00 2001 From: Onder Kalaci Date: Fri, 2 Jan 2015 18:44:12 +0200 Subject: [PATCH 5/5] Regression tests for foreign tables This commit improves regression tests for foreign tables in pg_shard. --- expected/create_shards.out.tmpl | 11 +++++++++++ expected/modifications.out.tmpl | 4 ++-- sql/create_shards.sql.tmpl | 13 ++++++++++++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/expected/create_shards.out.tmpl b/expected/create_shards.out.tmpl index 68addc4..c39d826 100644 --- a/expected/create_shards.out.tmpl +++ b/expected/create_shards.out.tmpl @@ -191,6 +191,7 @@ WARNING: could not create shard on "adeadhost:5432" (1 row) +\set VERBOSITY default SELECT storage, min_value, max_value FROM pgs_distribution_metadata.shard WHERE relation_id = 'foreign_table_to_distribute'::regclass ORDER BY (min_value COLLATE "C") ASC; @@ -214,3 +215,13 @@ SELECT storage, min_value, max_value FROM pgs_distribution_metadata.shard f | 805306357 | 1073741811 (16 rows) +-- cleanup foreign table, related shards and shard placements +DELETE FROM pgs_distribution_metadata.shard_placement + WHERE shard_id IN (SELECT shard_id FROM pgs_distribution_metadata.shard + WHERE relation_id = 'foreign_table_to_distribute'::regclass); + +DELETE FROM pgs_distribution_metadata.shard + WHERE relation_id = 'foreign_table_to_distribute'::regclass; + +DELETE FROM pgs_distribution_metadata.partition + WHERE relation_id = 'foreign_table_to_distribute'::regclass; diff --git a/expected/modifications.out.tmpl b/expected/modifications.out.tmpl index 500e998..4f08766 100644 --- a/expected/modifications.out.tmpl +++ b/expected/modifications.out.tmpl @@ -63,12 +63,12 @@ ERROR: cannot plan INSERT using row with NULL value in partition column INSERT INTO limit_orders VALUES (18811, 'BUD', 14962, '2014-04-05 08:32:16', 'sell', -5.00); WARNING: Bad result from localhost:$PGPORT -DETAIL: Remote message: new row for relation "limit_orders_10018" violates check constraint "limit_orders_limit_price_check" +DETAIL: Remote message: new row for relation "limit_orders_10034" violates check constraint "limit_orders_limit_price_check" ERROR: could not modify any active placements -- insert violating primary key constraint INSERT INTO limit_orders VALUES (32743, 'LUV', 5994, '2001-04-16 03:37:28', 'buy', 0.58); WARNING: Bad result from localhost:$PGPORT -DETAIL: Remote message: duplicate key value violates unique constraint "limit_orders_pkey_10019" +DETAIL: Remote message: duplicate key value violates unique constraint "limit_orders_pkey_10035" ERROR: could not modify any active placements -- queries with non-constant partition values are unsupported INSERT INTO limit_orders VALUES (random() * 100, 'ORCL', 152, '2011-08-25 11:50:45', diff --git a/sql/create_shards.sql.tmpl b/sql/create_shards.sql.tmpl index 6e2b755..8de9dd8 100644 --- a/sql/create_shards.sql.tmpl +++ b/sql/create_shards.sql.tmpl @@ -91,9 +91,20 @@ CREATE FOREIGN TABLE foreign_table_to_distribute SERVER fake_fdw_server; SELECT master_create_distributed_table('foreign_table_to_distribute', 'id'); - SELECT master_create_worker_shards('foreign_table_to_distribute', 16, 1); +\set VERBOSITY default SELECT storage, min_value, max_value FROM pgs_distribution_metadata.shard WHERE relation_id = 'foreign_table_to_distribute'::regclass ORDER BY (min_value COLLATE "C") ASC; + +-- cleanup foreign table, related shards and shard placements +DELETE FROM pgs_distribution_metadata.shard_placement + WHERE shard_id IN (SELECT shard_id FROM pgs_distribution_metadata.shard + WHERE relation_id = 'foreign_table_to_distribute'::regclass); + +DELETE FROM pgs_distribution_metadata.shard + WHERE relation_id = 'foreign_table_to_distribute'::regclass; + +DELETE FROM pgs_distribution_metadata.partition + WHERE relation_id = 'foreign_table_to_distribute'::regclass;