PostgreSQL实战-体系结构

体系结构
    数据库:PostgreSQL 数据库是由一系列位于文件系统上的物理文件组成,通常将这些物理文件称为数据库,
        将这些物理文件、管理这些物理文件的进程、进程管理的内存称为这个数据库的实例。
        
    PostgreSQL 的内部功能实现上,可以分为:
        系统控制器:负责接收外部连接请求
        查询分析器:对连接请求查询进行分析并生成优化后的查询解析树,从文件系统获取结果集或通过事务系统对数据做处理,并由文件系统持久化数据
        事务系统
        恢复系统、
        文件系统
        .....
        
    逻辑存储结构    
        数据库集簇( Database Cluster ):指由单个PostgreSQL 服务器实例管理的数据库集合,组成数据库集簇的这些数据库使用相同的全局配置文件和监昕端口、共用进程和内存结构
        数据库集群:一组数据库服务器构成的集群
        
        Database Cluster:
            数据库Database(Database1...Databasen)
                Schema
                    表、索引、序列、视图、函数等这些对象
            Users
            
        创建一个Database 时会为这个Database创建一个名为public 的默认Schema ,每个Database 可以有多个Schema
        在这个数据库中创建其他数据库对象时如果没有指定Schema ,默认创建在public这个Schema 中。
        Schema 可以理解为一个数据库中的命名空间,在数据库中创建的所有对象都在Schema中,不同的Schema 中可以有多个相同名称的Table 、Index 、View 、Sequence、Function 等数据库对象。
        一个用户可以从同一个客户端连接中访问不同的Schema 。

    物理存储结构
        数据库的文件默认保存在initdb 时创建的数据目录中。包括:
            数据文件
            参数文件
            控制文件
            数据库运行日志
            预写日志
            ......
            
            
        数据目录结构:
            ~]# yum install tree
            
            查看数据目录下文件
            ~]# tree -L 1 -d /opt/pg/data/9.5/
                /opt/pg/data/9.5/
                ├── base
                ├── global
                ├── pg_clog
                ├── pg_commit_ts
                ├── pg_dynshmem
                ├── pg_log
                ├── pg_logical
                ├── pg_multixact
                ├── pg_notify
                ├── pg_replslot
                ├── pg_serial
                ├── pg_snapshots
                ├── pg_stat
                ├── pg_stat_tmp
                ├── pg_subtrans
                ├── pg_tblspc
                ├── pg_twophase
                └── pg_xlog

                目录                    用途
            base                 包含每个数据库对应的子目录的子目录
            global                 包含集簇范围的表的子目录,比如pg_database
            pg_commit_ts         包含事务提交时间戳数据的子目录
            pg_xact             包含事务提交状态数据的子目录
            pg_dynshmem         包含被动态共享内存子系统所使用文件的子目录
            pg_logical             包含用于逻辑复制的状态数据的子目录
            pg_mult1xact         包含多事务状态数据的子目录(用于共享的行锁)
            pg_notify             包含LISTEN/NOTIFY 状态数据的子目录
            pg_replslot            包含复制槽数据的子目录
            pg_serial            包含已提交的可序列化事务信息的子目录
            pg_snapshots         包含导出的快照的子目录
            pg_stat             包含用于统计子系统的永久文件的子目录
            pg_stat_tmp         包含用于统计信息子系统临时文件的子目录
            pg_subtrans         包含子事务状态数据的子目录
            pg_tblspc             包含指向表空间的符号链接的子目录
            pg_twophase         用于预备事务状态文件的子目录
            pg_wal                 保存预写日志
            pg_xact                记录事务提交状态数据
            
            
            文件                    用途
            PG_VERSION             PostgreSQL 主版本号文件
            pg_hba.conf         客户端认证控制文件
            postgresql.conf     参数文件
            postgresql.auto.conf 参数文件,只保存ALTER SYSTEM 命令修改的参数
            postmaster.opts        记录服务器最后一次启动时使用的命令行参数
        
        数据文件布局
            数据目录中的base 子目录是我们的数据文件默认保存的位置,是数据库初始化后的默认表空间。
            
            对象标识符( OID ):
                PostgreSQL 中的所有数据库对象都由各自的对象标识符( OID )进行内部管理,它们是无符号的4 字节整数。
                
                pg=# SELECT oid, datname FROM pg_database WHERE datname='cdm';
                  oid  | datname
                -------+---------
                 24577 | cdm
                (1 row)
                
                数据库中的表、索引、序列等对象的OID 存储在pg_class 系统表中,可以查询获得这些对象的OID:
                pg=# \c cdm
                You are now connected to database "cdm" as user "pg".
                cdm=# SELECT oid, relname,relkind FROM pg_class WHERE relname='network_identity_thing';
                  oid   |        relname         | relkind
                --------+------------------------+---------
                 143110 | network_identity_thing | r
                (1 row)

            表空间
                数据库中创建的对象都保存在表空间中,例如表、索引和整个数据库都可以被分配到特定的表空间。
                在创建数据库对象时,可以指定数据库对象的表空间,如果不指定则使用默认表空间,也就是数据库对象的文件的位置。
                
                cdm=# \db
                      List of tablespaces
                    Name    | Owner | Location
                ------------+-------+----------
                 pg_default | pg    |
                 pg_global  | pg    |
                (2 rows)

                pg_global 表空间的物理文件位置在数据目录的 global目录中,它用来保存系统表。
                pg_default 表空间的物理文件位置在数据目录中的 base目录,是templateO 和 templatel 数据库的默认表空间,我们知道创建数据库时,默认从template1 数据库进行克隆,因此除非特别指定了新建数据库的表空间,默认使用templatel 的表空间pg_default 。
                
                用户还可以创建自定义表空间
                1. 使用操作系统的postgres 用户创建一个目录
                    -bash-4.2$ mkdir -p /opt/pg/data/9.5/steventblspc

                2. 连接到数据库
                    ~]$ psql -h pg01 -p 1523 -U pg

                3. 使用CREATE TABLESPACE 命令创建表空间
                    pg=# CREATE TABLESPACE stevespc LOCATION '/opt/pg/data/9.5/steventblspc';

                4. 创建数据库对象的时候指明使用的表空间
                    pg=# CREATE TABLE steven_test(id serial,name varchar) TABLESPACE stevespc;
                    
                我们在数据库pg下创建的,因此    
                pg=# SELECT oid, datname FROM pg_database WHERE datname ='pg' ;
                  oid  | datname
                -------+---------
                 16384 | pg
                (1 row)
                
                pg的表、索引都会保存在$PGDATA/base/16384 这个目录中/opt/pg/data/9.5/base/16384
                我们制定新建表的表空间stevespc,其数据位置 /opt/pg/data/9.5/steventblspc/PG_9.5_201510051/16384
                
        数据文件的命名:
            在数据库中创建对象,例如表、索引时首先会为表和索引分配段。在PostgreSQL 中,每个表和索引都用一个文件存储,新创建的表文件以表的OID 命名, 对于大小超出l GB 的表数据文件, PostgreSQL 会自动将其切分为多个文件来存储【超出lGB 之外的数据会按每GB 切割,】,切分出的文件用OID.<顺序号>来命名。
            但表文件并不是总是OID.<顺序号>命名,实际上真正管理表文件的是pg_class 表中的relfilenode 字段的值,在新创建对象时会在pg_class 系统表中插入该表的记录,默认会以OID 作为relfilenode 的值,但经过几次VACUUM 、TRUNCATE 操作之后,relfilenode 的值会发生变化。有可能命名规则为<relfilenode>.<顺序号> 。
            SELECT oid,relfilenode FROM pg_class WHERE relname ='steven_test';
            
            pg=# SELECT oid,relfilenode FROM pg_class WHERE relname='steven_test';
              oid   | relfilenode
            --------+-------------
             532824 |      532824
            (1 row)
            
            
            ~]# ll /opt/pg/data/9.5/steventblspc/PG_9.5_201510051/16384
            total 8
            -rw-------. 1 pg dba    0 Jul 16 04:31 532824
            -rw-------. 1 pg dba    0 Jul 16 04:31 532828
            -rw-------. 1 pg dba 8192 Jul 16 04:31 532830
            
        表文件内部结构
            在PostgreSQL 中:
                将保存在磁盘中的块称为Page
                将内存中的块称为Buffer
                表和索引称为Relation
                行称为Tuple
                    每个 Tuple 包含两部分的内容:
                        一部分为HeapTupleHeader ,用来保存Tuple 的元信息,包含该Tuple 的OID 、xmin 、cmin 等;
                        另一部分为HeapTuple ,用来保存Tuple 的数据。
            数据的读写是以Page 为最小单位, 每个Page 默认大小为8kB ,在编译PostgreSQL 时指定的。BLCKSZ 大小决定Page 的大小。
            每个表文件由多个BLCKSZ 字节大小的Page 组成, 每个Page 包含若干Tuple 。

    进程结构:
        PostgreSQL 是一用户一进程的客户端/服务器的应用程序。
        数据库启动时会启动若干个进程,其中有
            postmaster (守护进程)、
            postgres (服务进程)、
            sys_logger 、
            check_point
            bgwriter
            walwriter 等辅助进程。
            
        守护进程与服务进程
            postmaster 进程的主要职责有:
                口数据库的启停。
                口监听客户端连接。
                口为每个客户端连接fork 单独的postgres 服务进程。
                口当服务进程出错时进行修复。
                口管理数据文件。
                口管理与数据库运行相关的辅助进程。
                
                当客户端调用接口库向数据库发起连接请求,守护进程postmaster 会fork 单独的服务进程postgres 为客户端提供服务,此后将由postgres 进程为客户端执行各种命令,客户端也不再需要postmaster 中转,直接与服务进程postgres 通信,直至客户端断开连接,
                
        辅助进程
            口background writer :也可以称为bgwriter 进程, bgwriter 进程很多时候都是在休眠状态,每次唤醒后它会搜索共享缓冲池找到被修改的页,并将它们从共享缓冲池刷出。
            口autovacuum launcher : 自动清理回收垃圾进程。
            口WALwriter :定期将WAL 缓冲区上的WAL 数据写入磁盘。
            口statistics collector :统计信息收集进程。
            口logging collector :日志进程,将消息或错误信息写入日志。
            口archiver : WAL 归档进程。
            口checkpointer :检查点进程。
            
    内存结构
        PostgreSQL 的内存分为两大类:
            本地内存
            共享内存
            另外还有一些为辅助进程分配的内存等
            
        本地内存
            本地内存由每个后端服务进程分配以供自己使用,当后端服务进程被fork 时,每个后端进程为查询分配一个本地内存区域。
            本地内存由三部分组成: work_mem 、maintenance_work_mem 和temp_buffers。
                work_mem :当使用ORDER BY 或DISTINCT 操作对元组进行排序时会使用这部分内存。
                maintenance_work mem : 维护操作,例如VACUUM 、REINDEX 、CREATE INDEX等操作使用这部分内存。
                temp_buffers :临时表相关操作使用这部分内存。
                
        共享内存
            共享内存在PostgreSQL 服务器启动时分配,由所有后端进程共同使用。共享内存主要由三部分组成:
                shared buffer pool : PostgreSQL 将表和索引中的页面从持久存储装载到这里, 并直接操作它们。
                WAL buffer: WAL 文件持久化之前的缓冲区。
                CommitLog buffer : PostgreSQL 在Commit_Log 中保存事务的状态,并将这些状态保留在共享内存缓冲区中,在整个事务处理过程中使用。
            

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值