2_PostgreSQL深入解析數據文件page擴展規律
1、研究方法概述
本文通過回顧Oracle內核原理,指導分析和研究pg15數據庫,Oracle通過位圖結構將并發dml語句均勻分配到extent中不同的data blocks,從而提高數據庫并發量,pg中是否會預分配大量空pages從而提高數據庫的并發呢?這是一個問題,待下文分析?
2、Oracle 原理回顧
2.1、BUFFER訪問機制

步驟1、客戶端發起dml語句變更 file:5 blk_id: 1234 所在的行 步驟2、通過hash算法 file5: blk_id: 1234在 bucket x 步驟3、以獨占方式獲取CBC Latch 步驟4、在獨占CBC Latch的保護下,修改BH中的Buffer Pin鎖,將鎖狀態改為X 步驟5、BH中的Buffer Pin鎖狀態修改完畢,釋放獨占的CBC Latch 步驟6、在獨占Buffer Pin鎖保護下修改buffer
2.2、ASSM位圖原理

步驟1、查找數據字典,確定段頭位置 步驟2、在段頭中找到第一個L2位置信息 步驟3、到L2塊中根據執行插入操作進程PID號,做HASH運算,得到一個隨機數N,在L2中,找到第N個L1塊的位置信息。 步驟4、到第三步中確定的L1塊中,再根據執行插入操作進程的PID號,做HASH運算,得到一個隨機數M,在L1中找到第M號數據塊。 步驟5、向第M號數據塊中插入。
小結:
- Oracle通過cbc latch保護鏈表結構,通過buffer pin latch保護ba指向的buffer結構
- Oracle通過位圖結構將并發dml語句均勻分配到extent中不同的data blocks,從而提高數據庫并發量
3、測試腳本用法解釋
3.1、腳本下載地址
http://www.sunline.cc/download/634246
3.2、使用方法解釋
Usage: pg_page_extend_test_20220622 -t/-b <value> -ls/-du explain: -t: stop by number of tuples -b: stop by number of blocks -ls/-du: check filesize Method by ls/du -nocr/-cr: whether recreate the table or not
4、page擴展規律測試-du判斷文件大小
4.1、測試on pg9
### 執行腳本
[postgres@enmo ~]$ sh pg_page_extend_test.sh -b 999999 -du -cr
### 測試結果
| inc_number | file_size(8K) | add_size(8K) | file_name | pg_version |
| ---------- | ------------- | ------------ | -------------------------------- | ------------------------ |
| 1 | 1 | 1 | /u01/pg9/pgdata/base/13323/16502 | psql (PostgreSQL) 9.6.24 |
| 2 | 2 | 1 | /u01/pg9/pgdata/base/13323/16502 | psql (PostgreSQL) 9.6.24 |
| 3 | 3 | 1 | /u01/pg9/pgdata/base/13323/16502 | psql (PostgreSQL) 9.6.24 |
| 4 | 4 | 1 | /u01/pg9/pgdata/base/13323/16502 | psql (PostgreSQL) 9.6.24 |
| 5 | 5 | 1 | /u01/pg9/pgdata/base/13323/16502 | psql (PostgreSQL) 9.6.24 |
| 6 | 6 | 1 | /u01/pg9/pgdata/base/13323/16502 | psql (PostgreSQL) 9.6.24 |
| 7 | 7 | 1 | /u01/pg9/pgdata/base/13323/16502 | psql (PostgreSQL) 9.6.24 |
| 8 | 8 | 1 | /u01/pg9/pgdata/base/13323/16502 | psql (PostgreSQL) 9.6.24 |
| 9 | 16 | 8 | /u01/pg9/pgdata/base/13323/16502 | psql (PostgreSQL) 9.6.24 |
| 10 | 32 | 16 | /u01/pg9/pgdata/base/13323/16502 | psql (PostgreSQL) 9.6.24 |
| 11 | 64 | 32 | /u01/pg9/pgdata/base/13323/16502 | psql (PostgreSQL) 9.6.24 |
| 12 | 128 | 64 | /u01/pg9/pgdata/base/13323/16502 | psql (PostgreSQL) 9.6.24 |
| 13 | 256 | 128 | /u01/pg9/pgdata/base/13323/16502 | psql (PostgreSQL) 9.6.24 |
| 14 | 512 | 256 | /u01/pg9/pgdata/base/13323/16502 | psql (PostgreSQL) 9.6.24 |
| 15 | 1024 | 512 | /u01/pg9/pgdata/base/13323/16502 | psql (PostgreSQL) 9.6.24 |
| 16 | 2048 | 1024 | /u01/pg9/pgdata/base/13323/16502 | psql (PostgreSQL) 9.6.24 |
| 17 | 4096 | 2048 | /u01/pg9/pgdata/base/13323/16502 | psql (PostgreSQL) 9.6.24 |
| 18 | 8192 | 4096 | /u01/pg9/pgdata/base/13323/16502 | psql (PostgreSQL) 9.6.24 |
| 19 | 16384 | 8192 | /u01/pg9/pgdata/base/13323/16502 | psql (PostgreSQL) 9.6.24 |
| 20 | 32768 | 16384 | /u01/pg9/pgdata/base/13323/16502 | psql (PostgreSQL) 9.6.24 |
| 21 | 65536 | 32768 | /u01/pg9/pgdata/base/13323/16502 | psql (PostgreSQL) 9.6.24 |
| 22 | 131072 | 65536 | /u01/pg9/pgdata/base/13323/16502 | psql (PostgreSQL) 9.6.24 |
4.2、測試on pg15
### 執行腳本
[postgres@enmo ~]$ sh pg_page_extend_test.sh -b 999999 -du -cr
### 測試結果
| inc_number | file_size(8K) | add_size(8K) | file_name | pg_version |
| ---------- | ------------- | ------------ | ----------------------------- | ------------------------- |
| 1 | 1 | 1 | /u01/pg15/pgdata/base/5/58048 | psql (PostgreSQL) 15beta1 |
| 2 | 2 | 1 | /u01/pg15/pgdata/base/5/58048 | psql (PostgreSQL) 15beta1 |
| 3 | 3 | 1 | /u01/pg15/pgdata/base/5/58048 | psql (PostgreSQL) 15beta1 |
| 4 | 4 | 1 | /u01/pg15/pgdata/base/5/58048 | psql (PostgreSQL) 15beta1 |
| 5 | 5 | 1 | /u01/pg15/pgdata/base/5/58048 | psql (PostgreSQL) 15beta1 |
| 6 | 6 | 1 | /u01/pg15/pgdata/base/5/58048 | psql (PostgreSQL) 15beta1 |
| 7 | 7 | 1 | /u01/pg15/pgdata/base/5/58048 | psql (PostgreSQL) 15beta1 |
| 8 | 8 | 1 | /u01/pg15/pgdata/base/5/58048 | psql (PostgreSQL) 15beta1 |
| 9 | 16 | 8 | /u01/pg15/pgdata/base/5/58048 | psql (PostgreSQL) 15beta1 |
| 10 | 32 | 16 | /u01/pg15/pgdata/base/5/58048 | psql (PostgreSQL) 15beta1 |
| 11 | 64 | 32 | /u01/pg15/pgdata/base/5/58048 | psql (PostgreSQL) 15beta1 |
| 12 | 128 | 64 | /u01/pg15/pgdata/base/5/58048 | psql (PostgreSQL) 15beta1 |
| 13 | 256 | 128 | /u01/pg15/pgdata/base/5/58048 | psql (PostgreSQL) 15beta1 |
| 14 | 512 | 256 | /u01/pg15/pgdata/base/5/58048 | psql (PostgreSQL) 15beta1 |
| 15 | 1024 | 512 | /u01/pg15/pgdata/base/5/58048 | psql (PostgreSQL) 15beta1 |
| 16 | 2048 | 1024 | /u01/pg15/pgdata/base/5/58048 | psql (PostgreSQL) 15beta1 |
| 17 | 4096 | 2048 | /u01/pg15/pgdata/base/5/58048 | psql (PostgreSQL) 15beta1 |
| 18 | 8192 | 4096 | /u01/pg15/pgdata/base/5/58048 | psql (PostgreSQL) 15beta1 |
| 19 | 16384 | 8192 | /u01/pg15/pgdata/base/5/58048 | psql (PostgreSQL) 15beta1 |
| 20 | 32768 | 16384 | /u01/pg15/pgdata/base/5/58048 | psql (PostgreSQL) 15beta1 |
| 21 | 65536 | 32768 | /u01/pg15/pgdata/base/5/58048 | psql (PostgreSQL) 15beta1 |
| 22 | 131072 | 65536 | /u01/pg15/pgdata/base/5/58048 | psql (PostgreSQL) 15beta1 |
小結:
- pg中的page擴展規則為 pages = pages < 8 ? pages++ : 2*pages ??? --不正確
- Oracle工程師看到這里,會覺得比較熟悉,原來pa和Oracle比較類似,通過增加空pages從而提高系統并發性。–和預期結果一樣,不一定正確
5、page擴展規律測試-ls判斷文件大小
5.1、測試on pg9
### 執行腳本
[postgres@enmo ~]$ sh pg_page_extend_test.sh -b 999999 -ls
### 測試結果
| inc_number | file_size(8K) | add_size(8K) | file_name | pg_version |
| ---------- | ------------- | ------------ | -------------------------------- | ------------------------ |
| 1 | 1 | 1 | /u01/pg9/pgdata/base/13323/16481 | psql (PostgreSQL) 9.6.24 |
| 2 | 2 | 1 | /u01/pg9/pgdata/base/13323/16481 | psql (PostgreSQL) 9.6.24 |
| 3 | 3 | 1 | /u01/pg9/pgdata/base/13323/16481 | psql (PostgreSQL) 9.6.24 |
| 4 | 4 | 1 | /u01/pg9/pgdata/base/13323/16481 | psql (PostgreSQL) 9.6.24 |
| 5 | 5 | 1 | /u01/pg9/pgdata/base/13323/16481 | psql (PostgreSQL) 9.6.24 |
| 6 | 6 | 1 | /u01/pg9/pgdata/base/13323/16481 | psql (PostgreSQL) 9.6.24 |
| 7 | 7 | 1 | /u01/pg9/pgdata/base/13323/16481 | psql (PostgreSQL) 9.6.24 |
| 8 | 8 | 1 | /u01/pg9/pgdata/base/13323/16481 | psql (PostgreSQL) 9.6.24 |
...
| 27 | 27 | 1 | /u01/pg9/pgdata/base/13323/16481 | psql (PostgreSQL) 9.6.24 |
| 45 | 54098 | 1 | /u01/pg9/pgdata/base/13323/16481 | psql (PostgreSQL) 9.6.24 |
...
| 75 | 108182 | 1 | /u01/pg9/pgdata/base/13323/16481 | psql (PostgreSQL) 9.6.24 |
5.2、測試on pg15
### 執行腳本
[postgres@enmo ~]$ sh pg_page_extend_test.sh -b 999999 -ls
### 測試結果
| inc_number | file_size(8K) | add_size(8K) | file_name | pg_version |
| ---------- | ------------- | ------------ | ----------------------------- | ------------------------- |
| 1 | 1 | 1 | /u01/pg15/pgdata/base/5/41580 | psql (PostgreSQL) 15beta1 |
| 2 | 2 | 1 | /u01/pg15/pgdata/base/5/41580 | psql (PostgreSQL) 15beta1 |
| 3 | 3 | 1 | /u01/pg15/pgdata/base/5/41580 | psql (PostgreSQL) 15beta1 |
| 4 | 4 | 1 | /u01/pg15/pgdata/base/5/41580 | psql (PostgreSQL) 15beta1 |
| 5 | 5 | 1 | /u01/pg15/pgdata/base/5/41580 | psql (PostgreSQL) 15beta1 |
| 6 | 6 | 1 | /u01/pg15/pgdata/base/5/41580 | psql (PostgreSQL) 15beta1 |
| 7 | 7 | 1 | /u01/pg15/pgdata/base/5/41580 | psql (PostgreSQL) 15beta1 |
| 8 | 8 | 1 | /u01/pg15/pgdata/base/5/41580 | psql (PostgreSQL) 15beta1 |
....
| 93 | 54146 | 1 | /u01/pg15/pgdata/base/5/41580 | psql (PostgreSQL) 15beta1 |
....
| 137 | 108232 | 1 | /u01/pg15/pgdata/base/5/41580 | psql (PostgreSQL) 15beta1 |
5.3、測試第9個page產生-on pg15
[postgres@enmo ~]$ sh pg_page_extend_test.sh -b 9 -ls will drop and create table pg_page_extend_test_20220622,pls confirm?(yes/no):yes | inc_number | file_size(8K) | add_size(8K) | file_name | pg_version | | ---------- | ------------- | ------------ | ----------------------------- | ------------------------- | | 1 | 1 | 1 | /u01/pg15/pgdata/base/5/41513 | psql (PostgreSQL) 15beta1 | | 2 | 2 | 1 | /u01/pg15/pgdata/base/5/41513 | psql (PostgreSQL) 15beta1 | | 3 | 3 | 1 | /u01/pg15/pgdata/base/5/41513 | psql (PostgreSQL) 15beta1 | | 4 | 4 | 1 | /u01/pg15/pgdata/base/5/41513 | psql (PostgreSQL) 15beta1 | | 5 | 5 | 1 | /u01/pg15/pgdata/base/5/41513 | psql (PostgreSQL) 15beta1 | | 6 | 6 | 1 | /u01/pg15/pgdata/base/5/41513 | psql (PostgreSQL) 15beta1 | | 7 | 7 | 1 | /u01/pg15/pgdata/base/5/41513 | psql (PostgreSQL) 15beta1 | | 8 | 8 | 1 | /u01/pg15/pgdata/base/5/41513 | psql (PostgreSQL) 15beta1 | | 9 | 9 | 1 | /u01/pg15/pgdata/base/5/41513 | psql (PostgreSQL) 15beta1 | t_insert_count: 1481 128K /u01/pg15/pgdata/base/5/41513 -rw------- 1 postgres dba 72K Jun 26 19:10 /u01/pg15/pgdata/base/5/41513 [postgres@enmo ~]$
5.4、du/ls檢查文件大小–結果不一致

小結:
- 當使用ls檢查文件大小時,pg中的page擴展規則為 pages++
- 分別使用ls/du獲取文件大小,得到的page擴展規則不一致,哪個正確?
- 當產生第9個pages時,du/ls 獲取的文件大小不一致?
6、為什么du/ls 結果不一樣
6.1、sparse file解釋
稀疏文檔又稱稀疏文件(英語:sparse file),是一種計算機文件,它能嘗試在文件內容大多為空時更有效率地使用文件系統的空間。它的原理是以簡短的信息(元數據)表示空數據塊,而不是在在磁盤上占用實際空間來存儲空數據塊。只有真實(非空)的數據塊會按原樣寫入磁盤。 https://baike.baidu.com/item/%E7%A8%80%E7%96%8F%E6%96%87%E6%A1%A3/23316000?fromtitle=%E7%A8%80%E7%96%8F%E6%96%87%E4%BB%B6&fromid=1600319&fr=aladdin
6.2、sparse file測試
[root@enmo ~]# truncate -s 512M foo [root@enmo ~]# cat foo >bar [root@enmo ~]# ls -lh foo bar -rw-r--r-- 1 root root 512M Jun 25 05:03 bar -rw-r--r-- 1 root root 512M Jun 25 05:03 foo [root@enmo ~]# du foo bar 0 foo 524288 bar [root@enmo ~]# du -b foo bar 536870912 foo 536870912 bar [root@enmo ~]# We have two files both containing 512MB of zeros. The first one is stored sparse and does not use any disk space, while the second stores each byte explicitly on disk. -- Same file, but completely different disk usage.
6.3、驗證是否為sparse file
[postgres@enmo ~]$ ls -lh /u01/pg15/pgdata/base/5/41516 -rw------- 1 postgres dba 72K Jun 26 19:20 /u01/pg15/pgdata/base/5/41516 [postgres@enmo ~]$ du -sh /u01/pg15/pgdata/base/5/41516 128K /u01/pg15/pgdata/base/5/41516 [postgres@enmo ~]$ du -b /u01/pg15/pgdata/base/5/41516 73728 /u01/pg15/pgdata/base/5/41516 [postgres@enmo ~]$
7、什么原因造成的sparse file
7.1、檢查文件系統類別
[postgres@enmo ~]$ df -hT Filesystem Type Size Used Avail Use% Mounted on /dev/mapper/rhel_pg-root xfs 36G 21G 16G 58% /
7.2、xfs speculative preallocation 解釋
https://xfs.org/index.php/XFS_FAQ#Q:_Why_do_files_on_XFS_use_more_data_blocks_than_expected.3F

7.3、xfs speculative preallocation規則解釋
https://www.kernel.org/doc/Documentation/filesystems/xfs.txt

7.4、使用speculative_prealloc_lifetime驗證du/ls結果
### 檢查默認值
[postgres@enmo ~]$ cat /proc/sys/fs/xfs/speculative_prealloc_lifetime
300
[postgres@enmo ~]$
### 修改默認參數
[root@enmo ~]# echo 'fs.xfs.speculative_prealloc_lifetime=1' >> /etc/sysctl.conf
[root@enmo ~]# sysctl -p
[root@enmo ~]# cat /proc/sys/fs/xfs/speculative_prealloc_lifetime
1
[root@enmo ~]#
### 重啟pg數據庫
[postgres@enmo ~]$ pg_ctl stop
waiting for server to shut down.... done
server stopped
[postgres@enmo ~]$ pg_ctl start
waiting for server to start....2022-06-26 20:06:18.566 CST [35528] LOG: redirecting log output to logging collector process
2022-06-26 20:06:18.566 CST [35528] HINT: Future log output will appear in directory "log".
done
server started
[postgres@enmo ~]$
### 驗證測試結果
[postgres@enmo ~]$ sh pg_page_extend_test.sh -b 9 -ls
will drop and create table pg_page_extend_test_20220622,pls confirm?(yes/no):yes
|inc_number|file_size(8K)|add_size(8K)|file_name|pg_version|
|----|----|----|----|----|
|1|1|1|/u01/pg15/pgdata/base/5/41534|psql (PostgreSQL) 15beta1|
|2|2|1|/u01/pg15/pgdata/base/5/41534|psql (PostgreSQL) 15beta1|
|3|3|1|/u01/pg15/pgdata/base/5/41534|psql (PostgreSQL) 15beta1|
|4|4|1|/u01/pg15/pgdata/base/5/41534|psql (PostgreSQL) 15beta1|
|5|5|1|/u01/pg15/pgdata/base/5/41534|psql (PostgreSQL) 15beta1|
|6|6|1|/u01/pg15/pgdata/base/5/41534|psql (PostgreSQL) 15beta1|
|7|7|1|/u01/pg15/pgdata/base/5/41534|psql (PostgreSQL) 15beta1|
|8|8|1|/u01/pg15/pgdata/base/5/41534|psql (PostgreSQL) 15beta1|
|9|9|1|/u01/pg15/pgdata/base/5/41534|psql (PostgreSQL) 15beta1|
t_insert_count: 1481
72K /u01/pg15/pgdata/base/5/41534
-rw------- 1 postgres dba 72K Jun 26 20:06 /u01/pg15/pgdata/base/5/41534
[postgres@enmo ~]$
[postgres@enmo ~]$
[postgres@enmo ~]$ ls -lh /u01/pg15/pgdata/base/5/41534
-rw------- 1 postgres dba 72K Jun 26 20:06 /u01/pg15/pgdata/base/5/41534
[postgres@enmo ~]$ du -sh /u01/pg15/pgdata/base/5/41534
72K /u01/pg15/pgdata/base/5/41534
[postgres@enmo ~]$
小結:
- du/ls結果不一致的問題為xfs文件系統 speculative preallocation特性造成sparse file
- 文件真實使用情況以ls查詢文件大小為準
8、systemtap跟蹤page擴展程序
? 在debug pg源碼時,我們需要設置斷點 ,但斷點設置在哪里這是一個問題,本文使用systemtap跟蹤程序的方式梳理程序運行邏輯,判斷調試程序斷點位置。
8.1、安裝systemtap
### systemtap安裝步驟
yum -y install systemtap systemtap-runtime kernel-devel
### 得到Glibc debug版本信息:
rpm -qa | grep glibc
rpm -qi glibc
### 下載內核調試包和glibc調試包
cd /soft/
wget http://debuginfo.centos.org/7/x86_64/kernel-debuginfo-3.10.0-862.el7.x86_64.rpm
wget http://debuginfo.centos.org/7/x86_64/kernel-debuginfo-common-x86_64-3.10.0-862.el7.x86_64.rpm
wget http://debuginfo.centos.org/7/x86_64/glibc-debuginfo-2.17-157.el7_3.1.x86_64.rpm
wget http://debuginfo.centos.org/7/x86_64/glibc-debuginfo-common-2.17-157.el7_3.1.x86_64.rpm
### 安裝
rpm -ivh *.prm
8.2、在什么時間跟蹤程序?
通過上文分析,產生第9個blocks時,需要插入數據 1481個Tuples,我們測試插入1480行數據,然后跟蹤第1481行數據插入過程所執行的函數。
8.3、sess_1模擬插入 1480行數據
### 模擬插入 1480行數據
|inc_number|file_size(8K)|add_size(8K)|file_name|pg_version|
|----|----|----|----|----|
|1|1|1|/u01/pg15/pgdata/base/5/41589|psql (PostgreSQL) 15beta1|
|2|2|1|/u01/pg15/pgdata/base/5/41589|psql (PostgreSQL) 15beta1|
|3|3|1|/u01/pg15/pgdata/base/5/41589|psql (PostgreSQL) 15beta1|
|4|4|1|/u01/pg15/pgdata/base/5/41589|psql (PostgreSQL) 15beta1|
|5|5|1|/u01/pg15/pgdata/base/5/41589|psql (PostgreSQL) 15beta1|
|6|6|1|/u01/pg15/pgdata/base/5/41589|psql (PostgreSQL) 15beta1|
|7|7|1|/u01/pg15/pgdata/base/5/41589|psql (PostgreSQL) 15beta1|
|8|8|1|/u01/pg15/pgdata/base/5/41589|psql (PostgreSQL) 15beta1|
t_insert_count: 1480
64K /u01/pg15/pgdata/base/5/41589
-rw------- 1 postgres dba 64K Jun 26 22:21 /u01/pg15/pgdata/base/5/41589
insert into pg_page_extend_test_20220622 values(1) ;
select pg_backend_pid();
[postgres@enmo ~]$ psql
psql (15beta1)
Type "help" for help.
postgres=# select pg_backend_pid();
pg_backend_pid
----------------
56776
(1 row)
postgres=#
8.4、sess_2跟蹤pid of sess_1
[root@enmo ~]# cat pg_func.stp probe process("/u01/pg15/pgsql/bin/postgres").function("*") { printf("%d\t%s: %s\n", pid(), execname(), ppfunc()); } [root@enmo ~]# stap pg_func.stp > stap.out
8.5、sess_3執行插入sql
postgres=# insert into pg_page_extend_test_20220622 values(1) ; INSERT 0 1 postgres=#
8.6、檢查跟蹤結果
[root@enmo ~]# egrep -i 'extend' stap.out |sort|uniq -c 1 66045 postgres: ExtendCLOG 1 66045 postgres: ExtendCommitTs 1 66045 postgres: ExtendSUBTRANS 31 66045 postgres: LockAcquireExtended 1 66045 postgres: PageAddItemExtended 1 66045 postgres: RangeVarGetRelidExtended 41 66045 postgres: ReadBufferExtended 1 66045 postgres: mdextend --- 重點關注函數 1 66045 postgres: relation_openrv_extended 1 66045 postgres: smgrextend --- 重點關注函數 1 66045 postgres: table_openrv_extended [root@enmo ~]#
9、源碼分析——page擴展規律總結
9.1、call stack
### call stack
FileWrite fd.c:2215 <--after this step,new page created
mdextend md.c:449
smgrextend smgr.c:496
ReadBuffer_common bufmgr.c:986
ReadBufferExtended bufmgr.c:770
ReadBufferBI hio.c:96
RelationGetBufferForTuple hio.c:624
heap_insert heapam.c:2051
heapam_tuple_insert heapam_handler.c:252
table_tuple_insert tableam.h:1376
ExecInsert nodeModifyTable.c:1058
ExecModifyTable nodeModifyTable.c:3700
ExecProcNodeFirst execProcnode.c:463
ExecProcNode executor.h:259
ExecutePlan execMain.c:1636
standard_ExecutorRun execMain.c:363
ExecutorRun execMain.c:307
ProcessQuery pquery.c:160
PortalRunMulti pquery.c:1277
PortalRun pquery.c:791
exec_simple_query postgres.c:1250
PostgresMain postgres.c:4544
BackendRun postmaster.c:4504
BackendStartup postmaster.c:4232
ServerLoop postmaster.c:1806
PostmasterMain postmaster.c:1478
main main.c:202
9.2、核心函數分析

注:
源碼位置: ./src/backend/access/heap/hio.c
以上程序流程圖為簡化版
10、測試驗證
單進程測試時page擴展規律為pages++,以源碼分析結論為指導,這次我們測試一次擴展512個pages,
10.1、session1: 斷點位置 hio.c: 624
[postgres@enmo ~]$ sh pg_page_extend_test.sh -t 1480 -ls -cr may drop and create table pg_page_extend_test_20220622,pls confirm?(yes/no):yes |inc_number|file_size(8K)|add_size(8K)|file_name|pg_version| |----|----|----|----|----| |1|1|1|/u01/pg15/pgdata/base/5/58027|psql (PostgreSQL) 15beta1| |2|2|1|/u01/pg15/pgdata/base/5/58027|psql (PostgreSQL) 15beta1| |3|3|1|/u01/pg15/pgdata/base/5/58027|psql (PostgreSQL) 15beta1| |4|4|1|/u01/pg15/pgdata/base/5/58027|psql (PostgreSQL) 15beta1| |5|5|1|/u01/pg15/pgdata/base/5/58027|psql (PostgreSQL) 15beta1| |6|6|1|/u01/pg15/pgdata/base/5/58027|psql (PostgreSQL) 15beta1| |7|7|1|/u01/pg15/pgdata/base/5/58027|psql (PostgreSQL) 15beta1| |8|8|1|/u01/pg15/pgdata/base/5/58027|psql (PostgreSQL) 15beta1| t_insert_count: 1480 64K /u01/pg15/pgdata/base/5/58027 -rw------- 1 postgres dba 64K Jun 28 23:52 /u01/pg15/pgdata/base/5/58027 insert into pg_page_extend_test_20220622 values(1) ; select pg_backend_pid(); [postgres@enmo ~]$ psql psql (15beta1) Type "help" for help. postgres=# select pg_backend_pid(); pg_backend_pid ---------------- 34494 (1 row) postgres=# insert into pg_page_extend_test_20220622 values(1) ; <--debug
10.2、其它進程:并發26個進程執行插入操作
for p_num in $(seq 1 26); do psql -q -c "insert into pg_page_extend_test_20220622 values(1)" & done [postgres@enmo ~]$ ps -fu postgres|egrep -i 'INSERT waiting'|grep -v grep |wc -l 26 [postgres@enmo ~]$
10.3、檢查sess_1:
postgres=# insert into pg_page_extend_test_20220622 values(1) ; INSERT 0 1 postgres=# select count(1) from pg_page_extend_test_20220622; count ------- 1507 (1 row) postgres=# \q [postgres@enmo ~]$ ls -lk /u01/pg15/pgdata/base/5/58027 -rw------- 1 postgres dba 4276224 Jun 29 01:26 /u01/pg15/pgdata/base/5/58027 [postgres@enmo ~]$ expr 4276224 / 8192 522 <-- 8 + 512 + 2,與預測結果一致 [postgres@enmo ~]$
11、思考總結
### 規則總結
pg數據庫當freespace不足時,進程默認在文件末尾擴展一個page,擴展過程中如有阻塞,隨阻塞數增加擴展pages數增加,最大一次擴展512+2個pages。
### 優化建議
pages擴展多少是在性能與存儲之間平衡,建議可綜合參考Oracle的擴展規則,在大并發量insert場景可有效減少系統阻塞。
12、參考資料
1. WAITEVENT latch cache buffers chains Reference Note (Doc ID 2098064.1).pdf 2. WAITEVENT buffer busy waits Reference Note (Doc ID 34405.1).pdf 3. 《Oracle內核技術揭密》 4. https://xfs.org/index.php/XFS_FAQ#Q:_Why_do_files_on_XFS_use_more_data_blocks_than_expected.3F 5. https://www.kernel.org/doc/Documentation/filesystems/xfs.txt
最后修改時間:2023-05-23 08:41:28
「喜歡這篇文章,您的關注和贊賞是給作者最好的鼓勵」
關注作者
【版權聲明】本文為墨天輪用戶原創內容,轉載時必須標注文章的來源(墨天輪),文章鏈接,文章作者等基本信息,否則作者和墨天輪有權追究責任。如果您發現墨天輪中有涉嫌抄襲或者侵權的內容,歡迎發送郵件至:contact@modb.pro進行舉報,并提供相關證據,一經查實,墨天輪將立刻刪除相關內容。




