Skip to content

Commit d18dfa6

Browse files
committed
Merge branch 'release-1.2.3'
2 parents 7e6103f + 74effb9 commit d18dfa6

3 files changed

Lines changed: 141 additions & 41 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
### pg_shard v1.2.3 (October 28, 2015) ###
2+
3+
* Addresses a performance regression by caching metadata plans
4+
15
### pg_shard v1.2.2 (August 28, 2015) ###
26

37
* Changes default planner when running within CitusDB

META.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "pg_shard",
33
"abstract": "Easy sharding for PostgreSQL",
44
"description": "Shards and replicates PostgreSQL tables for horizontal scale and high availability. Seamlessly distributes SQL statements, without requiring any application changes.",
5-
"version": "1.2.2",
5+
"version": "1.2.3",
66
"maintainer": "\"Jason Petersen\" <jason@citusdata.com>",
77
"license": "lgpl_3_0",
88
"prereqs": {
@@ -17,7 +17,7 @@
1717
"abstract": "Easy sharding for PostgreSQL",
1818
"file": "sql/pg_shard--1.2.sql",
1919
"docfile": "README.md",
20-
"version": "1.2.2"
20+
"version": "1.2.3"
2121
}
2222
},
2323
"release_status": "stable",

src/distribution_metadata.c

Lines changed: 135 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ LoadShardIntervalList(Oid distributedTableId)
123123
Datum argValues[] = { ObjectIdGetDatum(distributedTableId) };
124124
const int argCount = sizeof(argValues) / sizeof(argValues[0]);
125125
int spiStatus PG_USED_FOR_ASSERTS_ONLY = 0;
126+
static SPIPlanPtr spiPlan = NULL;
126127

127128
/*
128129
* SPI_connect switches to its own memory context, which is destroyed by
@@ -135,8 +136,16 @@ LoadShardIntervalList(Oid distributedTableId)
135136

136137
SPI_connect();
137138

138-
spiStatus = SPI_execute_with_args(SHARD_QUERY_PREFIX " WHERE s.relation_id = $1",
139-
argCount, argTypes, argValues, NULL, false, 0);
139+
if (spiPlan == NULL)
140+
{
141+
spiPlan = SPI_prepare(SHARD_QUERY_PREFIX " WHERE s.relation_id = $1", argCount,
142+
argTypes);
143+
144+
spiStatus = SPI_keepplan(spiPlan);
145+
Assert(spiStatus == 0);
146+
}
147+
148+
spiStatus = SPI_execute_plan(spiPlan, argValues, NULL, false, 0);
140149
Assert(spiStatus == SPI_OK_SELECT);
141150

142151
oldContext = MemoryContextSwitchTo(upperContext);
@@ -170,6 +179,7 @@ LoadShardInterval(int64 shardId)
170179
Datum argValues[] = { Int64GetDatum(shardId) };
171180
const int argCount = sizeof(argValues) / sizeof(argValues[0]);
172181
int spiStatus PG_USED_FOR_ASSERTS_ONLY = 0;
182+
static SPIPlanPtr spiPlan = NULL;
173183

174184
/*
175185
* SPI_connect switches to an SPI-specific MemoryContext. See the comment
@@ -178,8 +188,15 @@ LoadShardInterval(int64 shardId)
178188
MemoryContext upperContext = CurrentMemoryContext, oldContext = NULL;
179189
SPI_connect();
180190

181-
spiStatus = SPI_execute_with_args(SHARD_QUERY_PREFIX " WHERE s.id = $1",
182-
argCount, argTypes, argValues, NULL, false, 1);
191+
if (spiPlan == NULL)
192+
{
193+
spiPlan = SPI_prepare(SHARD_QUERY_PREFIX " WHERE s.id = $1", argCount, argTypes);
194+
195+
spiStatus = SPI_keepplan(spiPlan);
196+
Assert(spiStatus == 0);
197+
}
198+
199+
spiStatus = SPI_execute_plan(spiPlan, argValues, NULL, false, 1);
183200
Assert(spiStatus == SPI_OK_SELECT);
184201

185202
if (SPI_processed != 1)
@@ -239,6 +256,7 @@ LoadShardPlacementList(int64 shardId)
239256
Datum argValues[] = { Int64GetDatum(shardId) };
240257
const int argCount = sizeof(argValues) / sizeof(argValues[0]);
241258
int spiStatus PG_USED_FOR_ASSERTS_ONLY = 0;
259+
static SPIPlanPtr spiPlan = NULL;
242260

243261
/*
244262
* SPI_connect switches to an SPI-specific MemoryContext. See the comment
@@ -247,8 +265,15 @@ LoadShardPlacementList(int64 shardId)
247265
MemoryContext upperContext = CurrentMemoryContext, oldContext = NULL;
248266
SPI_connect();
249267

250-
spiStatus = SPI_execute_with_args(SHARD_PLACEMENT_QUERY, argCount, argTypes,
251-
argValues, NULL, false, 0);
268+
if (spiPlan == NULL)
269+
{
270+
spiPlan = SPI_prepare(SHARD_PLACEMENT_QUERY, argCount, argTypes);
271+
272+
spiStatus = SPI_keepplan(spiPlan);
273+
Assert(spiStatus == 0);
274+
}
275+
276+
spiStatus = SPI_execute_plan(spiPlan, argValues, NULL, false, 0);
252277
Assert(spiStatus == SPI_OK_SELECT);
253278

254279
oldContext = MemoryContextSwitchTo(upperContext);
@@ -293,6 +318,7 @@ PartitionColumn(Oid distributedTableId)
293318
bool isNull = false;
294319
Datum keyDatum = 0;
295320
char *partitionColumnName = NULL;
321+
static SPIPlanPtr spiPlan = NULL;
296322

297323
/*
298324
* SPI_connect switches to an SPI-specific MemoryContext. See the comment
@@ -301,10 +327,16 @@ PartitionColumn(Oid distributedTableId)
301327
MemoryContext upperContext = CurrentMemoryContext, oldContext = NULL;
302328
SPI_connect();
303329

304-
spiStatus = SPI_execute_with_args("SELECT key "
305-
"FROM pgs_distribution_metadata.partition "
306-
"WHERE relation_id = $1", argCount, argTypes,
307-
argValues, NULL, false, 1);
330+
if (spiPlan == NULL)
331+
{
332+
spiPlan = SPI_prepare("SELECT key FROM pgs_distribution_metadata.partition "
333+
"WHERE relation_id = $1", argCount, argTypes);
334+
335+
spiStatus = SPI_keepplan(spiPlan);
336+
Assert(spiStatus == 0);
337+
}
338+
339+
spiStatus = SPI_execute_plan(spiPlan, argValues, NULL, false, 1);
308340
Assert(spiStatus == SPI_OK_SELECT);
309341

310342
if (SPI_processed != 1)
@@ -345,13 +377,21 @@ PartitionType(Oid distributedTableId)
345377
int spiStatus PG_USED_FOR_ASSERTS_ONLY = 0;
346378
bool isNull = false;
347379
Datum partitionTypeDatum = 0;
380+
static SPIPlanPtr spiPlan = NULL;
348381

349382
SPI_connect();
350383

351-
spiStatus = SPI_execute_with_args("SELECT partition_method "
352-
"FROM pgs_distribution_metadata.partition "
353-
"WHERE relation_id = $1", argCount, argTypes,
354-
argValues, NULL, false, 1);
384+
if (spiPlan == NULL)
385+
{
386+
spiPlan = SPI_prepare("SELECT partition_method "
387+
"FROM pgs_distribution_metadata.partition "
388+
"WHERE relation_id = $1", argCount, argTypes);
389+
390+
spiStatus = SPI_keepplan(spiPlan);
391+
Assert(spiStatus == 0);
392+
}
393+
394+
spiStatus = SPI_execute_plan(spiPlan, argValues, NULL, false, 1);
355395
Assert(spiStatus == SPI_OK_SELECT);
356396

357397
if (SPI_processed != 1)
@@ -388,6 +428,7 @@ IsDistributedTable(Oid tableId)
388428
Datum argValues[] = { ObjectIdGetDatum(tableId) };
389429
const int argCount = sizeof(argValues) / sizeof(argValues[0]);
390430
int spiStatus PG_USED_FOR_ASSERTS_ONLY = 0;
431+
static SPIPlanPtr spiPlan = NULL;
391432

392433
/* short-circuit if the input is invalid */
393434
if (tableId == InvalidOid)
@@ -411,10 +452,16 @@ IsDistributedTable(Oid tableId)
411452

412453
SPI_connect();
413454

414-
spiStatus = SPI_execute_with_args("SELECT NULL "
415-
"FROM pgs_distribution_metadata.partition "
416-
"WHERE relation_id = $1", argCount, argTypes,
417-
argValues, NULL, false, 1);
455+
if (spiPlan == NULL)
456+
{
457+
spiPlan = SPI_prepare("SELECT NULL FROM pgs_distribution_metadata.partition "
458+
"WHERE relation_id = $1", argCount, argTypes);
459+
460+
spiStatus = SPI_keepplan(spiPlan);
461+
Assert(spiStatus == 0);
462+
}
463+
464+
spiStatus = SPI_execute_plan(spiPlan, argValues, NULL, false, 1);
418465
Assert(spiStatus == SPI_OK_SELECT);
419466

420467
isDistributedTable = (SPI_processed == 1);
@@ -434,10 +481,20 @@ DistributedTablesExist(void)
434481
{
435482
bool distributedTablesExist = false;
436483
int spiStatus PG_USED_FOR_ASSERTS_ONLY = 0;
484+
static SPIPlanPtr spiPlan = NULL;
437485

438486
SPI_connect();
439487

440-
spiStatus = SPI_exec("SELECT NULL FROM pgs_distribution_metadata.partition", 1);
488+
if (spiPlan == NULL)
489+
{
490+
spiPlan = SPI_prepare("SELECT NULL FROM pgs_distribution_metadata.partition", 0,
491+
NULL);
492+
493+
spiStatus = SPI_keepplan(spiPlan);
494+
Assert(spiStatus == 0);
495+
}
496+
497+
spiStatus = SPI_execute_plan(spiPlan, NULL, NULL, true, 1);
441498
Assert(spiStatus == SPI_OK_SELECT);
442499

443500
distributedTablesExist = (SPI_processed > 0);
@@ -634,13 +691,21 @@ InsertPartitionRow(Oid distributedTableId, char partitionType, text *partitionKe
634691
};
635692
const int argCount = sizeof(argValues) / sizeof(argValues[0]);
636693
int spiStatus PG_USED_FOR_ASSERTS_ONLY = 0;
694+
static SPIPlanPtr spiPlan = NULL;
637695

638696
SPI_connect();
639697

640-
spiStatus = SPI_execute_with_args("INSERT INTO pgs_distribution_metadata.partition "
641-
"(relation_id, partition_method, key) "
642-
"VALUES ($1, $2, $3)", argCount, argTypes,
643-
argValues, NULL, false, 0);
698+
if (spiPlan == NULL)
699+
{
700+
spiPlan = SPI_prepare("INSERT INTO pgs_distribution_metadata.partition "
701+
"(relation_id, partition_method, key) VALUES ($1, $2, $3)",
702+
argCount, argTypes);
703+
704+
spiStatus = SPI_keepplan(spiPlan);
705+
Assert(spiStatus == 0);
706+
}
707+
708+
spiStatus = SPI_execute_plan(spiPlan, argValues, NULL, false, 0);
644709
Assert(spiStatus == SPI_OK_INSERT);
645710

646711
SPI_finish();
@@ -668,13 +733,21 @@ CreateShardRow(Oid distributedTableId, char shardStorage, text *shardMinValue,
668733
int spiStatus PG_USED_FOR_ASSERTS_ONLY = 0;
669734
bool isNull = false;
670735
Datum shardIdDatum = 0;
736+
static SPIPlanPtr spiPlan = NULL;
671737

672738
SPI_connect();
673739

674-
spiStatus = SPI_execute_with_args("INSERT INTO pgs_distribution_metadata.shard "
675-
"(relation_id, storage, min_value, max_value) "
676-
"VALUES ($1, $2, $3, $4) RETURNING id", argCount,
677-
argTypes, argValues, NULL, false, 1);
740+
if (spiPlan == NULL)
741+
{
742+
spiPlan = SPI_prepare("INSERT INTO pgs_distribution_metadata.shard "
743+
"(relation_id, storage, min_value, max_value) "
744+
"VALUES ($1, $2, $3, $4) RETURNING id", argCount, argTypes);
745+
746+
spiStatus = SPI_keepplan(spiPlan);
747+
Assert(spiStatus == 0);
748+
}
749+
750+
spiStatus = SPI_execute_plan(spiPlan, argValues, NULL, false, 1);
678751
Assert(spiStatus == SPI_OK_INSERT_RETURNING);
679752

680753
shardIdDatum = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1,
@@ -707,14 +780,22 @@ CreateShardPlacementRow(int64 shardId, ShardState shardState, char *nodeName,
707780
int spiStatus PG_USED_FOR_ASSERTS_ONLY = 0;
708781
bool isNull = false;
709782
Datum placementIdDatum = 0;
783+
static SPIPlanPtr spiPlan = NULL;
710784

711785
SPI_connect();
712786

713-
spiStatus = SPI_execute_with_args("INSERT INTO "
714-
"pgs_distribution_metadata.shard_placement "
715-
"(shard_id, shard_state, node_name, node_port) "
716-
"VALUES ($1, $2, $3, $4) RETURNING id", argCount,
717-
argTypes, argValues, NULL, false, 1);
787+
if (spiPlan == NULL)
788+
{
789+
spiPlan = SPI_prepare("INSERT INTO "
790+
"pgs_distribution_metadata.shard_placement "
791+
"(shard_id, shard_state, node_name, node_port) "
792+
"VALUES ($1, $2, $3, $4) RETURNING id", argCount, argTypes);
793+
794+
spiStatus = SPI_keepplan(spiPlan);
795+
Assert(spiStatus == 0);
796+
}
797+
798+
spiStatus = SPI_execute_plan(spiPlan, argValues, NULL, false, 1);
718799
Assert(spiStatus == SPI_OK_INSERT_RETURNING);
719800

720801
placementIdDatum = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1,
@@ -738,13 +819,20 @@ DeleteShardPlacementRow(int64 shardPlacementId)
738819
Datum argValues[] = { Int64GetDatum(shardPlacementId) };
739820
const int argCount = sizeof(argValues) / sizeof(argValues[0]);
740821
int spiStatus PG_USED_FOR_ASSERTS_ONLY = 0;
822+
static SPIPlanPtr spiPlan = NULL;
741823

742824
SPI_connect();
743825

744-
spiStatus = SPI_execute_with_args("DELETE FROM "
745-
"pgs_distribution_metadata.shard_placement "
746-
"WHERE id = $1", argCount, argTypes, argValues,
747-
NULL, false, 0);
826+
if (spiPlan == NULL)
827+
{
828+
spiPlan = SPI_prepare("DELETE FROM pgs_distribution_metadata.shard_placement "
829+
"WHERE id = $1", argCount, argTypes);
830+
831+
spiStatus = SPI_keepplan(spiPlan);
832+
Assert(spiStatus == 0);
833+
}
834+
835+
spiStatus = SPI_execute_plan(spiPlan, argValues, NULL, false, 0);
748836
Assert(spiStatus == SPI_OK_DELETE);
749837

750838
if (SPI_processed != 1)
@@ -773,12 +861,20 @@ UpdateShardPlacementRowState(int64 shardPlacementId, ShardState newState)
773861
};
774862
const int argCount = sizeof(argValues) / sizeof(argValues[0]);
775863
int spiStatus PG_USED_FOR_ASSERTS_ONLY = 0;
864+
static SPIPlanPtr spiPlan = NULL;
776865

777866
SPI_connect();
778867

779-
spiStatus = SPI_execute_with_args("UPDATE pgs_distribution_metadata.shard_placement "
780-
"SET shard_state = $2 WHERE id = $1",
781-
argCount, argTypes, argValues, NULL, false, 1);
868+
if (spiPlan == NULL)
869+
{
870+
spiPlan = SPI_prepare("UPDATE pgs_distribution_metadata.shard_placement "
871+
"SET shard_state = $2 WHERE id = $1", argCount, argTypes);
872+
873+
spiStatus = SPI_keepplan(spiPlan);
874+
Assert(spiStatus == 0);
875+
}
876+
877+
spiStatus = SPI_execute_plan(spiPlan, argValues, NULL, false, 1);
782878
Assert(spiStatus == SPI_OK_UPDATE);
783879

784880
if (SPI_processed != 1)

0 commit comments

Comments
 (0)