<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [TOC] # <span style="font-size:15px">**元組結構**</span> 元組由三部分組成,即HeapTupleHeaderData結構、空位圖和用戶數據。 ![](https://img.kancloud.cn/5c/ea/5ceab2d3e2887ac868084ca3fb2e9f07_987x194.png) * t_xmin:保存插入(insert)該元組的事務的txid。 * t_xmax:保存刪除或更新此元組的事務的txid。如果此元組尚未被刪除或更新,則t_xmax設置為0,這意味著無效。 * t_cid:保存命令id(cid)。這意味著在從0開始的當前事務中執行此命令之前執行了多少SQL命令。例如,假設我們在一個事務中執行三個INSERT命令:'BEGIN; INSERT; INSERT; INSERT; COMMIT;'。如果第一個命令插入這個元組,則t_cid設置為0。如果第二個命令插入此命令,則t_cid設置為1,依此類推。當這個元組被更新時,這個元組的t_ctid指向新的元組;否則,t\_ctid會指向自己。 # <span style="font-size:15px">**insert tuple**</span> 通過插入操作,一個新元組被直接插入到目標表的頁面中 ![](https://img.kancloud.cn/58/fa/58fac74698858294cbf89a2af0605ab7_1031x227.png) Tuple_1: 1. t_xmin被設置為99,因為這個元組是由txid 99插入的。 2. t_xmax設置為0,因為此元組尚未刪除或更新。 3. t_cid設置為0,因為此元組是txid 99插入的第一個元組。 4. t_ctid設置為(0,1),它指向自身,因為這是最新的元組。 <br> # <span style="font-size:15px">**delete tuple**</span> Tuple_1被 txid=111的事務刪除 ![](https://img.kancloud.cn/a4/b1/a4b18dd8f0ed420da8d20dcdeba245f1_991x230.png) Tuple\_1: &nbsp;&nbsp;&nbsp;&nbsp;t_xmax設置為111。 &nbsp;&nbsp;&nbsp;&nbsp;如果提交了txid 111,則不再需要Tuple_1。在PostgreSQL中,不需要的元組通常被稱為死元組。 <br> # <span style="font-size:15px">**update tuple**</span> 在更新操作中,PostgreSQL從邏輯上刪除最新的元組并插入一個新元組 ![](https://img.kancloud.cn/a2/ea/a2eadc9fdabd4d229280b735f4316470_1002x456.png) 假設txid 99插入的行被txid 100更新了兩次。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;當執行第一個更新命令時,通過將txid 100設置為t_xmax,邏輯上刪除Tuple_1,然后插入Tuple_2。然后,將Tuple_1的t_ctid重寫為指向Tuple_2。Tuple_1和Tuple_2的頭字段如下所示。 Tuple_1: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t_xmax設置為100。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t_ctid從(0,1)重寫為(0,2)。 Tuple_2: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t_xmin設置為100。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t_xmax設置為0。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t_cid設置為0。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t_ctid設置為(0,2)。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;當執行第二個更新命令時,與第一個更新命令一樣,邏輯上刪除Tuple_2,插入Tuple_3。Tuple_2和Tuple_3的頭字段如下所示。與刪除操作一樣,如果提交了txid 100,則Tuple_1和Tuple_2將是死元組,如果中止了txid 100,則Tuple_2和Tuple_3將是死元組。 Tuple_2: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t_xmax設置為100。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t_ctid從(0,2)重寫為(0,3)。 Tuple_3: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t_xmin設置為100。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t_xmax設置為0。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t_cid設置為1。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t_ctid設置為(0,3)。 # <span style="font-size:15px">**通過pageinspect擴展查看tuple**</span> ``` // 安裝pageinspect擴展 postgres=# CREATE EXTENSION pageinspect; CREATE EXTENSION // 建表并插入兩條數據 postgres=# CREATE TABLE tbl (data text); CREATE TABLE postgres=# INSERT INTO tbl VALUES('A'); INSERT 0 1 postgres=# INSERT INTO tbl VALUES('B'); INSERT 0 1 // 可以查看到兩條數據的元組頭部和元組原始數據 postgres=# SELECT lp as tuple, t_xmin, t_xmax, t_field3 as t_cid, t_ctid FROM heap_page_items(get_raw_page('tbl', 0)); tuple | t_xmin | t_xmax | t_cid | t_ctid -------+--------+--------+-------+-------- 1 | 493 | 0 | 0 | (0,1) 2 | 494 | 0 | 0 | (0,2) (2 rows) // 刪除 B 數據之后,B數據已被標識刪除,dead tuple,待回收 postgres=# delete from tbl where data = 'B'; DELETE 1 postgres=# SELECT lp as tuple, t_xmin, t_xmax, t_field3 as t_cid, t_ctid FROM heap_page_items(get_raw_page('tbl', 0)); tuple | t_xmin | t_xmax | t_cid | t_ctid -------+--------+--------+-------+-------- 1 | 493 | 0 | 0 | (0,1) 2 | 494 | 495 | 0 | (0,2) (2 rows) //更新A數據。邏輯上刪除Tuple_1,然后插入Tuple_3 postgres=# update tbl set data = 'C' where data = 'A'; UPDATE 1 postgres=# SELECT lp as tuple, t_xmin, t_xmax, t_field3 as t_cid, t_ctid FROM heap_page_items(get_raw_page('tbl', 0)); tuple | t_xmin | t_xmax | t_cid | t_ctid -------+--------+--------+-------+-------- 1 | 493 | 496 | 0 | (0,3) 2 | 494 | 495 | 0 | (0,2) 3 | 496 | 0 | 0 | (0,3) (3 rows) // 手動vacuum進行垃圾回收 postgres=# vacuum; VACUUM postgres=# SELECT lp as tuple, t_xmin, t_xmax, t_field3 as t_cid, t_ctid FROM heap_page_items(get_raw_page('tbl', 0)); tuple | t_xmin | t_xmax | t_cid | t_ctid -------+--------+--------+-------+-------- 1 | | | | // line pointers不會被回收 2 | | | | // 會產生空間碎片 3 | 496 | 0 | 0 | (0,3) (3 rows) // 全量垃圾回收,徹底回收,不會有空間碎片,重寫表 postgres=# vacuum full; VACUUM postgres=# SELECT lp as tuple, t_xmin, t_xmax, t_field3 as t_cid, t_ctid FROM heap_page_items(get_raw_page('tbl', 0)); tuple | t_xmin | t_xmax | t_cid | t_ctid -------+--------+--------+-------+-------- 1 | 496 | 0 | 0 | (0,1) (1 row) ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看