版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/ctypyb2002/article/details/84561192
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
确实发生了文件切割,符合预期。