系统明天上线,PG表空间还不规划好疯狂给同事埋雷

makefile 复制代码
作者:IT邦德
中国DBA联盟(ACDU)成员,10余年DBA工作经验
擅长主流数据Oracle、MySQL、PG、openGauss运维
备份恢复,安装迁移,性能优化、故障应急处理等

可提供技术业务:
1.DB故障处理/疑难杂症远程支援
2.Mysql/PG/Oracle/openGauss
数据库部署及数仓搭建
•••
微信:jem_db
QQ交流群:587159446
公众号:IT邦德
•••

@TOC

前言

PG表空间可以有效的解决集群分区不足或者是卷空间不足的问题,最终提高PG数据库性能,本文做了详细的说明

1.PG表空间

1.1 表空间概述

PostgreSQL支持表空间,相比较其他RDBMS不同。
PostgreSQL中的表空间是一个目录,
其中包含基本目录之外的一些数据。
是一个用于管理数据库对象(如表、索引等)物理存储位置的概念
简而言之,表空间是告诉PG服务器将数据库对象的物理文件放在哪里

1.2 表空间作用

1.磁盘布局控制:通过创建不同的表空间来优化磁盘布局,
以适应不同的存储需求和性能要求。
2.性能优化:表空间可以根据数据库对象的使用模式来优化性能。
3.多对多的关系:在PostgreSQL集群中,一个表空间可以被多个数据库使用,
而一个数据库也可以使用多个表空间。

总之:能合理利用磁盘性能和空间,
制定最优的物理存储方式来管理数据库表和索引

1.3 表空间分类

bash 复制代码
1.默认表空间:pg_default ,
是用户表、用户表index、和临时表、临时表index、内部临时表的默认空间。
对应文件系统目录$PADATA/base/。

2.系统字典表表空间:pg_global,存放系统字典表,
如pg_database、pg_authid、pg_tablespace等表以及它们的索引。
对应文件系统目录$PADATA/global/。

其中pg_default和pg_global是在PG集群initdb之后默认创建的
bash 复制代码
3.自定义表空间:用户创建的表空间。
对应文件系统目录$PGDATA/pg_tblspc/, 
当手动创建表空间时,该目录下会自动生成一个软链接,指向表空间设定的路径。

其中test_tbs是用户创建的表空间。
查看pg_tblspc目录下,发现有一个软链接16385
注:16471是这个表空间test_tbs的OID
postgres=# select oid,* from pg_tablespace;
指向表空间设定的路径,此处为/home/postgres/app_tbs

2.表空间使用授权

sql 复制代码
表空间的创建本身一般要求数据库超级用户完成
默认情况下,执行CREATE TABLESPACE语句的用户为该表空间的拥有者,
也可以使用OWNER选项指定拥有者。
对于普通用户,需要授予表空间上的对象创建权限才能使用该表空间
sql 复制代码
1.创建普通用户jeames
create user jeames login password '123456';
2.创建schema proadm
postgres=# create schema proadm;
3.为用户 jeames 授予表空间test_tbs上的使用权限:
postgres=# GRANT CREATE ON TABLESPACE test_tbs TO jeames;
--授权用户jeames使用schema:proadm
postgres=# grant all on schema proadm to jeames;
--修改用户jeames默认schema为proadm
postgres=# alter user jeames set search_path to proadm;
4.用户jeames登陆
postgres=# \c postgres jeames
You are now connected to database "postgres" as user "jeames".
4.用户jeames建表指定表空间
postgres=# CREATE TABLE test (id int) tablespace test_tbs;

5.查询表对应表空间
select schemaname,tablename,tablespace 
from pg_tables where schemaname='proadm';

3.表空间管理

3.1 新建表空间

sql 复制代码
--创建一个新目录,注意该目录需要属于"postgres"操作系统用户
[postgres@centos79 ~]$ mkdir -p /home/postgres/my_tbs
--登陆超级用户创建
postgres=# CREATE TABLESPACE mytbsp LOCATION '/home/postgres/my_tbs';
CREATE TABLESPACE
postgres=# \db
              List of tablespaces
    Name    |  Owner   |        Location        
------------+----------+------------------------
 mytbsp     | postgres | /home/postgres/my_tbs
 pg_default | postgres | 
 pg_global  | postgres | 
 test_tbs   | postgres | /home/postgres/app_tbs
(4 rows)

3.2 使用表空间

sql 复制代码
PostgreSQL 支持在
CREATE DATABASE、
CREATE TABLE、
CREATE INDEX以及ADD CONSTRAINT
语句中指定 tablespace_name 选项,
覆盖默认的表空间(pg_default)

--创建数据库指定
create database mydb tablespace mytbsp;

--创建表指定
CREATE TABLE newtab (
   id  integer NOT NULL,
   val text    NOT NULL
) TABLESPACE mytbsp;
注意:索引并不会继承与表的表空间。

--创建索引指定
CREATE INDEX newtab_idx ON newtab (val) TABLESPACE test_tbs;

--如果不想每次创建对象时手动指定表空间,
可以使用配置参数 default_tablespace:
alter user jeames SET default_tablespace to mytbsp;

3.3 修改表空间

sql 复制代码
只有表空间的拥有者或超级用户才能修改表空间的定义

1.表空间重命名
我们将表空间 app_tbs 重命名为 user_tbs:
ALTER TABLESPACE app_tbs RENAME TO user_tbs;

2.修改拥有者
接下来将表空间 user_tbs 的拥有者修改为 jeames
ALTER TABLESPACE user_tbs OWNER TO jeames;

3.更改任何对象的表空间
更改newtab的表空间为user_tbs。
alter table newtab set tablespace user_tbs;

4.表空间中的所有表(或索引)都移动到另外一个表空间
alter table all in tablespace mytbsp set tablespace user_tbs;

3.4 删除表空间

ini 复制代码
对于不再需要的表空间,可以使用DROP TABLESPACE语句进行删除:
DROP TABLESPACE user_tbs;

无法删除的表空间是因为数据库中存在使用该表空间创建的对象。
通过以下语句查询删除即可

SELECT ts.spcname,
cl.relname
FROM pg_class cl
JOIN pg_tablespace ts ON cl.reltablespace = ts.oid
WHERE ts.spcname = 'user_tbs';

4.常用数据字典

sql 复制代码
1.内置函数pg_relation_filepath
内置函数pg_relation_filepath非常有用,
因为此函数返回具有指定OID或名称的关系的文件路径名。

postgres=> SELECT pg_relation_filepath('test');
          pg_relation_filepath           
-----------------------------------------
 pg_tblspc/16471/PG_15_202209061/5/16474
 
cd $PGDATA
ls -la -h pg_tblspc/16471/PG_15_202209061/5/16474
-rw-------. 1 postgres postgres 0 Mar 18 22:11 pg_tblspc/16471/PG_15_202209061/5/16474
-rw-------. 1 postgres postgres 0 Mar 18 22:11 pg_tblspc/16471/PG_15_202209061/5/16474.1
 
注意:默认当表和索引的文件大小超过1GB时,
PostgreSQL会创建一个名为relfilenode.1的新文件并使用它。
如果新文件被填满,PostgreQL会创建另一个名的新文件,
如relfilenode.2,以此类推。


2.数据与表空间的对应关系
查看数据库存放在哪个表空间中
select a.datname,b.spcname from pg_database a , 
pg_tablespace b where a.dattablespace=b.oid;
  datname  |  spcname   
-----------+------------
 postgres  | pg_default
 template1 | pg_default
 template0 | pg_default
 mydb      | mytbsp
 
3.数据库的表空间
postgres=# select oid,* from pg_tablespace;
  oid  |  oid  |  spcname   | spcowner |                 spcacl                  | spcoptions 
-------+-------+------------+----------+-----------------------------------------+------------
  1663 |  1663 | pg_default |       10 |                                         | 
  1664 |  1664 | pg_global  |       10 |                                         | 
 16471 | 16471 | test_tbs   |       10 | {postgres=C/postgres,jeames=C/postgres} | 
 16477 | 16477 | mytbsp     |       10 | {postgres=C/postgres,jeames=C/postgres} | 
(4 rows)

5.注意事项

5.1 流复制场景

流复制场景下表空间的使用稍微复杂点,
因为新表空间的路径没有同步到备用服务器上。
备用服务器上会期望在与主服务器相同的位置上有一个现有目录,
并在该位置上创建一个表空间。

5.2 表空间备份

ini 复制代码
要将数据从表空间备份到不同的位置,
必须使用选项--tablespace-mapping=olddir=newdir。
对于多个表空间,可以多次使用此选项。
pg_basebackup --format=p \
--tablespace-mapping=/tmp/mytbsp=/tmp/newmytbsp \
-D plainbackup

6.其他说明

sql 复制代码
1.在构建PostgreSQL时,
可以使用配置选项"--with segsize"
更改表和索引的最大文件大小。

2.每个表有三个数据文件 
√一个文件用于存储数据,文件名是表的OID。 
√一个文件用于管理表的空闲空间,文件名是OID_fsm。 
√一个文件用于管理表的块是否可见,文件名是OID_vm。 
√索引没有_vm文件,只有OID和OID_fsm两个文件


3.大小小于1GB的每个表或索引都存储在其所属数据库目录下的单个文件中。
表和索引由各个OID进行内部管理,
而它们的数据文件由变量relfilenode进行管理。
表和索引的relfilenode值基本上但并不总是与各自的OID匹配
SELECT relname, oid, relfilenode FROM pg_class 
WHERE relname = 'sampletbl';

7.总结

PostgreSQL中的表空间允许在文件系统中定义用来存放表示数据库对象的文件的位置 希望这个篇文章给你带来帮助

相关推荐
2401_857622667 小时前
SpringBoot框架下校园资料库的构建与优化
spring boot·后端·php
2402_857589367 小时前
“衣依”服装销售平台:Spring Boot框架的设计与实现
java·spring boot·后端
哎呦没8 小时前
大学生就业招聘:Spring Boot系统的架构分析
java·spring boot·后端
_.Switch9 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
杨哥带你写代码10 小时前
足球青训俱乐部管理:Spring Boot技术驱动
java·spring boot·后端
AskHarries11 小时前
读《show your work》的一点感悟
后端
A尘埃11 小时前
SpringBoot的数据访问
java·spring boot·后端
yang-230711 小时前
端口冲突的解决方案以及SpringBoot自动检测可用端口demo
java·spring boot·后端
Marst Code11 小时前
(Django)初步使用
后端·python·django
代码之光_198011 小时前
SpringBoot校园资料分享平台:设计与实现
java·spring boot·后端