openGauss核心分析(九):資料庫表的建立過程
除了DML之外的所有查詢都透過ProcessUtility模組來執行,包括了各類DDL語句、事務相關語句、遊標相關語句等。上層呼叫函式為exec_simple_query函式,其中PortalStart函式和PortalDrop函式部分較為簡單。核心函式是PortalRun函式下層呼叫的standard_ProcessUtility函式,該函式透過switch case語句處理了各種型別的查詢語句,包括事務相關查詢、遊標相關查詢、schema相關操作、表空間相關操作、表定義相關操作等。
standard_ProcessUtility函式會根據nodeTag(parsetree)的值來確定sql的操作型別,create table一般都是進入T_CreateStmt分支,呼叫CreateCommand函式。
void standard_ProcessUtility(Node* parse_tree, const char* query_string, ParamListInfo params, bool is_top_level, DestReceiver* dest,#ifdef PGXC bool sent_to_remote,#endif /* PGXC */ char* completion_tag, bool isCTAS) { …… errno_t errorno = EOK; switch (nodeTag(parse_tree)) { // 根據nodeTag(parsetree)的值來確定sql的操作型別 …… case T_CreateStmt: { // create table#ifdef PGXC CreateCommand((CreateStmt*)parse_tree, query_string, params, is_top_level, sent_to_remote, isCTAS);#else CreateCommand((CreateStmt*)parse_tree, query_string, params, is_top_level, isCTAS);#endif } break; ……
CreateCommand函式先解析parse_tree獲取stmt,如果stmt為空則表明表已經存在。如果stmt不為空對stmts進行遍歷,如果是 CreateStmt就呼叫DefineRelation。AlterTableCreateToastTable判斷是否需要建立toast表並建立,AlterCStoreCreateTables判斷是否需要建立列存表並建立。
#ifdef PGXCvoid CreateCommand(CreateStmt *parse_tree, const char *query_string, ParamListInfo params, bool is_top_level, bool sent_to_remote, bool isCTAS)#elsevoid CreateCommand(CreateStmt *parse_tree, const char *query_string, ParamListInfo params, bool is_top_level, bool isCTAS)#endif{ …… /* Run parse analysis ... */ if (u_sess->attr.attr_sql.enable_parallel_ddl) // 先解析parse_tree獲取stmt stmts = transformCreateStmt((CreateStmt*)parse_tree, query_string, NIL, true, &namespace_id, is_first_node); else stmts = transformCreateStmt((CreateStmt*)parse_tree, query_string, NIL, false, &namespace_id); /* * If stmts is NULL, then the table is exists. * we need record that for searching the group of table. */ if (stmts == NIL) { // 如果stmt為空則表明表已經存在 table_is_exist = true; …… /* ... and do it */ foreach (l, stmts) { // 遍歷stmts Node* stmt = (Node*)lfirst(l); if (IsA(stmt, CreateStmt)) { // 如果是 CreateStmt就呼叫DefineRelation Datum toast_options; static const char* const validnsps[] = HEAP_RELOPT_NAMESPACES; /* forbid user to set or change inner options */ ForbidOutUsersToSetInnerOptions(((CreateStmt*)stmt)->options); /* Create the table itself */ rel_oid = DefineRelation((CreateStmt*)stmt, ((CreateStmt*)stmt)->relkind == RELKIND_MATVIEW ? RELKIND_MATVIEW : RELKIND_RELATION, InvalidOid, isCTAS); …… AlterTableCreateToastTable(rel_oid, toast_options, AccessShareLock); AlterCStoreCreateTables(rel_oid, toast_options, (CreateStmt*)stmt); AlterDfsCreateTables(rel_oid, toast_options, (CreateStmt*)stmt); AlterCreateChainTables(rel_oid, toast_options, (CreateStmt *)stmt); ……
DefineRelation函式獲取到表名relname、名字空間relnamespace、表空間reltablespace、表型別relkind和relpersistence等資訊後呼叫heap_create_with_catalog建立relation。
(gdb) f 0#0 heap_create_with_catalog (relname=0x7fb4fa872140 "t100", relnamespace=2200, reltablespace=0, relid=0, reltypeid=0, reloftypeid=0, ownerid=10, tupdesc=0x7fb4ff2e2e50, cooked_constraints=0x0, relkind=114 'r', relpersistence=112 'p', shared_relation=false, mapped_relation=false, oidislocal=false, oidinhcount=0, oncommit=ONCOMMIT_NOOP, reloptions=140415352057720, use_user_acl=true, allow_system_table_mods=false, partTableState=0x0, row_compress=1 '\001', bucketinfo=0x0, record_dependce=true, ceLst=0x0, storage_type=HEAP_DISK, partLockMode=1) at heap.cpp:2521
其中heap_create內部首先呼叫了RelationBuildLocalRelation建立RelationData,並加入到relCache,RelationData表示一個表的元資訊,這些資訊都可以由系統表元組中的資訊構造得到。然後根據這些資訊透過呼叫RelalionCreateStorage函式建立物理檔案。heap_create_with_catalog主要完成表物理檔案的建立和表元資訊註冊到系統表中,涉及系統包包括pg_class,pg_attribute,pg_depend,pg_object,pg_type,pg_index和pg_partition。
附:建立表create table的函式呼叫棧
#0 RelationCreateStorage #1 heap_create #2 heap_create_with_catalog #3 DefineRelation #4 CreateCommand #5 standard_ProcessUtility #6 gsaudit_ProcessUtility_hook #7 pgaudit_ProcessUtility #8 hypo_utility_hook #9 ProcessUtility #10 PortalRunUtility #11 PortalRunMulti #12 PortalRun #13 exec_simple_query #14 PostgresMain
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70023856/viewspace-2939606/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- openGauss核心分析(十):資料庫搜尋引的建立過程資料庫
- openGauss核心:SQL解析過程分析SQL
- standby 資料庫的建立過程資料庫
- 使用AnalyticDB MySQL建立資料庫及表過程MySql資料庫
- Oracle XE的資料庫建立過程Oracle資料庫
- 手工建立oracle資料庫的過程Oracle資料庫
- 手動建立資料庫過程資料庫
- Linux核心建立一個程式的過程分析Linux
- Standby資料庫簡單建立過程資料庫
- openGauss資料庫分析問題資料庫
- Mysql資料庫建立儲存過程實現往資料表中新增欄位的方法MySql資料庫儲存過程
- 建立資料庫表資料庫
- 走了一遍手動建立資料庫的過程資料庫
- MySQL 建立資料庫 建立表MySql資料庫
- Mysql 資料庫水平分表 儲存過程MySql資料庫儲存過程
- 一次使用duplicate建立測試資料庫的過程資料庫
- 資料庫 建立 3表資料庫
- 資料需求分析過程
- 一次資料庫硬解析的分析全過程資料庫
- 建立資料庫連線失敗ORA-12514的分析解決過程資料庫
- 資料庫的連線過程資料庫
- ORACLE 資料庫分析,重新編譯失敗過程Oracle資料庫編譯
- 在Oracle資料庫的最佳化過程中,表分析也是很重要的一步Oracle資料庫
- SQL建立資料庫和表SQL資料庫
- 【資料庫】資料庫儲存過程(一)資料庫儲存過程
- 大資料分析過程是如何的大資料
- SQL Server資料庫遠端更新目標表資料的儲存過程SQLServer資料庫儲存過程
- linux下Postgresql-9.2安裝及資料庫的建立過程LinuxSQL資料庫
- 資料庫擴充套件表設計過程記錄資料庫套件
- 資料庫恢復過程資料庫
- 資料庫啟動過程資料庫
- 資料庫儲存過程資料庫儲存過程
- oracle資料庫的關閉過程Oracle資料庫
- 儲存過程呼叫不同資料庫的資料儲存過程資料庫
- 通過現有的資料庫備份建立新的資料庫資料庫
- 通過命令在navicat中建立資料庫及表結構資料庫
- 【資料庫資料恢復】透過資料頁恢復Sql Server資料庫資料的過程資料庫資料恢復SQLServer
- 恢復MySQL資料庫建立儲存過程是遇到錯誤MySql資料庫儲存過程