安装:
yum install postgresql15-server postgresql15-contrib -y
默认安装在/usr/pgsql-15 目录, 数据在 /var/lib/pgsql/15/
安装完成默认执行了以下操作:
创建组和添加相关用户:
sudo groupadd postgres && sudo useradd -g postgres postgres
创建目数目录,并做相应的授权,每个VM上操作
mkdir -p /var/lib/pgsql/15/{data,backups} && chown -R postgres:postgres /var/lib/pgsql && chmod -R 700 /var/lib/pgsql/
并且默认创建了pgsql相关二进制程序的符合链接:
/usr/bin/pg_restore -> /etc/alternatives/pgsql-pg_restore
/usr/bin/pg_dumpall -> /etc/alternatives/pgsql-pg_dumpall
/usr/bin/pg_dump -> /etc/alternatives/pgsql-pg_dump
/usr/bin/pg_basebackup -> /etc/alternatives/pgsql-pg_basebackup
/etc/alternatives/pgsql-vacuumdbman -> /usr/pgsql-15/share/man/man1/vacuumdb.1
/etc/alternatives/pgsql-reindexdbman -> /usr/pgsql-15/share/man/man1/reindexdb.1
/etc/alternatives/pgsql-psqlman -> /usr/pgsql-15/share/man/man1/psql.1
/etc/alternatives/pgsql-pg_restoreman -> /usr/pgsql-15/share/man/man1/pg_restore.1
/etc/alternatives/pgsql-pg_dumpallman -> /usr/pgsql-15/share/man/man1/pg_dumpall.1
/etc/alternatives/pgsql-pg_dumpman -> /usr/pgsql-15/share/man/man1/pg_dump.1
/etc/alternatives/pgsql-pg_basebackupman -> /usr/pgsql-15/share/man/man1/pg_basebackup.1
/etc/alternatives/pgsql-dropuserman -> /usr/pgsql-15/share/man/man1/dropuser.1
/etc/alternatives/pgsql-dropdbman -> /usr/pgsql-15/share/man/man1/dropdb.1
/etc/alternatives/pgsql-createuserman -> /usr/pgsql-15/share/man/man1/createuser.1
/etc/alternatives/pgsql-createdbman -> /usr/pgsql-15/share/man/man1/createdb.1
/etc/alternatives/pgsql-clusterdbman -> /usr/pgsql-15/share/man/man1/clusterdb.1
/etc/alternatives/pgsql-vacuumdb -> /usr/pgsql-15/bin/vacuumdb
/etc/alternatives/pgsql-reindexdb -> /usr/pgsql-15/bin/reindexdb
/etc/alternatives/pgsql-pg_restore -> /usr/pgsql-15/bin/pg_restore
/etc/alternatives/pgsql-pg_dumpall -> /usr/pgsql-15/bin/pg_dumpall
/etc/alternatives/pgsql-pg_dump -> /usr/pgsql-15/bin/pg_dump
/etc/alternatives/pgsql-pg_basebackup -> /usr/pgsql-15/bin/pg_basebackup
/etc/alternatives/pgsql-dropuser -> /usr/pgsql-15/bin/dropuser
/etc/alternatives/pgsql-dropdb -> /usr/pgsql-15/bin/dropdb
/etc/alternatives/pgsql-createuser -> /usr/pgsql-15/bin/createuser
/etc/alternatives/pgsql-createdb -> /usr/pgsql-15/bin/createdb
/etc/alternatives/pgsql-clusterdb -> /usr/pgsql-15/bin/clusterdb
/etc/alternatives/pgsql-psql -> /usr/pgsql-15/bin/psql
/etc/alternatives/pgsql-ld-conf -> /usr/pgsql-15/share/postgresql-15-libs.conf
初始化:
su - postgres #不能以root用户运行,需要先切换到postgres用户
/usr/pgsql-15/bin/postgresql-15-setup initdb
PostgreSQL 15 在 initdb初始化时,默认创建的数据库模板(template1)和第一个数据库(通常也是 postgres)使用的默认字符编码是 UTF-8,对应的默认区域设置(locale)是操作系统的环境
可以通过以下命令来查看默认字符集:
SELECT datname, encoding, datcollate, datctype FROM pg_database WHERE datname = 'postgres';
其中:
encoding对应字符编码(如 6代表 UTF8)。
datcollate是排序规则区域设置(影响 ORDER BY)。
datctype是字符分类区域设置(影响大小写转换、字符分类等)。
建议在初始化时指定字符串编码:(zh_CN.UTF-8和en_US.UTF-8的区别主要是排序规则、时间和货币符合以及格式化,都是UTF-8字符集,zh-CN.UTF-8排序时按拼音字母排序)
/usr/pgsql-15/bin/initdb --pgdata=/var/lib/pgsql/15/data --encoding=UTF8 --locale=en_US.UTF-8
当需要设置主从备份时,需要设置SELinux规则以允许同步数据,简单操作直接关闭SELinux:
临时关闭:
setenforce 0 #通过 getenforce 查看 输出:Enforcing, Permissive, or Disabled
永久关闭:
vi /etc/selinux/config
添加 SELINUX=disable
开放防火墙相关端口:
firewall-cmd --permanent --add-port=5432/tcp
firewall-cmd --reload
启动:(配置保存在/usr/lib/systemd/system/postgresql-15.service)
systemctl enable postgresql-15
systemctl start postgresql-15
启动后会有如下进程:
/usr/pgsql-15/bin/postmaster -D /var/lib/pgsql/15/data/ // 主进程
postgres: logger // 日志进程
postgres: checkpointer // 检查点进程
postgres: background writer // 数据写入进程
postgres: walwriter // wal预写入日志进程
postgres: autovacuum launcher // 自动清理进程,执行delete时,不会马上清理数据,只是被标记为清除状态,而是等到没有事务时由autovacuum进程来处理
postgres: archiver last was 00000001000000FB000000EB // 归档进程
postgres: logical replication launcher
然后每连接一个客户端,主进程会fork一个客户端处理进程(MySQL是派生线程得方式)
2、调整配置:
主要配置文件有以下:
/var/lib/pgsql/15/data/pg_hba.conf:PostgreSQL 数据库的主机认证配置文件,用于控制哪些主机和用户可以连接到 PostgreSQL 数据库服务器以及使用哪种身份验证方法进行连接。
/var/lib/pgsql/15/data/postgresql.conf:是 PostgreSQL 数据库的主配置文件,它包含了许多数据库的全局设置和参数。
/var/lib/pgsql/15/data/recovery.conf:是 PostgreSQL 数据库中用于配置流复制(streaming replication)的配置文件。在 PostgreSQL 中,流复制是一种常见的高可用性解决方案,
它允许将一个主数据库的更改同步到一个或多个从数据库中,从而实现数据的冗余备份和故障转移。recovery.conf 文件只在从数据库中使用,主数据库不需要使用该文件。在配置流复制时,
需要将 recovery.conf 文件复制到从数据库的 PostgreSQL 数据目录中,并确保该文件的权限正确设置。从PostgreSQL 12开始,恢复文件改成postgresql.auto.conf
2.1、pg_hba.conf文件:
登录上数据库后 可以通过 show hba_file; 来查看pg_hba.conf配置的位置
pg_hba.conf是PostgreSQL的客户端认证配置文件,用于控制客户端访问数据库的权限。
TYPE DATABASE USER ADDRESS METHOD
"local" is for Unix domain socket connections only
local all all peer
IPv4 local connections:
host all all 0.0.0.0/0 scram-sha-256
host all all 127.0.0.1/32 scram-sha-256
IPv6 local connections:
host all all ::1/128 scram-sha-256
Allow replication connections from localhost, by a user with the
replication privilege.
local replication all peer
host replication all 127.0.0.1/32 scram-sha-256
host replication all ::1/128 scram-sha-256
每一行的格式通常是:
type database user address auth-method [auth-options]
其中:
type:连接类型,如"local"(Unix域套接字)、"host"(TCP/IP连接,包括SSL和非SSL)、"hostssl"(SSL加密的TCP/IP连接)、"hostnossl"(非SSL的TCP/IP连接)。
database:指定数据库名,"all"表示所有数据库,也可以指定多个数据库或用逗号分隔的列表,或使用前缀"@"来指定一个包含数据库列表的文件。
replication 特殊数据库,是用于主从复制的,允许用户以流复制的方式连接。这些用户必须具有REPLICATION权限
user:指定用户名,"all"表示所有用户,也可以指定多个用户或用逗号分隔的列表,或使用前缀"@"来指定一个包含用户列表的文件。
address:指定客户端地址,对于"local"类型此字段忽略,对于"host"等类型,可以是IP地址、CIDR地址范围、或者用逗号分隔的列表。还可以使用"samehost"或"samenet"来匹配服务器自身的IP或同子网的IP。
当type是local时,address字段不需要填,为空
auth-method:认证方法,如"trust"(无条件允许连接)、"reject"(无条件拒绝)、"md5"(要求客户端提供MD5加密的密码)、"password"(明文密码,不安全)、"scram-sha-256"(使用SCRAM-SHA-256加密的密码)、
"gss"(使用GSSAPI认证)、"sspi"(使用SSPI认证)、"ident"(通过ident服务器获取客户端操作系统用户名)、"peer"(从操作系统获取客户端用户名,仅适用于local连接)等。
peer:允许本地操作系统用户通过Unix域套接字连接所有数据库,使用peer认证(即使用客户端所在操作系统的用户名作为数据库用户名进行认证,不需要密码)
auth-options:可选,指定认证方法的选项。
su - postgres psql 这样不加-h参数连接的就是通过unix socket连接的,不是tcp/ip socket,即 通过local方式连接,而不是host
登录上数据库之后可以通过\conninfo 来查看当前的连接方式信息:
比如通过host方式的:
\conninfo
You are connected to database "bello" as user "postgres" on host "127.0.0.1" at port "5432".
通过local方式的:
\conninfo
You are connected to database "postgres" as user "postgres" via socket in "/run/postgresql" at port "5432".
修改完pg_hba.conf配置后,可以通过以下命令让配置生效:
/usr/pgsql-15/bin/pg_ctl reload 或者 systemctl reload postgresql-15
或者在数据库中执行:
SELECT pg_reload_conf()
2.2、修改postgresql.conf文件
在安装目录下data/postgresql.config文件中,可以通过:
show config_file;
获
SELECT name, setting FROM pg_settings WHERE name = 'config_file';
确认文件位置
-----------------------------
PostgreSQL 主库最佳实践配置
系统内存:16GB,OLTP 工作负载,带一个从库
-----------------------------
连接设置
listen_addresses = '*' # 允许从库连接
port = 5432
max_connections = 300 # 主库可能需要更多连接(应用+从库)
内存设置
shared_buffers = 4GB # 共享缓冲区,建议系统内存的 25%
#work_mem = 16MB # 单个SQL执行时,以及排序、Hash Join时使用的内存,SQL运行完毕后,该内存就会被释放
#maintenance_work_mem = 1GB # 维护操作(VACUUM, CREATE INDEX等)的内存
#effective_cache_size = 12GB # 系统缓存大小,通常设置为系统内存的 50-75%
WAL(Write-Ahead log) 设置 - 主从复制的关键
wal_level = replica # 必须为 replica 或 logical 以支持流复制
replica 支持物理流复制,需要创建复制槽,支持小版本差异
logical 支持逻辑复制,复制SQL操作逻辑(INSERT, UPDATE, DELETE),基于发布-订阅模式,支持大版本差异,
synchronous_commit = on # on (默认值)平衡模式 ,事务提交必须等待本地的 WAL 记录刷新到磁盘后才算成功。
off (或 local) 事务提交只需将 WAL 记录写入操作系统缓存即可返回成功。
remote_write 性能优先,事务提交必须等待主库的WAL刷新到磁盘,并且从库已接收到该WAL数据(可能还在从库的操作系统缓存中,未刷盘)。
remote_apply 强一致性,事务提交必须等待至少一个同步备库已经接收、应用了该事务的WAL记录。
#wal_buffers = 16MB # WAL缓冲区的内存大小。通常可以设置为-1(自动调整)或shared_buffers 的 1/32
max_wal_senders = 5 # 最大WAL发送进程数,用于流复制。单节点模式可以设为0,主从模式需要设置为大于0的值(至少等于从库数量)
max_wal_size = 1GB # 默认 1GB 对于现代服务器可能偏小,增加它可以减少检查点频率,提升性能。评估后调整 (建议 shared_buffers的 1-2 倍),控制整个 pg_wal目录下 所有 WAL 文件的总大小上限
wal_keep_size = 1GB # 保留的WAL段数量或大小,以便从库落后时可以从主库获取。主从模式下需要设置一个合适的值,防止从库因为WAL被删除而需要重新同步。建议为max_wal_size得1/2
归档设置(可选,但强烈推荐用于备份和从库追赶)
archive_mode = on # 开启归档;当为off时表示只能使用流复制
archive_command = 'cp %p /path/to/archive/%f' # 归档命令,需要根据环境修改
复制槽设置
max_replication_slots = 5 # 最大复制槽数,至少等于从库数
#-- 在主库执行
#SELECT * FROM pg_create_physical_replication_slot('standby1_slot');
#-- 在主库查看复制槽状态
#SELECT slot_name, active, restart_lsn, confirmed_flush_lsn FROM pg_replication_slots WHERE slot_name = 'standby1_slot';
删除复制槽
#SELECT pg_drop_replication_slot('bello_slot');
在从库的 postgresql.auto.conf 或恢复配置中添加,从库执行pg_basebackup命令后自动生成,同时生成standby.signal
#primary_conninfo = 'host=主库IP user=replicator password=xxx'
#primary_slot_name = 'standby1_slot' # 强烈推荐指定, pg_basebackup命令可以加上参数直接生成复制槽并在从库配置中设置对应的复制槽,所以无需手动配置
从库postgres.conf中设置,主库设置也无所谓,无副作用,到时候从库直接复制
hot_standby = on # 从库是否允许读查询。主从模式下,从库需要设置为on;从库不需要设置max_wal_senders等主库特有的参数
#max_standby_archive_delay = 30s # 归档延迟
#max_standby_streaming_delay = 30s # 流复制延迟
hot_standby_feedback = on # 向主库反馈查询信息,大部分从库参数在主库中设置也无副作用,但是当前参数例外
检查点设置,主要用以将内存脏数据写入磁盘,所以时间不能太大,防止崩溃丢失数据
checkpoint_timeout = 10min
checkpoint_completion_target = 0.9
日志设置(增加复制相关日志)
#log_destination = 'stderr'
#logging_collector = on # 是否开启日志收集,默认开启
#log_directory = 'log' # 日志目录
#log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # 日志文件命名模式
#log_connections = on # 记录连接,有助于监控复制
#log_disconnections = on # 记录断开连接
#log_line_prefix = '%m [%p] %q%u@%d ' # 日志行前缀,增加时间、进程ID、用户和数据库信息
#保留最近7天的日志,进行循环覆盖, 默认
log_filename = 'postgresql-%a.log'
log_truncate_on_rotation = on
log_rotation_age = 1d #每天生成一个新的日志文件
log_rotation_size = 0 #每当日志写满一定的大小(如10MB),则切换一个日志
2.3、配置生效:
当修改完pg_hba.conf配置后,可以通过以下命令让配置生效:
/usr/pgsql-15/bin/pg_ctl reload 或者 systemctl start postgresql-15
或者在数据库中执行:
SELECT pg_reload_conf()
但是有限制,listen_addresses, port, shared_buffers, max_connections 这些参数不能通过重载生效,work_mem, maintenance_work_mem, log_statement以及pg_hba.conf里面配置的参数可以
可以通过以下语句来判断参数是否可以通过重载生效:
SELECT name, context, unit, setting FROM pg_settings WHERE name = 'listen_addresses';
如果 context值为 postmaster,则意味着修改后必须重启服务
当重载不能生效时,需要重启pgsql来使参数生效:
#1、 使用 pg_ctl 重启(指定你的数据目录,如 -D /path/to/data)
/usr/pgsql-15/bin/pg_ctl restart -D /your/data/directory
#2、 如果使用 systemd 管理服务
sudo systemctl restart postgresql # 或 postgresql-<版本号>
3、常用sql语句:
3.1、角色和用户
默认新创建的用户只有一种权限:PUBLIC角色的权限
PUBLIC是一个特殊的内置角色,每个用户都会自动成为其成员。它的默认权限包括:
连接任何数据库:GRANT CONNECT ON DATABASE database_name TO PUBLIC;(但 pg_hba.conf必须首先允许连接)。
在 public模式上的 USAGE权限:GRANT USAGE ON SCHEMA public TO PUBLIC;。
这意味着一个新用户可以:
连接到数据库(如果 pg_hba.conf允许)。
看到 public模式。
但无法查看任何用户表,因为 SELECT权限没有被默认授予。
无法在 public模式中创建表(在现代版本中)。
在 PostgreSQL 中,CREATE USER和 CREATE ROLE几乎是等价的。唯一的区别是:CREATE USER默认具有 LOGIN权限,而 CREATE ROLE默认没有。
CREATE USER username WITH OPTION1 VALUE1 OPTION2 VALUE2 ...;
-- 或者
CREATE ROLE username WITH OPTION1 VALUE1 OPTION2 VALUE2 ...;
用户登录的认证与否以及认证方法是有pg_hba.conf配置的,如果pg_hba.conf设置的是trust或者peer,那么就无需密码认证,不管数据库里面创建用户时是否设置密码;
但是如果创建用户时没有设置密码,而pg_hba.conf里面又要求有密码,那么改用户是无法登录的
赋予表权限:
-- 1. 授予对特定表的 SELECT 权限
GRANT SELECT ON TABLE my_table TO my_user;
-- 2. 授予对某个模式中所有现有表的 SELECT 权限
GRANT SELECT ON ALL TABLES IN SCHEMA my_schema TO my_user;
-- 3. 授予对未来在某个模式中创建的所有表的 SELECT 权限(设置默认权限)
ALTER DEFAULT PRIVILEGES IN SCHEMA my_schema
GRANT SELECT ON TABLES TO my_user;
-- 4. 将一个用户添加到拥有某些权限的角色组
GRANT read_only_role TO my_user;
\h 显示帮助文档,比如\h create user显示创建用户的文档
\l 显示所有数据库,等同于下面的语句:
SELECT datname, datdba, pg_encoding_to_char(encoding), datcollate, datctype FROM pg_database;
\dt 显示当前数据库的所有表,等同于下面的语句:
SELECT table_name FROM information_schema.tables WHERE table_schema='public' AND table_type='BASE TABLE';
\d 显示结构,可以加名称或者通配符, 使用\d+ 可以显示更详细的信息
比如: \d t_quota*, \d显示的要比\dt \di等更详细
\dt 显示表
\di 显示索引
\ds 显示序列
\dv 显示试图
\df 显示函数
\du 显示所有用户
\dp 查看权限分配情况
\dn 显示所有schema
\c db_name 切换数据库,类似mysql的use db_name
\c 直接显示当前数据库,或者:SELECT CURRENT_DATABASE();
\timing on 显示执行sql语句的时间
\timing off 关闭执行sql语句的时间显示
\x on 开启扩展显示,按列显示,类似mysql 语句后面加 \G
\x off 关闭扩展显示
\pset 设置
默认情况下pgsql输出的只有内边框,\pset border 2 调整为带有外边框 \pset border 0 没有边框 \pset border 1 带内边框 默认
show hba_file; ---- 查看具体的hba配置文件路径
show config_file; --- 查看postgresql.conf路径
\set AUTOCOMMIT off 关闭psql客户端的自动提交功能
在启动psql客户端时加-E 参数会把执行的各种命令打印出来,特别是系统命令的,比如\d 回车后会显示\d对应的sql语句
对应该命令"\set ECHO_HIDDEN on|off",开启或者关闭
\q 退出
postgres 进程
logger 日志进程
checkpointer checkpoint进程
background writer 数据文件写进程
walwriter wal写进程
autovacuum launcher autovacuum进程
stats collector 统计信息收集进程
修改密码:
ALTER USER postgres WITH PASSWORD 'new_password';
PostgreSQL 创建用户/角色的详细语句
在 PostgreSQL 中,CREATE USER和 CREATE ROLE几乎是等价的。唯一的区别是:CREATE USER默认具有 LOGIN权限,而 CREATE ROLE默认没有。
- 基础创建语句
CREATE USER username WITH OPTION1 VALUE1 OPTION2 VALUE2 ...;
-- 或者
CREATE ROLE username WITH OPTION1 VALUE1 OPTION2 VALUE2 ...;
字段含义:
username:要创建的用户/角色名称。
- 常用权限选项(WITH 之后)详解
postgres=# \h create user
Command: CREATE USER
Description: define a new database role
Syntax:
CREATE USER name [ [ WITH ] option [ ... ] ]
where option can be:
SUPERUSER | NOSUPERUSER
| CREATEDB | NOCREATEDB
| CREATEROLE | NOCREATEROLE
| INHERIT | NOINHERIT
| LOGIN | NOLOGIN
| REPLICATION | NOREPLICATION
| BYPASSRLS | NOBYPASSRLS
| CONNECTION LIMIT connlimit
| [ ENCRYPTED ] PASSWORD 'password' | PASSWORD NULL
| VALID UNTIL 'timestamp'
| IN ROLE role_name [, ...]
| IN GROUP role_name [, ...]
| ROLE role_name [, ...]
| ADMIN role_name [, ...]
| USER role_name [, ...]
| SYSID uid
选项
含义
示例
说明
LOGIN
允许登录
WITH LOGIN
赋予用户连接数据库的权限。这是普通用户和复制用户必需的。
NOLOGIN
禁止登录
WITH NOLOGIN
默认角色(ROLE)的状态。适合用于角色组,不用于个人用户。
PASSWORD 'password'
ENCRYPTED PASSWORD ...
设置登录密码
WITH PASSWORD 'MyStr0ngP@ss!'
为用户设置密码。ENCRYPTED是默认且推荐的方式,可以省略。
SUPERUSER
超级用户
WITH SUPERUSER
极度危险! 授予用户所有权限,无视所有权限检查。仅限管理员。
NOSUPERUSER
非超级用户
WITH NOSUPERUSER
默认选项。绝大多数用户应该是非超级用户。
CREATEDB
允许创建数据库
WITH CREATEDB
允许用户执行 CREATE DATABASE命令。
NOCREATEDB
禁止创建数据库
WITH NOCREATEDB
默认选项。
CREATEROLE
允许创建角色
WITH CREATEROLE
允许用户创建、修改、删除其他角色(用户)。权限很大,需谨慎。
NOCREATEROLE
禁止创建角色
WITH NOCREATEROLE
默认选项。
INHERIT
继承权限
WITH INHERIT
默认选项。用户会自动继承其所属角色的权限。
NOINHERIT
不继承权限
WITH NOINHERIT
较少使用。
REPLICATION
流复制权限
WITH REPLICATION
关键选项! 允许用户建立流复制连接(用于主从备份)。此权限必须与 LOGIN一起使用。
NOREPLICATION
无复制权限
WITH NOREPLICATION
默认选项。绝大多数用户不应有此权限。
BYPASSRLS
绕过行级安全策略
WITH BYPASSRLS
高级安全特性,允许用户绕过任何行级安全策略(Row Level Security)。
NOBYPASSRLS
遵守行级安全
WITH NOBYPASSRLS
默认选项。
CONNECTION LIMIT n
连接数限制
WITH CONNECTION LIMIT 5
限制该用户的最大并发连接数。-1(默认)表示无限制。
VALID UNTIL 'timestamp'
密码有效期
WITH VALID UNTIL '2025-12-31'
设置密码的过期时间。过期后用户将无法登录。
IN ROLE role_name
立即成为成员
IN ROLE read_only_group
将新用户立即添加为一个或多个现有角色的成员。
ROLE role_name
立即添加成员
ROLE new_user
将一个或多个现有用户添加为新角色的成员。较少使用。
查看数据库大小
SELECT pg_size_pretty(pg_database_size('postgres'));
7.查看表大小
SELECT pg_size_pretty(pg_relation_size('table_test'));
8.查看索引大小
SELECT pg_size_pretty(pg_relation_size('table_test_pkey'));
9.查看表空间大小
SELECT pg_size_pretty(pg_tablespace_size('pg_default'));
10.查看表大小(包含索引)
SELECT pg_size_pretty(pg_total_relation_size(cast('text_table' as text)));
-- 创建数据库
CREATE DATABASE name
\[ WITH \] \[ OWNER \[=\] user_name
TEMPLATE \[=\] template
ENCODING \[=\] encoding
LC_COLLATE \[=\] lc_collate
LC_CTYPE \[=\] lc_ctype
TABLESPACE \[=\] tablespace
CONNECTION LIMIT \[=\] connlimit \]
CREATE DATABASE mydb; // OWNER用于指定新建的数据库属于哪个用户,如果不指定,新建的数据库就属于当前执行命令的用户。
-- 创建带有指定参数的数据库
CREATE DATABASE mydb
WITH
OWNER = postgres
ENCODING = 'UTF8'
LC_COLLATE = 'zh_CN.UTF-8' -- 排序规则
LC_CTYPE = 'zh_CN.UTF-8' -- 字符分类
TABLESPACE = pg_default -- 表空间
CONNECTION LIMIT = -1; -- 连接限制,-1表示无限制
-- 删除数据库
DROP DATABASE IF EXISTS mydb;
-- 创建学生表
CREATE TABLE students (
id SERIAL PRIMARY KEY, -- 自增主键
name VARCHAR(50) NOT NULL, -- 非空约束
age INTEGER CHECK (age > 0 AND age < 100), -- 检查约束
email VARCHAR(100) UNIQUE, -- 唯一约束
gender CHAR(1),
major VARCHAR(50),
enrollment_date DATE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- 默认值
);
-- 创建成绩表,包含外键关联
CREATE TABLE scores (
id SERIAL PRIMARY KEY,
student_id INTEGER REFERENCES students(id) ON DELETE CASCADE, -- 外键,级联删除
subject VARCHAR(50) NOT NULL,
score NUMERIC(5,2) CHECK (score >= 0 AND score <= 100), -- 数值类型约束
exam_date DATE,
-- 创建复合索引
CONSTRAINT unique_student_subject UNIQUE (student_id, subject)
);
-- 删除表
DROP TABLE IF EXISTS students;
-- 添加新列
ALTER TABLE students ADD COLUMN address TEXT;
-- 修改列定义
ALTER TABLE students ALTER COLUMN age TYPE NUMERIC(3,0); -- 改变数据类型
ALTER TABLE students ALTER COLUMN major SET NOT NULL; -- 添加非空约束
-- 重命名列
ALTER TABLE students RENAME COLUMN gender TO sex;
-- 删除列
ALTER TABLE students DROP COLUMN address;
-- 添加约束
ALTER TABLE students ADD CONSTRAINT valid_sex CHECK (sex IN ('M', 'F', 'U'));
PSQL引入了角色(role):ROLE 是核心,USER 只是能登录的 ROLE
-- 创建用户
-- 没有 用户名@host 概念,权限通过 pg_hba.conf + GRANT 控制。
CREATE USER testuser WITH PASSWORD 'testpassword';
-- 创建带有更多选项的用户
CREATE USER appuser WITH
PASSWORD 'apppass123'
NOSUPERUSER -- 不是超级用户
NOCREATEDB -- 不能创建数据库
NOCREATEROLE -- 不能创建角色
INHERIT -- 可以继承角色权限
LOGIN -- 允许登录
CONNECTION LIMIT 10; -- 最大连接数
-- 创建角色
CREATE ROLE student_role;
-- 授予表权限
GRANT SELECT, INSERT, UPDATE ON students TO student_role;
GRANT SELECT ON scores TO student_role;
GRANT ALL PRIVILEGES ON DATABASE exampledb to dbuser;
-- PostgreSQL 15支持列级权限控制
GRANT UPDATE (age, email) ON students TO appuser;
-- 将角色授予用户
GRANT student_role TO testuser;
-- 对于自增字段,需要授予序列权限
-- MySQL 的 AUTO_INCREMENT 属于表属性,无独立序列对象,也就没有对应授权概念;PostgreSQL 序列是独立对象,权限必须显式授予
GRANT USAGE, SELECT ON SEQUENCE students_id_seq TO appuser;
--撤销授权
-- 撤销student_role对students表的权限
REVOKE SELECT, INSERT, UPDATE ON students FROM student_role;
-- 撤销student_role对scores表的权限
REVOKE SELECT ON scores FROM student_role;
-- 撤销用户的所有表权限
REVOKE ALL PRIVILEGES ON students FROM appuser;
-- 从testuser收回student_role角色
REVOKE student_role FROM testuser;
select oid, datname from pg_database;
oid | datname
-------+-----------
12937 | postgres
16384 | osdba
1 | template1
12936 | template0
ls -l $PGDATA/base
total 0
drwx------ 304 osdba staff 9728 Jan 27 17:22 1
drwx------ 304 osdba staff 9728 Jan 27 17:22 12936
drwx------ 304 osdba staff 9728 Feb 12 09:59 12937
drwx------ 329 osdba staff 10528 Feb 12 22:09 16384
drwx------ 2 osdba staff 64 Feb 5 23:00
可以看到数据的目录跟oid一致
select relnamespace, relname, relfilenode from pg_class where relname='test01';
relnamespace | relname | relfilenode
--------------+---------+-------------
2200 | test01 | 33103
(1 row)
可以看出这个表的relfilenode为"33103",则这张表的数据文
件为"$PGDATA/base/16384/33103":
主从配置:
主:
创建角色replica用来主从同步:
CREATE ROLE replica WITH login replication password 'replica';
在主库的/var/lib/pgsql/15/data/pg_hba.conf中添加如下配置,允许从节点连入
"local" is for Unix domain socket connections only
local all all peer
IPv4 local connections:
host all all 0.0.0.0/0 scram-sha-256
host all all 127.0.0.1/32 scram-sha-256
IPv6 local connections:
host all all ::1/128 scram-sha-256
Allow replication connections from localhost, by a user with the
replication privilege.
local replication all peer
host replication all 127.0.0.1/32 scram-sha-256
host replication all ::1/128 scram-sha-256
通常在/var/lib/pgsql/15/data/postgresql.conf 配置文件中修改监听地址为*,即监听本地所有网卡地址
允许归档
archive_mode = on
通过命令指定归档路径/
archive_command = 'cp %p /opt/pgsql/pg_archive/%f'
w# 写入WAL的级别(minimal:不能通过基础备份和wal日志恢复数据库; replica: 支持wal归档和复制; logical: 在replica级别添加了逻辑解码所需的信息)
wal_level = replica
允许最多的流复制连接发送数量, 根据从节点数量来设定
max_wal_senders = 32
设置流复制保留的最多的xlog数目
wal_keep_segments = 256
设置流复制发送数据的超时时间
wal_sender_timeout = 60s
最大连接数量,根据从节点与客户端连接数来设定
max_connections = 1000
从机不仅用于数据归档,也可用于数据查询
hot_standby = on
使用systemctl restart postgresql命令重启数据库
从:
删除数据目录:
/var/lib/pgsql/15/data/
使用postgres用户执行pg_basebackup命令
输入pg_basebackup -D /var/lib/pgsql/15/data/ -Fp -Xstream -R -c fast -v -P -h 主库地址 -U replica -W
pg_basebackup -h primary_ip -D /var/lib/pgsql/data -U replication_user -P -v --wal-method=stream
-h <host>/ --host=<host> 数据库服务器的主机名或套接字目录
-p <port>/ --port=<port> 数据库服务器监听的端口号
-U <username>/ --username=<username> 连接数据库时使用的用户名,该用户必须具有 REPLICATION权限或为超级用户
-W/ --password 强制提示输入密码
-D <directory>/ --pgdata=<directory> (必需) 指定接收备份数据的目标目录
-F <format>/ --format=<format> 备份输出格式。p或 plain为原样格式(与运行中数据库的数据目录结构相同);t或 tar为 tar 归档格式
-R/ --write-recovery-conf (重要) 自动创建 standby.signal文件,并将主库连接信息(如 primary_conninfo)写入 postgresql.auto.conf。这在配置流复制备库时非常有用,强烈建议使用该参数
-X <method>/ --wal-method=<method> 指定如何包含 WAL 文件。fetch表示在备份结束时获取;stream表示在备份期间实时流式传输 WAL 日志,这是最安全的方式,推荐使用;none则不包含
-P/ --progress 显示备份进度信息
-v/ --verbose 启用详细输出模式
-r <rate>/ --max-rate=<rate> 限制数据传输的最大速率(单位 kB/s),可用于减少对网络或磁盘 I/O 的影响
-S <slot_name>/ --slot=<slot_name> 指定要使用的复制槽名称。使用此参数时,备份将通过这个指定的复制槽来预留所需的 WAL 日志,这对于保证备份一致性至关重要
-C/ --create-slot 在开始备份前,创建由 -S选项命名的复制槽。如果指定的复制槽尚不存在,此选项会先创建它
使用pg_basebackup获取基础备份
sudo -u postgres pg_basebackup \
-h 192.168.1.100 \
-p 5432 \
-U replicator \
-D /var/lib/pgsql/15/data \
-Fp \
-Xs \
-P \
-R
然后输入设置的replica用户密码即可将主库复制到从库
在从库/var/lib/pgsql/15/data/postgresql.conf配置文件中添加下列配置
写入WAL的级别(minimal:不能通过基础备份和wal日志恢复数据库; replica: 支持wal归档和复制; logical: 在replica级别添加了逻辑解码所需的信息)
wal_level = replica
根据实际应用情况, 设定最大连接数
max_connections = 1000
从机不仅用于数据归档,也可用于数据查询
hot_standby = on
数据流备份的最大延迟时间
max_standby_streaming_delay = 30s
多久向主报告一次从的状态,当然从每次数据复制都会向主报告状态,这里只是设置最长的间隔时间
wal_receiver_status_interval = 10s
如果有错误的数据复制,是否向主进行反馈
hot_standby_feedback = on
验证主从同步:
在主库PostgreSQL命令行下执行select * from pg_stat_replication;验证同步状态信息
从库上执行该语句select pg_is_in_recovery();
故障转移测试
使用
pg_ctl -D /var/lib/pgsql/15/data promote
会自动调整standby.signal 文件
或者:
在备库上可以通过创建 promote_trigger_file 来触发故障转移,使备库成为主库:(需要先在postgres.conf里面配置)
touch /tmp/pg_failover_trigger
检测到trigger_file指定的文件后会自动删除standby.signal文件,并且会删除trigger_file
创建该文件后,备库会脱离流复制模式,并提升为主数据库
通过命令:su postgres -c 'psql -c "select pg_is_in_recovery();"'
f - false, 表示不是从库
t - true, 表示是从库
主从切换:
原从库配置
在 /etc/postgresql/10/main/pg_hba.conf中添加配置,允许原主库复制数据
host replication all[复制用户名] [新从库IP]/32 scram-sha-256
从库升级为主库,执行下列命令:
pg_ctl -D /var/lib/pgsql/15/data/ promote
3.原主库切换为从库
使用 systemctl stop postgresql命令关停原主库
添加recovery.conf配置文件,配置文件内容与之前原从库内容一致,需要把primary_conninfo参数中的信息改为新主库对应的, recover.conf在PostgreSQL12版本以后被取消了,改成postgres.auto.conf配置文件了
也可以通过rm -rf *删除原主库数据文件,然后通过pg_basebackup -D /var/lib/pgsql/15/data/ -Fp -Xs -R -c fast -v -P -h <新主库地址> -U <用于复制的用户名> -W备份新主库数据文件,
这样数据目录下会自动生成recovery.conf文件
若数据文件下已有recovery.done文件,也可以将其改为recovery.conf,命令:mv /var/lib/pgsql/15/data/recovery.done /var/lib/pgsql/15/data/recovery.conf
配置 /var/lib/pgsql/15/data/postgresql.conf 添加从库配置
WAL 全程是write ahead log,是一种预写日志,在postgreSQL分析完sql语句后修改完内存数据页,写入数据文件前,写入WAL文件
从库启动前需要先使用pg_basebackup 从主库中拷贝数据文件以及增量的WAL文件,
从库启动后会创建standby.signal文件,然后从主库中定时拷贝WAL文件,也就是流复制
归档 是将WAL文件进行归档
查看流复制的信息可以使用主库上的视图"pg_stat_replication":
select pid,state,client_addr, sync_priority,sync_state from pg_stat_replication;
另外,pg_stat_replication视图中的以下几个字段记录了一些WAL日志的位置。
·sent_lsn:发送WAL的位置。
·write_lsn:可以认为是备库已经接收到了这部分日志,但还没有刷到磁盘中。
·flush_lsn:备库已经把WAL日志刷到磁盘中的位置。
·replay_lsn:备库应用日志的位置。
查看备库落后主库多少字节的WAL日志:
select pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn) from pg_stat_replication;
导出:
pg_dump -h [主机名] -p [端口] -U [用户名] -d [数据库名] -f [输出文件路径]
常用参数说明
-h:指定数据库服务器的主机名或IP地址,默认为本地连接
-p:指定数据库服务器的端口号,默认为5432
-U:指定连接数据库的用户名
-d:指定要导出的数据库名
-f:指定备份输出的文件路径。如果省略,则输出到标准输出(屏幕)
-F:指定备份文件的格式。常见的有 p(纯文本SQL,默认)、c(自定义压缩格式)、d(目录格式)
-t:只导出指定的表,可以多次使用该参数指定多张表,例如 -t table1 -t table2。
-s:只导出表结构(定义),不包含数据
-a:只导出数据,不包含表结构
-v:启用详细模式,输出备份过程的详细信息
-W:强制 pg_dump在连接前提示输入密码。为避免阻塞自动化脚本,更常见的做法是设置 PGPASSWORD环境变量,如 export PGPASSWORD=你的密码
或者导出所有库:
pg_dumpall -h [主机名] -p [端口] -U [用户名] -f [输出文件路径]