Return early if there is no citus table in VACUUM

pull/4221/head
Sait Talha Nisanci 2020-10-08 21:17:16 +03:00
parent 99bb79745a
commit dc40758355
3 changed files with 67 additions and 27 deletions

View File

@ -52,7 +52,7 @@ typedef struct CitusVacuumParams
} CitusVacuumParams; } CitusVacuumParams;
/* Local functions forward declarations for processing distributed table commands */ /* Local functions forward declarations for processing distributed table commands */
static bool IsDistributedVacuumStmt(int vacuumOptions, List *vacuumRelationIdList); static bool IsDistributedVacuumStmt(int vacuumOptions, List *VacuumCitusRelationIdList);
static List * VacuumTaskList(Oid relationId, CitusVacuumParams vacuumParams, static List * VacuumTaskList(Oid relationId, CitusVacuumParams vacuumParams,
List *vacuumColumnList); List *vacuumColumnList);
static char * DeparseVacuumStmtPrefix(CitusVacuumParams vacuumParams); static char * DeparseVacuumStmtPrefix(CitusVacuumParams vacuumParams);
@ -62,6 +62,8 @@ static List * ExtractVacuumTargetRels(VacuumStmt *vacuumStmt);
static void ExecuteVacuumOnDistributedTables(VacuumStmt *vacuumStmt, List *relationIdList, static void ExecuteVacuumOnDistributedTables(VacuumStmt *vacuumStmt, List *relationIdList,
CitusVacuumParams vacuumParams); CitusVacuumParams vacuumParams);
static CitusVacuumParams VacuumStmtParams(VacuumStmt *vacstmt); static CitusVacuumParams VacuumStmtParams(VacuumStmt *vacstmt);
static List * VacuumCitusRelationIdList(VacuumStmt *vacuumStmt, CitusVacuumParams
vacuumParams);
/* /*
* PostprocessVacuumStmt processes vacuum statements that may need propagation to * PostprocessVacuumStmt processes vacuum statements that may need propagation to
@ -77,39 +79,82 @@ void
PostprocessVacuumStmt(VacuumStmt *vacuumStmt, const char *vacuumCommand) PostprocessVacuumStmt(VacuumStmt *vacuumStmt, const char *vacuumCommand)
{ {
CitusVacuumParams vacuumParams = VacuumStmtParams(vacuumStmt); CitusVacuumParams vacuumParams = VacuumStmtParams(vacuumStmt);
LOCKMODE lockMode = (vacuumParams.options & VACOPT_FULL) ? AccessExclusiveLock : const char *stmtName = (vacuumParams.options & VACOPT_VACUUM) ? "VACUUM" : "ANALYZE";
ShareUpdateExclusiveLock;
/*
* No table in the vacuum statement means vacuuming all relations
* which is not supported by citus.
*/
if (list_length(vacuumStmt->rels) == 0)
{
/* WARN for unqualified VACUUM commands */
ereport(WARNING, (errmsg("not propagating %s command to worker nodes", stmtName),
errhint("Provide a specific table in order to %s "
"distributed tables.", stmtName)));
}
List *citusRelationIdList = VacuumCitusRelationIdList(vacuumStmt, vacuumParams);
if (list_length(citusRelationIdList) == 0)
{
return;
}
if (vacuumParams.options & VACOPT_VACUUM) if (vacuumParams.options & VACOPT_VACUUM)
{ {
/* /*
* We commit the current transaction here so that the global lock * We commit the current transaction here so that the global lock
* taken from the shell table for VACUUM is released, which would block execution * taken from the shell table for VACUUM is released, which would block execution
* of shard placements. * of shard placements. We don't do this in case of "ANALYZE <table>" command because
* its semantics are different than VACUUM and it doesn't acquire the global lock.
*/ */
CommitTransactionCommand(); CommitTransactionCommand();
StartTransactionCommand(); StartTransactionCommand();
} }
/*
* Here we get the relation list again because we might have
* closed the current transaction and the memory context got reset.
* Vacuum's context is PortalContext, which lasts for the whole session
* so committing/starting a new transaction doesn't affect it.
*/
citusRelationIdList = VacuumCitusRelationIdList(vacuumStmt, vacuumParams);
bool distributedVacuumStmt = IsDistributedVacuumStmt(vacuumParams.options,
citusRelationIdList);
if (!distributedVacuumStmt)
{
return;
}
ExecuteVacuumOnDistributedTables(vacuumStmt, citusRelationIdList, vacuumParams);
}
/*
* VacuumCitusRelationIdList returns the oid of the relations in the given vacuum statement.
*/
static List *
VacuumCitusRelationIdList(VacuumStmt *vacuumStmt, CitusVacuumParams vacuumParams)
{
LOCKMODE lockMode = (vacuumParams.options & VACOPT_FULL) ? AccessExclusiveLock :
ShareUpdateExclusiveLock;
List *vacuumRelationList = ExtractVacuumTargetRels(vacuumStmt); List *vacuumRelationList = ExtractVacuumTargetRels(vacuumStmt);
List *relationIdList = NIL; List *relationIdList = NIL;
RangeVar *vacuumRelation = NULL; RangeVar *vacuumRelation = NULL;
foreach_ptr(vacuumRelation, vacuumRelationList) foreach_ptr(vacuumRelation, vacuumRelationList)
{ {
Oid relationId = RangeVarGetRelid(vacuumRelation, lockMode, false); Oid relationId = RangeVarGetRelid(vacuumRelation, lockMode, false);
if (!IsCitusTable(relationId))
{
continue;
}
relationIdList = lappend_oid(relationIdList, relationId); relationIdList = lappend_oid(relationIdList, relationId);
} }
bool distributedVacuumStmt = IsDistributedVacuumStmt(vacuumParams.options, return relationIdList;
relationIdList);
if (!distributedVacuumStmt)
{
return;
}
ExecuteVacuumOnDistributedTables(vacuumStmt, relationIdList, vacuumParams);
} }
@ -165,27 +210,16 @@ ExecuteVacuumOnDistributedTables(VacuumStmt *vacuumStmt, List *relationIdList,
* false otherwise. * false otherwise.
*/ */
static bool static bool
IsDistributedVacuumStmt(int vacuumOptions, List *vacuumRelationIdList) IsDistributedVacuumStmt(int vacuumOptions, List *VacuumCitusRelationIdList)
{ {
const char *stmtName = (vacuumOptions & VACOPT_VACUUM) ? "VACUUM" : "ANALYZE";
bool distributeStmt = false; bool distributeStmt = false;
int distributedRelationCount = 0; int distributedRelationCount = 0;
/* const char *stmtName = (vacuumOptions & VACOPT_VACUUM) ? "VACUUM" : "ANALYZE";
* No table in the vacuum statement means vacuuming all relations
* which is not supported by citus.
*/
int vacuumedRelationCount = list_length(vacuumRelationIdList);
if (vacuumedRelationCount == 0)
{
/* WARN for unqualified VACUUM commands */
ereport(WARNING, (errmsg("not propagating %s command to worker nodes", stmtName),
errhint("Provide a specific table in order to %s "
"distributed tables.", stmtName)));
}
Oid relationId = InvalidOid; Oid relationId = InvalidOid;
foreach_oid(relationId, vacuumRelationIdList) foreach_oid(relationId, VacuumCitusRelationIdList)
{ {
if (OidIsValid(relationId) && IsCitusTable(relationId)) if (OidIsValid(relationId) && IsCitusTable(relationId))
{ {

View File

@ -117,6 +117,9 @@ VACUUM ref, test;
VACUUM ANALYZE test(x); VACUUM ANALYZE test(x);
ANALYZE ref; ANALYZE ref;
ANALYZE test_2; ANALYZE test_2;
VACUUM local;
VACUUM local, ref, test, test_2;
VACUUM FULL test, ref;
BEGIN; BEGIN;
ALTER TABLE test ADD COLUMN z INT DEFAULT 66; ALTER TABLE test ADD COLUMN z INT DEFAULT 66;
SELECT count(*) FROM test WHERE z = 66; SELECT count(*) FROM test WHERE z = 66;

View File

@ -63,6 +63,9 @@ VACUUM ref, test;
VACUUM ANALYZE test(x); VACUUM ANALYZE test(x);
ANALYZE ref; ANALYZE ref;
ANALYZE test_2; ANALYZE test_2;
VACUUM local;
VACUUM local, ref, test, test_2;
VACUUM FULL test, ref;
BEGIN; BEGIN;
ALTER TABLE test ADD COLUMN z INT DEFAULT 66; ALTER TABLE test ADD COLUMN z INT DEFAULT 66;