【数据库系列】postgresql

打印 上一主题 下一主题

主题 1791|帖子 1791|积分 5373

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
PostgreSQL 是一款功能强大的开源关系型数据库,以高扩展性、SQL 标准兼容性和丰富的高级功能著称。以下从架构、核心功能、应用场景到优化实践,全面剖析 PostgreSQL 的独特上风与利用细节:

一、架构与核心机制


  • 多版本并发控制(MVCC)​

    • 实现原理:每个事件看到的数据快照(Snapshot)独立,通过 xmin 和 xmax 标记数据的可见性,避免读写锁竞争。
    • 上风:高并发场景下读不壅闭写,写不壅闭读,适合 OLTP 系统。
    • 清理机制:VACUUM 进程回收旧版本数据空间,AUTO_VACUUM 可配置自动清理。

  • 存储引擎与表结构

    • 堆表(Heap Table)​:数据按行存储,通过 TID(行物理地址)快速定位。
    • TOAST 机制:自动压缩大字段(如 TEXT、JSONB),超过 2KB 的数据存储到扩展存储区。
    • 页面结构:默认 8KB 页巨细,包含页头、行指针(ItemId)和实际数据行。

  • 进程模型

    • 主进程(Postmaster)​:管理连接请求,派生子进程处理查询。
    • 子进程(Backend)​:每个客户端连接对应一个子进程,独立内存上下文。
    • 背景进程:包括 BgWriter(脏页刷盘)、Checkpointer(查抄点)、WalWriter(WAL 日记写入)等


二、流复制的核心机制


  • WAL(Write-Ahead Logging)的作用

    • 数据持久化基础:全部数据修改(增删改)必须先写入 WAL 文件,再写入数据文件。
    • 复制基础:流复制的本质是主库将 WAL 记载及时传输到备库,备库重放这些记载以保持数据同等性。

  • 流复制的核心组件

    • 主库(Primary)​

      • WAL Sender 进程:负责将 WAL 数据发送到备库。

    • 备库(Standby)​

      • WAL Receiver 进程:接收主库发送的 WAL 数据。
      • Startup 进程:剖析并应用接收到的 WAL 记载到当地数据文件。



​三、流复制的工作流程


  • 主库写入数据

    • 事件提交时天生 WAL 记载,写入当地 pg_wal 目录。
    • WAL Sender 进程读取 WAL 文件,通过网络发送给备库。

  • 备库接收并应用 WAL

    • WAL Receiver 进程接收 WAL 数据,暂存到备库的 pg_wal 目录。
    • Startup 进程按次序剖析 WAL 记载,重放(Replay)到备库的数据文件中。

  • 同步与异步模式

    • 异步复制(默认)​

      • 主库提交事件后无需期待备库确认,性能高但存在数据丢失风险。

    • 同步复制

      • 主库提交事件后需至少一个备库确认 WAL 写入(synchronous_commit = on)。
      • 确保数据零丢失,但增长事件延迟。



四、部署

主:192.168.88.123 
从:192.168.88.124 
版本:9.2.23 

master
  1. [root@master ~]# yum install postgresql-server -y             
  2. [root@master ~]# id postgres 
  3. uid=26(postgres) gid=26(postgres) groups=26(postgres) 
  4. [root@master ~]# postgresql-setup initdb 
  5. Initializing database ... OK 
  6. [root@master ~]# su - postgres 
  7. -bash-4.2$ exit 
  8. logout 
  9. [root@master ~]# systemctl start postgresql 
  10. [root@master ~]# systemctl status postgresql 
  11. ● postgresql.service - PostgreSQL database server 
  12.    Loaded: loaded (/usr/lib/systemd/system/postgresql.service; disabled; vendor preset: disabled) 
  13.    Active: active (running) since Thu 2023-08-31 15:09:13 CST; 6s ago 
  14.   Process: 15849 ExecStart=/usr/bin/pg_ctl start -D ${PGDATA} -s -o -p ${PGPORT} -w -t 300 (code=exited, status=0/SUCCESS) 
  15.   Process: 15844 ExecStartPre=/usr/bin/postgresql-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS) 
  16.  Main PID: 15852 (postgres) 
  17.    CGroup: /system.slice/postgresql.service 
  18.            ├─15852 /usr/bin/postgres -D /var/lib/pgsql/data -p 5432 
  19.            ├─15853 postgres: logger process    
  20.            ├─15855 postgres: checkpointer process    
  21.            ├─15856 postgres: writer process    
  22.            ├─15857 postgres: wal writer process    
  23.            ├─15858 postgres: autovacuum launcher process    
  24.            └─15859 postgres: stats collector process    
  25. Aug 31 15:09:12 master systemd[1]: Starting PostgreSQL database server... 
  26. Aug 31 15:09:12 master pg_ctl[15849]: LOG:  could not bind IPv6 socket: Cannot assign requested address 
  27. Aug 31 15:09:12 master pg_ctl[15849]: HINT:  Is another postmaster already running on port 5432? If not, wait ...retry. 
  28. Aug 31 15:09:13 master systemd[1]: Started PostgreSQL database server. 
  29. Hint: Some lines were ellipsized, use -l to show in full. 
  30. [root@master ~]# su - postgres               
  31. Last login: Thu Aug 31 15:08:39 CST 2023 on pts/0 
  32. -bash-4.2$ psql 
  33. psql (9.2.24) 
  34. Type "help" for help. 
  35. #设置postgres密码 
  36. postgres=# ALTER USER postgres WITH PASSWORD '123456'; 
  37. ALTER ROLE 
  38. #创建用户replica 
  39. postgres=# create role replica login replication encrypted password '123456'; 
  40. CREATE ROLE 
  41. postgres=# SELECT usename from pg_user; 
  42.  usename   
  43. ---------- 
  44.  postgres 
  45.  replica 
  46. (2 rows) 
  47. #查看权限 
  48. postgres=# SELECT rolname from pg_roles; 
  49.  rolname   
  50. ---------- 
  51.  postgres 
  52.  replica 
  53. (2 rows) 
  54. postgres=# \q 
  55. -bash-4.2$ exit 
  56. logout 
  57. #设置 replica 用户白名单 
  58. [root@master ~]# diff -U0 /var/lib/pgsql/data/pg_hba.conf{,.2023-08-31} 
  59. --- /var/lib/pgsql/data/pg_hba.conf     2023-08-31 15:14:04.793067629 +0800 
  60. +++ /var/lib/pgsql/data/pg_hba.conf.2023-08-31  2023-08-31 15:12:20.773067629 +0800 
  61. @@ -90,2 +89,0 @@ 
  62. -host   all             all             192.168.88.124/32       md5 
  63. -host   replication     replica         192.168.88.124/32       md5 
  64. #更改配置文件 
  65. [root@master ~]# diff -U0 /var/lib/pgsql/data/postgresql.conf{,.2023-08-31} 
  66. --- /var/lib/pgsql/data/postgresql.conf 2023-08-31 15:19:54.652898220 +0800 
  67. +++ /var/lib/pgsql/data/postgresql.conf.2023-08-31      2023-08-31 15:16:49.376908465 +0800 
  68. @@ -59 +59 @@ 
  69. -listen_addresses = '*'                 # what IP address(es) to listen on; 
  70. +#listen_addresses = 'localhost'        # what IP address(es) to listen on; 
  71. @@ -165 +165 @@ 
  72. -wal_level = hot_standby                # minimal, archive, or hot_standby 
  73. +#wal_level = minimal                   # minimal, archive, or hot_standby 
  74. @@ -168 +168 @@ 
  75. -synchronous_commit = on                # synchronization level; 
  76. +#synchronous_commit = on               # synchronization level; 
  77. @@ -212 +212 @@ 
  78. -max_wal_senders = 2            # max number of walsender processes 
  79. +#max_wal_senders = 0           # max number of walsender processes 
  80. #重启主节点进程 
  81. [root@master ~]# systemctl restart postgresql            
  82. [root@master ~]# systemctl status postgresql  
  83. ● postgresql.service - PostgreSQL database server 
  84.    Loaded: loaded (/usr/lib/systemd/system/postgresql.service; disabled; vendor preset: disabled) 
  85.    Active: active (running) since Thu 2023-08-31 15:21:59 CST; 17s ago 
  86.   Process: 16545 ExecStop=/usr/bin/pg_ctl stop -D ${PGDATA} -s -m fast (code=exited, status=0/SUCCESS) 
  87.   Process: 16570 ExecStart=/usr/bin/pg_ctl start -D ${PGDATA} -s -o -p ${PGPORT} -w -t 300 (code=exited, status=0/SUCCESS) 
  88.   Process: 16565 ExecStartPre=/usr/bin/postgresql-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS) 
  89.  Main PID: 16573 (postgres) 
  90.    CGroup: /system.slice/postgresql.service 
  91.            ├─16573 /usr/bin/postgres -D /var/lib/pgsql/data -p 5432 
  92.            ├─16574 postgres: logger process    
  93.            ├─16576 postgres: checkpointer process    
  94.            ├─16577 postgres: writer process    
  95.            ├─16578 postgres: wal writer process    
  96.            ├─16579 postgres: autovacuum launcher process    
  97.            └─16580 postgres: stats collector process    
  98. Aug 31 15:21:58 master systemd[1]: Starting PostgreSQL database server... 
  99. Aug 31 15:21:59 master systemd[1]: Started PostgreSQL database server. 
  100. [root@master ~]# find / -name recovery.conf.sample 
  101. /usr/share/pgsql/recovery.conf.sample 
  102. [root@master ~]# cp /usr/share/pgsql/recovery.conf.sample /var/lib/pgsql/data/ 
复制代码

slave
  1. [root@slave ~]# yum install postgresql-server -y   
  2. #验证是否可以登录主库 
  3. [root@slave ~]# psql -h 192.168.88.123 -p 5432 postgres replica 
  4. Password for user replica:  
  5. psql: FATAL:  password authentication failed for user "replica" 
  6. [root@slave ~]# psql -h 192.168.88.123 -p 5432 postgres replica 
  7. Password for user replica:  
  8. psql (9.2.24) 
  9. Type "help" for help. 
  10. postgres=>  
  11. postgres=>  
  12. postgres=> exit 
  13. postgres-> \q 
  14. #备库上执行对于主库的基础备份 
  15. [root@slave ~]# pg_basebackup -D /var/lib/pgsql/data -h 192.168.88.123 -p 5432 -U replica -X stream -P 
  16. Password:  
  17. 20178/20178 kB (100%), 1/1 tablespace 
  18.   
  19. #确定从节点 
  20. [root@slave data]# diff -U0 recovery.conf{,.sample} 
  21. --- recovery.conf       2023-08-31 16:47:46.554902886 +0800 
  22. +++ recovery.conf.sample        2023-08-31 16:43:09.641911034 +0800 
  23. @@ -88 +88 @@ 
  24. -recovery_target_timeline = 'latest' 
  25. +#recovery_target_timeline = 'latest' 
  26. @@ -108 +108 @@ 
  27. -standby_mode = on 
  28. +#standby_mode = off 
  29. @@ -115 +115 @@ 
  30. -primary_conninfo = 'host=192.168.88.123 port=5432 user=replica password=123456'   # e.g. 'host=localhost port=5432' 
  31. +#primary_conninfo = ''         # e.g. 'host=localhost port=5432' 
  32. #开启热备 
  33. [root@slave data]# cp pg_hba.conf.2023-08-31 pg_hba.conf 
  34. [root@slave data]# cp postgresql.conf.2023-08-31 postgresql.conf 
  35. [root@slave data]# diff -U0 postgresql.conf{,.2023-08-31} 
  36. --- postgresql.conf     2023-08-31 16:32:36.968655754 +0800 
  37. +++ postgresql.conf.2023-08-31  2023-08-31 15:50:01.314461009 +0800 
  38. @@ -230 +230 @@ 
  39. -hot_standby = on                       # "on" allows queries during recovery 
  40. +#hot_standby = off                     # "on" allows queries during recovery 
  41. #启动从节点进程 
  42. [root@slave ~]# systemctl start postgresql 
复制代码

查看进程
  1. #查看主节点sender进程 
  2. [root@master data]# ps -ef |grep wal                                              
  3. postgres 16578 16573  0 15:21 ?        00:00:00 postgres: wal writer process    
  4. postgres 25332 16573  0 16:50 ?        00:00:00 postgres: wal sender process replica 192.168.88.124(10010) streaming 0/60000B8 
  5. root     25348 20780  0 16:50 pts/1    00:00:00 grep --color=auto wal 
  6. #查看从节点receiver进程 
  7. [root@slave data]# ps -ef |grep wal 
  8. postgres 26541 26535  0 16:50 ?        00:00:00 postgres: wal receiver process   streaming 0/60000B8 
  9. root     26552 15622  0 16:50 pts/0    00:00:00 grep --color=auto wal 
  10. #主节点进程信息 
  11. [root@master data]# ps -ef |grep postgres 
  12. postgres 16573     1  0 15:21 ?        00:00:00 /usr/bin/postgres -D /var/lib/pgsql/data -p 5432 
  13. postgres 16574 16573  0 15:21 ?        00:00:00 postgres: logger process    
  14. postgres 16576 16573  0 15:21 ?        00:00:00 postgres: checkpointer process    
  15. postgres 16577 16573  0 15:21 ?        00:00:00 postgres: writer process    
  16. postgres 16578 16573  0 15:21 ?        00:00:00 postgres: wal writer process    
  17. postgres 16579 16573  0 15:21 ?        00:00:00 postgres: autovacuum launcher process    
  18. postgres 16580 16573  0 15:21 ?        00:00:00 postgres: stats collector process    
  19. postgres 25332 16573  0 16:50 ?        00:00:00 postgres: wal sender process replica 192.168.88.124(10010) streaming 0/60000B8 
  20. root     25458 20780  0 16:51 pts/1    00:00:00 grep --color=auto postgres 
  21. #备节点进程信息 
  22. [root@slave data]# ps -ef |grep postgres 
  23. postgres 26535     1  0 16:50 ?        00:00:00 /usr/bin/postgres -D /var/lib/pgsql/data -p 5432 
  24. postgres 26536 26535  0 16:50 ?        00:00:00 postgres: logger process    
  25. postgres 26537 26535  0 16:50 ?        00:00:00 postgres: startup process   recovering 000000010000000000000006 
  26. postgres 26538 26535  0 16:50 ?        00:00:00 postgres: checkpointer process    
  27. postgres 26539 26535  0 16:50 ?        00:00:00 postgres: writer process    
  28. postgres 26540 26535  0 16:50 ?        00:00:00 postgres: stats collector process    
  29. postgres 26541 26535  0 16:50 ?        00:00:00 postgres: wal receiver process   streaming 0/60000B8 
  30. root     26578 15622  0 16:51 pts/0    00:00:00 grep --color=auto postgres 
  31. #数据库信息,主库里有从的数据 
  32. postgres=# select * from pg_stat_replication; 
  33.   pid  | usesysid | usename | application_name |  client_addr   | client_hostname | client_port |         backend_start         |   state   | sent 
  34. _location | write_location | flush_location | replay_location | sync_priority | sync_state  
  35. -------+----------+---------+------------------+----------------+-----------------+-------------+-------------------------------+-----------+----- 
  36. ----------+----------------+----------------+-----------------+---------------+------------ 
  37.  25332 |    16384 | replica | walreceiver      | 192.168.88.124 |                 |       10010 | 2023-08-31 16:50:27.803408+08 | streaming | 0/60 
  38. 000B8     | 0/60000B8      | 0/60000B8      | 0/60000B8       |             0 | async 
  39. (1 row) 
复制代码

测试
  1. #测试同步,主库增加和删除数据库 
  2. postgres=# create database new; 
  3. CREATE DATABASE 
  4. postgres=# drop database test; 
  5. DROP DATABASE 
  6. postgres=# \l 
  7.                                   List of databases 
  8.    Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges    
  9. -----------+----------+----------+-------------+-------------+----------------------- 
  10.  new       | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |  
  11.  postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |  
  12.  template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          + 
  13.            |          |          |             |             | postgres=CTc/postgres 
  14.  template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          + 
  15.            |          |          |             |             | postgres=CTc/postgres 
  16. (4 rows) 
  17. #从库跟着改变 
  18. postgres-# \l 
  19.                                   List of databases 
  20.    Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges    
  21. -----------+----------+----------+-------------+-------------+----------------------- 
  22.  new       | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |  
  23.  postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |  
  24.  template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          + 
  25.            |          |          |             |             | postgres=CTc/postgres 
  26.  template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          + 
  27.            |          |          |             |             | postgres=CTc/postgres 
  28. (4 rows) 
复制代码
 
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
继续阅读请点击广告
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

悠扬随风

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表