PostgreSQL技术内幕3:PG逻辑存储层级和物理存储结构

目录

0.概述

本篇用来介绍PG存储的逻辑层级关系,database->schema,到schema中可以存在的各种信息,像table,索引等(理解隔离的方式和隔离的目的)。同时介绍PG的物理存储目录和文件布局(理解这么设计的作用和好处)以及TOAST存储策略。

1.PG数据组织(逻辑包含关系)

在PG初始化的时候会默认创建三个数据库:template0、template1、postgres。其作用分别为:

1)template0:不可修改,主要用于系统恢复

2)template1: 用户创建新的database时使用的模板,可以在里面定制表和组件,这样新建的库就会带着定制的表和组件

3)postgres:先创建一个库,可以直接使用,没有特殊作用

如果想查看所有库的话可以使用psql 连接后用\l(小写L)命令查看,使用\c 库名可以切换数据库

在库中有schema的概念,schema即命名空间,可以避免一个数据库中有一样名字的对象间的冲突。Schema属于数据库,不同数据库间可以创建各自的schema。创建和查看schema的语法:create schema testschema; 查看schema: SELECT schema_name FROM information_schema.schemata;

可以看到有很多内置的schema,如public、pg_catalog、information_schema、pg_toast等。其中,PG元数据信息和表都放置在pg_catalog schema中,包括系统表 、索引 、内置数据类型、内置函数等。对于系统表,pg_class,其中储存了表的描述信息;pg_database 存储PG中已经创建的数据库的信息;pg_am 用于存储表访问方法的元数据。对于要搜索的表,PG如何知道查找哪个schema下的数据表呢?为此,PG引入了一个配置参数search_path。search_path是一个schema的列表,用逗号分隔。用户可以通过search_path来指定要查找的schema列表的优先顺序,从前到后优先级依次递减。如果search_path中所有的schema都没有匹配的表名,就会报告错误,即使数据库中其他schema中存在匹配的表名;也可以在表名前加上schema名称。

2.存储目录

目录结构如下,可以按照其功能去理解这么分的目的。

下面是主要的目录和文件的说明,基本的职责是比较明确的:

3.文件布局

PG在物理存储上引入tablespace的概念,可以指定表的存储路径,默认时pg_default,也可以自定义tablespace。

如上图所示,pg_global tablespace的映射到路径是PGDATA/global;pg_default 会映射到 PGDATA/base/;用户自定义的tablespace 会映射到 $PGDATA/pg_tblspc/目录下,然后创建一个符号链接到实际的数据目录。可以通过tablespace实现冷热数据分离:将热数据存在SSD的路径上,冷数据则存到SATA磁盘对应的路径上。这样既实现了统一的管理又可以做到数据的分离。

存储如下图:

1)main fork存储数据本身:即表和索引行。main fork可用于任何关系(不包含数据的视图除外)。通常,文件会被切割成1 GB大小的文件,称为segment 文件,以保证不同的文件系统都是可用的。限制文件的大小是为了更好地支持不同的文件系统,因为其中一些文件系统无法处理较大的文件。

2)free space map(空闲空间映射)文件:用于管理文件内空闲空间,记录跟踪数据页面内部空闲空间的位置信息。PG会动态维护空闲空间映射文件中的内容。比如通过vacuum进行无用数据回收后,它会将新增空闲页信息记录到空闲空间映射文件中,以便将来能够快速复用回收的空闲页面。

3)visibility map:用来记录一个页面中的数据是否都"可见",即不需要对页内每行数据逐个进行MVCC可见性检查,进一步提升数据扫描性能。

4.页内数据存储和TOAST策略

PG页面大小默认时8k,当PG元组(表的一行)特别大,页内无法容纳时,PG需要使用超大属性存储技术(TOAST), PG支持以下的存储TOAST策略:1)PLAIN:避免压缩和行外存储。只有那些不需要TOAST策略就能存放的数据类型允许选择(例如 int 类型),而对于text这类要求存储长度超过页大小的类型,是不允许采用此策略的。

2)EXTENDED:允许压缩和行外存储。先尝试压缩,还超过限制,采用行外存储。

3)EXTERNAL:允许行外存储,但不许压缩。该方式时为了更好的性能。

4)MAIN:允许压缩,但不许行外存储。实际是尽可能不进行行外存储。

相关推荐
好吃的肘子7 分钟前
MongoDB 应用实战
大数据·开发语言·数据库·算法·mongodb·全文检索
weixin_4723394616 分钟前
MySQL MCP 使用案例
数据库·mysql
lqlj22331 小时前
Spark SQL 读取 CSV 文件,并将数据写入 MySQL 数据库
数据库·sql·spark
遗憾皆是温柔2 小时前
MyBatis—动态 SQL
java·数据库·ide·sql·mybatis
未来之窗软件服务2 小时前
Cacti 未经身份验证SQL注入漏洞
android·数据库·sql·服务器安全
fengye2071613 小时前
在MYSQL中导入cookbook.sql文件
数据库·mysql·adb
Ailovelearning3 小时前
neo4j框架:ubuntu系统中neo4j安装与使用教程
数据库·neo4j
_星辰大海乀4 小时前
表的设计、聚合函数
java·数据结构·数据库·sql·mysql·数据库开发
未来之窗软件服务4 小时前
solidwors插件 开发————仙盟创梦IDE
前端·javascript·数据库·ide·仙盟创梦ide
yc_12245 小时前
SqlHelper 实现类,支持多数据库,提供异步操作、自动重试、事务、存储过程、分页、缓存等功能。
数据库·c#