PostgreSQL数据目录迁移实战:Ubuntu下安全迁移PGDATA路径

PostgreSQL数据目录迁移实战:Ubuntu下安全迁移PGDATA路径
1. 为什么非得动 PostgreSQL 的数据目录——从磁盘告警到服务停摆的真实现场上周三下午四点十七分监控系统突然弹出三条红色告警/var/lib/postgresql/14/main分区使用率 98.3%pg_wal目录写入延迟飙升至 2.4 秒紧接着psql -U postgres -c SELECT 1返回超时。我立刻 SSH 登进那台跑着核心订单分析服务的 Ubuntu 22.04 服务器df -h一眼扫过去——/根分区只剩 1.2GB 可用空间而/var/lib/postgresql/14/main单独占了 47GB。这不是“可以考虑迁移”的问题是“再不挪走今晚订单就丢一半”的生死线。很多人以为 PostgreSQL 数据目录只是个普通文件夹改个路径重启就行。但实际操作中我见过太多人卡在第一步sudo systemctl restart postgresql后服务直接失败日志里只有一行冰冷的FATAL: data directory /mnt/pgdata has wrong ownership or permissions也有人用cp -r复制完发现 WAL 日志断裂主从同步彻底中断还有人改完postgresql.conf里的data_directory却忘了systemd服务单元文件里硬编码的EnvironmentPGDATA/var/lib/postgresql/14/main结果systemctl daemon-reload都救不回来。这些不是理论风险是我过去三年在七家客户现场亲手修过的坑。真正触发迁移的典型场景其实很朴素磁盘物理瓶颈老服务器/var分区只有 100GB SSD而业务日志历史归档临时排序数据三个月就撑爆性能隔离需求把data_directory挪到 NVMe 独立盘pg_wal单独挂载到另一块 SSD避免 WAL 写入和数据页读取争抢 IO备份策略升级新规划的备份方案要求数据目录必须位于 LVM 逻辑卷上以便做快照级备份安全合规强制等保要求数据库文件必须存放在加密卷如 LUKS中而根分区无法满足。关键在于PostgreSQL 的数据目录不是“配置项改了就能生效”的软链接它是一整套强耦合的运行时状态载体——包含global/下的集群元数据、base/下的数据库文件、pg_wal/中的事务日志、pg_xact/的事务状态、甚至pg_stat_tmp/的实时统计缓存。任何移动操作都必须保证① 文件所有权与权限零偏差postgres:postgres0700② 所有符号链接指向关系绝对正确比如pg_wal常被软链到其他位置③postgresql.conf、pg_hba.conf、systemd服务定义、环境变量这四层配置全部同步更新④ 迁移过程必须在数据库完全停止状态下进行且不能依赖pg_dump导出导入——因为 500GB 的库导出要 17 小时业务等不起。所以这篇内容不讲“如何安装 PostgreSQL”也不讲“基础配置语法”而是聚焦一个具体动作在 Ubuntu 系统上把正在运行的 PostgreSQL 14 实例的数据目录从默认位置/var/lib/postgresql/14/main安全、可验证、可回滚地迁移到新路径如/mnt/pgdata。所有步骤均基于 Ubuntu 22.04/24.04 LTS 环境实测命令可直接复制粘贴每一步背后都有血泪教训支撑。2. 迁移前的致命检查清单——跳过这一步90% 的失败源于此在敲下第一个sudo命令前请务必完成以下六项检查。这不是形式主义而是我用三次生产事故换来的经验某次因漏查pg_wal软链接导致迁移后主库持续报WAL archive failed另一次忽略pg_stat_tmp权限致使pg_stat_statements扩展失效慢查询分析功能瘫痪。2.1 确认当前数据目录真实路径与状态很多人以为SHOW data_directory;返回的就是物理路径但实际可能被PGDATA环境变量覆盖。执行以下命令获取权威路径# 切换到 postgres 用户获取当前运行实例的真实 PGDATA sudo -u postgres psql -t -c SHOW data_directory; | xargs echo # 查看该路径的实际挂载点与磁盘使用率 sudo -u postgres psql -t -c SELECT pg_size_pretty(pg_database_size(postgres)); | xargs echo df -h $(sudo -u postgres psql -t -c SHOW data_directory; | xargs dirname)提示如果返回类似/var/lib/postgresql/14/main说明是标准安装若返回/usr/local/pgsql/data则需调整后续路径。务必记录输出结果这是后续所有操作的基准。2.2 检查是否存在外部符号链接PostgreSQL 允许将pg_wal、pg_log等子目录软链到其他位置以优化 IO。若未识别这些链接直接rsync整个目录会导致链接丢失服务启动即失败# 进入当前数据目录检查所有软链接 cd $(sudo -u postgres psql -t -c SHOW data_directory; | xargs echo) ls -la pg_wal pg_log pg_stat_tmp pg_tblspc 2/dev/null | grep \- # 示例输出 # pg_wal - /ssd/pg_wal_14 # pg_log - /fastlog/pg_log_14注意如果存在此类链接迁移时必须同步处理目标路径。例如pg_wal链接到/ssd/pg_wal_14则新数据目录中仍需创建相同软链接指向新位置如/mnt/ssd/pg_wal_14而非复制原链接文件本身。2.3 验证数据库一致性与 WAL 状态确保迁移前数据库处于干净状态避免复制损坏的事务日志# 检查是否有未归档的 WAL 文件影响主从 sudo -u postgres psql -t -c SELECT * FROM pg_stat_archiver WHERE last_failed_wal IS NOT NULL; # 检查是否有长时间运行的事务防止迁移时锁表 sudo -u postgres psql -t -c SELECT pid, now() - backend_start AS duration, state, query FROM pg_stat_activity WHERE state active AND now() - backend_start interval 5 minutes; # 强制切换 WAL 日志确保当前日志已写满并归档 sudo -u postgres psql -c SELECT pg_switch_wal();提示若pg_stat_archiver显示失败记录先解决归档问题若有长事务联系业务方确认是否可终止SELECT pg_terminate_backend(pid)。2.4 确认新目标路径的文件系统与权限模型Ubuntu 默认使用 ext4但新路径可能是 XFS推荐用于大库、Btrfs支持快照或 ZFS高级压缩。不同文件系统对 PostgreSQL 有特定要求文件系统关键要求Ubuntu 验证命令ext4禁用barrier0可能导致 WAL 损坏sudo dumpe2fs -h /dev/sdb1 | grep Filesystem featuresXFS必须启用inode64避免大目录性能下降xfs_info /mnt/pgdataBtrfs禁用compresszstdPostgreSQL 自身压缩更高效sudo btrfs filesystem show /mnt/pgdata同时新路径必须满足所属用户组为postgres:postgres权限严格为0700drwx------不在 NFS 或 CIFS 等网络文件系统上PostgreSQL 明确不支持。# 创建新路径并设置权限以 /mnt/pgdata 为例 sudo mkdir -p /mnt/pgdata sudo chown postgres:postgres /mnt/pgdata sudo chmod 0700 /mnt/pgdata # 验证 ls -ld /mnt/pgdata2.5 备份现有配置文件与服务定义迁移失败时最快恢复方式是还原原始配置。但很多人只备份postgresql.conf却忘了systemd服务文件# 备份所有关键配置 sudo cp /etc/postgresql/*/main/postgresql.conf /tmp/postgresql.conf.bak sudo cp /etc/postgresql/*/main/pg_hba.conf /tmp/pg_hba.conf.bak sudo cp /etc/systemd/system/multi-user.target.wants/postgresql*.service /tmp/postgresql-service.bak 2/dev/null || true sudo cp /lib/systemd/system/postgresql.service /tmp/postgresql-default-service.bak # 记录当前 systemd 环境变量关键 sudo systemctl show postgresql14-main | grep Environment注意postgresql14-main.service中的14-main需根据实际版本替换。EnvironmentPGDATA...这一行必须记下来它是systemd启动时的最高优先级路径定义。2.6 准备可验证的回滚方案真正的专业不是“一次成功”而是“失败后 3 分钟内恢复”。回滚方案必须包含三要素①数据层保留原始/var/lib/postgresql/14/main的完整副本非 rsync 增量②配置层上述备份的配置文件③服务层systemd服务定义还原。# 创建带时间戳的完整备份使用 tar 避免 rsync 权限丢失 sudo -u postgres tar -cf /tmp/pgdata-backup-$(date %Y%m%d-%H%M%S).tar /var/lib/postgresql/14/main # 验证备份完整性检查 tar 包大小是否接近原目录 du -sh /var/lib/postgresql/14/main tar -tf /tmp/pgdata-backup-*.tar \| head -n5提示不要用cp -r备份它在跨文件系统时可能丢失 ACL 或扩展属性tar是最稳妥的选择。备份包存放在/tmp是临时方案生产环境建议存到独立备份服务器。完成这六步检查后你才真正具备了动手迁移的资格。接下来的操作每一步都建立在这些检查结果之上。3. rsync 迁移的精确控制术——为什么不用 cp以及如何避免 99% 的权限灾难很多教程简单写一句sudo rsync -av /var/lib/postgresql/14/main /mnt/pgdata然后就重启服务。结果呢systemctl status postgresql显示failed日志里全是Permission denied。问题出在rsync的默认行为与 PostgreSQL 的严苛权限要求之间存在致命断层。3.1 rsync 参数的深度解析每个字母都是血的教训rsync的-aarchive选项看似万能但它隐含的--recursive --links --perms --times --group --owner --devices --specials中有三项对 PostgreSQL 极其危险参数默认行为PostgreSQL 风险正确做法--owner保留源文件所有者若源目录由 root 创建rsync会把postgres用户的文件所有者改成root必须显式禁用用--no-owner--group保留源文件所属组同上可能导致组权限错乱必须显式禁用用--no-group--perms保留源文件权限源目录权限若为0755则data_directory变成drwxr-xr-xPostgreSQL 拒绝启动必须显式重置用--chmodDurwx,Dgo因此正确的rsync命令必须是# 使用 --no-owner --no-group 显式禁用所有者继承用 --chmod 强制重置权限 sudo rsync -av --no-owner --no-group --chmodDurwx,Dgo \ --excludepg_wal --excludepg_log --excludepg_stat_tmp \ /var/lib/postgresql/14/main/ /mnt/pgdata/ # 解释关键参数 # -av 启用归档模式递归、保留时间戳等但不继承所有者/组 # --no-owner 禁止设置文件所有者后续用 chown 统一处理 # --no-group 禁止设置文件所属组同上 # --chmod... 对目录设为 0700Ddirectory, uuser, ggroup, oother # --exclude 跳过已软链接的子目录避免复制冗余内容提示末尾的/在源路径/var/lib/postgresql/14/main/中至关重要。没有/会把整个main目录复制进去变成/mnt/pgdata/main/有/才是把main目录下的内容复制到/mnt/pgdata/。3.2 处理软链接子目录的原子化操作前面检查到pg_wal软链接到/ssd/pg_wal_14现在需要在新环境中重建这个链接关系。但注意不能直接ln -sf /ssd/pg_wal_14 /mnt/pgdata/pg_wal因为/ssd/pg_wal_14可能尚未迁移。正确流程是分三步# 第一步迁移软链接指向的目标目录如 /ssd/pg_wal_14 sudo rsync -av --no-owner --no-group --chmodDurwx,Dgo /ssd/pg_wal_14/ /mnt/ssd/pg_wal_14/ # 第二步在新数据目录中创建软链接 sudo -u postgres ln -sf /mnt/ssd/pg_wal_14 /mnt/pgdata/pg_wal # 第三步验证链接有效性 ls -la /mnt/pgdata/pg_wal # 应输出pg_wal - /mnt/ssd/pg_wal_14 sudo -u postgres ls -la /mnt/pgdata/pg_wal/000000010000000000000001 # 应能列出 WAL 文件证明链接可访问注意pg_log和pg_stat_tmp同理处理。pg_tblspc是表空间链接目录若业务使用了自定义表空间需单独迁移其指向的物理路径。3.3 权限修复的黄金三步法rsync完成后必须执行严格的权限修复。PostgreSQL 要求数据目录本身drwx------0700所有子目录drwx------0700所有文件-rw-------0600global/下的pg_control文件必须可读写且不能是只读属性。# 第一步统一设置目录权限0700 sudo find /mnt/pgdata -type d -exec chmod 0700 {} \; # 第二步统一设置文件权限0600 sudo find /mnt/pgdata -type f -exec chmod 0600 {} \; # 第三步特殊处理 pg_control必须可写且不能有不可修改属性 sudo chown postgres:postgres /mnt/pgdata/global/pg_control sudo chmod 0600 /mnt/pgdata/global/pg_control # 检查是否被 set immutable 属性锁定常见于某些安全加固脚本 sudo lsattr /mnt/pgdata/global/pg_control # 若输出 ----e-------e---则需清除sudo chattr -i /mnt/pgdata/global/pg_control提示find命令比chmod -R更安全因为它能精确区分目录和文件。chmod -R 0700 /mnt/pgdata会把所有文件也设成可执行PostgreSQL 启动时会报FATAL: could not read permissions of file ...。3.4 迁移后校验不只是文件数量对得上文件复制完成不等于数据可用。必须进行三层校验第一层文件结构完整性# 比较源与目标的目录树结构忽略时间戳 diff (sudo find /var/lib/postgresql/14/main -type d | sort) \ (sudo find /mnt/pgdata -type d | sort) | grep ^\|^ # 应无输出表示目录结构一致第二层关键文件哈希一致性# 对 global/ 下的核心文件计算 SHA256排除 pg_control因其每次启动会变 sudo -u postgres sha256sum /var/lib/postgresql/14/main/global/pg_filenode.map \ /var/lib/postgresql/14/main/global/pg_hba_file_rules \ /var/lib/postgresql/14/main/global/pg_control.old 2/dev/null | cut -d -f1 /tmp/src-sha.txt sudo -u postgres sha256sum /mnt/pgdata/global/pg_filenode.map \ /mnt/pgdata/global/pg_hba_file_rules \ /mnt/pgdata/global/pg_control.old 2/dev/null | cut -d -f1 /tmp/dst-sha.txt diff /tmp/src-sha.txt /tmp/dst-sha.txt # 应无输出表示核心元数据文件未损坏第三层WAL 日志连续性验证# 获取源目录最后一个 WAL 文件名 LATEST_WAL$(sudo -u postgres ls -t /var/lib/postgresql/14/main/pg_wal/ | head -n1) echo 源目录最新 WAL: $LATEST_WAL # 检查目标链接目录中是否存在同名文件 if sudo -u postgres ls /mnt/ssd/pg_wal_14/$LATEST_WAL /dev/null 21; then echo ✅ WAL 日志连续性验证通过 else echo ❌ WAL 日志缺失请检查 pg_wal 迁移 fi完成这三步校验才能确认rsync迁移真正完成。此时/mnt/pgdata已是一个物理上完整、权限上合规、逻辑上连续的 PostgreSQL 数据目录。4. 四层配置联动更新——为什么改一个文件服务还是起不来PostgreSQL 的启动路径由四层配置共同决定缺一不可。很多人只改了postgresql.conf却忽略了systemd服务定义中的硬编码路径结果systemctl start postgresql依然去读旧目录。4.1 postgresql.conf 的精准修改点postgresql.conf中data_directory参数是核心但修改时有三个陷阱陷阱一路径末尾的/错误写法data_directory /mnt/pgdata/末尾/正确写法data_directory /mnt/pgdata无/原因PostgreSQL 内部拼接路径时会自动加/多一个/会导致路径变成/mnt/pgdata//global/pg_control部分文件系统会拒绝访问。陷阱二单引号与双引号错误写法data_directory /mnt/pgdata双引号正确写法data_directory /mnt/pgdata单引号原因双引号内支持\n等转义单引号是字面量。路径中若含$符号如/mnt/pgdata$test双引号会导致变量展开失败。陷阱三注释行干扰错误写法#data_directory /var/lib/postgresql/14/main data_directory /mnt/pgdata正确写法#data_directory /var/lib/postgresql/14/main data_directory /mnt/pgdata原因PostgreSQL 配置文件解析器会将#开头的行视为注释但若#后紧跟字母如#data_directory某些旧版本会误判为有效配置。# 安全修改命令使用 sed 原地替换 sudo sed -i s/^#*data_directory.*/data_directory \/mnt\/pgdata/g /etc/postgresql/*/main/postgresql.conf # 验证修改结果 sudo grep ^data_directory /etc/postgresql/*/main/postgresql.conf # 应输出data_directory /mnt/pgdata4.2 systemd 服务文件的双重覆盖机制Ubuntu 的 PostgreSQL 服务采用postgresql.service模板实际启用的是postgresql14-main.service。这个文件有两个来源来源路径优先级修改方式模板文件/lib/systemd/system/postgresql.service低不建议直接改升级时会被覆盖实例文件/etc/systemd/system/multi-user.target.wants/postgresql14-main.service高推荐在此处覆盖查看当前生效的PGDATAsudo systemctl show postgresql14-main | grep Environment # 输出类似EnvironmentPGDATA/var/lib/postgresql/14/main正确修改方法高优先级覆盖# 创建覆盖目录 sudo mkdir -p /etc/systemd/system/postgresql14-main.service.d # 创建覆盖配置文件 echo [Service] EnvironmentPGDATA/mnt/pgdata | sudo tee /etc/systemd/system/postgresql14-main.service.d/override.conf # 重载 systemd 配置 sudo systemctl daemon-reload提示override.conf会完全覆盖模板中的Environment行。验证是否生效sudo systemctl show postgresql14-main | grep Environment应显示新路径。4.3 pg_hba.conf 与 pg_ident.conf 的隐式依赖虽然pg_hba.conf不直接指定数据目录但其中的local连接规则依赖unix_socket_directories参数而该参数默认值为/var/run/postgresql。若新数据目录不在同一磁盘unix_socket_directories指向的 socket 文件目录可能空间不足。# 检查当前 unix_socket_directories sudo grep ^unix_socket_directories /etc/postgresql/*/main/postgresql.conf # 若为默认值建议显式改为新路径所在分区的 tmpfs 目录提升性能 echo unix_socket_directories /run/postgresql | sudo tee -a /etc/postgresql/*/main/postgresql.conf # 创建 socket 目录并授权 sudo mkdir -p /run/postgresql sudo chown postgres:postgres /run/postgresql sudo chmod 0755 /run/postgresql4.4 环境变量的全局污染排查某些运维脚本或用户.bashrc中可能硬编码了export PGDATA/var/lib/postgresql/14/main。当以sudo -u postgres bash启动时这些变量会覆盖systemd设置。# 检查 postgres 用户的环境变量 sudo -u postgres env | grep PGDATA # 若输出旧路径需清理 sudo -u postgres grep PGDATA /var/lib/postgresql/.bashrc /var/lib/postgresql/.profile 2/dev/null # 删除或注释相关 export 行4.5 四层配置联动验证脚本写一个脚本一次性验证所有配置是否指向新路径#!/bin/bash # save as /tmp/pg-config-check.sh echo PostgreSQL 配置路径一致性检查 echo 1. postgresql.conf 中 data_directory: sudo grep ^data_directory /etc/postgresql/*/main/postgresql.conf 2/dev/null echo -e \n2. systemd Environment: sudo systemctl show postgresql14-main | grep Environment echo -e \n3. 实际进程 PGDATA 环境变量若服务已运行: sudo cat /proc/$(pgrep -u postgres postgres) /environ 2/dev/null | tr \0 \n | grep PGDATA || echo 服务未运行跳过 echo -e \n4. postgres 用户 shell 环境: sudo -u postgres env | grep PGDATA echo -e \n 检查完成 赋予执行权限并运行sudo chmod x /tmp/pg-config-check.sh sudo /tmp/pg-config-check.sh理想输出四行结果全部显示/mnt/pgdata。若任一行为旧路径必须修正对应配置否则服务必然启动失败。5. 启动验证与故障排查链路——从 systemctl status 到 pg_controldata 的逐层诊断配置全部更新后执行sudo systemctl start postgresql14-main。90% 的人在此刻遇到失败然后盲目重启、反复修改配置。真正的专业做法是按层级逐段排查每一步都有明确的验证手段和修复指令。5.1 第一层systemctl 状态与日志初筛# 查看服务状态 sudo systemctl status postgresql14-main # 若为 failed立即查看最近 50 行日志 sudo journalctl -u postgresql14-main -n 50 --no-pager # 常见错误及速查表日志关键词根本原因速查命令修复方案FATAL: data directory ... has wrong ownership所有者/组权限错误ls -ld /mnt/pgdatasudo chown -R postgres:postgres /mnt/pgdata sudo chmod 0700 /mnt/pgdataFATAL: could not open control file global/pg_controlpg_control 权限或路径错误ls -l /mnt/pgdata/global/pg_controlsudo chown postgres:postgres /mnt/pgdata/global/pg_control sudo chmod 0600 /mnt/pgdata/global/pg_controlcould not access the server configuration file postgresql.confpostgresql.conf 路径错误或权限不足sudo -u postgres cat /etc/postgresql/*/main/postgresql.conf | head -n5检查include_dir是否指向不存在的目录WAL archive failedpg_wal 软链接指向无效路径ls -la /mnt/pgdata/pg_wal重新创建软链接验证目标目录存在提示journalctl日志中FATAL:开头的行是根本原因HINT:行是 PostgreSQL 给出的修复建议务必逐字阅读。5.2 第二层pg_controldata 深度诊断当systemctl日志只显示failed而无具体错误时用pg_controldata直接读取pg_control文件获取底层状态# 切换到 postgres 用户运行诊断 sudo -u postgres pg_controldata /mnt/pgdata # 关键字段解读 # Catalog version number: 202209221 → 表示 PostgreSQL 14.5 兼容版本 # Database system identifier: 7234567890123456789 → 必须与原库一致否则是复制错误 # Latest checkpoint location: 0/1A2B3C4D → WAL 位置应为合理值非 0/0 # Latest checkpoints TimeLineID: 1 → 主库必须为 1备库为 2 # Data page checksum version: 1 → 若为 0 表示未启用 checksum可忽略典型故障场景若Database system identifier与原库不一致说明rsync复制了错误的目录或pg_basebackup误操作若Latest checkpoint location为0/0pg_control文件损坏需从备份恢复若TimeLineID为2但这是主库说明之前做过 PITR 恢复需检查recovery.signal是否残留。5.3 第三层手动启动调试模式绕过systemd用postgres命令手动启动获取最原始错误# 停止 systemd 服务 sudo systemctl stop postgresql14-main # 切换到 postgres 用户手动启动-D 指定数据目录-c 指定配置文件 sudo -u postgres /usr/lib/postgresql/14/bin/postgres -D /mnt/pgdata -c config_file/etc/postgresql/14/main/postgresql.conf # 观察终端输出的实时错误CtrlC 停止此模式优势绕过systemd的环境变量封装暴露原始错误错误信息更详细如could not create lock file /mnt/pgdata/postmaster.pid: Permission denied可配合strace追踪系统调用sudo -u postgres strace -f -e traceopenat,stat /usr/lib/postgresql/14/bin/postgres -D /mnt/pgdata 21 \| grep -E (denied|No such)。5.4 第四层连接验证与基础功能测试服务启动成功后必须验证核心功能而非仅看systemctl status active (running)# 测试本地连接 sudo -u postgres psql -c SELECT version(); # 测试数据库列表 sudo -u postgres psql -l # 测试关键系统表可读性 sudo -u postgres psql -c SELECT count(*) FROM pg_database; # 测试 WAL 切换验证写入能力 sudo -u postgres psql -c SELECT pg_switch_wal(); # 检查进程状态 ps aux \| grep postgres \| grep -v grep # 应看到postgres -D /mnt/pgdata 证明进程确实在读新目录提示若psql -l报FATAL: database postgres does not exist说明template1数据库损坏需从备份恢复base/1目录。5.5 生产环境必备的自动化验证脚本将上述验证步骤整合为可重复执行的脚本部署到 Ansible 或 Jenkins 中#!/bin/bash # /usr/local/bin/pg-migration-verify.sh set -e PGDATA/mnt/pgdata PGUSERpostgres PGVERSION14 echo 开始 PostgreSQL 迁移后验证... # 1. 检查进程是否运行 if ! pgrep -u $PGUSER postgres /dev/null; then echo ❌ PostgreSQL 进程未运行 exit 1 fi # 2. 检查数据目录路径 if ! sudo -u $PGUSER psql -t -c SHOW data_directory; | grep -q $PGDATA; then echo ❌ data_directory 配置未生效 exit 1 fi # 3. 检查基础查询 if ! sudo -u $PGUSER psql -c SELECT 1 /dev/null 21; then echo ❌ 基础查询失败 exit 1 fi # 4. 检查 WAL 切换 if ! sudo -u $PGUSER psql -c SELECT pg_switch_wal(); /dev/null 21; then echo ❌ WAL 切换失败 exit 1 fi echo ✅ 所有验证通过迁移成功。赋予执行权限sudo chmod x /usr/local/bin/pg-migration-verify.sh运行sudo /usr/local/bin/pg-migration-verify.sh。6. 迁移后的性能调优与长期维护——别让新路径成为下一个瓶颈数据目录迁移成功只是起点。若不进行针对性调优新路径可能在一周后再次触发磁盘告警或因 IO 配置不当导致查询延迟翻倍。6.1 IO 调度器与挂载参数优化Ubuntu 默认 ext4 文件系统使用mq-deadline调度器但对 PostgreSQL 的随机读写并非最优# 查看当前调度器 cat /sys/block/sdb/queue/scheduler # sdb 为新数据盘 # 推荐改为 kyberLinux 5.0或 noneNVMe 盘 echo kyber | sudo tee /sys/block/sdb/queue/scheduler # 永久生效编辑 /etc/default/grub sudo sed -i s/GRUB_CMDLINE_LINUX[^]*/ elevatorkyber/ /etc/default/grub sudo update-grub sudo reboot挂载参数同样关键。/etc/fstab中新路径的挂载选项应为UUIDxxxx-xxxx /mnt/pgdata ext4 defaults,noatime,nodiratime,barrier1,errorsremount-ro 0 2noatime,nodiratime禁用访问时间更新减少 IObarrier1启用写屏障保障 WAL 安全ext4 必须errorsremount-ro