【一文搞懂PGSQL】3.进程和关键文件介绍

体系结构

C/S结构

PostgreSQL 是典型的 C/S 模型的关系型数据库。

进程简介

  • PM(连接)进程

postmaster进程,提供监听、连接协议、验证功能,fork其他进程。监听哪个IP是受到postgresql.conf影响的。默认提供sockte和TCP/IP方式连接。

  • SP(会话)进程

Session Processors,会话进程。用户验证成功就会fork一个新的进程。

  • SysLogger(系统日志)进程

需要在Postgres.conf 中 logging_collection设置为on,此使主进程才会启动Syslogger辅助进程。

  • BgWriter(后台写)进程

把共享内存中的脏页写到磁盘上的进程。主要是为了提高插入、更新和删除数据的性能。

  • WALWrite(预写式日志)进程

Write Ahead Log (预写式日志),在修改数据之前把修改操作记录到磁盘中,以便后面更新实时数据时不需要数据持久化到文件中。

  • PgArch(归档)进程

WAL日志会被循环使用,PgArch在归档前会把WAL日志备份出来。通过PITY (Pointin Time Recovery)技术,可以对数据库进行一次全量备份后,该技术将备份时间点之后的WAL日志通过归档进行备份,使用数据库的全量备份再加上后面产生的WAL日志,即可把数据库向前推到全量备份后的任意一个时间点。

  • AutoVacuum(系统自动清理)进程

在PostgreSQL数据库中,对表进行DELETE操作后,旧的数据并不会立即被删除,并且,在更新数据时,也并不会在旧的数据上做更新,而是新生成一行数据。

旧的数据只是被标识为删除状态,只有在没有并发的其他事务读到这些旧数据时,他们才会被清除。这个清除工作就由AutoVacuum进程完成。

  • Pgstat(统计收集)进程

做数据的统计收集工作。主要用于查询优化时的代价估算,包括一个表和索引进行了多少次的插入、更新、删除操作。磁盘块读写的次数、行的读次数。pg_statistic中存储了PgStat收集的各类信息。

  • CheckPoint(检查点)进程

checkpoint又名检查点,一般checkpoint会将某个时间点之前的脏数据全本刷新到磁盘,以实现数据的一致性与完整性。目前各个流行的关系型数据库都具备checkpoint功能,其主要目的是为了缩短崩溃恢复时间,以Oracle为例,在进行数据恢复时,会以最近的Checkpoint为参考点执行事务前滚。而在WAL机制的浅析中,也提过PostgreSQL在崩溃恢复时会以最近的Checkpoint为基础,不断应用之后的WAL日志。

  • control 文件

记录了pg服务器内部的信息,如最新检查点时间、服务器状态、WAL文件位置,总之和数据库可能损坏相关的信息这里都有维护,还包括LC_CTYPE/LC_COLLATE等信息,和oracle控制文件差不多的。如果该文件被删除,实例将无法启动。运行时,会在共享内存中维护一份pg_control的镜像。

关键文件介绍

日志文件种类

  • P G D A T A / l o g 运行日志( p g 10 之前为 PGDATA/log 运行日志(pg10之前为 PGDATA/log运行日志(pg10之前为PGDATA/pg_log)

  • PGDATA/pg_wal 重做日志(pg10之前为$PGDATA/pg_xlog)

  • PGDATA/pg_xact 事务提交日志(pg10之前为$PGDATA/pg_clog)

  • 服务器日志,可以在启动的时候指定,比如pg_ctl start -l ./alert.log

运行日志参数

参数简介
log_destination = ‘csvlog’日志输出到哪 stderr, csvlog, syslog, and eventlog四选一,默认stderr
logging_collector = on开启关闭日志 默认为off / 需要重启
log_directory = ‘log’该参数是配置日志的目录,可以是绝对目录,也可以是相对目录
log_file_mode = 0600日志文件的权限,默认是600也不用更改
log_filename = ‘postgresql-%Y-%m-%d_%H%M%S.log’该参数是配置log的名字,一般用这个就行了,不用修改
log_truncate_on_rotation = off当日志文件轮转时,名字已存在时,该配置如果为off,新生成的日志将在文件尾部追加,如果为on,则会覆盖原来的日志。同时也需要注意该参数只是针对时间到期的切换,如果是因为大小或者系统重启发生切换时,并不会覆盖已有的文件。
log_rotation_age = 1d单个日志文件的生命周期,默认1天,在日志文件大小没有达到log_rotation_size时,一天只生成一个日志文件
log_rotation_size = 10MB单个日志文件的大小,如果时间没有超过log_rotation_age,一个日志文件最大只能到10M,否则将新生成一个日志文件。
log_min_messages=warning控制PG 系统日志级别,log_min_error_statement 要大于等于 log_min_messages 时,SQL语句才会被记录(默认ERROR,足够)。默认是WARNING。
log_min_duration_statement = -1-1 表示不可用记录任何慢查0 将记录所有SQL语句和它们的耗时 大于0时比如N,单位是ms,表示系统会记录 耗时大于等于N ms的SQL语句
log_checkpoints = on记录发生检查点的日志
log_connections = off记录客户端会话连接操作
log_disconnections = off记录客户断开的日志
log_duration = off记录每条SQL语句执行完成消耗的时间,将此配置设置为on,用于统计哪些SQL语句耗时较长。开启该参数会消耗IO性能,如果客户端使用扩展查询协议,则会记录解析、绑定、执行三个阶段的时间。
log_lock_waits = off控制会话等待时间超过 deadlock_timeout而被锁时是否产生一个日志信息。在判断一个锁等待是否会影响性能时是有用的,缺省是off。
log_statement = ‘ddl’控制记录哪些SQL语句。none不记录,ddl 记录所有数据定义命令,比如CREATE,ALTER,和DROP 语句。mod 记录所有ddl语句,加上数据修改语句INSERT,UPDATE等,all记录所有执行的语句,将此配置设置为all可跟踪整个数据库执行的SQL语句。

CSV日志入库存储

-- 创建日志存储表
CREATE TABLE postgres_log
(
  log_time timestamp(3) with time zone,
  user_name text,
  database_name text,
  process_id integer,
  connection_from text,
  session_id text,
  session_line_num bigint,
  command_tag text,
  session_start_time timestamp with time zone,
  virtual_transaction_id text,
  transaction_id bigint,
  error_severity text,
  sql_state_code text,
  message text,
  detail text,
  hint text,
  internal_query text,
  internal_query_pos integer,
  context text,
  query text,
  query_pos integer,
  location text,
  application_name text,
  PRIMARY KEY (session_id, session_line_num)
);

-- 将日志导入表中
copy postgres.postgres_log from '/data/pg_log/postgresql-202-04-14_000000.csv' with csv;

postgresql.conf

参数简介
listen_addresses = ‘*’监听客户端的地址,默认是本地连接,需要需改为’*’ 或者 0.0.0.0
port = 5432pg连接端口,默认5432
max_connections = 1000最大连接数 默认100
unix_socket_directories = ‘/tmp’sockte配置路径,默认 /tmp
shared_buffers数据缓存区核心参数,建议值服务器内存的 1/4 - 1/2
maintenance_work_mem维护工作内存。用于VACUUM、CREATE INDEX和ALTER TABLE ADD FOREIGN KEY等操作,建议 (服务器内存的 1/4)/autovacuum_max_workers
autovacuum_max_workers设置能同时运行的最大的自动垃圾收集工作进程的数目。默认值是3。
max_worker_processes = 8如果要使用 worker process,最多可以允许 fork多少个 worker进程
max_parallel_workers_per_gather单条query 允许开启并行计算的worker数,默认2
wal_level = minimal预写日志模式 11+默认是replica
wal_buffers需重启/指定事务日志缓冲区中包含的数据块的个数,每个数据块的大小是8KB,所以默认的事务日志缓冲区的大小是8*8=64KB。
checkpoint_timeoutcheckpoint时间间隔
max_wal_size控制wal的数量
min_wal_size控制wal的数量
archive_command开启归档
autovacuum开启自动vacuum

控制文件

pg_controldata可以查看控制文件的内容

[postgres@test01 ~]$ pg_controldata $PGDATA
pg_control version number:            1201                # PostgreSQL 版本号
Catalog version number:               201909212           # 目录版本号
Database system identifier:           7356493727464752915 # 数据库系统标识符(DBSID)
Database cluster state:               in production       # 数据库集群状态
pg_control last modified:             Thu 11 Apr 2024 05:01:01 PM CST  # pg_control 最后修改时间
Latest checkpoint location:           0/6084AC0           # 最新检查点位置
Latest checkpoint's REDO location:    0/6084A88           # 最新检查点的 REDO 位置
Latest checkpoint's REDO WAL file:    000000010000000000000006  # 最新检查点的 REDO WAL 文件
Latest checkpoint's TimeLineID:       1      # 最新检查点的时间线 ID
Latest checkpoint's PrevTimeLineID:   1      # 最新检查点的上一个时间线 ID
Latest checkpoint's full_page_writes: on     # 最新检查点的全页写开关状态
Latest checkpoint's NextXID:          0:521  # 最新检查点的 NextXID
Latest checkpoint's NextOID:          24577  # 最新检查点的 NextOID
Latest checkpoint's NextMultiXactId:  1      # 最新检查点的 NextMultiXactId
Latest checkpoint's NextMultiOffset:  0      # 最新检查点的 NextMultiOffset
Latest checkpoint's oldestXID:        480    # 最新检查点的最旧事务 ID(oldestXID)
Latest checkpoint's oldestXID's DB:   1      # 最新检查点的最旧事务 ID 所属数据库
Latest checkpoint's oldestActiveXID:  521    # 最新检查点的最旧活跃事务 ID(oldestActiveXID)
Latest checkpoint's oldestMultiXid:   1      # 最新检查点的最旧多版本事务 ID(oldestMultiXid)
Latest checkpoint's oldestMulti's DB: 1      # 最新检查点的最旧多版本事务所属数据库
Latest checkpoint's oldestCommitTsXid:0      # 最新检查点的最旧提交时间戳事务 ID(oldestCommitTsXid)
Latest checkpoint's newestCommitTsXid:0      # 最新检查点的最新提交时间戳事务 ID(newestCommitTsXid)
Time of latest checkpoint:            Thu 11 Apr 2024 05:01:01 PM CST  # 最新检查点时间
Fake LSN counter for unlogged rels:   0/3E8  # 未记录关系的虚拟 LSN 计数器
Minimum recovery ending location:     0/0    # 最小恢复结束位置
Min recovery ending loc's timeline:   0      # 最小恢复结束位置的时间线
Backup start location:                0/0    # 备份开始位置
Backup end location:                  0/0    # 备份结束位置
End-of-backup record required:        no     # 是否需要备份结束记录
wal_level setting:                    replica  # WAL 日志级别设置
wal_log_hints setting:                on     # WAL 日志提示设置
max_connections setting:              2000   # 最大连接数设置
max_worker_processes setting:         8      # 最大工作进程数设置
max_wal_senders setting:              10     # 最大 WAL 发送者数设置
max_prepared_xacts setting:           0      # 最大预处理事务数设置
max_locks_per_xact setting:           64     # 每个事务的最大锁数设置
track_commit_timestamp setting:       off    # 跟踪提交时间戳设置
Maximum data alignment:               8      # 最大数据对齐大小
Database block size:                  8192   # 数据库块大小
Blocks per segment of large relation: 131072 # 大型关系的每个段的块数
WAL block size:                       8192   # WAL 块大小
Bytes per WAL segment:                16777216  # 每个 WAL 段的字节数
Maximum length of identifiers:        64     # 标识符的最大长度
Maximum columns in an index:          32     # 索引中的最大列数
Maximum size of a TOAST chunk:        1996   # TOAST 块的最大大小
Size of a large-object chunk:         2048   # 大对象块的大小
Date/time type storage:               64-bit integers  # 日期/时间类型存储方式
Float4 argument passing:              by value  # Float4 参数传递方式
Float8 argument passing:              by value  # Float8 参数传递方式
Data page checksum version:           0         # 数据页校验版本
Mock authentication nonce:            b1482276658b9aa5b638bad162d3d4fea064cbabd6889303f5d179131ad66c93  # 模拟认证 nonce

数据文件

pg中,每个索引和表都是一个单独的文件,pg中叫做page。默认是每个大于1G的page会被分割 pg_class.relfilenode.1这样的文件。page的的大小在initdb的时候指定 (–with.segsize)。

page物理位置

page的物理位置在 $PGDATA/BASE/DATABASE_OID/PG_CLASS.RELFILENODE

# 查看t1 表存储在哪个物理文件
select relfilenode from pg_class where relname='t1';

# 查看t1表存储在哪个路径下的物理文件
select pg_relation_filepath('t1');

# 查看数据目录路径
show data_directory;

# 查找文件是否存在
ll /pgdata/12/data/base/16384/16385

需要注意的是,pg_class.relfilenode类似dbaobjects.data_objectid,truncate表之后relfilenode会变。对应的物理文件名字也会变。

Online WAL 日志(redo)

关于Online WAL日志

  • 这个日志存在的目的是为了保证崩溃后的安全,如果系统崩溃,可以“重放“从最后一次检查点以来的日志项来恢复数据库的一致性。

  • 但是也存在日志膨胀的问题

设置Online WAL日志

pg提供如下參数控制wal日志的大小

max_wal_size = 1GB
min_wal_size = 80MB

max_wal_size (integerl)

在自动 WAL 检查点之间允许WAL 增长到的最大尺寸。这是一个软限制,在特殊的情况下 WAL 尺寸可能会超过max_waLsize,例如在重度负荷下、archive_command失败或者高的 wal_keep_segments设置。如果指定值时没有单位,则以兆字节为单位。默认为 1GB。增加这个参数 可能导致崩溃恢复所需的时间。这个参数只能在postgresql.conf 或者服务器命令行中设置。

min_wal_size (integer)

只要 WAL 磁盘用是保持在这个设置之下,在检查点时旧的 WAL 文件总是被回收以便未来使用,而不是直接被删除。这可以被用来确保有足够的 WAL 空间被保留来应付 WAL 使用的高峰,例如运行大型的批处理任务。如果指定估时没有单位,则以兆字节为单位。默认是80MB。这个参数只能在postgresql。conf 或者服务器命令行中设置。

wal 位置

wal在$PGDATA/pg_wal 下。10之前在pg_xlog

[postgres@pg-01 pg_wal]$ cd /pgdata/12/data/
[postgres@pg-01 data]$ cd pg_wal/
[postgres@pg-01 pg_wal]$ ll
total 16384
-rw-------. 1 postgres postgres 16777216 Apr 22 22:16 000000010000000000000001
drwx------. 2 postgres postgres        6 Apr 20 21:01 archive_status

wal 命名格式

文件名称为16进制的24个字符组成,每8个字符一组,每组的意义如下:

[postgres@pg-01 pg_wal]$ ll
-rw-------. 1 postgres postgres 16777216 Apr 22 22:16 000000010000000000000001
00000001 00000000 00000001
时间线     逻辑ID    物理ID

查看 wal 时间

postgres=# select pg_walfile_name(pg_current_wal_lsn());
     pg_walfile_name      
--------------------------
 000000010000000000000001
(1 row)

postgres=# select * from pg_ls_waldir() order by modification asc;
           name           |   size   |      modification      
--------------------------+----------+------------------------
 000000010000000000000001 | 16777216 | 2022-04-22 22:16:07+08
(1 row)

postgres=# 

切换 wal 日志

postgres=# select pg_switch_wal();
 pg_switch_wal 
---------------
 0/3000000
(1 row)


postgres=# select * from pg_ls_waldir() order by modification asc;
           name           |   size   |      modification      
--------------------------+----------+------------------------
 000000010000000000000004 | 16777216 | 2022-04-22 22:54:41+08
 000000010000000000000005 | 16777216 | 2022-04-22 22:54:46+08
 000000010000000000000003 | 16777216 | 2022-04-22 22:56:03+08

pg_waldump 查看 wal 重做日志

pg_waldump 可以查看wal的具体内容

[postgres@pg-01 pg_wal]$ pg_waldump /pgdata/12/data/pg_wal/000000010000000000000003 
rmgr: Standby     len (rec/tot):     50/    50, tx:          0, lsn: 0/03000028, prev 0/02000060, desc: RUNNING_XACTS nextXid 527 latestCompletedXid 526 oldestRunningXid 527
rmgr: Standby     len (rec/tot):     50/    50, tx:          0, lsn: 0/03000060, prev 0/03000028, desc: RUNNING_XACTS nextXid 527 latestCompletedXid 526 oldestRunningXid 527
rmgr: XLOG        len (rec/tot):    114/   114, tx:          0, lsn: 0/03000098, prev 0/03000060, desc: CHECKPOINT_ONLINE redo 0/3000060; tli 1; prev tli 1; fpw true; xid 0:527; oid 16422; multi 1; offset 0; oldest xid 480 in DB 1; oldest multi 1 in DB 1; oldest/newest commit timestamp xid: 0/0; oldest running xid 527; online
rmgr: Standby     len (rec/tot):     50/    50, tx:          0, lsn: 0/03000110, prev 0/03000098, desc: RUNNING_XACTS nextXid 527 latestCompletedXid 526 oldestRunningXid 527
pg_waldump: fatal: error in WAL record at 0/3000110: invalid record length at 0/3000148: wanted 24, got 0

5.8 ARCH WAL log

重做日志是几个文件轮询使用的,当这几个文件被写满之后会覆盖掉之前的数据,而我们如果想要保存这些将要被覆盖掉的日志就需要ARCH进行归档。在数据库发生故障后可以将归档日志应用到数据库中进行数据恢复。

// wal_level = replica # pg11+ 默认开启replica
该参数的可选的值有minimal, replica和nlogical, wal的级别依次增高,在wal的信息也越多。由于minimal这一级别的wal不包含从基础的备份和wal日志重建数据的足够信息,在该模式下,无法开启wal日志归档。

// archive_mode = on # 开启归档
上述参数为on,表示打开归档备份,可选的参数为on,off,always 认值为off,所以要手动打开。

// archive. command = ’test !-f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f‘
该参数的默认信是—个空字符串,他的值可以是一条shell命令或者一个复杂的shell脚本.在shell脚本或命令中可以用"%p"表示将要归档的wal文件包含完整路径的信息的文件名,用"%f代表不包含路径信息的wal文件的文件名。
注意:wal_level和archive_mode参数修改都需要重新启动数据库才可以生效。而修改 archive_command 则不需要。所以一般配置新系统时,无论当时是否需要归档,都建议将这两个参数开启。

配置参数

# 开启归档
archive_mode = on

# 指定归档日志级别
wal_level = replica 

# 选择归档路径
archive_command = 'test ! -f /archive/%f && cp %p /archive/%f'

重启数据库

pg_ctl restart

切换日志

select pg_switch_wal();

# 查看归档文件
[postgres@pg-01 archive]$ ll /archive/
total 32768
-rw------- 1 postgres postgres 16777216 Apr 22 23:47 000000010000000000000003
-rw------- 1 postgres postgres 16777216 Apr 22 23:47 000000010000000000000004

归档的作用是防止数据库删除过期的 wal 日志,可以在数据库出现问题后使用归档的 wal 恢复数据。

  • 18
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值