VCSA内置PostgreSQL数据库备份实战:pg_dump逻辑备份与恢复全攻略

发布时间:2026/9/10 6:34:22
VCSA内置PostgreSQL数据库备份实战:pg_dump逻辑备份与恢复全攻略 先说明一个背景我写这篇东西是因为最近接手了一台跑在 ESXi 上的 VCSA 6.0客户报障说 vCenter 服务全挂进管理界面一看根分区 100% 满。清理完日志和临时文件之后service-control --start vmware-invsvc还是起不来折腾了大半天才发现是内置 PostgreSQL 的数据目录里有大量残留 WAL 文件手动删掉之后服务才恢复正常。这件事让我意识到平时大家对 VCSA 的关注点都放在 Web Client、补丁、证书这些看得见摸得着的地方真正核心的配置和清单数据其实都在它自带的 PostgreSQL 数据库里而很多人从来没有想过要给这个库做一次主动备份。如果你也管着 VCSA或者你正在学习 vSphere 环境下的数据保护这篇文章就把我这次备份 VCSA 内置 PostgreSQL 数据库的完整过程、踩坑记录和最终可用的脚本方案写出来。内容不绕弯子直接讲怎么登录 VCSA 底层系统、怎么找到嵌入式数据库、怎么用 pg_dump 做逻辑备份、怎么恢复验证以及备份完怎么处理“服务起不来”“磁盘又满”等一系列后续细节。1. 备份前先搞清楚VCSA 里的 PostgreSQL 到底是什么角色1.1 VCSA 内置数据库的结构与职责VCSAvCenter Server Appliance本身就是一套优化过的 Linux 虚拟机里面预装了一个 PostgreSQL 实例这个实例承载了 vCenter 几乎所有核心业务数据。常见的库有 VCDBvCenter 配置和清单库、VUMDBUpdate Manager 数据库、SBRS 相关的组件库等。对于绝大多数中小型环境来说这个内置库就是 vCenter 的“大脑”——一旦损坏且没有备份重建 vCenter 几乎等于重新梳理全部主机、虚拟机、权限、告警规则和分布式交换机配置。需要注意VCSA 内置 PostgreSQL 的服务名不是直接的postgresql而是vmware-vpostgres。服务管理的底层工具是service-control不是 systemctlVCSA 6.x 时代还没有完全切到 systemd。第一次操作时不熟悉这套命令很容易用错启动方式这是后话。1.2 数据库备份不等于“快照备份”很多人习惯在 vSphere 里直接给 VCSA 打快照认为这样就算备份了。快照确实是很好的临时回滚手段但对于生产环境里的 VCSA长时间挂快照会带来两个问题一是快照文件持续膨胀占满存储二是 VCSA 内部对数据库文件的操作非常频繁长期带快照运行会影响磁盘 IO增加故障概率。快照只适合“准备升级前临时做一次”的场景而真正可长期保存、可移植、可验证的备份应该是数据库逻辑备份也就是 PostgreSQL 的 dump 文件。我个人的建议是快照用于短期回滚逻辑备份用于长期灾备。两者不可互相替代。这篇文章讲的备份方式正是后者。1.3 备份时机与频率的判断VCSA 内置库的备份不能过于频繁因为 pg_dump 全量备份会产生不小的 IO 和 CPU 消耗。对于中小环境几十台主机几百台虚拟机一周一次全量备份基本够用。如果环境变更频繁大量创建删除虚拟机、调整权限、批量增删主机建议把周期缩短到每天一次。另外在进行任何升级、补丁安装、证书更换、存储迁移操作之前必须手动触发一次备份。2. 实操第一步登进 VCSA 底层系统确认数据库引擎状态2.1 启用 SSH 和 Bash ShellVCSA 默认 SSH 是关闭的。要通过命令行操作内置数据库必须先在 VAMIVCSA 管理界面端口 5480里开启 SSH 和 Bash Shell。登录 https://vcsa-ip:5480使用 root 账号进入在“访问”-“SSH 和 Bash Shell”里把 SSH 服务设为“启用”Bash Shell 设为“启用”。这个操作本质是为了让你可以通过 SSH 连到 VCSA 的底层操作系统并在 shell 里执行 manage 命令。等备份完成后建议把 SSH 重新关闭减少暴露面。2.2 检查 vmware-vpostgres 服务状态SSH 登录 VCSA 后第一件事是确认数据库服务没有异常。service-control --status vmware-vpostgres正常输出会包含类似vmware-vpostgres is running的信息。如果服务是停止状态需要先启动service-control --start vmware-vpostgres如果出现服务起不来的情况不要急着继续备份先排查数据目录、磁盘空间、日志目录。那次客户的 VCSA 一直报vmware-invsvc起不来查到最后就是 postgresql 的 WAL 文件把数据目录塞满了数据库一直处于恢复状态。这种情况下备份出来的文件也不一定完整先修复再备份。2.3 查看磁盘空间是否足够数据库 dump 文件虽然通常不大但 VCSA 根分区本身就比较紧张。备份前必须确认/storage/db和/tmp目录所在分区的剩余空间df -h du -sh /storage/db/pgdata如果根分区剩余空间不到 10GB先把日志、临时文件、旧的备份清一清否则 dump 过程中磁盘写满容易把整个数据库目录搞出问题。2.4 确认数据库版本和连接方式VCSA 内置 PostgreSQL 的版本随 VCSA 版本不同而不同早期 6.0 用的是 PostgreSQL 9.3 左右6.5 之后版本有所提升7.0 之后可能更高。可以通过下面命令确认版本/opt/vmware/vpostgres/9.3/bin/psql --version具体路径以实际目录结构为准7.0 的 VCSA 中路径可能变成/opt/vmware/vpostgres/current/bin/psql。知道版本是为了避免后续恢复时出现工具版本不匹配问题。3. 核心备份操作用 pg_dump 和 pg_dumpall 做逻辑备份3.1 切换到 vpostgres 用户VCSA 内置 PostgreSQL 不允许 root 直接连接本地实例必须切换到名为vpostgres的操作系统用户。这个用户的 home 目录是/var/lib/vmware/vpostgres它拥有数据目录和数据库进程的权限。chsh -s /bin/bash vpostgres su - vpostgres为什么需要chsh因为 VCSA 里 vpostgres 用户默认 shell 是/bin/false直接su - vpostgres会直接退出。有的版本里 vpostgres 的 shell 本身就是可用的具体可以先grep vpostgres /etc/passwd看一下。如果已经是/bin/bash或/bin/sh就不用改。3.2 列出当前所有数据库切换用户后先看看实例里有哪些数据库/opt/vmware/vpostgres/9.3/bin/psql -U postgres -lVCSA 6.x 通常能看到的库包括VCDB、VUMDB和一些内部维护库。加-U postgres是因为 vpostgres 用户对应 PostgreSQL 的超级用户 postgres本地 socket 认证默认是 trust不需要密码。3.3 单库备份VCDB、VUMDB 分开处理对于 VCSA 来说最核心的库是 VCDB。建议每个业务库单独 dump这样恢复时更灵活单独一个库损坏时不会牵连其他库。/opt/vmware/vpostgres/9.3/bin/pg_dump -U postgres -Fc -d VCDB -f /tmp/VCDB_$(date %Y%m%d).dump /opt/vmware/vpostgres/9.3/bin/pg_dump -U postgres -Fc -d VUMDB -f /tmp/VUMDB_$(date %Y%m%d).dump参数说明-Fc表示自定义格式压缩比高配合pg_restore可以灵活恢复单表是运维备份首选。-f指定输出文件。$(date %Y%m%d)让文件名带上日期方便保留多份。如果库比较大可以加-j 4并发提升速度配合-Fd目录格式使用。需要注意的是-Fc是“自定义格式”不是明文 SQL不要拿文本编辑器打开看内容也不要直接 psql 导入。恢复要用pg_restore这一点新手很容易搞错。如果不放心可以加一条明文 SQL 备份作为双保险/opt/vmware/vpostgres/9.3/bin/pg_dump -U postgres -d VCDB -f /tmp/VCDB_$(date %Y%m%d).sql3.4 全实例备份pg_dumpall 的适用场景如果想一次性把所有数据库和全局对象角色、表空间、权限都导出来可以使用pg_dumpall/opt/vmware/vpostgres/9.3/bin/pg_dumpall -U postgres -f /tmp/vpostgres_all_$(date %Y%m%d).sqlpg_dumpall默认输出明文 SQL包含角色定义、表空间定义和所有数据库的完整数据。它的优点是“全”缺点是恢复时是一条大 SQL没有单表恢复能力。作为 VCSA 的应急兜底方案很合适但日常我仍以分库pg_dump -Fc为主。为什么不能只用 pg_dumpall因为 VCSA 里的库之间可能有依赖关系跨库备份与恢复要格外小心。分库备份加全库备份等于“点”和“面”都有了。3.5 检查备份文件完整性备份完成后立即用ls -lh看文件大小是否合理。一个几百个虚拟机的环境VCDB 备份通常有几十到几百 MB如果你导出来只有几 KB很可能是连接到了错误实例或者 dump 过程被中断。还可以用 pg_restore 查看归档内容/opt/vmware/vpostgres/9.3/bin/pg_restore -l /tmp/VCDB_$(date %Y%m%d).dump | head -20如果能看到表、索引、序列等信息说明备份文件结构正常。这一步虽然简单但能从源头避免“备份了个寂寞”。3.6 备份文件必须复制出 VCSA备份文件如果只留在 VCSA 本机的/tmp那等于白备份——VCSA 本身盘挂了文件也没了。需要把 dump 文件下载到本地电脑或复制到独立的备份存储。我个人常用方法# 在本地电脑执行 scp rootvcsa-ip:/tmp/VCDB_*.dump /backup/vcsa/ scp rootvcsa-ip:/tmp/vpostgres_all_*.sql /backup/vcsa/如果有集中备份服务器也可以从 VCSA 反向推送到 NFS 共享或 FTP。注意 scp 在 VCSA 6.0 上默认可能不带可以改用 SFTP 工具如 WinSCP、FileZilla通过 SSH 协议下载。下载完成后再回到 VCSA 清理/tmp下的临时文件避免给本来就紧张的磁盘添堵。4. 恢复演练验证备份能否真正救命备份不经过恢复验证就不能叫备份只能叫“心理安慰”。我建议每次备份后都至少在测试环境做一次恢复演练尤其是第一次搭建备份方案时必须完整走一遍恢复流程。4.1 在临时实例上恢复 dump 文件在 VCSA 上不要随意覆盖现有数据库。恢复演练最好在另外一套环境比如一台安装了相同 PostgreSQL 版本的 Linux 虚拟机上进行。# 先创建一个空库 /opt/vmware/vpostgres/9.3/bin/createdb -U postgres VCDB_test # 用 pg_restore 恢复自定义格式备份 /opt/vmware/vpostgres/9.3/bin/pg_restore -U postgres -d VCDB_test /tmp/VCDB_$(date %Y%m%d).dump如果备份是明文 SQL/opt/vmware/vpostgres/9.3/bin/psql -U postgres -d VCDB_test -f /tmp/VCDB_$(date %Y%m%d).sql4.2 恢复常见报错与处理恢复过程中大概率会遇到对象已存在、权限不足、序列冲突等问题。VCSA 内置库依赖很强直接恢复到全新库时部分扩展如plpgsql可能需要提前创建。pg_restore加--clean和--if-exists可以清理已存在对象并容错/opt/vmware/vpostgres/9.3/bin/pg_restore -U postgres -d VCDB_test --clean --if-exists /tmp/VCDB_$(date %Y%m%d).dump需要注意正式恢复进 VCSA 的库时--clean要非常谨慎它会先删掉现有对象再创建操作不当会加重破坏。这也是为什么我强调恢复演练一定要在独立环境先做。4.3 恢复后验证清单恢复完可以执行几个查询验证数据SELECT count(*) FROM vpx_vm; SELECT count(*) FROM vpx_host; SELECT count(*) FROM vpx_alarm;如果查询结果和备份前对得上说明库基本可用。如果能启动 vCenter 服务并正常显示清单才算恢复成功。VCSA 的组件之间习惯相互调用数据库存储过程光看表数量还不够。5. 自动化备份脚本让备份变成习惯而不是临时抱佛脚5.1 脚本核心思路手动备份容易忘记生产环境一定要写成脚本配合 crontab 定时执行。脚本的核心逻辑是检查 db 服务状态。创建备份目录区分日期。执行 pg_dumpall 和分库 pg_dump。删除超过保留天数的旧备份。可选推送备份到远端备份服务器。5.2 可直接使用的备份脚本下面这个脚本我在 VCSA 6.0 上验证过VCSA 6.5、6.7 也能用核心是路径要根据find /opt/vmware/vpostgres -name psql的结果调整。#!/bin/bash export PATH/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin DATE$(date %Y%m%d_%H%M%S) BK_DIR/storage/backup/vcsa-pg RETENTION_DAYS14 PGBIN/opt/vmware/vpostgres/9.3/bin PGUSERpostgres mkdir -p ${BK_DIR}/${DATE} # 检查数据库服务 ${PGBIN}/pg_isready -U ${PGUSER} /dev/null 21 if [ $? -ne 0 ]; then echo [ERROR] PostgreSQL is not ready at ${DATE} ${BK_DIR}/backup.log exit 1 fi # 全实例备份 ${PGBIN}/pg_dumpall -U ${PGUSER} -f ${BK_DIR}/${DATE}/all_databases.sql # 分库备份按需调整库名 for DB in VCDB VUMDB; do ${PGBIN}/pg_dump -U ${PGUSER} -Fc -d ${DB} -f ${BK_DIR}/${DATE}/${DB}.dump done # 清理旧备份 find ${BK_DIR} -maxdepth 1 -type d -mtime ${RETENTION_DAYS} -exec rm -rf {} \; echo [OK] Backup completed at ${DATE} ${BK_DIR}/backup.log关于脚本有两个细节说明备份目录我习惯放在/storage/backup而不是/tmp因为 VCSA 临时目录容易在重启后被清理而且/tmp空间通常不大。保留天数写了 14对于大多数环境足够了。如果想要更长保留周期可以放到外部存储再归档。5.3 配置 crontab 定时任务使用 root 身份执行crontab -e添加一行0 1 * * 0 /root/backup_vcsa_pg.sh /dev/null 21这表示每周日凌晨 1 点执行一次。如果变更频繁可以改成每天一次0 1 * * *。5.4 注意 VCSA 系统升级后脚本路径变化VCSA 大版本升级后PostgreSQL 的安装路径可能从/opt/vmware/vpostgres/9.3变成/opt/vmware/vpostgres/current或者二进制版本变成 12、14 等。脚本里的路径要跟着改。我吃过一次亏升级 VCSA 后脚本报错找不到 psql但 crontab 又不会弹邮件提醒直到某天要恢复备份才发现过去一个月备份全是空目录。6. 常见问题与排查技巧实录6.1 磁盘满导致 vpostgres 无法启动这是 VCSA 最经典的“隐形杀手”。根分区一旦满了vmware-vpostgres会拒绝启动同时service-control --start vmware-invsvc这类命令也会因为依赖的数据库还挂着而反复失败。排查时先别急着重启服务按这个顺序处理# 查看空间占用 df -h # 找到大文件目录 du -xh --max-depth2 / 2/dev/null | sort -rh | head -20常见占用大头是/storage/log、/storage/db/pgdata/pg_xlog或pg_wal以及/tmp。清理时不要直接删数据目录文件优先清/storage/log下旧日志再考虑 WAL 归档。6.2psql: could not connect to server: No such file or directory执行 psql 连不上很多情况下是因为 socket 目录不对。VCSA 默认 socket 路径可能是/var/run/vmware/vpostgres使用 psql 时指定-h为 socket 目录位置/opt/vmware/vpostgres/9.3/bin/psql -h /var/run/vmware/vpostgres -U postgres -l6.3 备份文件过大或者过小备份文件如果超出预期很多倍通常是因为 VCDB 里积累了太多历史性能数据、事件数据或任务数据。VCSA 6.x 里有vpx_history_*等表会保留大量历史数据。如果备份太大影响备份速度和迁移效率可以考虑在 vCenter 管理界面调整统计数据的保留时间或清理过期事件后再备份。备份文件如果过小比如 VCDB 导出来只有几 MB多见于 vCenter 运行时并没有把数据写入这个库数据库只是空壳或者你连到了错误的实例。VCSA 里可能同时存在postgres默认库和 VCDB 库注意区分。6.4 恢复时提示role vsphere does not existVCSA 内部库有很多专属角色和用户比如vsphere、vc、vumadmin等。如果你的分库 dump 文件没有包含全局角色定义只导出了表数据恢复到新实例时会因为角色缺失报错。解决办法是先恢复pg_dumpall生成的包含角色定义的文件再恢复分库数据或者在 pg_restore 前手动创建缺失角色。6.5 备份目录权限导致的执行失败VCSA 对操作系统用户的权限检查比较严格。如果/storage/backup目录是 root 创建的vpostgres 用户写不进去脚本会执行到 pg_dump 那一步失败。创建目录后记得授权mkdir -p /storage/backup/vcsa-pg chown -R vpostgres:vpostgres /storage/backup6.6 VCSA 7.0 及以上版本的备份差异VCSA 7.x 内置的 PostgreSQL 版本更高同时多了更多内部组件service-control --status看到的服务更多了。但核心思路不变找到vmware-vpostgres使用内置 psql 和 pg_dump。唯一要注意的是路径变成了/opt/vmware/vpostgres/current/bin/如果还按 9.3 找肯定会撞墙。另外VCSA 7 以后官方开始推荐用 VAMI 里的“备份与还原”功能做整体备份那个方式会把全套配置文件带出来恢复时更省事。不过数据库粒度的 pg_dump 备份仍然有独特价值——当只需要救援 VCDB 时它更直接。7. 备份策略与最终建议7.1 推荐的备份组合方案我把这套环境里最终落地的备份方案写出来供参考备份类型方式频率保存周期系统级快照vSphere 打快照升级/补丁前临时做升级完成后删除全库逻辑备份pg_dumpall每周30 天分库逻辑备份pg_dump -Fc每天14 天配置文件备份/etc/vmware-vpx 目录打包每周30 天配置文件打包虽然不属于数据库备份但对恢复 VCSA 同样重要。可以加一行脚本tar czf ${BK_DIR}/${DATE}/etc_vpx.tar.gz /etc/vmware-vpx7.2 卡片式经验如果从头再做一次根据我这次处理的经历如果再让我给一套新的 VCSA 建立备份机制我会按这个顺序走先在 VAMI 开启 SSH 和 Bash Shell。用df -h和du -sh摸清磁盘现状确保根分区有充足余量。确认 vmware-vpostgres 服务健康。手动执行一次分库 pg_dump 和 pg_dumpall测试命令路径和权限。把 dump 文件 scp 到外部存储验证文件大小。写自动化脚本加入 crontab。在测试环境做一次恢复演练。把 SSH 关掉只在需要维护时临时开启。7.3 我的一些额外提醒备份这事最怕的不是技术不懂而是“以为备份了”。我见过太多朋友拍着胸脯说“VCSA 我有快照”结果快照跟 VCSA 放在同一个数据存储里存储一坏全完也见过备份脚本跑了半年文件全是 0 字节因为脚本里的用户名写错了。一定要像验证生产数据一样去验证备份这与 vSphere 本身的稳定性同样重要。另外VCSA 的数据库备份有个天然局限直接恢复到同一台 VCSA 上不一定能完美还原整个 vCenter 全貌因为 VCSA 还有证书、身份来源、VAMI 配置等”库外“组件。所以如果你的目标是“整机灾难恢复”我更推荐结合 VAMI 的整体备份方案把数据库备份当作第一道防线和应急手段来用。两者搭配既能在关键时刻救回数据又能减少维护负担。