02-PG存储——表空间和数据文件

1.Tablespace

表空间像是文件系统上的一个虚拟目录,允许DBA在文件系统上指定不同数据库对象的文件位置,表空间创建后,就可以在创建数据库对象时引用。

使用表空间有如下两个好处,首先,如果初始化时指定的数据目录所在的磁盘分区或卷被用光,需要扩充空间,就可以指定新的表空间来存放数据;其次,可以根据数据对象对磁盘IO的要求不同来指定不同表空间,如对应归档数据,存放在读写慢的磁盘,对应频繁访问的核心数据,存放在高性能磁盘。

2.表空间测试

#创建目录
[root@node1 bin]# mkdir /pg_tbs
[root@node1 bin]# chown pg14:pg14 /pg_tbs/
#创建表空间
postgres=# create tablespace tbs_test location '/pg_tbs';
CREATE TABLESPACE
#创建后后再指定的目录下生成一个带有版本号的目录
[pg14@node1 pg_tbs]$ ll
total 0
drwx------ 2 pg14 pg14 6 Aug 19 07:54 PG_14_202107181

#数据库内查看表空间
postgres=# \db
       List of tablespaces
    Name    |  Owner   | Location 
------------+----------+----------
 pg_default | postgres | 
 pg_global  | postgres | 
 tbs_test   | postgres | /pg_tbs
 
 #在表空间上创建一个数据库
 postgres=# create user lys superuser password 'lys';
CREATE ROLE
postgres=# create database test  with owner=lys tablespace tbs_test;
CREATE DATABASE
[pg14@node1 pg_tbs]$ cd /pg_tbs/PG_14_202107181/
[pg14@node1 PG_14_202107181]$ ll
total 12
drwx------ 2 pg14 pg14 8192 Aug 19 08:00 16387

16387 即为数据库test的oid
postgres=# select oid,datname from pg_database where datname='test';
  oid  | datname 
-------+---------
 16387 | test
 
 #在test数据库下创建一个表t1
postgres=# \c test lys
You are now connected to database "test" as user "lys".
test=# create table t1 (id int,name varchar(10));
CREATE TABLE


[pg14@node1 16387]$ pwd
/pg_tbs/PG_14_202107181/16387
[pg14@node1 16387]$ ll 16388*
-rw------- 1 pg14 pg14 0 Aug 19 08:03 16388
未插入数据前,数据文件大小为0

#向表内插入2条数据
test=# insert into t1 values(1,'aaa');
INSERT 0 1
test=# insert into t1 values(2,'bbb');
INSERT 0 1
[pg14@node1 16387]$ ll 16388*
-rw------- 1 pg14 pg14 8192 Aug 19 08:12 16388

当一个表空间被创建时,会在$PGDATA/pg_tblspc目录下创建一个名为表空间oid的符号链接,执行该表空间的目录位置

[root@node1 pgdata02]# cd pg_tblspc/
[root@node1 pg_tblspc]# ls
16385
[root@node1 pg_tblspc]# ll
total 0
lrwxrwxrwx 1 pg14 pg14 7 Aug 19 07:54 16385 -> /pg_tbs

在PostgreSQL中可以使用pg_relation_filepath函数查看对象文件所在位置

test=# select pg_relation_filepath('t1');
            pg_relation_filepath             
---------------------------------------------
 pg_tblspc/16385/PG_14_202107181/16387/16388

如果我们在tbs_test下创建另一个新表,但新表所属的数据库创建在默认表空间pg_default,那么pg会首先在表空间目录下创建名称与所属数据相同oid的子目录,然后将新表文件放在刚创建的目录下

test=# \c postgres postgres
You are now connected to database "postgres" as user "postgres".
postgres=# create table t2(id int,name varchar(10)) tablespace tbs_test;
CREATE TABLE
postgres=# select pg_relation_filepath('t2');

            pg_relation_filepath             
---------------------------------------------

 pg_tblspc/16385/PG_14_202107181/13892/16391
(1 row)

#13892为postgres数据库的oid,16391为t2表oid
postgres=# select oid,datname from pg_database where datname='postgres';
  oid  | datname  
-------+----------
 13892 | postgres
[pg14@node1 16387]$ cd /pgdata02/pg_tblspc/16385/PG_14_202107181/13892/
[pg14@node1 13892]$ ll
total 0
-rw------- 1 pg14 pg14 0 Aug 19 08:47 16391

3.文件和分支

在PostgreSQL中,一个表一般由一个或多个数据文件组成,这些数据文件又由后缀被划分为多个分支(fork)。如空闲空间位图,后缀为_fsm;可视位图,后缀为 _vm;

还有一个不常用的分支为init分支,后缀为_init,对于在建表时指定unlogged参数的表和对应的索引,这些表的所以操作都不会写入wal日志,这样存储可以提高效率,但是在发生故障时,您将无法恢复一致的数据。因此,Postgre在恢复过程中删除所有这些对象的分支,并用初始化分支覆盖主分支,从而创建一个虚拟文件。

最开始时,一个表创建时,只会有一个名为oid的主分支,随着表数据越来越多,当主分支超过1G时(编译时由–with-segsize 指定),主分支会另创建一个文件,名为oid.1,此文件再超过1G时,创建oid.2。随着表数据增多,也会创建_fsm和vm分支,增长规则也会跟主分支一样。

#创建测试表
create table if not exists t_test(
	id serial ,
	username varchar(255),
	password varchar(255),
	create_time date,
	dr char(1)
);
#插入数据100万数据
insert into t_test select generate_series(1,100*10000),'username'||round(random()*1000000),'password'||round(random()*1000000),now(),0;
test=# select pg_relation_filepath('t_test');
            pg_relation_filepath             
---------------------------------------------
 pg_tblspc/16385/PG_14_202107181/16387/16404

#查看分支
[pg14@node1 pgdata02]$ ll pg_tblspc/16385/PG_14_202107181/16387/16404*
-rw------- 1 pg14 pg14 76423168 Aug 19 09:48 pg_tblspc/16385/PG_14_202107181/16387/16404
-rw------- 1 pg14 pg14    40960 Aug 19 09:48 pg_tblspc/16385/PG_14_202107181/16387/16404_fsm
多了空闲位图分支
#修改一条数据
test=# update t_test set dr='1' where id=round(random()*1000000);
UPDATE 1
[pg14@node1 pgdata02]$ ll pg_tblspc/16385/PG_14_202107181/16387/16404*
-rw------- 1 pg14 pg14 76423168 Aug 19 09:51 pg_tblspc/16385/PG_14_202107181/16387/16404
-rw------- 1 pg14 pg14    40960 Aug 19 09:48 pg_tblspc/16385/PG_14_202107181/16387/16404_fsm
-rw------- 1 pg14 pg14     8192 Aug 19 09:49 pg_tblspc/16385/PG_14_202107181/16387/16404_vm
多了可见位图分区

#创建unlogged表
test=# create unlogged table t_unlog(id int,name varchar(10));
CREATE TABLE
test=# insert into t_unlog values(1,'aaa');
INSERT 0 1
test=# select pg_relation_filepath('t_unlog');
            pg_relation_filepath             
---------------------------------------------
 pg_tblspc/16385/PG_14_202107181/16387/16410
#查看分支
[pg14@node1 pgdata02]$ ll  pg_tblspc/16385/PG_14_202107181/16387/16410*
-rw------- 1 pg14 pg14 8192 Aug 19 09:55 pg_tblspc/16385/PG_14_202107181/16387/16410
-rw------- 1 pg14 pg14    0 Aug 19 09:54 pg_tblspc/16385/PG_14_202107181/16387/16410_init
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南風_入弦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值