您好,登錄后才能下訂單哦!
本篇內容介紹了“PostgreSQL中vacuum主流程分析”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
宏定義
Vacuum和Analyze命令選項
/* ---------------------- * Vacuum and Analyze Statements * Vacuum和Analyze命令選項 * * Even though these are nominally two statements, it's convenient to use * just one node type for both. Note that at least one of VACOPT_VACUUM * and VACOPT_ANALYZE must be set in options. * 雖然在這里有兩種不同的語句,但只需要使用統一的Node類型即可. * 注意至少VACOPT_VACUUM/VACOPT_ANALYZE在選項中設置. * ---------------------- */ typedef enum VacuumOption { VACOPT_VACUUM = 1 << 0, /* do VACUUM */ VACOPT_ANALYZE = 1 << 1, /* do ANALYZE */ VACOPT_VERBOSE = 1 << 2, /* print progress info */ VACOPT_FREEZE = 1 << 3, /* FREEZE option */ VACOPT_FULL = 1 << 4, /* FULL (non-concurrent) vacuum */ VACOPT_SKIP_LOCKED = 1 << 5, /* skip if cannot get lock */ VACOPT_SKIPTOAST = 1 << 6, /* don't process the TOAST table, if any */ VACOPT_DISABLE_PAGE_SKIPPING = 1 << 7 /* don't skip any pages */ } VacuumOption;
VacuumStmt
存儲vacuum命令的option&Relation鏈表
typedef struct VacuumStmt { NodeTag type;//Tag //VacuumOption位標記 int options; /* OR of VacuumOption flags */ //VacuumRelation鏈表,如為NIL-->所有Relation. List *rels; /* list of VacuumRelation, or NIL for all */ } VacuumStmt;
VacuumParams
vacuum命令參數
/* * Parameters customizing behavior of VACUUM and ANALYZE. * 客戶端調用VACUUM/ANALYZE時的定制化參數 */ typedef struct VacuumParams { //最小freeze age,-1表示使用默認 int freeze_min_age; /* min freeze age, -1 to use default */ //掃描整個table的freeze age int freeze_table_age; /* age at which to scan whole table */ //最小的multixact freeze age,-1表示默認 int multixact_freeze_min_age; /* min multixact freeze age, -1 to * use default */ //掃描全表的freeze age,-1表示默認 int multixact_freeze_table_age; /* multixact age at which to scan * whole table */ //是否強制wraparound? bool is_wraparound; /* force a for-wraparound vacuum */ //以毫秒為單位的最小執行閾值 int log_min_duration; /* minimum execution threshold in ms at * which verbose logs are activated, -1 * to use default */ } VacuumParams;
VacuumRelation
VACUUM/ANALYZE命令的目標表信息
/* * Info about a single target table of VACUUM/ANALYZE. * VACUUM/ANALYZE命令的目標表信息. * * If the OID field is set, it always identifies the table to process. * Then the relation field can be NULL; if it isn't, it's used only to report * failure to open/lock the relation. * 如設置了OID字段,該值通常是將要處理的數據表. * 那么關系字段可以為空;如果不是,則僅用于報告未能打開/鎖定關系。 */ typedef struct VacuumRelation { NodeTag type; RangeVar *relation; /* table name to process, or NULL */ Oid oid; /* table's OID; InvalidOid if not looked up */ List *va_cols; /* list of column names, or NIL for all */ } VacuumRelation;
ExecVacuum函數,手工執行VACUUM/ANALYZE命令時的主入口,vacuum()函數的包裝器(wrapper).
/* * Primary entry point for manual VACUUM and ANALYZE commands * 手工執行VACUUM/ANALYZE命令時的主入口 * * This is mainly a preparation wrapper for the real operations that will * happen in vacuum(). * 這是vacuum()函數的包裝器(wrapper) */ void ExecVacuum(VacuumStmt *vacstmt, bool isTopLevel) { VacuumParams params; /* sanity checks on options */ //驗證&檢查 Assert(vacstmt->options & (VACOPT_VACUUM | VACOPT_ANALYZE)); Assert((vacstmt->options & VACOPT_VACUUM) || !(vacstmt->options & (VACOPT_FULL | VACOPT_FREEZE))); Assert(!(vacstmt->options & VACOPT_SKIPTOAST)); /* * Make sure VACOPT_ANALYZE is specified if any column lists are present. * 如出現字段列表,則確保指定了VACOPT_ANALYZE選項 */ if (!(vacstmt->options & VACOPT_ANALYZE)) { ListCell *lc; foreach(lc, vacstmt->rels) { VacuumRelation *vrel = lfirst_node(VacuumRelation, lc); if (vrel->va_cols != NIL) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("ANALYZE option must be specified when a column list is provided"))); } } /* * All freeze ages are zero if the FREEZE option is given; otherwise pass * them as -1 which means to use the default values. * 如指定了FREEZE選項則設置所有freeze ages為0. * 否則的話,傳遞-1(即使用默認值). */ if (vacstmt->options & VACOPT_FREEZE) { //指定VACOPT_FREEZE params.freeze_min_age = 0; params.freeze_table_age = 0; params.multixact_freeze_min_age = 0; params.multixact_freeze_table_age = 0; } else { params.freeze_min_age = -1; params.freeze_table_age = -1; params.multixact_freeze_min_age = -1; params.multixact_freeze_table_age = -1; } /* user-invoked vacuum is never "for wraparound" */ //用戶調用的vacuum永遠不會是wraparound params.is_wraparound = false; /* user-invoked vacuum never uses this parameter */ //用戶調用vacuum永遠不會使用該參數 params.log_min_duration = -1; /* Now go through the common routine */ //調用vacuum vacuum(vacstmt->options, vacstmt->rels, ¶ms, NULL, isTopLevel); }
測試腳本
17:19:28 (xdb@[local]:5432)testdb=# vacuum t1;
啟動gdb,設置斷點
(gdb) b ExecVacuum Breakpoint 1 at 0x6b99a1: file vacuum.c, line 92. (gdb) c Continuing. Breakpoint 1, ExecVacuum (vacstmt=0x210e9c0, isTopLevel=true) at vacuum.c:92 92 Assert(vacstmt->options & (VACOPT_VACUUM | VACOPT_ANALYZE)); (gdb)
輸入參數
options = 1 —> VACOPT_VACUUM
(gdb) p *vacstmt $1 = {type = T_VacuumStmt, options = 1, rels = 0x210e988} (gdb)
獲取Relation相關信息
gdb) n 93 Assert((vacstmt->options & VACOPT_VACUUM) || (gdb) 95 Assert(!(vacstmt->options & VACOPT_SKIPTOAST)); (gdb) 100 if (!(vacstmt->options & VACOPT_ANALYZE)) (gdb) 104 foreach(lc, vacstmt->rels) (gdb) 106 VacuumRelation *vrel = lfirst_node(VacuumRelation, lc); (gdb) 108 if (vrel->va_cols != NIL) (gdb) p *vrel $3 = {type = T_VacuumRelation, relation = 0x210e8d0, oid = 0, va_cols = 0x0} (gdb) p *vrel->relation $4 = {type = T_RangeVar, catalogname = 0x0, schemaname = 0x0, relname = 0x210e8b0 "t1", inh = true, relpersistence = 112 'p', alias = 0x0, location = 7} (gdb)
設置vacuum參數
(gdb) n 104 foreach(lc, vacstmt->rels) (gdb) 119 if (vacstmt->options & VACOPT_FREEZE) (gdb) 128 params.freeze_min_age = -1; (gdb) 129 params.freeze_table_age = -1; (gdb) 130 params.multixact_freeze_min_age = -1; (gdb) 131 params.multixact_freeze_table_age = -1; (gdb) 135 params.is_wraparound = false; (gdb) (gdb) n 138 params.log_min_duration = -1; (gdb)
調用vacuum
141 vacuum(vacstmt->options, vacstmt->rels, ¶ms, NULL, isTopLevel); (gdb) 142 } (gdb) standard_ProcessUtility (pstmt=0x210ea80, queryString=0x210dec8 "vacuum t1;", context=PROCESS_UTILITY_TOPLEVEL, params=0x0, queryEnv=0x0, dest=0x210ed70, completionTag=0x7fff1d69dea0 "") at utility.c:672 672 break;
“PostgreSQL中vacuum主流程分析”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。