活动公告

系统通知
05-18 21:22
系统通知
通知:本站资源由网友上传分享,如有违规等问题请到版务模块进行投诉,资源失效请在帖子内回复要求补档,会尽快处理!
10-23 09:31

PostgreSQL线上维护操作全攻略 从日常备份到紧急故障处理的实用技巧与最佳实践确保数据库稳定高效运行

SunJu_FaceMall

3万

主题

2860

科技点

3万

积分

白金月票

碾压王

积分
32872

塔罗立华奏

<font color=白金月票" /> 发表于 2025-9-11 18:20:01 | 显示全部楼层 |阅读模式

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

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

x
引言

PostgreSQL作为世界上最先进的开源关系型数据库管理系统之一,广泛应用于各种关键业务场景。随着数据量的增长和业务复杂性的提高,对PostgreSQL数据库进行有效的线上维护变得至关重要。本文将全面介绍PostgreSQL的线上维护操作,从日常备份策略到紧急故障处理,提供实用技巧和最佳实践,帮助数据库管理员确保PostgreSQL数据库的稳定高效运行。

日常维护操作

数据备份策略

数据备份是数据库维护的基础,合理的备份策略能够在数据丢失或损坏时快速恢复系统。

物理备份直接复制数据库的物理文件,包括数据文件、WAL日志等。PostgreSQL提供了多种物理备份方法:

1. pg_basebackup:这是PostgreSQL提供的在线物理备份工具,可以在数据库运行时创建基础备份。
  1. # 创建一个基础备份
  2. pg_basebackup -D /backup/dir -Ft -z -P -U replication_user -h primary_host -p 5432 -R
复制代码

参数说明:

• -D:指定备份目录
• -Ft:指定备份格式为tar
• -z:启用压缩
• -P:显示进度信息
• -U:指定连接用户
• -h:指定主服务器主机名
• -p:指定端口号
• -R:创建standby.signal文件并设置连接信息

1. 文件系统快照:使用文件系统或存储系统的快照功能创建物理备份。
  1. # 使用LVM快照创建备份
  2. lvcreate --size 1G --snapshot --name postgres_snap /dev/vg00/lv_postgres
  3. mount /dev/vg00/postgres_snap /mnt/postgres_snap
  4. rsync -av /mnt/postgres_snap/ /backup/postgres/
  5. umount /mnt/postgres_snap
  6. lvremove -f /dev/vg00/postgres_snap
复制代码

逻辑备份导出数据库的逻辑结构和数据,通常使用SQL脚本或自定义格式存储。

1. pg_dump:用于备份单个数据库。
  1. # 备份单个数据库为SQL文件
  2. pg_dump -U username -h hostname -d dbname -f backup.sql
  3. # 备份为自定义格式(推荐)
  4. pg_dump -U username -h hostname -d dbname -Fc -f backup.dump
复制代码

1. pg_dumpall:用于备份整个PostgreSQL集群,包括所有数据库和全局对象。
  1. # 备份所有数据库
  2. pg_dumpall -U username -h hostname -f full_backup.sql
复制代码

1. 定期完整备份:每周或每月进行一次完整备份。
2. 增量备份:每天进行增量备份,基于WAL日志。
3. 异地备份:将备份文件存储在异地,以防灾难发生。
4. 备份验证:定期验证备份的可用性。
  1. # 示例备份脚本
  2. #!/bin/bash
  3. # 设置变量
  4. BACKUP_DIR="/var/backups/postgresql"
  5. DATE=$(date +%Y%m%d_%H%M%S)
  6. RETENTION_DAYS=30
  7. # 创建备份目录
  8. mkdir -p $BACKUP_DIR/$DATE
  9. # 执行pg_dumpall进行完整备份
  10. pg_dumpall -U postgres -h localhost | gzip > $BACKUP_DIR/$DATE/full_backup.sql.gz
  11. # 执行WAL日志备份
  12. pg_receivewal -U replication -D $BACKUP_DIR/$DATE/wal --compress=9
  13. # 清理旧备份
  14. find $BACKUP_DIR -type d -mtime +$RETENTION_DAYS -exec rm -rf {} \;
  15. # 记录日志
  16. echo "Backup completed at $(date)" >> $BACKUP_DIR/backup_log.txt
复制代码

定期维护任务

PostgreSQL需要定期执行一些维护任务以保持最佳性能。

VACUUM用于回收由更新和删除操作产生的”死元组”占用的空间。

1. 常规VACUUM:
  1. -- 对单个表执行VACUUM
  2. VACUUM verbose table_name;
  3. -- 对整个数据库执行VACUUM
  4. VACUUM verbose;
复制代码

1. VACUUM FULL:重写表,回收更多空间,但会锁定表。
  1. VACUUM FULL verbose table_name;
复制代码

1. 自动VACUUM:PostgreSQL提供了自动VACUUM守护进程,通过调整以下参数可以优化自动VACUUM行为:
  1. -- 查看当前自动VACUUM设置
  2. SHOW autovacuum;
  3. SHOW autovacuum_vacuum_threshold;
  4. SHOW autovacuum_vacuum_scale_factor;
  5. -- 修改自动VACUUM设置
  6. ALTER SYSTEM SET autovacuum_vacuum_scale_factor = 0.01;
  7. ALTER SYSTEM SET autovacuum_vacuum_threshold = 1000;
  8. -- 重启PostgreSQL使设置生效
  9. SELECT pg_reload_conf();
复制代码

ANALYZE收集表统计信息,帮助查询优化器生成更好的执行计划。
  1. -- 对单个表执行ANALYZE
  2. ANALYZE table_name;
  3. -- 对整个数据库执行ANALYZE
  4. ANALYZE VERBOSE;
复制代码

通常将VACUUM和ANALYZE一起执行:
  1. -- 对单个表执行VACUUM和ANALYZE
  2. VACUUM ANALYZE table_name;
  3. -- 对整个数据库执行VACUUM和ANALYZE
  4. VACUUM ANALYZE VERBOSE;
复制代码

WAL(Write-Ahead Logging)是PostgreSQL的关键组件,需要适当管理。

1. WAL归档:配置WAL归档以支持时间点恢复(PITR)。
  1. -- 在postgresql.conf中设置
  2. wal_level = replica
  3. archive_mode = on
  4. archive_command = 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'
复制代码

1. WAL保留:设置WAL段保留数量,防止过早删除。
  1. -- 在postgresql.conf中设置
  2. wal_keep_size = 1GB
复制代码

1. 清理旧的WAL文件:
  1. # 使用pg_archivecleanup清理旧的WAL文件
  2. pg_archivecleanup /path/to/wal/directory 000000010000000000000005
复制代码

性能监控与优化

持续监控数据库性能是确保高效运行的关键。

1. 启用查询日志:
  1. -- 在postgresql.conf中设置
  2. log_statement = 'all'   # 记录所有语句
  3. log_min_duration_statement = 1000  # 记录执行时间超过1000ms的语句
复制代码

1. 使用pg_stat_statements扩展:
  1. -- 创建扩展
  2. CREATE EXTENSION pg_stat_statements;
  3. -- 查看最耗时的查询
  4. SELECT query, calls, total_time, mean_time, rows
  5. FROM pg_stat_statements
  6. ORDER BY total_time DESC
  7. LIMIT 10;
复制代码

1. 使用pg_stat_activity监控活动会话:
  1. -- 查看当前活动会话
  2. SELECT pid, datname, usename, application_name, client_addr,
  3.        state, query, query_start
  4. FROM pg_stat_activity;
  5. -- 查看长时间运行的查询
  6. SELECT pid, now() - query_start AS duration, query
  7. FROM pg_stat_activity
  8. WHERE (now() - query_start) > interval '5 minutes'
  9. ORDER BY duration DESC;
复制代码

1. 终止长时间运行的查询:
  1. -- 终止特定查询
  2. SELECT pg_terminate_backend(pid);
复制代码
  1. -- 查看索引使用情况
  2. SELECT schemaname, tablename, indexname, idx_scan, idx_tup_read, idx_tup_fetch
  3. FROM pg_stat_user_indexes
  4. ORDER BY idx_scan ASC;
复制代码

根据服务器硬件和工作负载调整PostgreSQL配置:
  1. -- 查看当前配置
  2. SHOW ALL;
  3. -- 修改内存相关参数
  4. ALTER SYSTEM SET shared_buffers = '4GB';
  5. ALTER SYSTEM SET work_mem = '64MB';
  6. ALTER SYSTEM SET maintenance_work_mem = '512MB';
  7. ALTER SYSTEM SET effective_cache_size = '12GB';
  8. -- 修改WAL相关参数
  9. ALTER SYSTEM SET wal_buffers = '16MB';
  10. ALTER SYSTEM SET checkpoint_completion_target = 0.9;
  11. -- 修改连接相关参数
  12. ALTER SYSTEM SET max_connections = 200;
  13. ALTER SYSTEM SET shared_preload_libraries = 'pg_stat_statements';
  14. -- 重启使设置生效
  15. SELECT pg_reload_conf();
复制代码

高级维护技巧

索引维护

索引是提高查询性能的关键,但需要适当维护以保持高效。

随着时间推移,索引可能会变得膨胀,影响性能。定期重建索引可以提高效率。
  1. -- 使用REINDEX重建索引
  2. REINDEX INDEX index_name;
  3. -- 重建表上的所有索引
  4. REINDEX TABLE table_name;
  5. -- 重建整个数据库的所有索引
  6. REINDEX DATABASE database_name;
复制代码

对于大型表,可以使用CONCURRENTLY选项在线重建索引,避免锁定表。
  1. -- 并行重建索引(不锁定表)
  2. REINDEX INDEX CONCURRENTLY index_name;
  3. -- 并行重建表上的所有索引
  4. REINDEX TABLE CONCURRENTLY table_name;
复制代码

注意:CONCURRENTLY选项需要更多的资源和时间,但不会阻塞读写操作。

分析索引的使用情况,识别未使用的索引:
  1. -- 查找未使用的索引
  2. SELECT schemaname, tablename, indexname, pg_size_pretty(pg_relation_size(indexname::regclass)) AS index_size
  3. FROM pg_stat_user_indexes
  4. WHERE idx_scan = 0
  5. ORDER BY pg_relation_size(indexname::regclass) DESC;
复制代码

对于大型表,考虑创建部分索引以减少索引大小和维护开销:
  1. -- 创建部分索引(只索引满足条件的行)
  2. CREATE INDEX idx_active_users ON users (username) WHERE status = 'active';
复制代码

表空间管理

表空间允许将数据库对象存储在不同的位置,有助于提高I/O性能和管理存储。
  1. -- 创建表空间
  2. CREATE TABLESPACE fastspace LOCATION '/mnt/ssd/postgresql/fastspace';
  3. -- 创建表空间并指定所有者
  4. CREATE TABLESPACE fastspace OWNER dbuser LOCATION '/mnt/ssd/postgresql/fastspace';
复制代码
  1. -- 在特定表空间创建表
  2. CREATE TABLE products (
  3.     product_id integer,
  4.     name text,
  5.     price numeric
  6. ) TABLESPACE fastspace;
  7. -- 将现有表移动到新表空间
  8. ALTER TABLE products SET TABLESPACE fastspace;
  9. -- 在特定表空间创建索引
  10. CREATE INDEX idx_product_name ON products (name) TABLESPACE fastspace;
复制代码
  1. -- 查看表空间信息
  2. SELECT spcname AS tablespace_name,
  3.        pg_size_pretty(pg_tablespace_size(spcname)) AS size
  4. FROM pg_tablespace;
  5. -- 查看数据库对象在表空间中的分布
  6. SELECT nspname AS schema_name,
  7.        relname AS table_name,
  8.        spcname AS tablespace_name
  9. FROM pg_class pgc
  10. JOIN pg_namespace pgn ON pgc.relnamespace = pgn.oid
  11. JOIN pg_tablespace pgts ON pgc.reltablespace = pgts.oid
  12. WHERE relkind = 'r'  -- 只显示表
  13. ORDER BY nspname, relname;
复制代码

统计信息收集

准确的统计信息对查询优化器至关重要。
  1. -- 对单个表收集统计信息
  2. ANALYZE table_name;
  3. -- 收集更详细的统计信息
  4. ANALYZE VERBOSE table_name;
  5. -- 设置统计信息目标(列的采样值数量)
  6. ALTER TABLE table_name ALTER COLUMN column_name SET STATISTICS 1000;
  7. -- 收集特定列的统计信息
  8. ANALYZE table_name (column_name);
复制代码
  1. -- 查看默认统计信息目标
  2. SHOW default_statistics_target;
  3. -- 修改默认统计信息目标
  4. ALTER SYSTEM SET default_statistics_target = 1000;
  5. SELECT pg_reload_conf();
复制代码

PostgreSQL支持创建扩展统计信息,帮助优化器更好地理解列之间的关系。
  1. -- 创建扩展统计信息
  2. CREATE STATISTICS stats_products_name_price (dependencies) ON name, price FROM products;
  3. -- 查看扩展统计信息
  4. SELECT stxrelid::regclass AS table_name,
  5.        stxname AS statistics_name,
  6.        stxkeys AS columns
  7. FROM pg_statistic_ext;
复制代码

紧急故障处理

常见故障类型

当客户端无法连接到PostgreSQL服务器时,可能是以下原因:

1. 服务器未运行:
  1. # 检查PostgreSQL服务状态
  2. systemctl status postgresql
  3. # 启动PostgreSQL服务
  4. systemctl start postgresql
复制代码

1. 连接限制:
  1. -- 查看当前连接数
  2. SELECT count(*) FROM pg_stat_activity;
  3. -- 查看最大连接数设置
  4. SHOW max_connections;
  5. -- 临时增加最大连接数(需要超级用户权限)
  6. ALTER SYSTEM SET max_connections = 300;
  7. SELECT pg_reload_conf();
复制代码

1. 网络问题:
  1. # 检查PostgreSQL端口是否监听
  2. netstat -tlnp | grep 5432
  3. # 检查防火墙设置
  4. iptables -L -n
复制代码

磁盘空间不足是导致PostgreSQL停止工作的常见原因。
  1. # 检查磁盘空间
  2. df -h
  3. # 查看PostgreSQL数据目录大小
  4. du -sh /var/lib/postgresql/main
  5. # 查看数据库大小
  6. SELECT pg_database.datname AS database_name,
  7.        pg_size_pretty(pg_database_size(pg_database.datname)) AS size
  8. FROM pg_database;
复制代码

解决方法:

1. 清理WAL日志:
  1. -- 检查WAL日志数量
  2. SELECT count(*) AS wal_files FROM pg_ls_waldir();
  3. -- 设置checkpoint以清理WAL
  4. CHECKPOINT;
复制代码

1. 清理旧数据:
  1. -- 删除旧数据
  2. DELETE FROM old_table WHERE date < current_date - interval '1 year';
  3. -- 执行VACUUM回收空间
  4. VACUUM VERBOSE old_table;
复制代码

1. 扩展表空间:
  1. # 添加新的磁盘空间到表空间
  2. lvextend -L +10G /dev/vg00/lv_postgres
  3. resize2fs /dev/vg00/lv_postgres
复制代码

查询突然变慢可能由多种原因引起。

1. 锁争用:
  1. -- 查看当前锁
  2. SELECT locktype, relation::regclass, mode, pid
  3. FROM pg_locks
  4. WHERE NOT granted;
  5. -- 查看被阻塞的查询
  6. SELECT blocked_locks.pid AS blocked_pid,
  7.        blocked_activity.usename AS blocked_user,
  8.        blocking_locks.pid AS blocking_pid,
  9.        blocking_activity.usename AS blocking_user,
  10.        blocked_activity.query AS blocked_statement,
  11.        blocking_activity.query AS current_statement_in_blocking_process
  12. FROM pg_catalog.pg_locks blocked_locks
  13. JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
  14. JOIN pg_catalog.pg_locks blocking_locks
  15.     ON blocking_locks.locktype = blocked_locks.locktype
  16.     AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE
  17.     AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
  18.     AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
  19.     AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
  20.     AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
  21.     AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
  22.     AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
  23.     AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
  24.     AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
  25.     AND blocking_locks.pid != blocked_locks.pid
  26. JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
  27. WHERE NOT blocked_locks.GRANTED;
复制代码

1. 统计信息过时:
  1. -- 更新统计信息
  2. ANALYZE VERBOSE;
复制代码

1. 索引问题:
  1. -- 检查损坏的索引
  2. REINDEX TABLE CONCURRENTLY problem_table;
复制代码

故障诊断方法

PostgreSQL日志是诊断问题的首要资源。
  1. -- 查看日志设置
  2. SHOW log_destination;
  3. SHOW logging_collector;
  4. SHOW log_directory;
  5. SHOW log_filename;
  6. -- 启用详细日志
  7. ALTER SYSTEM SET log_min_messages = 'INFO';
  8. ALTER SYSTEM SET log_min_error_statement = 'ERROR';
  9. ALTER SYSTEM SET log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h ';
  10. SELECT pg_reload_conf();
复制代码

使用外部工具分析日志:
  1. # 使用pgBadger分析日志
  2. pgbadger /var/log/postgresql/postgresql-*.log -o report.html
复制代码

使用系统工具监控PostgreSQL资源使用情况:
  1. # 使用top监控进程
  2. top -p $(pgrep -o postgres)
  3. # 使用iotop监控I/O
  4. iotop -p $(pgrep -o postgres)
  5. # 使用vmstat监控内存和交换
  6. vmstat 1
  7. # 使用iostat监控磁盘I/O
  8. iostat -xz 1
复制代码

分析慢查询的执行计划:
  1. -- 获取查询的执行计划
  2. EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON) SELECT * FROM large_table WHERE condition;
  3. -- 查看查询统计信息
  4. SELECT query, calls, total_time, mean_time, rows, 100.0 * shared_blks_hit / nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent
  5. FROM pg_stat_statements
  6. ORDER BY total_time DESC
  7. LIMIT 10;
复制代码

恢复策略

时间点恢复允许将数据库恢复到特定时间点。

1. 准备基础备份:
  1. # 使用pg_basebackup创建基础备份
  2. pg_basebackup -D /backup/basebackup -Ft -z -P -U replication_user
复制代码

1. 配置恢复:
  1. # 创建恢复配置文件
  2. echo "restore_command = 'cp /mnt/wal_archive/%f %p'" > /backup/basebackup/recovery.conf
  3. echo "recovery_target_time = '2023-05-15 14:30:00'" >> /backup/basebackup/recovery.conf
复制代码

1. 启动恢复:
  1. # 启动PostgreSQL进行恢复
  2. pg_ctl -D /backup/basebackup start
复制代码

从逻辑备份恢复:
  1. # 从SQL备份恢复
  2. psql -U username -d dbname -f backup.sql
  3. # 从自定义格式备份恢复
  4. pg_restore -U username -d dbname -v backup.dump
复制代码

从物理备份恢复:
  1. # 停止PostgreSQL
  2. pg_ctl stop -D /var/lib/postgresql/main
  3. # 备份当前数据目录
  4. mv /var/lib/postgresql/main /var/lib/postgresql/main.bak
  5. # 恢复基础备份
  6. mkdir /var/lib/postgresql/main
  7. tar -xzf backup.tar.gz -C /var/lib/postgresql/main
  8. # 配置恢复
  9. echo "restore_command = 'cp /mnt/wal_archive/%f %p'" > /var/lib/postgresql/main/recovery.conf
  10. # 启动PostgreSQL
  11. pg_ctl start -D /var/lib/postgresql/main
复制代码

在严重损坏的情况下,可能需要使用紧急修复模式。
  1. # 以单用户模式启动PostgreSQL
  2. postgres --single -D /var/lib/postgresql/main dbname
  3. # 在单用户模式下执行SQL命令
  4. SELECT pg_start_backup('emergency_repair');
  5. -- 执行修复操作
  6. SELECT pg_stop_backup();
复制代码

最佳实践

高可用性配置

PostgreSQL流复制提供高可用性和读扩展能力。

1. 主服务器配置:
  1. -- 在postgresql.conf中设置
  2. wal_level = replica
  3. max_wal_senders = 3
  4. max_replication_slots = 3
  5. synchronous_commit = on
  6. synchronous_standby_names = 'standby1,standby2'
复制代码

1. 创建复制用户:
  1. CREATE USER replication_user REPLICATION LOGIN CONNECTION LIMIT 3 PASSWORD 'secure_password';
复制代码

1. 配置pg_hba.conf:
  1. # 允许复制连接
  2. host replication replication_user 192.168.1.0/24 md5
复制代码

1. 备用服务器设置:
  1. # 使用pg_basebackup创建备用服务器
  2. pg_basebackup -h primary_host -D /var/lib/postgresql/main -U replication_user -X stream -P
  3. # 创建standby.signal文件
  4. touch /var/lib/postgresql/main/standby.signal
  5. # 配置primary_conninfo
  6. echo "primary_conninfo = 'host=primary_host port=5432 user=replication_user password=secure_password'" >> /var/lib/postgresql/main/postgresql.auto.conf
复制代码

在主服务器故障时,将备用服务器提升为主服务器:
  1. # 在备用服务器上执行
  2. pg_ctl promote -D /var/lib/postgresql/main
复制代码

或者使用触发器文件:
  1. # 创建触发器文件
  2. touch /var/lib/postgresql/main/failover.trigger
复制代码

使用工具如Patroni或repmgr实现自动故障转移:
  1. # 使用Patroni示例
  2. # 安装Patroni
  3. pip install patroni
  4. # 创建Patroni配置文件
  5. cat > /etc/patroni.yml <<EOF
  6. scope: postgres-cluster
  7. namespace: /service/
  8. name: postgresql1
  9. restapi:
  10.   listen: 192.168.1.100:8008
  11.   connect_address: 192.168.1.100:8008
  12. etcd:
  13.   hosts: 192.168.1.100:2379
  14. bootstrap:
  15.   dcs:
  16.     ttl: 30
  17.     loop_wait: 10
  18.     retry_timeout: 10
  19.     maximum_lag_on_failover: 1048576
  20.     postgresql:
  21.       use_pg_rewind: true
  22.       parameters:
  23.         wal_level: replica
  24.         hot_standby: "on"
  25.         wal_keep_size: 1GB
  26.         max_wal_senders: 5
  27.         max_replication_slots: 5
  28.         hot_standby_feedback: on
  29. postgresql:
  30.   listen: 0.0.0.0:5432
  31.   connect_address: 192.168.1.100:5432
  32.   data_dir: /var/lib/postgresql/main
  33.   bin_dir: /usr/lib/postgresql/13/bin
  34.   pgpass: /tmp/pgpass
  35.   authentication:
  36.     replication:
  37.       username: replicator
  38.       password: rep-pass
  39.     superuser:
  40.       username: postgres
  41.       password: secretpassword
  42.   parameters:
  43.     unix_socket_directories: /var/run/postgresql
  44. tags:
  45.     nofailover: false
  46.     noloadbalance: false
  47.     clonefrom: false
  48.     nosync: false
  49. EOF
  50. # 启动Patroni
  51. patroni /etc/patroni.yml
复制代码

安全性考虑

1. pg_hba.conf配置:
  1. # 只允许特定IP访问
  2. host    all             all             192.168.1.0/24            md5
  3. # 要求SSL连接
  4. hostssl all             all             0.0.0.0/0                 md5
复制代码

1. 角色和权限管理:
  1. -- 创建角色
  2. CREATE ROLE read_only;
  3. GRANT CONNECT ON DATABASE mydb TO read_only;
  4. GRANT USAGE ON SCHEMA public TO read_only;
  5. GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only;
  6. -- 创建用户并分配角色
  7. CREATE USER user1 WITH PASSWORD 'secure_password';
  8. GRANT read_only TO user1;
复制代码

1. 传输加密:
  1. -- 在postgresql.conf中启用SSL
  2. ssl = on
  3. ssl_cert_file = 'server.crt'
  4. ssl_key_file = 'server.key'
复制代码

1. 数据加密:
  1. -- 使用pgcrypto扩展加密数据
  2. CREATE EXTENSION pgcrypto;
  3. -- 创建加密列
  4. CREATE TABLE sensitive_data (
  5.     id serial PRIMARY KEY,
  6.     encrypted_data bytea
  7. );
  8. -- 插入加密数据
  9. INSERT INTO sensitive_data (encrypted_data)
  10. VALUES (encrypt('Secret data', 'encryption_key', 'aes'));
  11. -- 查询解密数据
  12. SELECT convert_from(decrypt(encrypted_data, 'encryption_key', 'aes'), 'SQL_ASCII')
  13. FROM sensitive_data;
复制代码
  1. -- 安装pgAudit扩展
  2. CREATE EXTENSION pgaudit;
  3. -- 配置审计日志
  4. ALTER SYSTEM SET pgaudit.log = 'all';
  5. ALTER SYSTEM SET pgaudit.log_catalog = off;
  6. ALTER SYSTEM SET pgaudit.log_level = notice;
  7. SELECT pg_reload_conf();
复制代码

升级与迁移

PostgreSQL主版本升级需要特殊处理,因为数据文件格式可能不兼容。

1. 使用pg_dumpall:
  1. # 从旧版本导出数据
  2. pg_dumpall -U postgres -h old_host -p 5432 > full_backup.sql
  3. # 导入到新版本
  4. psql -U postgres -h new_host -p 5432 -f full_backup.sql
复制代码

1. 使用pg_upgrade:
  1. # 安装新版本PostgreSQL但不初始化数据目录
  2. # 停止旧版本PostgreSQL
  3. pg_ctl -D /var/lib/postgresql/old_version stop
  4. # 运行pg_upgrade
  5. /usr/lib/postgresql/13/bin/pg_upgrade \
  6.   -b /usr/lib/postgresql/12/bin \
  7.   -B /usr/lib/postgresql/13/bin \
  8.   -d /var/lib/postgresql/12/main \
  9.   -D /var/lib/postgresql/13/main \
  10.   -j 4  # 使用4个CPU核心并行处理
  11. # 启动新版本PostgreSQL
  12. pg_ctl -D /var/lib/postgresql/13/main start
复制代码
  1. # 使用pg_dump和pg_restore进行跨平台迁移
  2. pg_dump -Ft -U source_user -h source_host source_db > source_db.tar
  3. # 在目标服务器上恢复
  4. pg_restore -U target_user -h target_host -d target_db -v source_db.tar
复制代码

1. 迁移前准备:
  1. -- 在源数据库上分析表大小
  2. SELECT schemaname, tablename, pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) as size
  3. FROM pg_tables
  4. WHERE schemaname = 'public'
  5. ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;
  6. -- 检查依赖对象
  7. SELECT nspname AS schema_name, relname AS table_name,
  8.        pg_get_userbyid(relowner) AS owner,
  9.        relkind AS object_type
  10. FROM pg_class
  11. JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid
  12. WHERE relkind IN ('r', 'S', 'v', 'm', 'f')
  13. AND nspname NOT IN ('pg_catalog', 'information_schema')
  14. ORDER BY nspname, relname;
复制代码

1. 迁移脚本示例:
  1. #!/bin/bash
  2. # 设置变量
  3. SOURCE_HOST="source.example.com"
  4. SOURCE_USER="source_user"
  5. SOURCE_DB="source_db"
  6. TARGET_HOST="target.example.com"
  7. TARGET_USER="target_user"
  8. TARGET_DB="target_db"
  9. DUMP_FILE="/tmp/source_db.dump"
  10. # 导出数据
  11. echo "Exporting data from source..."
  12. pg_dump -Fc -U $SOURCE_USER -h $SOURCE_HOST -d $SOURCE_DB -f $DUMP_FILE
  13. # 传输数据
  14. echo "Transferring data to target server..."
  15. scp $DUMP_FILE $TARGET_USER@$TARGET_HOST:/tmp/
  16. # 在目标服务器上恢复数据
  17. echo "Restoring data on target server..."
  18. ssh $TARGET_USER@$TARGET_HOST "pg_restore -U $TARGET_USER -d $TARGET_DB -v /tmp/source_db.dump"
  19. # 清理
  20. echo "Cleaning up..."
  21. rm $DUMP_FILE
  22. ssh $TARGET_USER@$TARGET_HOST "rm /tmp/source_db.dump"
  23. echo "Migration completed successfully."
复制代码

结论

PostgreSQL线上维护是一项复杂但至关重要的任务,涵盖了从日常备份到紧急故障处理的多个方面。通过实施本文介绍的策略和最佳实践,数据库管理员可以确保PostgreSQL数据库的稳定高效运行。

关键要点包括:

1. 建立可靠的备份策略,包括物理备份和逻辑备份,并定期验证备份的可用性。
2. 执行定期的维护任务,如VACUUM和ANALYZE,以保持数据库性能。
3. 持续监控数据库性能,及时识别和解决潜在问题。
4. 实施高可用性解决方案,如流复制,以减少停机时间。
5. 制定详细的故障恢复计划,并定期进行演练。
6. 遵循安全最佳实践,包括适当的访问控制和数据加密。
7. 在升级和迁移过程中谨慎操作,确保数据完整性。

通过系统化的维护方法和持续改进,组织可以最大限度地发挥PostgreSQL的潜力,支持关键业务应用的稳定运行。记住,数据库维护不是一次性任务,而是一个持续的过程,需要专业知识、细致规划和严格执行。
「七転び八起き(ななころびやおき)」
回复

使用道具 举报

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

本版积分规则