【项目实战】记录一次PG数据库迁移至GaussDB测试
本文作者
本文内容来自于从事数据库运维的subverter老师,先后就职于互联网企业和能源企业,拥有9年的数据库开发和管理经验,擅长主流数据库的运维开发、备份恢复、安装迁移、故障处置、性能优化等,随着国产数据库的崛起,对华为的GaussDB系列数据库进行了深入学习,目前针对主流数据库迁入GaussDB数据库积攒了大量案例,同时希望以后再接再厉,为国产信创版块贡献绵薄之力。
一、说明
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 配置操作环境变量
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 |
3.2.2 GaussDB轻量化解决方案
在GaussDB轻量化场景下,DRS属于GaussDB轻量化解决方案的一部分,此章节仅介绍DRS在该场景下的部署架构,安装部署方式参考 4 安装DRS(多节点部署)。
GaussDB轻量化单DC场景下DRS部署架构图
3.3 系统要求
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管控运行日志和操作日志存储目录 |
|
|||||
本地备份集盘 |
分区2 |
/opt/drs-backup |
ext4 |
500G |
备份恢复目录 |
存放备份数据目录,本地盘备份数据目录 |
|
单个任务所需机器配置
硬件 |
配置 |
---|---|
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支持下列浏览器:
|
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的服务器。
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
通过以下方法,使修改生效,优先选择方法一。
- 方法一
- 登录数据库,切换到omm用户。omm为GaussDB的OS用户(步骤9中的os_user),需根据实际情况进行替换。
- 执行以下命令并退出。
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.2 GaussDB替代方案:分布式不支持外键,使用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 (‘’,’’);
手动执行索引定义
- 点赞
- 收藏
- 关注作者
评论(0)