百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 优雅编程 > 正文

迁移实战:一次 AntDB 数据库迁移经验分享

sinye56 2024-10-06 00:34 4 浏览 0 评论

一、前言

AntDB是一款基于PG内核的分布式数据库。根据AntDB官方介绍,该数据具备持续的集群自动高可用,秒级在线扩容,强大的Oracle兼容,异地容灾,sql语句级自定义分片,分布式事务和MVCC。是一款非常强大的企业级国产分布式数据库。其架构如下(本图参考网络图片):

在当前的情况下,大部分企业关心的是如何将Oracle数据库迁移到mysql数据库、postgresql数据库等开源及国产数据库中。而很少关注这些开源及国产数据库本身的迁移与升级。

由于AntDB在使用过程中,与pgxl很相近,所以本文对pgxl的情况下应该还是有一定的帮助。

二、背景

最近,某客户现场需要将其之前使用的AntDB进行升级。由于本次升级,涉及的版本不同、节点数量不同。因此,综合考虑只能选用逻辑的方式完成本次数据库的迁移和升级。

三、迁移思路

Postgresql中,我们可以通过pg_dump和pg_restore进行逻辑导入和恢复。但是在本次迁移中,源AntDB存放的表数量以及数据量都非常大(表数量基本由22w张,数据量大约有46T)。所以,如果使用pg_dump和pg_restore的方式,其效率将会非常低。

因此,我们则选择使用postgresql中的copy的方式进行迁移。COPY是PostgreSQL中表和标准文件系统文件之间交换数据的方式,可以理解为直接将文件系统文件中的数据直接装载到数据库中,而不是传统的通过insert语句方式逐条插入数据。因此,在postgreSQL中,通过COPY的方式,将会使数据导入更快。

四、迁移步骤

AntDB的迁移总体分为两个步骤:

1)表结构迁移

2)数据迁移

接下来,我将分别分享这两个步骤中的迁移经验和遇到的问题。

1. 表结构迁移

在本场景的迁移过程中,由于源端是基于PostgreSQL 9.6的数据库,目标端是基于PostgreSQL 11.6的数据库。而9.6和11.6两个大版本数据库中很多特性又是不同的,故也为迁移造成一些难度。其中,在本场景中最重要的就是分区表。

PostgreSQL 9.6数据库中,并没有分区表的概念,其分区表则主要是通过继承表+触发器来实现的,表数据是根据触发器条件来写入到不同子表中的;

PostgreSQL 11.6数据库中则加入了分区表的概念,可以直接创建基于基表的分区表,数据可以根据分区键条件插入到各自的分区中。
那么在迁移中遇到的一个难点就是:如何将9.6中的父表、子表的关系转换成11.6中的分区表。

在postgreSQL中,我们无法像Oracle里面的get_ddl函数一样,获取表的创建语句。但是,我们可以通过pg_dump的方式,将PosgreSQL中的表结构导出,生成SQL语句。

因此,我们首先需要从源端数据库中找出分区表和非分区表,通过以下SQL就可以在PostgreSQL中找到分区表和非分区表。

查询分区表有哪些:

select distinct p.relname fq_table
from pg_class p,pg_inherits i
where p.oid=i.inhparent and reltype<>0 order by fq_table;

查询非分区表有哪些:

select tablename from pg_tables where tablename not in
(select partrelid::regclass::text fq_table
from pg_partitioned_table order by fq_table) and tablename not in(select c.relname
from pg_class a left join pg_inherits b  on a.oid=b.inhparent
left  join pg_class c on b.inhrelid=c.oid where c.relname is not null) and schemaname='itv' order by tablename;

确定好分区表和非分区表以后,我们可以将查出的表名写到一个txt文本文件中,然后通过以下脚本来生成pg_dump语句(当然也可以自己写脚本或者程序进行生成,其核心就是生成:pg_dump -h $host_name_ip -p $port_number -d $db_name -U $user_name -n $schema_name -s -t $x -f $x_MyPartition.sql的语句):

vi pg_dump_table.sh

read -p "请输入读取的文件:" read_file
read -p "是否为分区表 ?yes/no:" partition_table
read -p "请输入主机名或者IP:" host_name_ip
read -p "请输入端口:" port_number
read -p "请输入数据库名字:" db_name
read -p "请输入用户名:" user_name
read -p "请输入模式名:" schema_name

if [ "$partition_table" = "yes" ] || [ "$partition_table" = "y" ]; then
        echo '' > $read_file.sh
        for x in `cat $read_file.txt`
        do
                echo pg_dump -h $host_name_ip -p $port_number -d $db_name -U $user_name -n $schema_name -s -t $x -f $x\_MyPartition.sql >> $read_file.sh
        done
                echo script complete.
elif [ "$partition_table" = "no" ] || [ "$partition_table" = "no" ]; then
        echo '' > $read_file.sh
        for x in `cat $read_file.txt`
        do
                echo pg_dump -h $host_name_ip -p $port_number -d $db_name -U $user_name -n $schema_name -s -t $x -f $x.sql >> $read_file.sh
        done
                echo script complete.
else
        echo 'please input yes/no'
fi

生成的.sh脚本中的内容即为pg_dump导出表结构的语句。

但是,按照我们在上面提到的PostgreSQL 9.6中没有分区表概念。所以,我们导出的表结构也不会有分区键在里面。

因此,我们就需要手动去修改这些表结构创建语句,根据其实际的分区键添加partition by (segment_name)。这个工作,需要对所有表的分区情况和分区键比较熟悉,整个过程是一个体力活,所以不展开叙述。但当我们了解所有分区表的分区定义后,也可以直接通过脚本在文本上进行增加,举例如下(核心就是通过sed匹配建表语句中的结尾括号,然后进行替代):

vi modify_partition_sql.sh

mkdir -p ./partition_table_by_date_no
mkdir -p ./partition_table_by_date_no_result
mv ./*_MyPartition.sql ./partition_table_by_date_no/

for x in `ls ./partition_table_by_date_no/`
do
        echo $x
        sed -i "s/^)$/) partition by list(date_no)/g" ./partition_table_by_date_no/$x
        mv ./partition_table_by_date_no/$x ./partition_table_by_date_no_result/$x
done

mv *.sql ./partition_table_by_date_no/
tar -cvf partition_table_by_date_no.tar partition_table_by_date_no/
tar -cvf partition_table_by_date_no_result.tar partition_table_by_date_no_result/

修改完分区表信息后,则可以通过以下脚本直接连接到数据库中执行:

--分区表
vi create_partitionBase_table.sh

for x in `ls partition_table_by_date_no_result`
do
        echo $x >> ./create_partitionBase_table.log
        psql -h antdb01 -p 15432 -Udctest -d dcrptdb1 -f ./partition_table_by_date_no_result/$x >> ./create_partitionBase_table.log
done
--非分区表
vi create_nopartition_table.sh

for x in `ls partition_table_by_date_no`
do
        echo $x >> ./create_nopartition_table.log
        psql -h antdb01 -p 15432 -Udctest -d dcrptdb1 -f ./partition_table_by_date_no/$x >> ./create_nopartition_table.log
done

到这里所有分区基表和非分区表的表结构就创建好了,那么下一步针对分区表我们就要创建对应的分区了。

创建分区首先我们需要从源库将原来的分区信息查出来,故通过以下语句可以查出表的分区信息:

select a.relname,c.relname
from pg_class a left join pg_inherits b  on a.oid=b.inhparent
left  join pg_class c on b.inhrelid=c.oid
 where a.relname = table_name::text;

找到这些分区后,则需要手动根据分区名字创建分区表,以下举例说明:

create table partition_table_name partition of partition_base_table_name for values in('20200201');partition_base_table

另外,在导数过程中,源端数据可能有变化,对分区进行删除,那么部分数据可能已经查到,但不属于任何一个分区,这样在导入数据时则会报错,因此为了保证导数不报错,我们则可以考虑创建一个default分区,用来存放不属于任何分区的数据,以下举例说明:

create table partition_table_default partition of partition_base_table_name default;

至此,所有的表结构就都创建好了。

2. 表数据迁移

...

? 接下来内容请访问原文(https://www.modb.pro/db/29946?YYF)进行查看~

更多数据库相关内容,可访问墨天轮(https://www.modb.pro/?YYF)进行浏览。

相关推荐

Linux基础知识之修改root用户密码

现象:Linux修改密码出现:Authenticationtokenmanipulationerror。故障解决办法:进入单用户,执行pwconv,再执行passwdroot。...

Linux如何修改远程访问端口

对于Linux服务器而言,其默认的远程访问端口为22。但是,出于安全方面的考虑,一般都会修改该端口。下面我来简答介绍一下如何修改Linux服务器默认的远程访问端口。对于默认端口而言,其相关的配置位于/...

如何批量更改文件的权限

如果你发觉一个目录结构下的大量文件权限(读、写、可执行)很乱时,可以执行以下两个命令批量修正:批量修改文件夹的权限chmod755-Rdir_name批量修改文件的权限finddir_nam...

CentOS「linux」学习笔记10:修改文件和目录权限

?linux基础操作:主要介绍了修改文件和目录的权限及chown和chgrp高级用法6.chmod修改权限1:字母方式[修改文件或目录的权限]u代表所属者,g代表所属组,o代表其他组的用户,a代表所有...

Linux下更改串口的权限

问题描述我在Ubuntu中使用ArduinoIDE,并且遇到串口问题。它过去一直有效,但由于可能不必要的原因,我觉得有必要将一些文件的所有权从root所有权更改为我的用户所有权。...

Linux chown命令:修改文件和目录的所有者和所属组

chown命令,可以认为是"changeowner"的缩写,主要用于修改文件(或目录)的所有者,除此之外,这个命令也可以修改文件(或目录)的所属组。当只需要修改所有者时,可使用...

chmod修改文件夹及子目录权限的方法

chmod修改文件夹及子目录权限的方法打开终端进入你需要修改的目录然后执行下面这条命令chmod777*-R全部子目录及文件权限改为777查看linux文件的权限:ls-l文件名称查看li...

Android 修改隐藏设置项权限

在Android系统中,修改某些隐藏设置项或权限通常涉及到系统级别的操作,尤其是针对非标准的、未在常规用户界面显示的高级选项。这些隐藏设置往往与隐私保护、安全相关的特殊功能有关,或者涉及开发者选项、权...

完蛋了!我不小心把Linux所有的文件权限修改了!在线等修复!

最近一个客户在群里说他一不小心把某台业务服务器的根目录权限给改了,本来想修改当前目录,结果执行成了根目录。...

linux改变安全性设置-改变所属关系

CentOS7.3学习笔记总结(五十八)-改变安全性设置-改变所属关系在以前的文章里,我介绍过linux文件权限,感兴趣的朋友可以关注我,阅读一下这篇文章。这里我们不在做过的介绍,注重介绍改变文件或者...

Python基础到实战一飞冲天(一)--linux基础(七)修改权限chmod

#07_Python基础到实战一飞冲天(一)--linux基础(七)--修改权限chmod-root-groupadd-groupdel-chgrp-username-passwd...

linux更改用户权限为root权限方法大全

背景在使用linux系统时,经常会遇到需要修改用户权限为root权限。通过修改用户所属群组groupid为root,此操作只能使普通用户实现享有部分root权限,普通用户仍不能像root用户一样享有超...

怎么用ip命令在linux中添加路由表项?

在Linux中添加路由表项,可以使用ip命令的route子命令。添加路由表项的基本语法如下:sudoiprouteadd<network>via<gateway>这...

Linux配置网络

1、网卡名配置相关文件回到顶部网卡名命名规则文件:/etc/udev/rules.d/70-persistent-net.rules#PCIdevice0x8086:0x100f(e1000)...

Linux系列---网络配置文件

1.网卡配置文件在/etc/sysconfig/network-scripts/下:[root@oldboynetwork-scripts]#ls/etc/sysconfig/network-s...

取消回复欢迎 发表评论: