PG獲取檔案大小的幾種方式

yzs87發表於2020-12-14

PG 獲取檔案大小的方式

1 、透過元命令獲取表檔案大小

透過\dt+可以得到該表大小。該元命令會轉換成SQL語句去執行,實際上是透過pg_table_size函式進行獲取。該函式呼叫calulate_table_size(rel)其中rel為表的描述結構Relation。透過這個方式計算表大小包括fsm、vm檔案大小,如果有toast索引,還包括toast表大小。那麼具體獲取檔案大小的方式是什麼呢?看calculate_relation_size函式:最終透過stat函式來獲取,這個得到的是檔案大小,而不是佔用磁碟大小。同樣,對於toast索引也是透過這種方式計算得到。

2 、內部計算表有多少頁

透過RelationGetNumberOfBlocks只計算表主檔案的多少頁,呼叫函式RelationGetNumberOfBlocksInFork進行計算。該函式對於序列、索引或者分割槽索引,直接透過smgrnblocks->mdnblocks獲得,對於表、toast和物化檢視,呼叫函式table_relation_size計算出檔案大小然後除以一頁大小得到多少頁。table_relation_size呼叫heapam_relation_size->smgrnblocks,和上一個方法不同之處在於是否需要包括fsm、vm在內。

3 、內部估算表大小

透過estimate_rel_size->table_relation_estimate_size->heapam_estimate_rel_size估算表有多少頁、多少記錄:

curpages = RelationGetNumberOfBlocks(rel);//真實多少頁
//pg_class中統計的多少頁和多少記錄
relpages = (BlockNumber) rel->rd_rel->relpages;
reltuples = (double) rel->rd_rel->reltuples;
//真實頁數少於10,真實記錄少於0,且無子表,那麼估算頁數為10
if (curpages < 10 && reltuples < 0 && !rel->rd_rel->relhassubclass)
     curpages = 10;
if (curpages == 0){//當前0頁,那麼0個記錄
     *tuples = 0;
}
if (reltuples >= 0 && relpages > 0)
    density = reltuples / (double) relpages;//統計平均每頁多少記錄
else{
    tuple_width = get_rel_data_width(rel, attr_widths);
    tuple_width += overhead_bytes_per_tuple;
    density = usable_bytes_per_page / tuple_width;
}
*tuples = rint(density * (double) curpages);


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31493717/viewspace-2742200/,如需轉載,請註明出處,否則將追究法律責任。

相關文章