从9.6到10.4的Postgresql更新(在Fedora 28上)让我陷入困境:一个数据库中的一个表有一列数据类型为“未知”。我很乐意删除该列,但由于我无法启动postgresql服务(因为“找到了旧版本的数据库格式”),我无权访问该数据库。更详细:
postgresql-setup --upgrade
失败。
/var/lib/pgsql/upgrade_postgresql.log
将此失败归因于数据类型为“unknown”的列:“...检查无效'未知'用户列:致命....检查tables_using_unknown.txt”。并且“tables_using_unknown.txt”指定一个表中我希望可以丢弃的一列但不能,因为我无法启动服务器:
systemctl start postgresql.service
失败,并且
systemctl status postgresql.service抱怨“旧版本的数据库”
我没有找到在Fedora 28上安装postgresql 9.6的明显方法。
有没有办法在没有正在运行的服务器的情况下删除列?或者至少产生一个数据库转储?或者我可以强制升级工具删除数据类型为“未知”的列吗?还是有其他明显的解决方案我不知道?
答案 0 :(得分:1)
这终于对我有用:
不漂亮,但是可以工作。更详细地:
我将Postgresql的数据目录(在Fedora中为/var/lib/pgsql/data/
)复制到一个新的空目录/home/hj/pg-problem/
。该目录包含无法转换的数据库。
我创建了一个名为“ Docker-pg-problem”的Dockerfile(文本文件)
FROM postgres:9.6
# my databases need German locale;
# if you just need en_US, comment the next two lines out.
RUN localedef -i de_DE -c -f UTF-8 -A /usr/share/locale/locale.alias de_DE.UTF-8
ENV LANG de_DE.utf8
,并将其保存为新的空文件夹/home/hj/pg-problem/docker/
中的唯一文件。
我启动了docker守护程序,并运行了一个容器,该容器使用我的有问题数据副本中的数据(位于/home/hj/pg-problem/data/
中)作为容器中postgres 9.6服务器的数据目录。 (注意:第三行中的“ docker build”命令需要有效的互联网连接,需要一段时间,并且应该说“成功构建”。)
root@host: cd /home/hj/pg-problem/docker
root@host: service docker start
root@host: docker build -t hj/failed-update -f Dockerfile .
root@host: docker run -it --rm -p 5431:5432 -v /home/hj/pg-problem/data:/var/lib/postgresql/data:z --name failed-update -e POSTGRES_PASSWORD=secret hj/failed-update
然后,我在容器中打开一个终端来修复数据库:
hj@host: docker exec -it failed-update bash
在容器内,我修复并转储了数据库:
root@container: su postgres
postgres@container: psql <DB-name>
postgres@container: alter table <Table-name> alter column <Col-Name> type text;
postgres@container: \q
postgres@container: dump_db <DB-name> /var/lib/postgresql/data/dbREPAIRED.sql
我将数据库直接转储到数据目录中,以便可以轻松地从Docker主机访问转储的文件。
在docker主机上,显然,转储的数据库位于/home/hj/pg-problem/data/dbREPAIRED.sql
中,并且可以从那里将其加载到postgresql 10中:
postgres@host: createdb <DB-name>
postgres@host: psql <DB-name> < /home/hj/pg-problem/data/dbREPAIRED.sql
由于我使用的是磁盘空间有限的笔记本电脑,因此删除了docker内容:
root@host: docker rm $(docker ps -a -q)
root@host: docker rmi $(docker images -q)