暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

记录一次PG数据库迁移至GaussDB测试

原创 subverter 2024-02-23
826

PG库到GaussDB迁移测试

文档控制:

版本号

编写人

日期

备注

1

1.0版

subverter

2023-12-08

初始版本

目录

一、说明 4

1.1、参考文档 4

1.2、注意事项 4

1.3、环境基本情况 4

二、GaussDB新环境安装 5

2.1 配置操作环境变量 5

2.1.1 关闭防火墙 5

2.1.2设置时区 5

2.1.3 关闭 swap 交换内存 5

2.1.4设置网卡 MTU 值 5

2.1.5 文件句柄设置 6

2.1.6系统支持的最大进程数设置 6

2.1.7 配置时钟源 6

2.1.8 创建文件目录 7

2.2 安装GaussDB数据库 7

2.3、查看实例状态 12

三、DRS迁移工具搭建 13

3.1系统架构 13

3.2部署架构 14

3.2.1 DRS独立部署 14

3.2.2 GaussDB轻量化解决方案 15

3.3 系统要求 16

3.3.1操作系统要求 16

3.3.2 纳管实例 16

3.3.3 磁盘空间划分要求 17

3.3.4 软件要求 20

3.4 安装GaussDB 21

3.5 安装DRS-Service服务 26

3.6 安装DRS-Node服务 29

四、 迁移前操作 31

4.1 源端(pg) 31

4.2 目标端(GaussDB库) 32

五、 DRS迁移数据 32

5.1 创建复制用户drs 32

5.2创建迁移任务。 33

六、迁移后一致性检查 37

6.1使用DRS工具对比 37

6.2手动对比 37

七、问题总结及解决方法 37

7.1、用户迁移 37

7.2、序列迁移 44

7.3、分区表迁移 45

7.4、自建函数迁移 46

7.5、自建定时任务迁移 46

7.6、索引改造 46

一、说明

1.1、参考文档

  • GaussDB Installer 1.0.6.1
  • HCS Data Replicate Software 2.23.07.211 安装指南 01
  • HCS Data Replicate Software 2.23.07.211 用户指南 01

1.2、注意事项

  • 迁移前,需收集好业务侧所有数据库账号的密码;
  • 正式迁移前,禁止新创建数据库、用户、模式等,如必须创建,务必告之;
  • 正式迁移当天,前后台均需停止大业务操作(如JOB、前台业务等);

1.3、环境基本情况

配置类型

新环境

原环境

主机

Kunlun服务器

架构

分布式

主备

内存

256G

1024G

CPU(逻辑)

单机为96核

160

操作系统版本

麒麟V10

Redhat7

存储

SSD

SATA盘

网络

万兆

千兆

节点

3

2

数据库版本

GaussDBKernel 503.1.0.SPC1200

Postgressql 12.4

数据量

800G

GaussDB新环境安装

配置操作环境变量

2.1.1 关闭防火墙

需在防火墙关闭的状态下进行安装,关闭防火墙操作步骤如下。

步骤1 执行以下命令,检查防火墙是否关闭。

systemctl status firewalld

● 若防火墙状态显示为active (running),则表示防火墙未关闭,请执行步骤2。

● 若防火墙状态显示为inactive (dead),则表示防火墙已关闭,无需再关闭防火

墙。

步骤2 执行以下命令,关闭防火墙并禁止开机启动。

systemctl stop firewalld

systemctl disable firewalld

步骤3 修改/etc/selinux/config文件中的“SELINUX”值为“permissive”。

说明

一般情况下,开启selinux会提高系统的安全性,但是可能导致程序无法运行。为保证安装顺

利,建议用户设置值为permissive。

1. 使用vim打开config文件。

vim /etc/selinux/config

2. 修改“SELINUX”的值“permissive”,执行:wq保存并退出修改。

SELINUX=permissive

步骤4 执行以下命令,重新启动操作系统。

reboot

2.1.2设置时区

将各主机的字符集设置为相同的字符集。

步骤1 使用vim打开/etc/profile文件。

vim /etc/profile

步骤2 在/etc/profile文件中添加"export LANG=en_US.UTF-8"。

步骤3 执行:wq保存并退出修改。

2.1.3 关闭 swap 交换内存

swapoff -a

2.1.4设置网卡 MTU 值

将各主机的网卡MTU值设置为相同大小。万兆网卡MTU值推荐8192(ARM),1500(X86),要求不小于1500。设置之后确保各节点之间可以在新的MTU值下通过SSH连接,并且可以通过scp传输文件的大小应

大于原MTU值的文件。

ifconfig enp1s0f0 mtu 8192

ifconfig enp1s0f1 mtu 8192

ifconfig enp2s0f0 mtu 8192

ifconfig enp2s0f1 mtu 8192

ifconfig bond1 mtu 8192

ifconfig | grep RUNNING

2.1.5 文件句柄设置

echo "* soft nofile 1000000" >>/etc/security/limits.conf

echo "* hard nofile 1000000" >>/etc/security/limits.conf

2.1.6系统支持的最大进程数设置

系统支持的最大进程数设置

步骤1 执行如下命令,打开conf文件。

vim /etc/security/limits.d/90-nproc.conf

步骤2 修改* soft nproc参数。

步骤3 执行如下命令,需重启操作系统使得设置的参数生效。

reboot

----结束

2.1.7 配置时钟源

配置NTP时钟源前,确保您拥有所有机器的root用户权限。

步骤1 执行以下命令,在每台机器上通过YUM包管理器安装 NTP。

yum install ntp ntpdate -y

步骤2 配置 ntp.conf 文件,配置前做好备份。

【NTP服务器的搭建】

[root@xxx /]# vim /etc/ntp.conf

restrict default ignore

restrict 127.0.0.1

restrict 10.8.2.0 mask 255.255.0.0

driftfile /var/lib/ntp/drift

pidfile /var/run/ntpd.pid

#logfile /var/log/ntp.log

# local clock

server 127.127.1.0

fudge 127.127.1.0 stratum 10

【NTP客户端的搭建】

[root@xxx /]# vim /etc/ntp.conf

restrict default ignore

restrict 127.X.X.1

restrict 192.X.X.0 mask 255.255.0.0

driftfile /var/lib/ntp/drift

pidfile /var/run/ntpd.pid

#logfile /var/log/ntp.log

# local clock

server 192.X.X.X iburst minpoll 4 maxpoll 6

fudge 192.X.X.X stratum 10

Vi /etc/ntpd.conf

末尾追加

server 10.234.8.14

步骤3 执行以下命令,重启 NTP 同步服务。

systemctl restart ntpd

systemctl status ntpd

步骤4 执行以下命令,检查 NTP 同步状态。

ntpq -p

2.1.8 创建文件目录

mkdir /GaussDB/cluster/data/data1

mkdir /GaussDB/cluster/data/data2

mkdir /GaussDB/cluster/data/data3

mkdir /GaussDB/cluster/data/data4

2.2 安装GaussDB数据库

注:GaussDB分布式数据库环境为3个节点安装

1、解压安装文件

mkdir /data

tar -xvf /opt/GaussDBInstaller_1.0.6.1_20230726111747.tar.gz -C /data

tar -xvf /opt/GaussDB_ARM_Kylinv10_Distributed_2.23.01.230_20230705094619.tar.gz -C /data/GaussDBInstaller/pkgDir

2、编辑配置文件

Vim install_cluster.conf

[COMMON]

os_user = omm

os_user_group = ${os_user}

os_user_home = /home/${os_user}

os_user_passwd = Gauss_246

root_passwd = Huawei@123

ssh_port = 22

node_ip_list = 10.11.9.49,10.11.9.50,10.11.9.51

[OMAGENT]

gauss_home = /GaussDB/cluster/

om_agent_port = 30170

mgr_net = bond1

data_net = bond1

virtual_net = bond1

log_dir = ${gauss_home}/logs/gaussdb

cn_dir = ${gauss_home}/data/cn

gtm_dir = ${gauss_home}/data/gtm

cm_dir = ${gauss_home}/data/cm

tmp_dir = ${gauss_home}/temp

data_dir = ${gauss_home}/data/data1/dn,${gauss_home}/data/data2/dn,${gauss_home}/data/data3/dn

tool_dir = ${gauss_home}/tools

etcd_dir = ${gauss_home}/data/etcd

编辑安装json文件

{

"rdsAdminUser":"rdsAdmin",

"rdsAdminPasswd":"Gauss_123",

"rdsMetricUser":"rdsMetric",

"rdsMetricPasswd":"huawei@123Pwd",

"rdsReplUser":"rdsRepl",

"rdsReplPasswd":"huawei@123Pwd",

"rdsBackupUser":"rdsBackup",

"rdsBackupPasswd":"huawei@123Pwd",

"dbPort":"15432",

"dbUser":"root",

"dbUserPasswd":"huawei@123Pwd",

"clusterMode":"combined",

"params":{

"enable_thread_pool":"on",

"enable_bbox_dump":"on",

"bbox_dump_path":"/home/core"

},

"cnParams":{

},

"dnParams":{

},

"cmParams":{

},

"clusterConf":{

"clusterName":"Gauss_Dis_2",

"encoding": "utf8",

"shardingNum": 3,

"replicaNum": 3,

"solution":"hws",

"cm":[

{

"rack": "gauss001",

"az": "AZ1",

"ip": "10.11.9.49",

"dataIp":"10.11.9.49",

"virtualIp":"10.11.9.49"

},

{

"rack": "gauss002",

"az": "AZ2",

"ip": "10.11.9.50",

"dataIp":"10.11.9.50",

"virtualIp":"10.11.9.50"

},

{

"rack": "gauss003",

"az": "AZ3",

"ip": "10.11.9.51",

"dataIp":"10.11.9.51",

"virtualIp":"10.11.9.51"

}

],

"cn":[

{

"rack": "gauss001",

"az": "AZ1",

"ip": "10.11.9.49",

"dataIp":"10.11.9.49",

"virtualIp":"10.11.9.49"

},

{

"rack": "gauss002",

"az": "AZ2",

"ip": "10.11.9.50",

"dataIp":"10.11.9.50",

"virtualIp":"10.11.9.50"

},

{

"rack": "gauss003",

"az": "AZ3",

"ip": "10.11.9.51",

"dataIp":"10.11.9.51",

"virtualIp":"10.11.9.51"

}

],

"gtm":[

{

"rack": "gauss001",

"az": "AZ1",

"ip": "10.11.9.49",

"dataIp":"10.11.9.49",

"virtualIp":"10.11.9.49"

},

{

"rack": "gauss002",

"az": "AZ2",

"ip": "10.11.9.50",

"dataIp":"10.11.9.50",

"virtualIp":"10.11.9.50"

},

{

"rack": "gauss003",

"az": "AZ3",

"ip": "10.11.9.51",

"dataIp":"10.11.9.51",

"virtualIp":"10.11.9.51"

}

],

"shards":[

[

{

"rack": "gauss001",

"az": "AZ1",

"ip": "10.11.9.49",

"dataIp":"10.11.9.49",

"virtualIp":"10.11.9.49"

},

{

"rack": "gauss002",

"az": "AZ2",

"ip": "10.11.9.50",

"dataIp":"10.11.9.50",

"virtualIp":"10.11.9.50"

},

{

"rack": "gauss003",

"az": "AZ3",

"ip": "10.11.9.51",

"dataIp":"10.11.9.51",

"virtualIp":"10.11.9.51"

}

],

[

{

"rack": "gauss002",

"az": "AZ2",

"ip": "10.11.9.50",

"dataIp":"10.11.9.50",

"virtualIp":"10.11.9.50"

},

{

"rack": "gauss001",

"az": "AZ1",

"ip": "10.11.9.49",

"dataIp":"10.11.9.49",

"virtualIp":"10.11.9.49"

},

{

"rack": "gauss003",

"az": "AZ3",

"ip": "10.11.9.51",

"dataIp":"10.11.9.51",

"virtualIp":"10.11.9.51"

}

],

[

{

"rack": "gauss003",

"az": "AZ3",

"ip": "10.11.9.51",

"dataIp":"10.11.9.51",

"virtualIp":"10.11.9.51"

},

{

"rack": "gauss002",

"az": "AZ2",

"ip": "10.11.9.50",

"dataIp":"10.11.9.50",

"virtualIp":"10.11.9.50"

},

{

"rack": "gauss001",

"az": "AZ1",

"ip": "10.11.9.49",

"dataIp":"10.11.9.49",

"virtualIp":"10.11.9.49"

}

]

],

"etcd":{

"nodes":[

{

"rack": "gauss001",

"az": "AZ1",

"ip": "10.11.9.49",

"dataIp":"10.11.9.49",

"virtualIp":"10.11.9.49"

},

{

"rack": "gauss002",

"az": "AZ2",

"ip": "10.11.9.50",

"dataIp":"10.11.9.50",

"virtualIp":"10.11.9.50"

},

{

"rack": "gauss003",

"az": "AZ3",

"ip": "10.11.9.51",

"dataIp":"10.11.9.51",

"virtualIp":"10.11.9.51"

}

]

}

}

}

安装包配置完成后检查

在开始执行安装之前,执行以下命令,查看脚本解压后的目录GaussDBInstaller下的文

件。

ll /data/GaussDBInstaller

如图需要确保有如下文件:

● gaussdb_install.py

● install_cluster.sh

● install_cluster.conf

● install_cluster.json

开始安装

步骤1 执行以下命令,进入到解压后的目录。

cd /data/GaussDBInstaller

步骤2 执行以下命令,进行安装。

python3 gaussdb_install.py --action main

2.3、查看实例状态

查看实例状态

步骤1 执行以下命令,切换用户。

su - omm

步骤2 执行以下命令,进入到用户目录。

cd /home/omm

步骤3 执行以下命令,导入环境变量。

source ~/gauss_env_file

步骤4 执行以下命令,查看集群状态。

cm_ctl query -Cvipd

三、DRS迁移工具搭建

3.1系统架构

DRS基于B/S架构开发,主要由DRS-Service,DRS-Node,元数据库GaussDB,Monitor-Agent组成。

  • DRS-Service:管理DRS-Node节点,提供WEB服务和控制台页面。
  • 元数据库GaussDB:DRS业务数据库,负责存储DRS运行过程中产生的业务数据。
  • DRS-Node:可在DRS-Node上创建运行DRS同步任务,DRS-Node节点可以横向扩展。
  • Monitor-Agent:负责监控DRS-Service节点与元数据库GaussDB节点的性能指标并上报。

DRS系统架构

3.2部署架构

3.2.1 DRS独立部署

DRS支持将DRS-Service,元数据库GaussDB,DRS-Node,Monitor-Agent部署在同一节点上,机器规格详见表1-1,部署架构图见图1-2。

功能调测规格

硬件

配置

CPU

≥16核处理器

内存

≥64 GB

磁盘

≥1.6 TB

网络带宽

≥10 GE

DRS单节点部署架构

3.2.2 GaussDB轻量化解决方案

在GaussDB轻量化场景下,DRS属于GaussDB轻量化解决方案的一部分,此章节仅介绍DRS在该场景下的部署架构,安装部署方式参考 4 安装DRS(多节点部署)。

GaussDB轻量化单DC场景下DRS部署架构图

系统要求

3.3.1操作系统要求

安装DRS的操作系统要求如下表1-6所示:

支持的操作系统及相应安装包

服务器类型

操作系统

支持的安装包版本

通用x86服务器

银河麒麟 V10

SP1,SP2

统信UnionTechos 20

UP1

华为TaiShan ARM服务器

银河麒麟 V10

SP1,SP2

统信UnionTechos 20

UP1

3.3.2 纳管实例

根据纳管实例占用CPU和内存资源的不同,换算最多支持纳管实例或节点数如下表1-7所示:

纳管实例或节点数

服务器规格

最多可创建的任务数。

GaussDB建议规格:16U128G

DRS-Service建议规格:8U16G

DRS-Node建议规格:16U32G

最大可支持100个任务。

GaussDB和DRS-Service机器规格决定了创建任务的上限(当前建议规格可以创100个任务数),实际可以创建的任务数量需要DRS-Node的规格和数量来确定。

说明

4U8G加500G磁盘空间的机器可创建一个任务、若增加创建任务数量,需满足CPU、内存、磁盘空间三者同步增加。

GaussDB最小规格:8U32G

DRS-Service最小规格:4U8G

DRS-Node最小规格:4U8G

1个任务,仅支持做功能调试时使用。

3.3.3 磁盘空间划分要求

安装DRS各节点的磁盘空间划分要求如下表所示:

DRS-Gaussdb元数据库

磁盘

分区

挂载点

文件系统类型

分区大小

目录

用途

说明

系统盘

/

/

ext4

100G

系统根目录

操作系统运行目录

-

数据盘

分区1

/data/cluster

ext4

1024G

进程目录

数据库程序安装目录

-

工具目录

数据库系统工具目录

数据目录

数据库系统数据目录

日志目录

数据库系统日志目录

DRS-Node

磁盘

分区

挂载点

文件系统类型

分区大小

目录

用途

说明

系统盘

/

/

ext4

100G

系统根目录

操作系统运行目录

-

数据盘

分区1

/drs

ext4

100G

安装包目录

安装存放目录

-

进程目录

DRS内核进程软件目录

-

工具目录

DRS内核工具目录

-

日志目录

DRS内核日志目录

-

配置文件目录

DRS内核配置文件

-

分区2

/data

ext4

根据实际任务数计算,计算方式见《独立部署形态LLD模板》附录章节。

同步日志目录

同步数据库日志文件

-

DRS-Service

磁盘

分区

挂载点

文件系统类型

分区大小

目录

用途

说明

系统盘

/

/

ext4

100G

系统根目录

操作系统运行目录

-

数据盘

分区1

/opt/drs

ext4

200G

进程目录

DRS管控程序安装目录

-

工具目录

DRS管控工具脚本目录

配置文件目录

DRS管控配置文件目录

证书目录

DRS管控需要证书目录

密钥目录

DRS密钥目录

日志目录

DRS管控运行日志和操作日志存储目录

  • /opt/drs 目录为存储日志和业务数据,请保证磁盘空间充足。

本地备份集盘

分区2

/opt/drs-backup

ext4

500G

备份恢复目录

存放备份数据目录,本地盘备份数据目录

  • DRS-Service备份磁盘空间,存储drs-Service备份数据,默认路径是:/opt/drs-backup
  • DRS-Service备份磁盘空间,建议单独挂盘,可参考章节8.3 数据盘/data目录准备,以确保磁盘空间充足

单个任务所需机器配置

硬件

配置

CPU

4vCPU

实际可用内存

8 GB

磁盘

500G

网络带宽

任务数小于5需要10GE,大于等于5个任务需要25GE。

注:

建议 DRS-GaussDB元数据库,DRS-Servcie,DRS-Node的每个挂载点单独挂盘。

若DRS-Service所有路径规划在同一个磁盘分区,总计需要800GB空闲空间。

4U8G加500G磁盘空间的机器可创建一个任务、若增加创建任务数量,需满足CPU、内存、磁盘空间三者同步增加。

3.3.4 软件要求

安装DRS的软件要求如下表所示:

DRS软件要求

软件

规格

浏览器

DRS支持下列浏览器:

  • Chrome 70.0+
  • Microsoft Edge 106.0.1370.42+

Python

麒麟X86 V10 SP1:系统镜像python3 版本必须是3.7.9

麒麟ARM V10 SP1:系统镜像python3 版本必须是3.7.4

统信X86 UnionTechos 20 UP1:系统镜像python3 版本必须是3.7.9

统信ARM UnionTechos 20 UP1:系统镜像python3 版本必须是3.7.9

可执行如下指令,检查Python版本。

python3 --version

Expect (操作系统实用软件)

操作系统应包含Expect 实用软件。执行如下指令,检查系统是否安装Expect软件。

expect -v

Openssl

操作系统应包含Openssl。执行如下指令,检查系统是否安装Openssl。

openssl version

3.4 安装GaussDB

前提条件

此处的GaussDB是作为DRS的中间库使用,禁止和其他GaussDB数据库混用。GaussDB不能安装在/drs目录下,会有文件属主权限冲突。

安装步骤:

以root用户登录任意一台待安装GaussDB的服务器。

执行以下命令,查看系统是X86还是ARM架构以及操作系统。

uname -a

回显信息为aarch,则系统为ARM架构。

回显信息为X86,则系统为X86架构。

cat /etc/os-release

回显信息名称,Kylin则为麒麟操作系统。

回显信息名称,UnionTech则为统信操作系统。

执行以下命令,创建gauss文件夹。

mkdir -p /root/package/gauss

根据步骤2中系统类型,上传对应GaussDB软件包和安装包到/root/package/gauss文件夹中。

X86架构:

GaussDBInstaller_x.x.x.x.tar.gz -----安装包

GaussDB_X86_Kylinv10_x.x.x.x.tar.gz -----X86麒麟环境软件包

GaussDB_X86_UnionTech20_x.x.x.x.tar.gz -----X86统信环境软件包

ARM架构:

GaussDBInstaller.tar_x.x.x.x.gz -----安装包

GaussDB_ARM_Kylinv10_x.x.x.x.tar.gz -----ARM麒麟环境软件包

GaussDB_ARM_UnionTech20_x.x.x.x.tar.gz ------ ARM统信环境软件包

执行以下命令,进入目录。

cd /root/package/gauss

执行以下命令,解压安装脚本。

tar -xvf GaussDBInstaller_*.tar.gz -C /data

此处以解压到/data目录下为例。

执行以下命令,解压软件包。

X86架构:

tar -xf GaussDB_X86_Kylinv10_Centralized_*.tar.gz

ARM架构:

tar -xf GaussDB_ARM_Kylinv10_Centralized_*.tar.gz

解压后得到所需的软件包,此处截图为麒麟X86集中式安装包作为安装示例。

执行以下命令,将解压后的3个软件包复制到/data/GaussDBInstaller/pkgDir目录下。

cp /root/package/gauss/DBS-GaussDB-Adaptor*.tar.gz /data/GaussDBInstaller/pkgDir

cp /root/package/gauss/GaussDB-Kernel*.tar.gz /data/GaussDBInstaller/pkgDir

ll /data/GaussDBInstaller/pkgDir

执行如下命令,配置install_cluster.conf文件。

vim /data/GaussDBInstaller/install_cluster.conf

执行如下命令,查看安装脚本内容。

ll /data/GaussDBInstaller

ll /data/GaussDBInstaller/jsonFileSample/

拷贝json文件到脚本解压后的目录GaussDBInstaller下。

单节点部署:

cp /data/GaussDBInstaller/jsonFileSample/1_node.json /data/GaussDBInstaller/install_cluster.json

配置install_cluster.json 文件,此处以单节点部署配置文件为例。

vim /data/GaussDBInstaller/install_cluster.json

进入安装目录,执行脚本开始安装

cd /data/GaussDBInstaller

python3 gaussdb_install.py --action main

安装完成后,执行以下步骤检查安装是否成功。

检查回显的安装日志:installCluster installation is successful. 则代表元数据库GaussDB数据库安装成功。

安装完成后,可通过命令切换用户,本地登录检查元数据库是否安装成功。其中omm为GaussDB的OS用户,15432为端口号

su - omm

gsql -d postgres -h 127.0.0.1 -U root -p 15432

# gsql -d postgres -h 127.0.0.1 -U root -p 15432
Password for user root: # 请输入root用户密码
gsql ((GaussDB Kernel V500R002C10 build c3db7c07) compiled at 2022-09-24 21:19:15 commit 3864 last mr 8636 release)
SSL connection (cipher: ECDHE-RSA-AES128-GCM-SHA256, bits: 128)
Type "help" for help.

openGauss=> select version(); # 查询版本 version
openGauss=>\q # 退出
安装后配置

在安装完GaussDB数据库后,需检查待安装节点是否能够正常连接GaussDB,如果连接失败,需修改pg_hba.conf配置文件。

执行以下命令,检查待安装节点是否能够正常连接GaussDB。

gsql -d postgres -h[GaussDB 节点IP] -U root -p 30100

  • 如果连接失败,执行步骤2修改pg_hba.conf配置文件。
  • 如果连接成功,则无需执行后续配置操作。

以root用户登录GaussDB部署节点,执行以下命令打开pg_hba.conf配置文件,其中[]中内容需要实际情况修改。

vim /data/cluster/data/dn/dn_[xxx]/pg_hba.conf

注释掉这条记录。

#host all all [GaussDB 节点IP]/32 trust
#host all all 0.0.0.0/0 sha256

加入DRS-Service服务全部节点的IP地址及DRS-Node服务全部节点的IP地址。

host all all [DRS-Service服务节点IP]/32 sha256
host all all [DRS-Node服务节点IP]/32 sha256

通过以下方法,使修改生效,优先选择方法一。

  • 方法一
    1. 登录数据库,切换到omm用户。omm为GaussDB的OS用户(步骤9中的os_user),需根据实际情况进行替换。
    2. 执行以下命令并退出。

gaussdb=# select * from pg_reload_conf();

  • 方法二:

执行以下命令,重启GaussDB节点,其中omm为GaussDB的OS用户(步骤9中的os_user),需根据实际情况进行替换。

dn_data=`ls /data/cluster/data/dn`

su - omm -c "source ~/gauss_env_file;gs_ctl restart -D /data/cluster/data/dn/${dn_data} -M primary"

当显示如下日志“server started”,则代表GaussDB数据库重启成功。

[2023-03-19 00:47:54.959][64079][][gs_ctl]: done
[2023-03-19 00:47:54.959][64079][][gs_ctl]: server started (/data/cluster/data/dn/dn_6001)

执行以下命令,切换用户。其中omm为GaussDB的OS用户(步骤9中的os_user),需根据实际情况进行替换。

su omm

再次执行以下命令,连接GaussDB数据库。

gsql -d postgres -h[GaussDB 节点IP] -U root -p 30100

回显如下,则代表连接GaussDB数据库成功。

Password for user root: # 请输入root用户密码
gsql ((GaussDB Kernel V500R002C10 build c3db7c07) compiled at 2022-09-24 21:19:15 commit 3864 last mr 8636 release)
SSL connection (cipher: ECDHE-RSA-AES128-GCM-SHA256, bits: 128)
Type "help" for help.

----结束

3.5 安装DRS-Service服务

操作场景

  • DRS-Service服务运行依赖GaussDB库,需要确保上一步骤环境安装成功。
  • DRS-Service服务部署需要输入内网IP地址,需要提前获取内网IP地址。

操作步骤

以root用户登录待安装DRS的服务器,执行以下命令,创建package文件夹。

mkdir -p /root/package

将DRS-Service软件包上传到/root/package文件夹中。

tar -xzf DRS-Service-*.tar.gz

cd DRS-Service-*

vim install.conf

[meta db]
metaDB_engine = gaussdb
metaDB_address = 127.0.0.1:30100 # 元数据库IP地址,多IP地址可用逗号分隔
metaDB_root_user = root # 元数据库用户名
metaDB_root_password = # 元数据库密码
metaDB_drs_user = drs # 元数据库DRS用户名
metaDB_drs_password = # 元数据库DRS密码
[drs]
external_ip = 10.11.9.48 # 本机内网IP地址
external_port = 7443 # service服务端口,默认7443
drs_admin_username = admin # DRS管理帐户名
drs_admin_password = # DRS管理帐户密码
ca_phrase = ${drs_admin_password} # https自动生成证书密码,默认与管理帐户密码一致,也可自行配置
# deploy mode: ha/independent
deploy_scene = independent # 部署场景
# node role when deploy_scene is ha: primary/standby
node_type = primary # 部署节点角色,默认请填写primary
#config cgroup
use_cgroup = no # 是否使用cgroup限制资源(轻量化单DC标准场景,DRS管理面与TPOPS使用三台物理机进行高可用部署:使用cgroup限制GaussDB及DRS管理面cpu、memory 资源,配置为yes;其余场景配置为no)

安装前环境预检查,执行以下命令,检查安装环境。

sh precheck_env.sh

回显信息如下:

================== START TO PRECHECK ENVIRONMENT ====================
Item1: User Check
User is root
User Check Pass!

Item2: Hardware Check
cpu_num is 32U
memory_capacity is 61G
Hardware Check Complete!

Item3: Openssl Check
OpenSSL 1.1.1f 31 Mar 2020
Openssl Check Pass!
=================== PRECHECK RESULT=====================
Item Actual/Recommand
1.User Check: Pass/Pass #检查项1:安装用户检查,要求root用户,安装必要条件
2.Hardware Check: #检查项2:机器规格检查,建议8U16G,非必要条件
CPU Check: 32U/8U
Memory Check: 61G/16G
3.Openssl Check: Pass/Pass #检查项3:openssl开启检查,要求开启,安装必要条件
=================== PRECHECK END =======================
[2023-08-01 11:12:54][root][INFO] --- Precheck environment success.
[2023-08-01 11:12:54][root][INFO] --- Precheck begin.
[2023-08-01 11:12:54][root][INFO] --- Check drs_service success
[2023-08-01 11:12:54][root][INFO] --- Precheck success.

检查项说明

检查项

说明

用户检查

需root安装,非root安装失败。

机器规格

建议:8U16G。

如果规格不满足,当任务数量大时,会出现界面卡顿,响应慢,影响性能。

Openssl检查

需开启openssl,不开启安装失败。

执行以下命令,运行安装脚本。

sh install.sh

安装完成后,可通过在浏览器打开回显IP地址验证DRS-Service是否安装成功。

3.6 安装DRS-Node服务

操作场景

DRS-Node服务运行依赖元数据库GaussDB、DRS-Service服务部署,需要确保上一步骤安装成功。

操作步骤

以root用户登录待安装DRS的服务器。将DRS-Node软件包上传到/root/package文件夹中。

执行以下命令,进入目录。

cd /root/package

执行以下命令,解压并进入DRS-Node文件夹,其中DRS-Node-*版本号以实际为准。

tar -xzf DRS-Node-*.tar.gz

cd DRS-Node-*

执行如下命令,配置install.conf文件。

vim install.conf

[meta db]
metaDB_engine = gaussdb
metaDB_address = 127.0.0.1:30100 # 元数据库IP地址,多IP地址可用逗号分隔
metaDB_drs_user = drs # 元数据库DRS用户名
metaDB_drs_password = # 元数据库DRS密码
metaDB_database = drs # 元数据库database

[drs]
node_ip = 10.11.9.48 # 节点IP地址
node_maxJobCount =

[system]
swap_space = 2G # swap分区大小

安装前环境预检查。执行以下命令,检查安装环境。

sh precheck_env.sh

检查项说明

检查项

说明

用户检查

需root安装,非root安装失败。

机器规格

建议:16U32G 。

如果规格不满足,当迁移数据量或任务数量大时,数据迁移慢,影响性能。

磁盘检查

建议:/drs /data目录可用共2.5T;若不存在此目录则根目录需存在可用2.5T磁盘空间。

如果磁盘大小不满足,当迁移数据量或任务量大时,可能磁盘爆满导致迁移任务失败。

执行以下命令,运行安装脚本。

sh install.sh

打开浏览器页面,单击创建任务,DRS-Node服务启动后,将在任务可用IP地址分配给安装时填写的Node IP。如果未显示,最多请等待1分钟,DRS-Node服务将完成初始化并启动,如图所示。

任务基本信息

迁移前操作

4.1 源端(PG)

确定迁移的对象

统计源数据库对象

1、统计数据库个数

psql –d postgres -p 15432

\l+ --统计数据库名称以及大小

\du –统计数据库所有用户

\c 数据库名称 -- \dn 统计数据中schema的名称

3.1.1.2 创建迁移用户及赋权

创建只读用户用于读取数据库全部对象,该用户用于DRS工具迁移数据

Create user drs_read password ‘Drs_read#2023’;

grant usage on schema power_tf,power_reliability,power_work,power_ds,power_tech,power_quality,power_sch,power_common to drs_read;

grant usage on schema power_tf,power_reliability,power_work,power_ds,power_tech,power_quality,power_sch,power_common to drs_read;

grant select on all sequence in schema power_common,power_tf,power_reliability,power_work,power_ds,power_tech,power_quality,power_sch to drs_read;

grant select on all sequences in schema power_work,power_ds,power_tech,power_quality,power_sch to drs_read;

grant select on all tables in schema power_work,power_ds,power_tech,power_quality,power_sch to drs_read;

4.2 目标端(GaussDB库)

创建复制用户及赋权

gsql –d postgres –p 15432

gauss=#create user drs_rep password ‘Drs_rep#2023’;

gauss=#alter user drs_rep sysadmin;

UGO迁移表结构

使用UGO工具,可以迁移数据库结构、表结构、索引、函数等元数据。

1、创建项目,进行源端数据库评估。

迁移结构后会提示迁移成功和失败的对象百分比,如图所示:

DRS迁移数据

5.1 创建复制用户

通过管理员账号登录

创建资源组

5.2创建迁移任务。

使用复制账号drs登录,创建同步任务

点击测试连接,成功后执行下一步

选择要迁移的对象

从列表中可以看出,工具仅支持表和序列的迁移,同时只能迁移一个库。下方限速可针对迁移带宽速率进行调整。

下一步进入迁移前的检查,如果权限不足会提示需要哪些权限,需完成整改后进入下一步

六、迁移后一致性检查

6.1使用DRS工具对比

在DRS任务管理中,可以看到数据迁移进度,在任务结束后可以进行数据对比,如图所示

也可以通过日志看到迁移结果,如图所示:

6.2手动对比

通过登录源库和目标库,分别使用脚本统计各个对象数量。

七、问题总结及解决方法

7.1 用户迁移

问题描述:DRS工具和UGO工具无法迁移用户,需在目标库创建用户以及授权。

处理方法:手动创建。

# su – omm

gsql –d postgres –p 15432 –r

create user drmc password 'PAssw0rd_2023';

授权

连接测试

gsql -d postgres -p 15432 -U drmc -W PAssw0rd_2023 -r

7.2 序列迁移

问题描述:DRS工具或UGO工具迁移序列到目标库,序列会重新从初始值开始递增,如果业务切换至目标库会导致采用序列做为主键的列值冲突

解决方法:列举所有scheme的序列,收集当前序列值,在目标库重置当前值。

源库收集序列当前值

select * from pg_sequence;

收集每个序列last_value

目标库重置每个序列的当前值

Select setval(‘序列名称’,‘当前值’);

Gsql –p 15432 –d postgres -r

Gaussdb=#\d+ 序列名---查看当前值

7.3 分区表迁移

问题描述:DRS工具在迁移分区表时会将分区表转化成普通表。UGO在PG迁移至GaussDB数据库中,由于语法不兼容问题,需要手动修改语法来实现。

解决方法:1、手动创建分区表,然后导入数据。

# su – opostgres

收集所有分区表

select nmsp_parent.nspname as

parent_schema,

parent.relname as parent,

nmsp_child.nspname as child_schema,

child.relname as child_name

from pg_inherits

join pg_class parent

on pg_inherits.inhparent=parent.oid

join pg_class child

on pg_inherits.inhrelid=child.oid

join pg_namespace nmsp_parent

on nmsp_parent.oid=parent.relnamespace

join pg_namespace nmsp_child

on nmsp_child.oid=child.relnamespace;

手动创建分区表

示例:CREATE TABLE power_sch.abc (

obj_id NVARCHAR2(42) NOT NULL,

sun_year_month NVARCHAR2(42)

CONSTRAINT " abc_pkey" PRIMARY KEY (sun_year_month, obj_id)

)

PARTITION BY LIST (sun_year_month);

添加分区:

alter table power_sch.abc add partition abc_201201 VALUES ('201201');

7.4 函数迁移

问题描述:支持迁移普通自定义函数,依赖PG插件的函数需手动改写。

解决方法:1、手动改写实现相关功能。

select a.usename,b.proname from pg_user a,pg_proc b where a.usesysid=b.proowner and a.usename<>'postgres';

7.5 外键改造

问题描述:在迁移中发现GaussDB分布式数据库不支持外键,需要将表的外键用触发器形式实现,在UGO迁移过程中提示:FOREIGN KEY …REFERENCES constraint is not yet supported.

解决方法1:使用GaussDB集中式支持外键约束。

解决方法2:GaussDB分布式数据库处理外键约束的方法。

场景1:一个父表,一个子表,trigger完全等价

1.创建两个表,一个主表和一个从表,主表中包含主键列,从表中包含外键列。

CREATE TABLE parent (

id INT PRIMARY KEY,

name VARCHAR(50) NOT NULL

);

CREATE TABLE child (

id INT,

parent_id INT,

name VARCHAR(50) NOT NULL,

FOREIGN KEY (parent_id) REFERENCES parent(id)

);

2.向主表中插入数据。

INSERT INTO parent (id, name) VALUES (1, 'John');

INSERT INTO parent (id, name) VALUES (2, 'Jane');

INSERT INTO parent (id, name) VALUES (3, 'Jane');

3.向从表中插入数据,其中外键列的值应该与主表中的主键列的值相匹配。

INSERT INTO child (id, parent_id, name) VALUES (1, 1, 'Tom');

INSERT INTO child (id, parent_id, name) VALUES (2, 2, 'Jerry');

4.尝试插入一条不匹配的从表数据,即外键列的值与主表中不存在的主键列的值相匹配。此时应该抛出异常。

INSERT INTO child (id, parent_id, name) VALUES (4, 4, 'Spike');

---结果:ORA-02291: 违反完整约束条件 (UGO.SYS_C0087731) - 未找到父项关键字

5.update子表,无法成功

update child set parent_id=22 where id=2;

---结果:ORA-02291: 违反完整约束条件 (UGO.SYS_C0087731) - 未找到父项关键字

1.2GaussDB替代方案:分布式不支持外键,使用trigger保证外键约束的一致性,如果依赖的父表存在,insert,不存在raise

1.创建两个表,一个主表和一个从表,主表中包含主键列,从表中包含外键列。

CREATE TABLE parent (

id INT PRIMARY KEY,

name VARCHAR(50) NOT NULL

);

CREATE TABLE child (

id INT PRIMARY KEY,

parent_id INT,

name VARCHAR(50) NOT NULL/*,

FOREIGN KEY (parent_id) REFERENCES parent(id)*/ --注释掉外键

);

使用trigger实现等价功能--外键一致性

--触发函数

create or replace function func_child() return trigger

as

id_values int;

BEGIN

SELECT COUNT(id) INTO id_values

FROM parent

WHERE id = NEW.parent_id;

IF id_values=0 THEN

RAISE EXCEPTION '%' , 'Foreign key constraint violated because the id column value does not exist in the parent table.';

else

RETURN NEW;

END IF;

end;

/

--触发器

DROP TRIGGER if exists tri_child on child;

CREATE TRIGGER tri_child

before insert or update on child

FOR EACH ROW

EXECUTE PROCEDURE func_child();

2.向主表中插入数据。

INSERT INTO parent (id, name) VALUES (1, 'John');

INSERT INTO parent (id, name) VALUES (2, 'Jane');

INSERT INTO parent (id, name) VALUES (3, 'Jane');

3.向从表中插入数据,其中外键列的值应该与主表中的主键列的值相匹配。

INSERT INTO child (id, parent_id, name) VALUES (1, 1, 'Tom');

INSERT INTO child (id, parent_id, name) VALUES (2, 2, 'Jerry');

4.尝试插入一条不匹配的从表数据,即外键列的值与主表中不存在的主键列的值相匹配。此时应该抛出异常。

INSERT INTO child (id, parent_id, name) VALUES (4, 4, 'Spike');

ugo=> INSERT INTO child (id, parent_id, name) VALUES (4, 4, 'Spike');

ERROR: Foreign key constraint violated because the id column value does not exist in the parent table.

5.update子表,无法成功

update child set parent_id=22 where id=2;

ugo=> update child set parent_id=22 where id=2;

ERROR: Foreign key constraint violated because the id column value does not exist in the parent table.

场景2:多个父表,一个子表,trigger完全等价

2.1多外键:

1.创建两个表,两个主表和一个从表,主表中包含主键列,从表中包含外键列。

drop table parent;

CREATE TABLE parent (

id INT PRIMARY KEY,

name VARCHAR(50) NOT NULL

);

drop table parent1;

CREATE TABLE parent1 (

id INT ,

idname VARCHAR(50) PRIMARY KEY

);

drop table child;

CREATE TABLE child (

id INT ,

parent_id INT,

name VARCHAR(50) NOT NULL,

FOREIGN KEY (parent_id) REFERENCES parent(id),

FOREIGN KEY (name) REFERENCES parent1(idname)

);

2.向主表中插入数据。

INSERT INTO parent (id, name) VALUES (1, 'John');

INSERT INTO parent (id, name) VALUES (2, 'Jane');

INSERT INTO parent (id, name) VALUES (3, 'Jane');

INSERT INTO parent1 (id, idname) VALUES (1, 'John1');

INSERT INTO parent1 (id, idname) VALUES (2, 'Jane1');

INSERT INTO parent1 (id, idname) VALUES (3, 'xxJane1');

3.向从表中插入数据,其中外键列的值应该与主表中的主键列的值相匹配。

INSERT INTO child (id, parent_id, name) VALUES (1, 1, 'John1');

INSERT INTO child (id, parent_id, name) VALUES (2, 2, 'xxJane1');

4.尝试插入一条不匹配的从表数据,即外键列的值与主表中不存在的主键列的值相匹配。此时应该抛出异常。

INSERT INTO child (id, parent_id, name) VALUES (1, 1, 'Tom');

INSERT INTO child (id, parent_id, name) VALUES (1, 4, 'John1');

INSERT INTO child (id, parent_id, name) VALUES (4, 4, 'Spike');

---结果:ORA-02291: 违反完整约束条件 (UGO.SYS_C0087731) - 未找到父项关键字

5.update子表,无法成功

update child set parent_id=22 where id=2;

---结果:ORA-02291: 违反完整约束条件 (UGO.SYS_C0087731) - 未找到父项关键字

2.2GaussDB替代方案:分布式,使用trigger完全等价

1.创建两个表,两个主表和一个从表,主表中包含主键列,从表中包含外键列。

drop table parent;

CREATE TABLE parent (

id INT PRIMARY KEY,

name VARCHAR(50) NOT NULL

);

drop table parent1;

CREATE TABLE parent1 (

id INT ,

idname VARCHAR(50) PRIMARY KEY

);

drop table child;

CREATE TABLE child (

id INT ,

parent_id INT,

name VARCHAR(50) NOT NULL/*,

FOREIGN KEY (parent_id) REFERENCES parent(id),

FOREIGN KEY (name) REFERENCES parent1(idname)*/

);

trigger实现等价功能

--触发函数

create or replace function func_child() return trigger

as

parent_id_values int;

name_values int;

BEGIN

SELECT COUNT(id) INTO parent_id_values

FROM parent

WHERE id = NEW.parent_id;

SELECT COUNT(idname) INTO name_values

FROM parent1

WHERE idname = NEW.name;

IF parent_id_values=0 or name_values=0 THEN

RAISE EXCEPTION '%', 'Foreign key constraint violated because the id column value and idname column value does not exist in the parent table and parent1 table .';

else

RETURN NEW;

end if;

end;

/

--触发器

DROP TRIGGER if exists tri_child on child;

CREATE TRIGGER tri_child

before insert or update on child

FOR EACH ROW

EXECUTE PROCEDURE func_child();

2.向主表中插入数据。

INSERT INTO parent (id, name) VALUES (1, 'John');

INSERT INTO parent (id, name) VALUES (2, 'Jane');

INSERT INTO parent (id, name) VALUES (3, 'Jane');

INSERT INTO parent1 (id, idname) VALUES (1, 'John1');

INSERT INTO parent1 (id, idname) VALUES (2, 'Jane1');

INSERT INTO parent1 (id, idname) VALUES (3, 'xxJane1');

3.向从表中插入数据,其中外键列的值应该与主表中的主键列的值相匹配。

INSERT INTO child (id, parent_id, name) VALUES (1, 1, 'John1');

INSERT INTO child (id, parent_id, name) VALUES (2, 2, 'xxJane1');

4.尝试插入一条不匹配的从表数据,即外键列的值与主表中不存在的主键列的值相匹配。此时应该抛出异常。

INSERT INTO child (id, parent_id, name) VALUES (1, 1, 'Tom');

INSERT INTO child (id, parent_id, name) VALUES (1, 4, 'John1');

INSERT INTO child (id, parent_id, name) VALUES (4, 4, 'Spike');

ugo=> INSERT INTO child (id, parent_id, name) VALUES (1, 1, 'Tom');

ERROR: Foreign key constraint violated because the id column value and idname column value does not exist in the parent table and parent1 table .

ugo=> INSERT INTO child (id, parent_id, name) VALUES (1, 4, 'John1');

ERROR: Foreign key constraint violated because the id column value and idname column value does not exist in the parent table and parent1 table .

ugo=> INSERT INTO child (id, parent_id, name) VALUES (4, 4, 'Spike');

ERROR: Foreign key constraint violated because the id column value and idname column value does not exist in the parent table and parent1 table .

5.update子表,不成功

update child set parent_id=22 where id=1;

update child set name='xiaowang' where parent_id=2;

ERROR: Foreign key constraint violated because the id column value and idname column value does not exist in the parent table and parent1 table .

7.6 索引改造

问题描述1:目标库采用GaussDB分布式数据库时,在使用UGO工具迁移索引过程中,提示Cannot create index whose evaluation cannot be enforced to remote nodes.

问题描述2:在使用UGO工具迁移索引过程中,分区表索引无法迁移,需要手动获取源端索引定义手动创建。

处理方法1:到数据库中查找表对象的分布键,添加分布列id到索引个。

示例:power_ocp.config_info_bak对象,可以在数据库中使用

\d+ power_ocp.config_info_bak

来查找该对象的分布键,即下图红线中显示的Distribute By后的关键字

处理方法2:手动获取源端分区表索引定义

Select * from pg_indexes where tablename in (‘’,’’);

手动执行索引定义


本文作者

本文内容来自于从事数据库运维的subverter老师,先后就职于互联网企业和能源企业,拥有9年的数据库开发和管理经验,擅长主流数据库的运维开发、备份恢复、安装迁移、故障处置、性能优化等,随着国产数据库的崛起,对华为的GaussDB系列数据库进行了深入学习,目前针对主流数据库迁入GaussDB数据库积攒了大量案例,同时希望自己以后再接再厉,为国产信创版块贡献绵薄之力。


最后修改时间:2024-02-29 10:12:16
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论