成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

數據庫內核分析之GPDB and PostgreSQL Portal

開發 前端 其他數據庫
可優化語句包括DML,像insert/update/select等語句,這類語句特點是查詢滿足條件的元組返回給用戶或者元組操作后寫入磁盤,之所以稱之為可優化語句是因為這類語句通常會被優化器進行重寫與優化,從而加快查詢速度。

GPDB and PostgreSQL Portal內核分析

0.導論

Portal(門戶),也稱為策略選擇模塊,根據sql語句類型選擇不同的執行模塊(ProcessUtility、Executor)。

SQL語句類型包括:可優化語句、數據定義語句。

可優化語句包括DML,像insert/update/select等語句,這類語句特點是查詢滿足條件的元組返回給用戶或者元組操作后寫入磁盤,之所以稱之為可優化語句是因為這類語句通常會被優化器進行重寫與優化,從而加快查詢速度。

數據定義語句主要是功能性語句,例如:DDL(Create、Alter、Drop)、DCL(Grant、COMMIT、ROLLBACK)等。

圖片

1.Portal

1.1 入口層

QD執行會從exec_simple_query進入,QE執行從exec_mpp_query進入。

1.2 Portal層

1.2.1 初識Portal

首先初識Portal內部數據結構:

圖片

策略只包含一個SELECT查詢。

select * from t1;

包含一個INSERT/UPDATE/DELETE查詢,且帶RETURNING條件。

INSERT INTO ret_tbl (id) VALUES (3) RETURNING id INTO tableId;

包含一個SELECT查詢并且有修改的CTE。

WITH ins AS (
INSERT INTO t1 (t1_id) VALUES(1) RETURNING t1_id
)
SELECT * from ins;

例如:下面這個就不是PORTAL_ONE_MOD_WITH,而是PORTAL_MULTI_QUERY。

WITH ins AS (
SELECT * from t1
) INSERT INTO t2
(t2_id, col2)
SELECT * from ins;

包含一個utility語句,且該語句執行會返回像SELECT那樣有輸出結果。

postgres=# explain select * from t1;
QUERY PLAN
-------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=12)
-> Seq Scan on t1 (cost=0.00..431.00 rows=1 width=12)
Optimizer: Pivotal Optimizer (GPORCA)
(3 rows)

postgres=# EXECUTE t1_fn_ret(2, 'helloworld');
t1_id | col1
-------+------------
2 | helloworld
(1 row)

INSERT 0 1

其他情況,例如:PORTAL_MULTI_QUERY + PORTAL_MULTI_QUERY

PREPARE t1_fn (int, text) AS INSERT INTO t1 VALUES($1, $2);
  • PORTAL_MULTI_QUERY
  • PORTAL_UTIL_SELECT
  • PORTAL_ONE_MOD_WITH
  • PORTAL_ONE_RETURNING
  • PORTAL_ONE_SELECT

狀態

  • PORTAL_NEW
  • PORTAL_DEFINED
  • PORTAL_READY
  • PORTAL_QUEUE
  • PORTAL_ACTIVE
  • PORTAL_DONE
  • PORTAL_FAILED

這幾個狀態會在下面依次引入。

1.2.2 CreatePortal

創建一個新的Portal,傳入參數均為: CreatePortal("", true, true),表示創建一個匿名的Portal,允許重復且重復后保持沉默。

CreatePortal邏輯:

Portal
CreatePortal(const char *name, bool allowDup, bool dupSilent)
  • 根據傳入的第一個參數name從哈希表中查找
  • 根據傳入的第二個參數allowDup,如果第一步查找到,從哈希表中決定是否刪除。如果true,則刪除,否則報錯。在哈希表中查找到Portal且允許重復的情況下,在QD節點上會根據第三個參數dupSilent決定是否輸出告警信息。
  • 創建一個新的Portal,并初始化相應參數。

執行完畢后,便創建好了一個狀態為PORTAL_NEW的Portal。

1.2.3 PortalDefineQuery

定義portal數據,包含了:查詢語句sourceText、PlannedStmts、查詢完成標記qc。

注意:QD上根據傳遞進來的stmt來設置nodeTag,但是QE上為T_Query,因為QE上不是parsed statement,所以不是 T_SelectStmt。

最終設置Portal狀態為PORTAL_DEFINED。

1.2.4 PortalStart

準備好portal,主要有如下幾步:

  • 設置ddesc,該信息為QD到QE上的額外信息,QD上為NULL,QE上不為NULL。
  • 設置全局參數,例如:當前活躍的portal、resourceOwner、context。
  • 設置portal參數字段:portalParams,同樣QD上為NULL,QE上不為NULL。
  • 設置portal策略(ChoosePortalStrategy)。

如下圖所示:輸入為查詢計劃鏈表,針對PORTAL_ONE_SELECT、PORTAL_ONE_MOD_WITH、PORTAL_UTIL_SELECT、PORTAL_ONE_RETURNING都是要求一個計劃,首先判斷是Query還是PlannedStmt,一般情況下的查詢語句基本都是PlannedStmt,對于像PREPARE st(int) as select * from t1之類utility語句第一次調用ChoosePortalStrategy返回PORTAL_MULTI_QUERY(命中PlannedStmt),第二次調用返回PORTAL_ONE_SELECT(命中Query)。

圖片

choose

5. 根據portal策略初始化portal,最重要的是初始化tupDesc與cursor postion。

圖片

例如:"QUERY PLAN"、"t1_id、col1"就是tupDesc。

postgres=# explain select * from t1;
QUERY PLAN
-------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..431.00 rows=1 width=12)
-> Seq Scan on t1 (cost=0.00..431.00 rows=1 width=12)
Optimizer: Pivotal Optimizer (GPORCA)
(3 rows)

postgres=# EXECUTE t1_fn_ret(2, 'helloworld');
t1_id | col1
-------+------------
2 | helloworld
(1 row)

INSERT 0 1

不同tupleDesc函數區別

  • ExecTypeFromTL

skip resjunk column

  • ExecCleanTypeFromTL

with resjunk column

6. 在執行Portal過程中發生異常,設置portal的狀態為PORTAL_FAILED;否則,下一步。

7. 設置Portal狀態為PORTAL_READY。

1.2.5 PortalRun

根據sql的語句類型選擇不同的執行路徑,獲取元組數據,完成portal工作,運行完之后要么Done要么下一輪(READY,而非ACTIVE)。

portal策略執行路徑如下:

  • PORTAL_ONE_SELECT

set result = portal->atEnd

  • PORTAL_ONE_RETURNING|PORTAL_ONE_MOD_WITH|PORTAL_UTIL_SELECT

獲取時數據方向包含前進/后退

可以從holdStore中獲取,也可以從ExectorRun中獲取

填充holdStore(見下方)

調用PortalRunSelect返回n行數據

設置狀態為PORTAL_READY

設置是否完成運行標記為portal->atEnd

  • PORTAL_MULTI_QUERY

調用PortalRunMulti

設置狀態為PORTAL_Done

設置是否完成運行標記為true

圖片

此外,上述圖中填充holdStore邏輯如下:

  • 調用PortalCreateHoldStore填充portal->holdStore,通過工廠函數CreateDestReceiver構造DestReceiver(子類:TStoreState);
  • 根據portal策略執行查詢:PORTAL_ONE_RETURNING、PORTAL_ONE_MOD_WITH 調用PortalRunMulti,PORTAL_UTIL_SELECT調用PortalRunUtility。

PortalRunUtility

PortalRunMulti

ProcessQuery

PortalRunUtility

utilityStmt

not utilityStmt

PORTAL_ONE_RETURNING、PORTAL_ONE_MOD_WITH

PORTAL_UTIL_SELECT

圖片

2.游標Cursor

2.1 打開游標

如果不想一次執行整個命令,可以設置一個封裝該命令的游標(cursor), 然后每次讀取幾行命令結果。

name [ [ NO ] SCROLL ] CURSOR [ ( arguments ) ] FOR query;

例如:

DECLARE liahona SCROLL CURSOR FOR SELECT * FROM t1;

該命令運行機制為:首先識別到是一個數據定義語句,便會調用ProcessUtility,隨后解析從PlannedStmt中的utilityStmt識別出是一個T_DeclareCursorStmt節點,調用PerformCursorOpen執行Declare cursor命令。

PerformCursorOpen處理邏輯如下:

  • query重寫
  • 優化器優化,生成PlannedStmt
  • 創建Portal(名字為游標名),僅調用PortalStart

2.2 關閉游標

關閉游標,實際就是關閉Portal,調用PerformPortalClose。

如下兩個操作:

CLOSE cursor_name;
CLOSE ALL;

如果傳入的名字為空,則是CLOSE ALL關閉所有非活躍portal,否則,只關閉指定的portal(cursor)。

2.3 FETCH or MOVE

FETCH與MOVE語法分別如下:

FETCH [ direction { FROM | IN } ] cursor INTO target;
MOVE [ direction { FROM | IN } ] cursor;

FETCH從游標中檢索n行到目標中, 目標可以是一個行變量、記錄變量、逗號分隔的普通變量列表, 就像SELECT INTO一樣, 如果沒有獲取到數據,目標會設為NULL。

MOVE重新定位一個游標,而不需要檢索任何數據,例如:一旦游標位置確定,則可以刪除或更新行。

MOVE cursor_variable;
UPDATE table_name
SET column = value, ...
WHERE CURRENT OF cursor_variable;

從實現層面兩者都會進入到PerformPortalFetch,都被解析為FetchStmt,內部有個成員ismove決定是MOVE還是FETCH。

不管是哪個,都會指定cursor名,有了這個名字,便知道了portal,隨后調用PortalRunFetch來獲取結果。

PortalRunFetch內部會像PortalRun運行一樣,首先設置portal狀態為Active,隨后根據策略選擇不同的調用鏈。

  • PORTAL_ONE_SELECT

調用DoPortalRunFetch

  • PORTAL_ONE_RETURNING|PORTAL_ONE_MOD_WITH|PORTAL_UTIL_SELECT

首先判斷portal內部是否有holdStore,如果沒有會調用FillPortalStore,隨后調用DoPortalRunFetch。

DoPortalRunFetch內部實現,會考慮傳入的direction,決定是前向還是后向等不同方向的掃描,最后調用PortalRunSelect獲取數據,注意:gpdb不支持backward scan,但是pg支持。


圖片

責任編輯:武曉燕 來源: 光城
相關推薦

2017-08-24 13:29:19

UDB高可用數據庫

2023-02-10 09:21:31

PG數據庫內存

2023-06-28 11:14:18

2024-04-03 09:27:49

后端開發數據庫內核

2017-08-25 09:50:42

數據庫MySQL內核優化

2019-11-19 08:32:26

數據庫HLC事務

2010-05-26 11:10:12

MySQL數據庫

2009-03-23 10:32:47

SQLServer數據庫數據類型

2022-03-31 16:06:26

PingCAP開源

2019-11-20 09:08:46

PostgreSQL數據庫

2010-05-27 17:10:03

MySQL數據庫內存

2020-07-28 08:54:39

內核通信Netlink

2011-03-24 14:40:29

PostgreSQL數管理

2011-02-24 15:04:00

PostgreSQL數據庫psql

2009-12-30 13:26:48

2009-12-24 14:17:27

安全威脅Oracle數據庫

2013-09-24 15:19:28

甲骨文Oracle數據庫

2010-04-06 12:39:15

Oracle數據庫

2010-10-28 15:15:08

oracle內存參數
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美日韩亚洲视频 | 一级欧美| 日韩在线免费视频 | 欧美精品一区二区三区在线播放 | 草久久久| 成人免费激情视频 | 欧美日韩国产精品一区 | www.久久 | 午夜av成人 | 国产黄视频在线播放 | www,黄色,com | 国产最新精品视频 | 一区二区在线不卡 | av网站免费| 国产日韩欧美一区二区 | 精品国产乱码久久久久久丨区2区 | 亚洲精品乱码久久久久久久久 | 免费一级片| 久久日韩粉嫩一区二区三区 | 亚洲不卡在线观看 | 激情欧美日韩一区二区 | 日韩国产精品一区二区三区 | 91精品国产91久久久久青草 | 婷婷色国产偷v国产偷v小说 | 日韩另类 | av黄色免费 | 日韩欧美福利视频 | 成人在线免费观看视频 | 亚洲精品视频播放 | 国产精品久久久久久久久久久免费看 | 视频一区二区三区中文字幕 | 亚洲视频一区二区三区 | 精品国产一级 | 亚洲视频免费在线观看 | 懂色av一区二区三区在线播放 | 中文字幕加勒比 | 在线观看日韩av | 中文字幕一区二区三区乱码图片 | 日韩欧美国产精品一区二区 | av手机免费在线观看 | 久久精品一 |