1. 程式人生 > >postgresql 檔案大小分割引數 segment_size

postgresql 檔案大小分割引數 segment_size

os: centos 7.4
db: postgresql 9.6

segment_size 控制一個檔案段中可以儲存的塊(頁)的數量。由編譯伺服器時的 segsize 決定。一個段檔案的最大尺寸(以位元組計)等於 segment_size * block_size,默熱時1G。

該引數確實能夠避免檔案過大造成的系統損耗。

檢視 segment_size 引數

如果通過 yum,apt 方式安裝的,那基本可以肯定 segment_size 的大小為1G=131072 * 8192

postgres=# select name,setting from pg_settings where category = 'Preset Options' order by name;
         name          | setting 
-----------------------+---------
 block_size            | 8192
 data_checksums        | off
 debug_assertions      | off
 integer_datetimes     | on
 max_function_args     | 100
 max_identifier_length | 63
 max_index_keys        | 32
 segment_size          | 131072
 server_version        | 9.6.11
 server_version_num    | 90611
 wal_block_size        | 8192
 wal_segment_size      | 2048
(12 rows)

postgres=# 
postgres=# select (131072 * 8192)/1024/1024/1024;
 ?column? 
----------
        1
(1 row)

如果通過編譯方式安裝,可以在 ./configure 時新增 --with-segsize=n 來控制 toast 的切割大小,比如 ./configure --with-segsize=10 表示檔案大小在超過10G時會被切割成多個檔案。
調整 --with-segsize 為更大值的好處是在表變得更大時,對應的檔案數比較少。

實踐

postgres=# create table tmp_t0(c0 varchar(100),c1 varchar(100),c2 varchar(100),c3 varchar(100));
CREATE TABLE
postgres=# 
postgres=# insert into tmp_t0 select id::varchar,md5(id::varchar),md5(md5(id::varchar)),md5(md5(md5(id::varchar))) from generate_series(1,10000000) as id;
INSERT 0 10000000
postgres=#
postgres=# \d+ 
                     List of relations
 Schema |  Name  | Type  |  Owner   |  Size   | Description 
--------+--------+-------+----------+---------+-------------
 public | tmp_t0 | table | postgres | 1347 MB | 
(1 row)

postgres=# insert into tmp_t0 select id::varchar,md5(id::varchar),md5(md5(id::varchar)),md5(md5(md5(id::varchar))) from generate_series(1,10000000) as id;
INSERT 0 10000000

postgres=# \d+
                     List of relations
 Schema |  Name  | Type  |  Owner   |  Size   | Description 
--------+--------+-------+----------+---------+-------------
 public | tmp_t0 | table | postgres | 2695 MB | 
(1 row)

插入2000w條資料後檢視 pg_class

postgres=# select pg_relation_filenode(relname::varchar), pg_relation_filepath(relname::varchar),oid,pc.relname,pc.relfilenode,pc.relpages,pc.reltuples,pc.reltoastrelid from pg_class pc where 1=1 and pc.relname='tmp_t0';

 pg_relation_filenode | pg_relation_filepath |  oid  | relname | relfilenode | relpages |  reltuples  | reltoastrelid 
----------------------+----------------------+-------+---------+-------------+----------+-------------+---------------
                25171 | base/13323/25171     | 25171 | tmp_t0  |       25171 |   172406 | 1.00001e+07 |             0
(1 row)

檢視磁碟檔案

$ pwd
/var/lib/pgsql/9.6/data/base/13323

$ ls -l |grep -i 25171
-rw------- 1 postgres postgres 1073741824 Nov 24 23:14 25171
-rw------- 1 postgres postgres 1073741824 Nov 24 23:23 25171.1
-rw------- 1 postgres postgres  677208064 Nov 24 23:27 25171.2
-rw------- 1 postgres postgres     712704 Nov 24 23:27 25171_fsm

確實發生了檔案切割,符合預期。

參考:
http://postgres.cn/docs/9.6/runtime-config-preset.html