数据库迁移是实际工作中经常遇到的问题,比如由于磁盘空间、业务性能、项目改造等等原因,有从甲服务器迁移到乙服务器,从A种数据库迁移到B种数据库,从源路径迁移到另一个目标路径、同一个机器下从一个用户迁移到另一个用户等各种场景,有时需要整个数据库所有文件都迁移,有时只需要迁移部分数据文件如REDO、表空间文件等。
云原生数据库openGauss也支持若干数据库迁移工具,其中的pgloader是一个数据导入工具,使用COPY命令将数据导入到PostgreSQL。pgloader有两种工作模式,一种是从文件导入,一种是迁移数据库。pgloader在两种情况下都使用PostgreSQL的COPY协议高效的传输数据。
openGauss兼容PostgreSQL的通信协议以及绝大部分语法,本文就介绍如何使用pgloader将MySQL数据库迁移至openGauss。

整个过程可以基本分为四步:
迁移前准备 > 相关文件配置 > 执行迁移 > 结果验证
除了 源数据库MySQL 和目标数据库openGauss,它们之间需要网络互通外。还需要关键工具pgloader。因为某些网络原因,我这里使用的是docker 版本的pgloader 下载,安装在目标库所在服务器上。
默认pull最新版本。
[root@pekphisprb70593 software]# docker pull dimitri/pgloader
[root@pekphisprb70593 software]# docker run --rm --name pgloader dimitri/pgloader:latest pgloader --version
pgloader version "3.6.7~devel"
compiled with SBCL 2.1.1.debian
需要注意的是,它只是命令行工具,所以一旦执行完毕会自动退出。故每次都需要“docker run --rm --name pgloader dimitri/pgloader:latest pgloader + 具体操作”的命令。
用户密码存储在系统表pg_authid中,为防止用户密码泄露,openGauss对用户密码进行加密存储,所采用的加密算法由配置参数password_encryption_type决定。

由于MD5加密算法安全性低,存在安全风险,不建议使用。openGauss 对原生PostgreSQL的通信协议进行了安全加固,这导致与PostgreSQL的默认通信协议互相不兼容了,因此,使用pgloader的PostgreSQL原生版本默认是不能连接openGauss的。会报类似下述错误:

通过修改该GUC参数修改数据库加密算法,执行如下命令将参数修改为1 ,同时支持md5 和sha256
gs_guc reload -N all -I all -c "password_encryption_type=1"
一定要在设置完上述参数后,再新建用户。
若不设置,可能会像我一样遇到“Failed to connect to pgsql at “xxx” (port 15400) as user “opengauss_test”: Database error 28000: no pg_hba.conf entry for host “172.17.0.2”.”

设置方法:
cd /opt/huawei/install/data/dn/
vi pg_hba.conf
在IPv4中新增一行
host all all 0.0.0.0/0 md5
然后重启数据库
[omm@pekphisprb70593 dn]$ gs_om -t stop
[omm@pekphisprb70593 dn]$ gs_om -t start

这一步是可选的,包括源库的数据库、用户和原始数据,目标库的数据库和用户。如果都已经有了则直接跳过看下一步,缺啥补啥。
创建目标库openGauss的用户及database.
[omm@pekphisprb70593 ~]$ gsql -d postgres -p 15400
openGauss=# CREATE USER opengauss_test identified by 'Gauss_234';
openGauss=# GRANT ALL PRIVILEGES TO opengauss_test;
openGauss=# CREATE DATABASE opengauss_db with owner opengauss_test ENCODING 'utf8' template = template0;
新建了一个空表test2。
[omm@pekphisprb70593 dn]$ gsql -d opengauss_db -p 15400
opengauss_db=# create table if not exists test2(id integer);
CREATE TABLE
创建源数据库和用户,刷新系统授权表。
CREATE DATABASE IF NOT EXISTS mysql_db1 default charset utf8;
CREATE USER mysql_t1 identified by 'Mysql_234' ;
GRANT ALL PRIVILEGES ON *.* TO 'mysql_t1' WITH GRANT OPTION;
FLUSH PRIVILEGES;
构造数据
mysql@siaphisprk01345:~> mysql -u mysql_t1 -p
mysql> use mysql_db1;
create table if not exists test1 (id int(10),name char(20),salary float,time datetime(6),addr varchar(200),primary key(id)) ;
insert into test1 values (1,'zhangsan',2000.00,'2018-06-01 00:00:00','beijing');
insert into test1 values (2,'李四',2000.89,'2018-06-01 00:00:00','西安');
insert into test1 values (3,'Bob',2000,'2018-06-02 00:00:00','南京');
#创建了一个和目标数据库表结构不同的test2。
create table if not exists test2(id int(10),name varchar(20));
insert into test2 values (1234567,'Kevin');
#创建空表test3。
create table if not exists test3(id int(10));
pgloader提供丰富的配置项,我们可以自由定义迁移时的各类动作,如通过include drop,删除目标数据库中名称出现在MySQL数据库中的所有表,以允许连续多次使用同一命令,从干净的环境自动启动。
在pgloader所在服务器任意路径下创建一个配置文件,文件可以命名为opengauss.loader。下面是一个配置文件示例,里面的值需要修改为自己环境的实际值。
LOAD DATABASE
FROM mysql://mysql_t1:Mysql_234@1.1.1.1:3306/mysql_db1
INTO postgresql://opengauss_test:Gauss_234@2.2.2.2:15400/opengauss_db
WITH include drop, create tables, create indexes, reset no sequences,
workers = 8, concurrency = 1,
multiple readers per thread, rows per range = 50000
CAST
type varchar when(= 1 precision) to "boolean" drop typemod keep default keep not null;
几个配置项简单介绍下:
更详细的配置项解读,可查看官网的说明:https://pgloader.readthedocs.io/en/latest/ref/mysql.html
Migratinga MySQL Database to PostgreSQL — pgloader 3.4.1 documentation
启动docker:
docker run -tid --name pgloader_test dimitri/pgloader
复制配置文件到docker:
docker cp ./openGauss.loader pgloader_test:/
进入docker环境:
docker exec -it pgloader_test /bin/bash
启动迁移
root@548498fb64a6:/# pgloader opengauss.loader

如果遇到问题可以先按照上面的配置步骤去检查下。
现在来看下迁移结果与预期是否一致:
在目标库进行查询:
[omm@pekphisprb70593 dn]$ gsql -d opengauss_db -p 15400
可以看出表 test1和test3包括数据都已经迁移过来。test2由于迁移前后的数据库结构不一致并没有迁移成功。与预期一致。
但是之前mysql定义的float类型,被强制转成double precision。其他的一些不同和限制有兴趣或者必须要迁移的同学自行探索下。

总结:使用pgloader进行数据库的迁移过程还是比较简单的,有兴趣的同学可以尝试下。
openGauss: 一款高性能、高安全、高可靠的企业级开源关系型数据库。
🍒如果您觉得博主的文章还不错或者有帮助的话,请关注一下博主,如果三连点赞评论收藏就更好啦!谢谢各位大佬给予的支持!
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h