目录
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:允许压缩,但不许行外存储。实际是尽可能不进行行外存储。