本博客的目的在于简述MySQL和PostgreSQL之间如何跨数据库进行复制。涉及跨数据库复制的databases通常被称做异构databases。这是将数据从一种RDBMS server复制到另外一种server的一种很好的方法。html
PostgreSQL和MySQL都是传统的RDBMS数据库,可是他们也提供了NoSQL的能力。本文主要从RDBMS的角度讨论PostgreSQL和MySQL之间的复制问题。不对复制内部机制作详细介绍,只对一些基本元素、如何配置、有点、限制以及一些使用案例进行阐述。python
一般状况下,两个种类相同的主备之间使用binary模式或者query模式进行复制。复制的目的在于,在备上可以获得主的实时备份数据,从而造成一个active-passive模式(由于复制只配置单向复制)。固然,也能够配置成向同步,构建active-active模式。mysql
能够在两个不一样数据库server之间配置上面的两种模式,其中一个数据库server能够配置从另一个彻底不一样的数据库server上接收副本数据并维护副本数据的实时快照。MySQL和PostgreSQL经过原生机制或者第三方插件(包括binlog方法、磁盘块方法、基于语句和行的方法)完成上面提到的模式。linux
因为MySQL和PostgreSQL使用不一样的复制协议,因此他们之间不能互相交互。为了达到通讯流的目的,可使用一个开源软件pg_chameleon。sql
pg_chameleon是由python3开发的MySQL to PG的复制工具。该插件也会使用一个mysql-replication的开源库,该库也是由Python3开发。从MySQL表中拉取行镜像并存储成JSONB形式,而后同步到PG数据库。PG数据库经过pl/pgsql进行解析并回放。数据库
一、同一个集群中多个MySQL schema能够复制到一个PG database,造成many-to-one复制模式。app
二、源和目的schema名能够不同ide
三、复制数据能够从mysql级联副本中拉取。工具
四、会排除复制失败的表及复制过程当中产生错误的表。oop
五、每一个复制功能经过守护进程进行管理
六、配置参数和配置文件以yaml结构进行控制。
Host |
Vm1 |
Vm2 |
操做系统 |
Centos linux release 7.6 x86_64 |
Centos linux release 7.5 x86_64 |
数据库版本 |
MySQL5.7.26 |
PostgreSQL10.5 |
数据库端口号 |
3306 |
5433 |
IP地址 |
192.168.56.102 |
192.168.56.106 |
首先须要安装Python,他在建立虚拟环境以及激活的时候会用到。
$> wget https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tar.xz$> tar -xJf Python-3.6.8.tar.xz$> cd Python-3.6.8$> ./configure --enable-optimizations$> make altinstall
安装成功后须要建立并激活虚拟环境。另外须要将pip模块升级到最新版本。pg_chameleon最新版本是2.0.10,为了避免引入新的bug,建议先使用2.0.9版本。
$> python3.6 -m venv venv$> source venv/bin/activate(venv) $> pip install pip --upgrade(venv) $> pip install pg_chameleon==2.0.9
下一步须要经过set_configuration_files配置启用pg_chameleon,并建立默认路径以及配置文件:
(venv) $> chameleon set_configuration_filescreating directory /root/.pg_chameleoncreating directory /root/.pg_chameleon/configuration/creating directory /root/.pg_chameleon/logs/creating directory /root/.pg_chameleon/pid/copying configuration example in /root/.pg_chameleon/configuration//config-example.yml
此时,建立一个config-example.yml文件做为默认的配置文件。一个简单的配置例子以下所示:
$> cat default.yml---#global settingspid_dir: '~/.pg_chameleon/pid/'log_dir: '~/.pg_chameleon/logs/'log_dest: filelog_level: infolog_days_keep: 10rollbar_key: ''rollbar_env: ''# type_override allows the user to override the default type conversion into a different one.type_override: "tinyint(1)": override_to: boolean override_tables: - "*"#postgres destination connectionpg_conn: host: "192.168.56.106" port: "5433" user: "usr_replica" password: "pass123" database: "db_replica" charset: "utf8"sources: mysql: db_conn: host: "192.168.56.102" port: "3306" user: "usr_replica" password: "pass123" charset: 'utf8' connect_timeout: 10 schema_mappings: world_x: pgworld_x limit_tables:# - delphis_mediterranea.foo skip_tables:# - delphis_mediterranea.bar grant_select_to: - usr_readonly lock_timeout: "120s" my_server_id: 100 replica_batch_size: 10000 replay_max_rows: 10000 batch_retention: '1 day' copy_max_memory: "300M" copy_mode: 'file' out_dir: /tmp sleep_loop: 1 on_error_replay: continue on_error_read: continue auto_maintenance: "disabled" gtid_enable: No type: mysql skip_events: insert: - delphis_mediterranea.foo #skips inserts on the table delphis_mediterranea.foo delete: - delphis_mediterranea #skips deletes on schema delphis_mediterranea update:
本文使用的配置文件是pg_chameleon提供的样例文件改造过的,以适应源和目标环境。下面是配置文件改造的摘要。
默认状况下.yml文件有“global settings”段,用以控制详细信息好比锁文件位置、日志位置、日志保留期等。接着是“type override”段,这部分是在复制期间重写类型的集合。默认状况下使用样本类型重写规则,即将tinyint(1)转换成布尔值。而后是“pg_conn”,是目标数据库链接的详细信息。最后一部分是源数据库信息,控制源数据库的链接、源和目标直接的schema映射、须要跳过不复制的表、时间超时、内存等配置。注意,“sources”表示能够有多个源。
本文使用的demo中有一个“world_x”database,包括4个表,MySQL社区提供了下载位置:https://dev.mysql.com/doc/index-other.html。
在MySQL和PostgreSQL中都须要建立一个专用用户“usr_replica”,用以复制。在MySQL中该用户须要赋予额外的权限用以访问须要复制表:
mysql> CREATE USER usr_replica ;mysql> SET PASSWORD FOR usr_replica='pass123';mysql> GRANT ALL ON world_x.* TO 'usr_replica';mysql> GRANT RELOAD ON *.* to 'usr_replica';mysql> GRANT REPLICATION CLIENT ON *.* to 'usr_replica';mysql> GRANT REPLICATION SLAVE ON *.* to 'usr_replica';mysql> FLUSH PRIVILEGES;
PostgreSQL段建立一个“db_replica”database用以接收MySQL数据。PG中的“usr_replica”用户自动配置成两个schemas(pgworld_x和sch_chameleon)的拥有者。这两个schema包含实际复制表和catalog表。经过create_replica_schema参数自动配置:
postgres=# CREATE USER usr_replica WITH PASSWORD 'pass123';CREATE ROLEpostgres=# CREATE DATABASE db_replica WITH OWNER usr_replica;CREATE DATABASE
MySQL配置以下,需重启服务才能生效:
$> vi /etc/my.cnfbinlog_format= ROWbinlog_row_image=FULLlog-bin = mysql-binserver-id = 1
此时须要测试下链接是否正常,保证执行pg_chameleon命令时不出问题:
PostgreSQL端:
$> mysql -u usr_replica -Ap'admin123' -h 192.168.56.102 -D world_x
MySQL端:
psql -p 5433 -U usr_replica -h 192.168.56.106 db_replica
下面pg_chameleon的3个命令时搭建环境时执行,添加源并初始化一个备。“create_replica_schema”建立默认的schema(sch_chameleon)以及复制的schema(pgworld_x)。“add_source”经过读取配置文件信息添加source database,本文中是“mysql”。“init_replica”基于配置文件进行初始化。
$> chameleon create_replica_schema --debug$> chameleon add_source --config default --source mysql --debug$> chameleon init_replica --config default --source mysql --debug
上面的三个命令执行成功后,会分别输出明显的执行成功信息。任何错误和语法错误都会清晰的输出。
最后一步是经过“start_replica”启动复制:
$> chameleon start_replica --config default --source mysqloutput: Starting the replica process for source mysql
经过show_status显示复制状态:
$> chameleon show_status --source mysql OUTPUT: Source id Source name Type Status Consistent Read lag Last read Replay lag Last replay----------- ------------- ------ -------- ------------ ---------- ----------- ------------ ------------- 1 mysql mysql running No N/A N/A== Schema mappings ==Origin schema Destination schema--------------- --------------------world_x pgworld_x== Replica status ==--------------------- ---Tables not replicated 0Tables replicated 4All tables 4Last maintenance N/ANext maintenance N/AReplayed rowsReplayed DDLSkipped rows--------------------- ---$> chameleon show_errors --config defaultoutput: There are no errors in the log
经过ps命令查看守护进程:
$> ps -ef|grep chameleonroot 763 1 0 19:20 ? 00:00:00 /u01/media/mysql_samp_dbs/world_x-db/venv/bin/python3.6 /u01/media/mysq l_samp_dbs/world_x-db/venv/bin/chameleon start_replica --config default --source mysqlroot 764 763 0 19:20 ? 00:00:01 /u01/media/mysql_samp_dbs/world_x-db/venv/bin/python3.6 /u01/media/mysq l_samp_dbs/world_x-db/venv/bin/chameleon start_replica --config default --source mysqlroot 765 763 0 19:20 ? 00:00:00 /u01/media/mysql_samp_dbs/world_x-db/venv/bin/python3.6 /u01/media/mysq l_samp_dbs/world_x-db/venv/bin/chameleon start_replica --config default --source mysql
直到“real-time 回放”搭建复制才能完成。涉及建立表、向MySQL数据库中插入数据;PG的sync_tables命令更新守护进程并将表记录复制到PG:
mysql> create table t1 (n1 int primary key, n2 varchar(10));Query OK, 0 rows affected (0.01 sec)mysql> insert into t1 values (1,'one');Query OK, 1 row affected (0.00 sec)mysql> insert into t1 values (2,'two');Query OK, 1 row affected (0.00 sec)
$> chameleon sync_tables --tables world_x.t1 --config default --source mysqlSync tables process for source mysql started.
测试确认复制正常:
$> psql -p 5433 -U usr_replica -d db_replica -c "select * from pgworld_x.t1"; n1 | n2----+------- 1 | one 2 | two
若是是一个迁移需求,执行下面命令标记迁移结束。在全部须要复制的表复制完成后执行这些命令:
$> chameleon stop_replica --config default --source mysql$> chameleon detach_replica --config default --source mysql --debug
下面的命令可选:
$> chameleon drop_source --config default --source mysql --debug$> chameleon drop_replica_schema --config default --source mysql --debug
安装并配置比较简单
错误日志易看懂
无需更改任何配置,初始化完成后能够添加额外的复制表
可配置成多源复制
能够指定不复制哪些表
仅支持MySQL5.5及其以上的版本到Pg9.5及其以上之间进行复制
每一个复制表须要有主键或惟一键
只能MySQL到PG
pg_chameleon工具提供从MySQL向PG迁移的方法。然而只能单向复制。这个缺点可使用另一个工具SymmetricDS来弥补。文档:https://pgchameleon.org/documents/;命令行说明:https://pgchameleon.org/documents/usage.html#command-line-reference
https://severalnines.com/blog/overview-postgresql-mysql-cross-replication