Fedora28下PostgreSQL9.6升级至10.4遇unknown类型列故障求助
解决PostgreSQL 9.6→10.4升级中unknown类型列的困境
针对你在Fedora 28上遇到的这个升级卡壳问题,我整理了几个实用的解决方案,按优先级排序:
方案1:通过PostgreSQL单用户模式删除问题列
这是最直接的方法,不需要正常启动PostgreSQL服务,就能直接操作数据库:
- 先确保所有PostgreSQL进程都停止:
sudo systemctl stop postgresql.service sudo pkill -u postgres - 切换到
postgres系统用户(PostgreSQL的核心操作必须用这个用户执行):su - postgres - 启动单用户模式,指定你的数据库目录和目标数据库(如果不确定数据库名,先查看
/var/lib/pgsql/data/base下的文件夹,数字对应数据库OID;或者直接填默认库postgres先进入查看):
进入单用户模式后,会出现类似postgres --single -D /var/lib/pgsql/data your_database_namepostgres=#的提示符(即使没有也可以直接输入SQL命令)。 - 执行删除问题列的SQL命令,替换成你的实际表名和列名:
ALTER TABLE your_problem_table DROP COLUMN your_unknown_column; - 按
Ctrl+D退出单用户模式。 - 现在重新尝试执行升级命令:
sudo postgresql-setup --upgrade
方案2:手动调用pg_upgrade并允许未知类型
如果单用户模式操作遇到障碍,你可以绕过封装的postgresql-setup,直接用pg_upgrade工具添加允许未知类型的参数:
- 停止服务并切换到postgres用户(同方案1的前两步)。
- 先初始化PostgreSQL 10的新数据目录(如果尚未初始化):
/usr/pgsql-10/bin/initdb -D /var/lib/pgsql/10/data - 执行手动升级,指定旧版本和新版本的bin目录、数据目录,并加上
--allow-unknown-types参数跳过类型检查:
注意:这个参数只是临时绕过检查,升级完成后请立刻登录数据库删除那个unknown列,避免后续出现其他兼容性问题。pg_upgrade -b /usr/pgsql-9.6/bin -B /usr/pgsql-10/bin \ -d /var/lib/pgsql/data -D /var/lib/pgsql/10/data \ -U postgres --allow-unknown-types - 升级完成后,修改PostgreSQL服务配置指向新数据目录(Fedora通常是修改
/var/lib/pgsql/data的软链接,或调整/etc/postgresql/10/main/postgresql.conf的路径),然后启动服务:sudo systemctl start postgresql-10.service
方案3:编译安装PostgreSQL 9.6临时版本
如果以上方法都行不通,你可以临时编译安装PostgreSQL 9.6,启动服务删除列后再执行升级:
- 安装编译依赖:
sudo dnf install gcc make readline-devel zlib-devel openssl-devel - 下载PostgreSQL 9.6的源码包(选择对应小版本的tar.gz):
wget https://ftp.postgresql.org/pub/source/v9.6.24/postgresql-9.6.24.tar.gz tar xzf postgresql-9.6.24.tar.gz cd postgresql-9.6.24 - 编译并安装到独立目录,避免覆盖现有10版本:
./configure --prefix=/usr/local/pgsql96 make sudo make install - 用编译好的9.6版本启动服务:
sudo -u postgres /usr/local/pgsql96/bin/postgres -D /var/lib/pgsql/data & - 登录数据库删除问题列:
执行删除列的SQL后退出,停止服务,再执行原升级命令即可。/usr/local/pgsql96/bin/psql -U postgres your_database_name
额外提示:离线生成数据库转储
如果只是想先备份数据,你可以在单用户模式下用COPY命令直接导出表数据到文件:
COPY your_problem_table TO '/var/lib/pgsql/table_dump.csv' WITH CSV HEADER;
不过更稳妥的方式还是先修复列类型,再用正常的pg_dump工具生成完整转储。
内容的提问来源于stack exchange,提问作者Heiko Jakubzik
相关产品推荐
相关产品推荐

