X-Git-Url: http://sigaev.ru/git/gitweb.cgi?a=blobdiff_plain;f=online_analyze.c;h=299ae57ea487204e13f94e588669e6d71f9a7b87;hb=f248b98ef1f0850601f197310d917ca835976cf2;hp=a823216a011c3755a9ec1c31f0b9c6e594e96a3f;hpb=14e9a758e05dd5467bab85ef98fad76b8dbfcc87;p=online_analyze.git diff --git a/online_analyze.c b/online_analyze.c index a823216..299ae57 100644 --- a/online_analyze.c +++ b/online_analyze.c @@ -41,6 +41,8 @@ #include "utils/guc.h" #if PG_VERSION_NUM >= 90200 #include "catalog/pg_class.h" +#include "nodes/primnodes.h" +#include "tcop/utility.h" #include "utils/rel.h" #include "utils/relcache.h" #include "utils/timestamp.h" @@ -56,6 +58,11 @@ static double online_analyze_scale_factor = 0.1; static int online_analyze_threshold = 50; static double online_analyze_min_interval = 10000; +static ExecutorEnd_hook_type oldExecutorEndHook = NULL; +#if PG_VERSION_NUM >= 90200 +static ProcessUtility_hook_type oldProcessUtilityHook = NULL; +#endif + typedef enum { OATT_ALL = 0x03, @@ -118,11 +125,13 @@ tableListAssign(const char * newval, bool doit, TableList *tbl) foreach(l, namelist) { char *curname = (char *) lfirst(l); - Oid relOid = RangeVarGetRelid(makeRangeVarFromNameList(stringToQualifiedNameList(curname)), #if PG_VERSION_NUM >= 90200 - NoLock, -#endif + Oid relOid = RangeVarGetRelid(makeRangeVarFromNameList(stringToQualifiedNameList(curname)), + NoLock, true); +#else + Oid relOid = RangeVarGetRelid(makeRangeVarFromNameList(stringToQualifiedNameList(curname)), true); +#endif if (relOid == InvalidOid) { @@ -292,8 +301,6 @@ matchOid(TableList *tbl, Oid oid) return false; } -static ExecutorEnd_hook_type oldhook = NULL; - static void makeAnalyze(Oid relOid, CmdType operation, uint32 naffected) { @@ -303,6 +310,9 @@ makeAnalyze(Oid relOid, CmdType operation, uint32 naffected) if (relOid == InvalidOid) return; + if (get_rel_relkind(relOid) != RELKIND_RELATION) + return; + tabentry = pgstat_fetch_stat_tabentry(relOid); #if PG_VERSION_NUM >= 90000 @@ -327,6 +337,8 @@ makeAnalyze(Oid relOid, CmdType operation, uint32 naffected) VacuumStmt vacstmt; TimestampTz startStamp, endStamp; + memset(&startStamp, 0, sizeof(startStamp)); /* keep compiler quiet */ + /* * includeTables overwrites excludeTables */ @@ -388,8 +400,12 @@ makeAnalyze(Oid relOid, CmdType operation, uint32 naffected) if (online_analyze_verbose) startStamp = GetCurrentTimestamp(); - analyze_rel(relOid, &vacstmt, GetAccessStrategy(BAS_VACUUM) -#if (PG_VERSION_NUM < 90004) && (PG_VERSION_NUM >= 90000) + analyze_rel(relOid, &vacstmt +#if PG_VERSION_NUM >= 90018 + , true +#endif + , GetAccessStrategy(BAS_VACUUM) +#if (PG_VERSION_NUM >= 90000) && (PG_VERSION_NUM < 90004) , true #endif ); @@ -437,11 +453,9 @@ onlineAnalyzeHooker(QueryDesc *queryDesc) if (online_analyze_enable && queryDesc->plannedstmt && (queryDesc->operation == CMD_INSERT || queryDesc->operation == CMD_UPDATE || - queryDesc->operation == CMD_DELETE || -#if PG_VERSION_NUM >= 90200 - 0 /* (queryDesc->operation == CMD_SELECT && queryDesc->dest && queryDesc->dest == DestIntoRel) */ -#else - (queryDesc->operation == CMD_SELECT && queryDesc->plannedstmt->intoClause) + queryDesc->operation == CMD_DELETE +#if PG_VERSION_NUM < 90200 + || (queryDesc->operation == CMD_SELECT && queryDesc->plannedstmt->intoClause) #endif )) { @@ -470,20 +484,66 @@ onlineAnalyzeHooker(QueryDesc *queryDesc) } } - if (oldhook) - (*oldhook)(queryDesc); + if (oldExecutorEndHook) + oldExecutorEndHook(queryDesc); else standard_ExecutorEnd(queryDesc); } +#if PG_VERSION_NUM >= 90200 +static void +onlineAnalyzeHookerUtility(Node *parsetree, const char *queryString, +#if PG_VERSION_NUM >= 90300 + ProcessUtilityContext context, ParamListInfo params, +#else + ParamListInfo params, bool isTopLevel, +#endif + DestReceiver *dest, char *completionTag) { + RangeVar *tblname = NULL; + + if (IsA(parsetree, CreateTableAsStmt) && ((CreateTableAsStmt*)parsetree)->into) + tblname = (RangeVar*)copyObject(((CreateTableAsStmt*)parsetree)->into->rel); + + if (oldProcessUtilityHook) + oldProcessUtilityHook(parsetree, queryString, +#if PG_VERSION_NUM >= 90300 + context, params, +#else + params, isTopLevel, +#endif + dest, completionTag); + else + standard_ProcessUtility(parsetree, queryString, +#if PG_VERSION_NUM >= 90300 + context, params, +#else + params, isTopLevel, +#endif + dest, completionTag); + + if (tblname) { + Oid tblOid = RangeVarGetRelid(tblname, NoLock, true); + + makeAnalyze(tblOid, CMD_INSERT, 0); + } +} +#endif + void _PG_init(void); void _PG_init(void) { - oldhook = ExecutorEnd_hook; + oldExecutorEndHook = ExecutorEnd_hook; ExecutorEnd_hook = onlineAnalyzeHooker; +#if PG_VERSION_NUM >= 90200 + oldProcessUtilityHook = ProcessUtility_hook; + + ProcessUtility_hook = onlineAnalyzeHookerUtility; +#endif + + DefineCustomBoolVariable( "online_analyze.enable", "Enable on-line analyze", @@ -568,7 +628,7 @@ _PG_init(void) "online_analyze.min_interval", "minimum time interval between analyze call (in milliseconds)", "minimum time interval between analyze call (in milliseconds)", - &online_analyze_scale_factor, + &online_analyze_min_interval, #if PG_VERSION_NUM >= 80400 online_analyze_min_interval, #endif @@ -585,7 +645,7 @@ _PG_init(void) NULL ); -DefineCustomEnumVariable( + DefineCustomEnumVariable( "online_analyze.table_type", "Type(s) of table for online analyze: all(default), persistent, temporary, none", NULL, @@ -648,7 +708,10 @@ void _PG_fini(void); void _PG_fini(void) { - ExecutorEnd_hook = oldhook; + ExecutorEnd_hook = oldExecutorEndHook; +#if PG_VERSION_NUM >= 90200 + ProcessUtility_hook = oldProcessUtilityHook; +#endif if (excludeTables.tables) free(excludeTables.tables);