/* * Parse the string value of gp_autostats_mode and gp_autostats_mode_in_functions */ static int gpvars_parse_gp_autostats_mode(const char *newval, bool inFunctions) { int newtype = 0; if (newval == NULL || newval[0] == 0 || !pg_strcasecmp("none", newval)) { newtype = GP_AUTOSTATS_NONE; } else if (!pg_strcasecmp("on_change", newval) || !pg_strcasecmp("onchange", newval)) { newtype = GP_AUTOSTATS_ON_CHANGE; } else if (!pg_strcasecmp("on_no_stats", newval)) { newtype = GP_AUTOSTATS_ON_NO_STATS; } else { const char *autostats_mode_string; if (inFunctions) { autostats_mode_string = gpvars_show_gp_autostats_mode_in_functions(); } else { autostats_mode_string = gpvars_show_gp_autostats_mode(); } elog(ERROR, "Unknown autostats mode. (current type is '%s')", autostats_mode_string); } return newtype; }
/* * This method takes a decision to run analyze based on the query and the number of modified tuples based * on the policy set via gp_autostats_mode. The following modes are currently supported: * none : no automatic analyzes are issued. simply return. * on_change : if the number of modified tuples > gp_onchange_threshold, then an automatic analyze is issued. * on_no_stats : if the operation is a ctas/insert-select and there are no stats on the modified table, * an automatic analyze is issued. */ void auto_stats(AutoStatsCmdType cmdType, Oid relationOid, uint64 ntuples, bool inFunction) { TimestampTz start; bool policyCheck = false; start = GetCurrentTimestamp(); if (Gp_role != GP_ROLE_DISPATCH || relationOid == InvalidOid || rel_is_partitioned(relationOid)) { return; } Assert(relationOid != InvalidOid); Assert(cmdType >= 0 && cmdType <= AUTOSTATS_CMDTYPE_SENTINEL); /* it is a valid command * as per auto-stats */ GpAutoStatsModeValue actual_gp_autostats_mode; if (inFunction) { actual_gp_autostats_mode = gp_autostats_mode_in_functions; } else { actual_gp_autostats_mode = gp_autostats_mode; } switch (actual_gp_autostats_mode) { case GP_AUTOSTATS_ON_CHANGE: policyCheck = autostats_on_change_check(cmdType, ntuples); break; case GP_AUTOSTATS_ON_NO_STATS: policyCheck = autostats_on_no_stats_check(cmdType, relationOid); break; default: Assert(actual_gp_autostats_mode == GP_AUTOSTATS_NONE); policyCheck = false; break; } if (!policyCheck) { elog(DEBUG3, "In mode %s, command %s on (dboid,tableoid)=(%d,%d) modifying " UINT64_FORMAT " tuples did not issue Auto-ANALYZE.", gpvars_show_gp_autostats_mode(), autostats_cmdtype_to_string(cmdType), MyDatabaseId, relationOid, ntuples); return; } if (log_autostats) { const char *autostats_mode; if (inFunction) { autostats_mode = gpvars_show_gp_autostats_mode_in_functions(); } else { autostats_mode = gpvars_show_gp_autostats_mode(); } elog(LOG, "In mode %s, command %s on (dboid,tableoid)=(%d,%d) modifying " UINT64_FORMAT " tuples caused Auto-ANALYZE.", autostats_mode, autostats_cmdtype_to_string(cmdType), MyDatabaseId, relationOid, ntuples); } autostats_issue_analyze(relationOid); if (log_duration) { long secs; int usecs; int msecs; TimestampDifference(start, GetCurrentTimestamp(), &secs, &usecs); msecs = usecs / 1000; elog(LOG, "duration: %ld.%03d ms Auto-ANALYZE", secs * 1000 + msecs, usecs % 1000); } }