Skip to content

PostgreSQL 常用维护命令

表维护命令

表维护是确保PostgreSQL数据库性能稳定的重要操作,主要包括VACUUM、ANALYZE等命令。

1. VACUUM命令

VACUUM命令用于回收表中被删除元组占用的空间,防止表膨胀,提高查询性能。

sql
-- 基本VACUUM操作,仅回收空间,不更新统计信息
VACUUM table_name;

-- VACUUM所有表
VACUUM;

-- 查看VACUUM进度
SELECT pid, datname, relname, phase, heap_blks_total, heap_blks_scanned, heap_blks_vacuumed, index_vacuum_count FROM pg_stat_progress_vacuum;

-- 分析表,更新统计信息
ANALYZE table_name;

-- VACUUM并分析表
VACUUM ANALYZE table_name;

-- 完整VACUUM,会阻塞表,但回收更多空间
VACUUM FULL table_name;

-- 自动VACUUM配置查看
SELECT name, setting, short_desc FROM pg_settings WHERE name LIKE '%autovacuum%';

2. 表膨胀检查

表膨胀会导致磁盘空间浪费和性能下降,以下命令可以帮助检查表膨胀情况:

sql
-- 检查表的大小和膨胀情况
SELECT
  relname AS table_name,
  pg_size_pretty(pg_table_size(c.oid)) AS table_size,
  pg_size_pretty(pg_indexes_size(c.oid)) AS index_size,
  pg_size_pretty(pg_total_relation_size(c.oid)) AS total_size
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname NOT IN ('pg_catalog', 'information_schema')
  AND c.relkind = 'r'
ORDER BY pg_total_relation_size(c.oid) DESC;

索引维护命令

索引维护可以确保索引的高效使用,包括重建索引、检查索引有效性等操作。

1. 重建索引

当索引出现碎片或性能下降时,需要重建索引:

sql
-- 重建单个索引
REINDEX INDEX index_name;

-- 重建表的所有索引
REINDEX TABLE table_name;

-- 重建数据库的所有索引
REINDEX DATABASE database_name;

-- 重建系统表索引
REINDEX SYSTEM database_name;

-- 并发重建索引(PostgreSQL 12+),不阻塞写操作
REINDEX INDEX CONCURRENTLY index_name;

-- 查看REINDEX进度
SELECT pid, datname, relname, command, phase, blocks_total, blocks_done FROM pg_stat_progress_create_index WHERE command = 'REINDEX';

2. 索引有效性检查

检查索引是否有效,排除损坏的索引:

sql
-- 检查索引是否有效
SELECT indexrelid::regclass AS index_name, indisvalid FROM pg_index WHERE indrelid = 'table_name'::regclass;

-- 验证索引结构完整性
SELECT bt_index_check(indexrelid) FROM pg_index WHERE indrelid = 'table_name'::regclass AND indisunique;

3. 冗余索引识别

识别并清理冗余索引,减少维护开销:

sql
-- 查找可能的冗余索引(简化版)
SELECT
  schemaname,
  tablename,
  indexname,
  indexdef
FROM pg_indexes
WHERE schemaname NOT IN ('pg_catalog', 'information_schema')
ORDER BY schemaname, tablename, indexname;

系统维护命令

系统级别的维护命令用于监控和管理PostgreSQL实例的整体状态。

1. 数据库刷新

刷新数据库的各种缓存和统计信息:

sql
-- 刷新规划器统计信息
SELECT pg_stat_reset();

-- 刷新表统计信息
SELECT pg_stat_reset_single_table_counters('table_name'::regclass);

-- 刷新数据库统计信息
SELECT pg_stat_reset_shared('database');

-- 刷新WAL统计信息
SELECT pg_stat_reset_shared('wal');

2. 连接管理

管理数据库连接,清理空闲或异常连接:

sql
-- 查看所有连接
SELECT pid, usename, datname, application_name, client_addr, state, query_start, now() - query_start AS duration FROM pg_stat_activity;

-- 终止指定连接
SELECT pg_terminate_backend(pid);

-- 优雅终止连接(等待事务完成)
SELECT pg_cancel_backend(pid);

-- 终止所有空闲连接
SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE state = 'idle' AND pid <> pg_backend_pid();

3. 配置重载

重新加载配置文件,使修改后的配置生效:

sql
-- 重新加载配置文件
SELECT pg_reload_conf();

-- 查看配置文件位置
SHOW config_file;
SHOW hba_file;
SHOW ident_file;

备份和恢复相关命令

备份和恢复是数据库维护的重要组成部分,以下是常用的相关命令:

1. 备份命令

sql
-- 使用pg_dump备份单个数据库
pg_dump -h host -p port -U user -F c -b -v -f backup_file.backup database_name

-- 使用pg_dumpall备份所有数据库
pg_dumpall -h host -p port -U user -v > all_databases.sql

-- 使用pg_basebackup进行基础备份
pg_basebackup -h host -p port -U replication_user -D backup_dir -F t -X stream -v

2. 恢复命令

sql
-- 使用pg_restore恢复数据库
pg_restore -h host -p port -U user -d database_name -v backup_file.backup

-- 使用psql恢复SQL备份
psql -h host -p port -U user -d database_name -f backup_file.sql

日志管理命令

日志管理有助于监控数据库活动和排查问题:

sql
-- 查看日志相关配置
SELECT name, setting, short_desc FROM pg_settings WHERE name LIKE '%log%';

-- 手动切换日志文件
SELECT pg_rotate_logfile();

-- 查看当前日志文件位置
SHOW log_directory;
SHOW log_filename;

常见问题(FAQ)

Q1:何时需要执行VACUUM操作?

A1:VACUUM操作的执行时机取决于以下因素:

  • 自动VACUUM通常会根据表的更新频率自动执行
  • 对于频繁更新的表,建议定期手动执行VACUUM ANALYZE
  • 当表膨胀率超过50%时,应考虑执行VACUUM FULL
  • 在执行大型删除操作后,应立即执行VACUUM

Q2:REINDEX和REINDEX CONCURRENTLY有什么区别?

A2:主要区别在于:

  • REINDEX会阻塞表的写操作,执行速度快
  • REINDEX CONCURRENTLY(PostgreSQL 12+)不会阻塞写操作,但执行时间更长
  • REINDEX CONCURRENTLY需要更多的磁盘空间
  • REINDEX CONCURRENTLY在重建过程中会创建一个临时索引

Q3:如何查看VACUUM或REINDEX的执行进度?

A3:可以使用以下命令查看执行进度:

sql
-- 查看VACUUM进度
SELECT pid, datname, relname, phase, heap_blks_total, heap_blks_scanned, heap_blks_vacuumed FROM pg_stat_progress_vacuum;

-- 查看REINDEX进度
SELECT pid, datname, relname, command, phase, blocks_total, blocks_done FROM pg_stat_progress_create_index WHERE command = 'REINDEX';

Q4:如何优化自动VACUUM的性能?

A4:可以通过调整以下参数优化自动VACUUM:

sql
-- 调整自动VACUUM工作内存
ALTER SYSTEM SET autovacuum_work_mem = '256MB';

-- 调整自动VACUUM最大进程数
ALTER SYSTEM SET autovacuum_max_workers = 4;

-- 调整自动VACUUM触发阈值
ALTER SYSTEM SET autovacuum_vacuum_threshold = 50;
ALTER SYSTEM SET autovacuum_vacuum_scale_factor = 0.1;

Q5:如何安全地终止一个长时间运行的维护操作?

A5:可以使用以下方法:

  • 对于VACUUM FULL和REINDEX,可以使用pg_terminate_backend(pid)强制终止
  • 对于VACUUM和ANALYZE,强制终止后可能需要重新执行
  • 建议使用pg_cancel_backend(pid)先尝试优雅终止,如无效再使用pg_terminate_backend(pid)
  • 终止操作可能导致表或索引处于不一致状态,需要验证