提交 c86c7246 编写于 作者: K Kenan Yao

Remove the cache optimization of cdbRelSize, and rename it to avoid

misunderstanding, for following reasons:
(1) the performance improvement is little, it only works for some code
paths of ALTER TABLE ALTER COLUMN TYPE and CREATE UNIQUE/PRIMARY INDEX
(2) the feature is incomplete and buggy, especially the cache invalidation part
上级 09f00581
...@@ -532,7 +532,7 @@ checkPolicyForUniqueIndex(Relation rel, AttrNumber *indattr, int nidxatts, ...@@ -532,7 +532,7 @@ checkPolicyForUniqueIndex(Relation rel, AttrNumber *indattr, int nidxatts,
*/ */
if (!bms_is_subset(polbm, indbm)) if (!bms_is_subset(polbm, indbm))
{ {
if (cdbRelSize(rel) != 0 || has_pkey || has_ukey || has_exprs) if (cdbRelMaxSegSize(rel) != 0 || has_pkey || has_ukey || has_exprs)
{ {
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION), (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
......
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
* *
* cdbrelsize.h * cdbrelsize.c
*
* Get the max size of the relation across the segDBs
* *
* Copyright (c) 2006-2008, Greenplum inc * Copyright (c) 2006-2008, Greenplum inc
* *
*
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "postgres.h" #include "postgres.h"
...@@ -28,49 +25,21 @@ ...@@ -28,49 +25,21 @@
#include "cdb/cdbrelsize.h" #include "cdb/cdbrelsize.h"
#define relsize_cache_size 100 /*
* Get the max size of the relation across segments
struct relsize_cache_entry */
{ int64
Oid relOid; cdbRelMaxSegSize(Relation rel)
int64 size;
};
static struct relsize_cache_entry relsize_cache[relsize_cache_size] = { {0,0} };
static int last_cache_entry = -1; /* -1 for cache not initialized yet */
void clear_relsize_cache(void)
{ {
int64 size = 0;
int i; int i;
for (i=0; i < relsize_cache_size; i++) int resultCount = 0;
{
relsize_cache[i].relOid = InvalidOid;
relsize_cache[i].size = 0;
}
last_cache_entry = -1;
}
int64 cdbRelSize(Relation rel)
{
int64 size = 0;
int i;
int resultCount = 0;
struct pg_result **results = NULL; struct pg_result **results = NULL;
StringInfoData errbuf; StringInfoData errbuf;
StringInfoData buffer; StringInfoData buffer;
char *schemaName; char *schemaName;
char *relName; char *relName;
if (last_cache_entry >= 0)
{
for (i=0; i < relsize_cache_size; i++)
{
if (relsize_cache[i].relOid == RelationGetRelid(rel))
return relsize_cache[i].size;
}
}
/* /*
* Let's ask the QEs for the size of the relation * Let's ask the QEs for the size of the relation
...@@ -84,14 +53,14 @@ int64 cdbRelSize(Relation rel) ...@@ -84,14 +53,14 @@ int64 cdbRelSize(Relation rel)
RelationGetNamespace(rel)); RelationGetNamespace(rel));
relName = RelationGetRelationName(rel); relName = RelationGetRelationName(rel);
/* /*
* Safer to pass names than oids, just in case they get out of sync between QD and QE, * Safer to pass names than oids, just in case they get out of sync between QD and QE,
* which might happen with a toast table or index, I think (but maybe not) * which might happen with a toast table or index, I think (but maybe not)
*/ */
appendStringInfo(&buffer, "select pg_relation_size('%s.%s')", appendStringInfo(&buffer, "select pg_relation_size('%s.%s')",
quote_identifier(schemaName), quote_identifier(relName)); quote_identifier(schemaName), quote_identifier(relName));
/* /*
* In the future, it would be better to send the command to only one QE for the optimizer's needs, * In the future, it would be better to send the command to only one QE for the optimizer's needs,
* but for ALTER TABLE, we need to be sure if the table has any rows at all. * but for ALTER TABLE, we need to be sure if the table has any rows at all.
*/ */
...@@ -99,8 +68,9 @@ int64 cdbRelSize(Relation rel) ...@@ -99,8 +68,9 @@ int64 cdbRelSize(Relation rel)
if (errbuf.len > 0) if (errbuf.len > 0)
{ {
ereport(WARNING, (errmsg("cdbRelSize error (gathered %d results from cmd '%s')", resultCount, buffer.data), ereport(WARNING,
errdetail("%s", errbuf.data))); (errmsg("cdbRelMaxSegSize error (gathered %d results from cmd '%s')", resultCount, buffer.data),
errdetail("%s", errbuf.data)));
pfree(errbuf.data); pfree(errbuf.data);
pfree(buffer.data); pfree(buffer.data);
...@@ -108,48 +78,30 @@ int64 cdbRelSize(Relation rel) ...@@ -108,48 +78,30 @@ int64 cdbRelSize(Relation rel)
} }
else else
{ {
for (i = 0; i < resultCount; i++) for (i = 0; i < resultCount; i++)
{ {
if (PQresultStatus(results[i]) != PGRES_TUPLES_OK) if (PQresultStatus(results[i]) != PGRES_TUPLES_OK)
{ {
elog(ERROR,"cdbRelSize: resultStatus not tuples_Ok: %s %s",PQresStatus(PQresultStatus(results[i])),PQresultErrorMessage(results[i])); elog(ERROR,"cdbRelMaxSegSize: resultStatus not tuples_Ok: %s %s",
PQresStatus(PQresultStatus(results[i])),PQresultErrorMessage(results[i]));
} }
else else
{ {
/* Assert(PQntuples(results[i]) == 1);
* Due to funkyness in the current dispatch agent code, instead of 1 result int64 tempsize = 0;
* per QE with 1 row each, we can get back 1 result per dispatch agent, with (void) scanint8(PQgetvalue(results[i], 0, 0), false, &tempsize);
* one row per QE controlled by that agent. if (tempsize > size)
*/ size = tempsize;
int j;
for (j = 0; j < PQntuples(results[i]); j++)
{
int64 tempsize = 0;
(void) scanint8(PQgetvalue(results[i], j, 0), false, &tempsize);
if (tempsize > size)
size = tempsize;
}
} }
} }
pfree(errbuf.data); pfree(errbuf.data);
pfree(buffer.data); pfree(buffer.data);
for (i = 0; i < resultCount; i++) for (i = 0; i < resultCount; i++)
PQclear(results[i]); PQclear(results[i]);
free(results);
}
if (size >= 0) /* Cache the size even if it is zero, as table might be empty */ free(results);
{
if (last_cache_entry < 0)
last_cache_entry = 0;
relsize_cache[last_cache_entry].relOid = RelationGetRelid(rel);
relsize_cache[last_cache_entry].size = size;
last_cache_entry = (last_cache_entry+1) % relsize_cache_size;
} }
return size; return size;
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include "cdb/cdbutil.h" #include "cdb/cdbutil.h"
#include "cdb/cdbvars.h" #include "cdb/cdbvars.h"
#include "cdb/cdbmutate.h" #include "cdb/cdbmutate.h"
#include "cdb/cdbrelsize.h"
#include "cdb/cdbsrlz.h" #include "cdb/cdbsrlz.h"
#include "tcop/tcopprot.h" #include "tcop/tcopprot.h"
#include "utils/datum.h" #include "utils/datum.h"
...@@ -180,7 +179,7 @@ cdbdisp_dispatchPlan(struct QueryDesc *queryDesc, ...@@ -180,7 +179,7 @@ cdbdisp_dispatchPlan(struct QueryDesc *queryDesc,
int rootIdx; int rootIdx;
int oldLocalSlice; int oldLocalSlice;
PlannedStmt *stmt; PlannedStmt *stmt;
bool is_SRI; bool is_SRI = false;
DispatchCommandQueryParms queryParms; DispatchCommandQueryParms queryParms;
CdbComponentDatabaseInfo *qdinfo; CdbComponentDatabaseInfo *qdinfo;
...@@ -222,8 +221,6 @@ cdbdisp_dispatchPlan(struct QueryDesc *queryDesc, ...@@ -222,8 +221,6 @@ cdbdisp_dispatchPlan(struct QueryDesc *queryDesc,
* nextval() and currval() now, so that we get the QD's values, and a * nextval() and currval() now, so that we get the QD's values, and a
* consistent value for everyone * consistent value for everyone
*/ */
is_SRI = false;
if (queryDesc->operation == CMD_INSERT) if (queryDesc->operation == CMD_INSERT)
{ {
Assert(stmt->commandType == CMD_INSERT); Assert(stmt->commandType == CMD_INSERT);
...@@ -232,13 +229,9 @@ cdbdisp_dispatchPlan(struct QueryDesc *queryDesc, ...@@ -232,13 +229,9 @@ cdbdisp_dispatchPlan(struct QueryDesc *queryDesc,
* We might look for constant input relation (instead of SRI), but I'm afraid * We might look for constant input relation (instead of SRI), but I'm afraid
* that wouldn't scale. * that wouldn't scale.
*/ */
is_SRI = IsA(stmt->planTree, Result) is_SRI = IsA(stmt->planTree, Result) && stmt->planTree->lefttree == NULL;
&& stmt->planTree->lefttree == NULL;
} }
if (!is_SRI)
clear_relsize_cache();
if (queryDesc->operation == CMD_INSERT || if (queryDesc->operation == CMD_INSERT ||
queryDesc->operation == CMD_SELECT || queryDesc->operation == CMD_SELECT ||
queryDesc->operation == CMD_UPDATE || queryDesc->operation == CMD_UPDATE ||
......
...@@ -17,7 +17,6 @@ _init_cdbdisp_dispatchPlan(QueryDesc *queryDesc) ...@@ -17,7 +17,6 @@ _init_cdbdisp_dispatchPlan(QueryDesc *queryDesc)
queryDesc->operation = CMD_NOTHING; queryDesc->operation = CMD_NOTHING;
queryDesc->plannedstmt = (PlannedStmt *)palloc0(sizeof(PlannedStmt)); queryDesc->plannedstmt = (PlannedStmt *)palloc0(sizeof(PlannedStmt));
will_be_called(clear_relsize_cache);
expect_any(RootSliceIndex, estate); expect_any(RootSliceIndex, estate);
will_return(RootSliceIndex,0); will_return(RootSliceIndex,0);
} }
......
...@@ -61,7 +61,6 @@ ...@@ -61,7 +61,6 @@
#include "cdb/cdbhash.h" #include "cdb/cdbhash.h"
#include "cdb/cdbdispatchresult.h" #include "cdb/cdbdispatchresult.h"
#include "cdb/cdbsreh.h" #include "cdb/cdbsreh.h"
#include "cdb/cdbrelsize.h"
#include "cdb/cdbutil.h" #include "cdb/cdbutil.h"
#include "cdb/cdbvarblock.h" #include "cdb/cdbvarblock.h"
#include "cdb/cdbbufferedappend.h" #include "cdb/cdbbufferedappend.h"
......
...@@ -9237,7 +9237,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, ...@@ -9237,7 +9237,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
{ {
int ia = 0; int ia = 0;
if (cdbRelSize(rel) != 0) if (cdbRelMaxSegSize(rel) != 0)
{ {
for (ia = 0; ia < policy->nattrs; ia++) for (ia = 0; ia < policy->nattrs; ia++)
{ {
...@@ -9287,7 +9287,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, ...@@ -9287,7 +9287,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
{ {
int ia = 0; int ia = 0;
if (cdbRelSize(rel) != 0) if (cdbRelMaxSegSize(rel) != 0)
{ {
for (ia = 0; ia < policy->nattrs; ia++) for (ia = 0; ia < policy->nattrs; ia++)
{ {
...@@ -9425,7 +9425,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, ...@@ -9425,7 +9425,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
"a partitioning key"))); "a partitioning key")));
} }
if (cdbRelSize(rel) != 0) if (cdbRelMaxSegSize(rel) != 0)
{ {
for (ia = 0; ia < policy->nattrs; ia++) for (ia = 0; ia < policy->nattrs; ia++)
{ {
......
...@@ -49,7 +49,6 @@ ...@@ -49,7 +49,6 @@
#include "cdb/cdbpartition.h" #include "cdb/cdbpartition.h"
#include "cdb/cdbvars.h" #include "cdb/cdbvars.h"
#include "cdb/cdbsrlz.h" #include "cdb/cdbsrlz.h"
#include "cdb/cdbrelsize.h"
#include "cdb/cdbdispatchresult.h" /* CdbDispatchResults */ #include "cdb/cdbdispatchresult.h" /* CdbDispatchResults */
#include "cdb/cdbfilerepprimary.h" #include "cdb/cdbfilerepprimary.h"
#include "cdb/cdbpersistentfilesysobj.h" #include "cdb/cdbpersistentfilesysobj.h"
...@@ -382,9 +381,6 @@ vacuum(VacuumStmt *vacstmt, List *relids, ...@@ -382,9 +381,6 @@ vacuum(VacuumStmt *vacstmt, List *relids,
if (Gp_role == GP_ROLE_DISPATCH) if (Gp_role == GP_ROLE_DISPATCH)
elevel = DEBUG2; /* vacuum messages aren't interesting from the QD */ elevel = DEBUG2; /* vacuum messages aren't interesting from the QD */
if (Gp_role == GP_ROLE_DISPATCH)
clear_relsize_cache();
/* /*
* We cannot run VACUUM inside a user transaction block; if we were inside * We cannot run VACUUM inside a user transaction block; if we were inside
* a transaction, then our commit- and start-transaction-command calls * a transaction, then our commit- and start-transaction-command calls
......
...@@ -14,9 +14,7 @@ ...@@ -14,9 +14,7 @@
#include "utils/relcache.h" #include "utils/relcache.h"
extern void clear_relsize_cache(void); extern int64 cdbRelMaxSegSize(Relation rel);
extern int64 cdbRelSize(Relation rel);
#endif /*CDBRELSIZE_H_*/ #endif /*CDBRELSIZE_H_*/
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册