在实际项目中,由于使用的是 麒麟操作系统,系统自带软件源中的 PostgreSQL 版本被限制为 10.5。 而之前在其他环境中使用过较高版本 PostgreSQL,导致在迁移数据时遇到了大量兼容性问题。 本文记录一次完整的实战过程,以及我在这个过程中走过的弯路,希望能给后来者一些参考。
为了解决版本兼容问题,最终决定:
使用 Ubuntu 18 安装 PostgreSQL 10.5,作为中转环境进行数据备份。
1. 更新系统
sudo apt update
sudo apt upgrade -y
2. 安装 PostgreSQL 10
sudo apt install postgresql-10 postgresql-contrib -y
3. 确认版本
psql --version确认输出为 PostgreSQL 10.x(与麒麟系统保持一致)。
首先将原始数据库数据恢复到 Ubuntu 18 的 PostgreSQL 10.5 中, 确保数据结构与目标数据库版本完全一致。
1. 创建数据库
sudo -u postgres psql
CREATE DATABASE testdb;
\q
2. 导入原始备份
psql -U postgres -d testdb < source.sql此步骤的关键在于:
让 PostgreSQL 10.5 自己生成符合版本规范的数据结构。
这是整个迁移过程中最关键的一步。
1. 使用 pg_dump 重新备份
pg_dump -U postgres testdb > pg10.sql此时生成的 SQL 文件,已经完全符合 PostgreSQL 10.5 语法规范。
2. 推荐方式(dump 格式)
pg_dump -U postgres -Fc testdb > pg10.dumpscp pg10.sql root@kylin-server:/data/backup/或使用 pg10.dump 文件传输。
1. 创建数据库
sudo -u postgres psql
CREATE DATABASE testdb;
\q
2. 导入 SQL 文件
psql -U postgres -d testdb < pg10.sql
3. 使用 dump 文件恢复(推荐)
pg_restore -U postgres -d testdb pg10.dump至此,数据可完整、无报错地恢复。
这是一次典型的 PostgreSQL 版本兼容导致的数据迁移问题,解决思路具有通用参考价值。
本文记录的是一次真实的生产环境踩坑经历,适合在使用麒麟系统和 PostgreSQL 10.x 的场景中参考。
这个第九条之前是比较常规的正常路线,都是ai写的,下面是我自己把坑点记录一下,方便自己以后的查阅,也算分享给大家;
这个是我尝试了很久并且反复问了gpt,慢慢尝试出来的,我之前一直用mysql,这次项目要求用这个我也是没办法,我也不熟悉这个数据库。
关键的关键: PgSql 18 中导出语句
win (powershell下执行) :
./pg_dump.exe -U zzb -h 192.168.1.104 -p 5432 -d zzb --no-owner --no-privileges --disable-triggers --inserts --encoding=UTF8 --no-comments --no-security-labels --use-set-session-authorization=false -f d:/zzb10.dump
linux:
pg_dump \
-U zzb \
-h 192.168.1.104 \
-p 5432 \
-d zzb \
--no-owner \
--no-privileges \
--no-comments \
--no-security-labels \
--disable-triggers \
--inserts \
--use-set-session-authorization=false \
> zzb_pg10.sql
参数说明:
--no-owner (不生成 ALTER TABLE xxx OWNER TO some_user; 这样的语句, 避免 ERROR: role "xxx" does not exist 这样的报错)
--no-privileges (不生成 GRANT ...
和 REVOKE ... 这样的语句)
--no-comments (不生成 COMMENT ON TABLE ... 和 COMMENT ON COLUMN ... 这样的语句, 避免 ERROR: syntax error at or near ... 这样的报错)
--no-security-labels (不生成 SECURITY LABEL FOR selinux ON ... 这样的语句, 避免 ERROR: security label provider "selinux" is not loaded 这样的报错)
--disable-triggers
--inserts
--use-set-session-authorization=false参数说明:
清洗代码,要在导入前做的
sed -i \
> -e '/^\\restrict/d' \
> -e '/transaction_timeout/d' \
> -e '/default_table_access_method/d' \
> zzb10.dump
然后就是导入数据库
说明一下,我为什么要用ubuntu 18 的操作系统版本,因为 最新的ubuntu或者说18以上的ubuntu版本不支持 10.5版本,然后我本来本地开发是windows,但是windows10 ,也没有支持 PgSql 10.5版本了,没有这个版本的下载,只有源码,要自己去编译,我感觉太麻烦了,然后我本地调试环境是centos7,也没有PgSql 10.5,所以麒麟系统支持这个该有多老的操作系统,最后都是不断的问gpt的情况下,得到ubuntu18 是支持,并且可以简单的安装和下载到,用apt install 即可,又安全又稳定又简单,基本的安装我上面都写过了(虽然是AI写的),但是问题不大,大致没问题的。
数据库导入:
1、sudo -i -u postgres
2、psql -U postgres -d zzb -f /home/young/zzb10.dump
这样没有报错的话,就可以了,当然如果一切不是那么顺利的话:
我应该也不用解释下面的语句了,经过这么多代码下来,你已经是一个DBA高手了(我已经被折腾得死去活来了,到这边其实我已经成功导入到PgSql10.5了,但是我还没导入到麒麟系统里的数据库了,我觉得都是10.5应该没问题了,然后怕自己后面遗忘,赶紧来记录这一篇文章),下面就是导入有报错,重新来一遍!
1、sudo -i -u postgres
2、psql
3、DROP DATABASE zzb;
4、CREATE DATABASE zzb OWNER zzb
ENCODING 'UTF8'
LC_COLLATE 'C'
LC_CTYPE 'C'
TEMPLATE template0;
继续坑
如果你又碰到这个问题:
ERROR: permission denied for relation zzb_survey
跟着我做:
1、sudo -u postgres psql
2、\c zzb
3、SELECT current_database(); (查看当前数据库,确保在zzb)
4、(执行权限,会立即生效不用重启)
GRANT USAGE ON SCHEMA public TO zzb;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO zzb;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO zzb;
GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public TO zzb;
六、再给你一个“终极一劳永逸方案”(强烈推荐)
1、
ALTER DATABASE zzb OWNER TO zzb;
ALTER SCHEMA public OWNER TO zzb;
2、
DO $$
DECLARE r RECORD;
BEGIN
FOR r IN SELECT tablename FROM pg_tables WHERE schemaname='public'
LOOP
EXECUTE format('ALTER TABLE public.%I OWNER TO zzb', r.tablename);
END LOOP;
END$$;
👉 以后 再也不会碰到权限问题
你已经在做“版本回退迁移”的活了,不是很多人能一次性搞定的。
输入您的网址查询是否授权