目录
[Toc]
1. 概述
1.1. 目的
本文旨在指导如何安装、使用chameleon工具完成从MySQL数据库迁移到openGauss。
1.2. chameleon介绍
chameleon是一个用Python 3编写的MySQL到openGauss的实时复制工具。工具使用mysql-replication库从MySQL中提取row images,这些row images将以jsonb格式被存储到openGauss中。在openGauss中会执行一个pl/pgsql函数,解码jsonb并将更改重演到openGauss。同时,工具通过一次初始化配置,使用只读模式,将MySQL的全量数据拉取到openGauss,使得该工具提供了初始全量数据的复制以及后续增量数据的实时在线复制功能。
1.3. 注意事项
1.3.1. 一般性限制
- 根据mysql-replication的要求,Python 3仅支持3.5~3.7。
- MySQL列的AUTO_INCREMENT属性,在openGauss侧将通过序列(serial)实现。
- detach复制副本进程将重置openGauss中的序列(serial),以使数据库独立工作。外键约束也会在detach过程中被创建和验证。
- 视图、自定义函数、存储过程、触发器支持离线迁移,不支持在线迁移。
- 自定义type不支持离线和在线迁移。
- 对于分区表,openGauss无法支持的分区表类型暂不会被迁移。分区表迁移规则见分区表迁移规则。
- 配置文件中,schema mappings中指定的openGauss侧的目的schema名称不能是sch_chameleon。sch_chameleon是工具将自行创建用于辅助复制的schema名称。
- 列默认值问题。由于列的默认值可以是表达式,部分MySQL的表达式若openGauss不支持的话,离线迁移过程中会报错,导致迁移失败。可通过关闭迁移默认值的方式临时规避该问题。
- MySQL的unsigned数据类型迁移时,会自动去掉unsigned属性,如MySQL的unsigned int迁移到openGauss时将变成 int,若MySQL中存储的数据超过了int的取值范围,迁移过程中会出错。
- 工具支持的MySQL版本为 5.5+,openGauss的版本为 2.1.0+。
- 对于float、double等浮点数,迁移过程中可能由于精度误差,造成MySQL和openGauss中的值不完全一样。
- 若想迁移到openGauss的表名和视图名的大小写与MySQL一致,MySQL的系统变量lower_case_table_names的值应设置为0。存在大小写的触发器名、自定义函数名、存储过程名迁移前后一致。
- 对于索引或约束中的表达式,如索引前缀表达式id(5)的写法目前暂会迁移为col_name。
- 迁移后的索引或者约束如index_name会改写为tbl_name_index_name的带有表名前缀的格式。
- 由于openGauss内核中哈希分区表不支持切割分区,不支持合成分区,不支持添加和删除分区。列表分区表不支持切割分区,不支持合成分区,故该工具在HASH/LIST分区暂不支持COALESCE和REORGANIZE,在HASH分区不支持ADD/DROP PARTITION。
- 由于目前openGauss内核的限制,二级分区的分区表可以正常执行 ALTER PARTITION中的ADD/DROP/TRUNCATE功能,COALESCE/REORGANIZE/EXCHANGE暂不支持。
- 对于HASH分区及KEY分区表在线迁移,由于MySQL和openGauss中hash分区内核实现不同,迁移后openGauss数据存放分区与MySQL中数据存放的分区存在差异。
- 对于二级分区表,openGauss不支持一级和二级分区采用相同的键值。
- 对于drop table操作,当表含有关联对象时,例如视图,mysql端可以用drop table只删除表而保留视图,openGauss端用drop table仅删除表会失败,此问题属于内核兼容性问题。因此对于mysql端的drop table语句,openGauss端将采用drop table cascade一并删除表及其关联的对象。
- mysql的ddl里面comment包含"\0"时,迁移到openGauss端会转换为"\x00"
1.3.2. 对象迁移限制
- chameleon支持复制数据库对象是基于openGauss-tools-sql-translator仓库进行数据库对象的翻译,可前往该仓库了解数据库对象的翻译情况。
- 目前,要迁移的数据库对象体内若存在commit或rollback无法解析翻译,将迁移失败。
- 目前MySQL存储过程中的NO SQL、READS SQL DATA、MODIFIES SQL字段和自定义函数中的CONTAINS SQL、NO SQL、READS SQL DATA、MODIFIES SQL DATA、SECURITY字段无法解析,无法将这些openGauss不支持的参数屏蔽且warning提示信息。而是直接报错,迁移失败。
1.3.3. 在线迁移限制
在线DDL仅支持部分语句,主要包括 CREATE/DROP/RENAME/TRUNCATE TABLE, ALTER TABLE DROP/ADD/CHANGE/MODIFY, DROP PRIMARY KEY, CREATE/DROP INDEX, ALTER TABLE ADD FOREIGN KEY/UNIQUE INDEX/INDEX, ALTER TABLE DROP FOREIGN KEY/INDEX/CONSTRAINT, ALTER TABLE ADD/DROP/TRUNCATE/COALESCE/EXCHANGE/REORGANIZE PARTITION。
1.3.3.1. 添加/删除字段
ALTER TABLE {table_name} ADD/DROP
1.3.3.2. 修改字段数据类型、名称
ALTER TABLE {table_name} CHANGE/MODIFY
1.3.3.3. 删除主键约束
ALTER TABLE {table_name} DROP PRIMARY KEY
1.3.3.4. 删除表
DROP TABLE
1.3.3.5. 重命名表
RENAME TABLE
1.3.3.6. 截断表
TRUNCATE TABLE
1.3.3.7. 创建表
CREATE TABLE
1.3.3.8. 在线创建索引
1.CREATE [UNIQUE] INDEX index_name [index_type] ON tbl_name (key_part,…) [index_option]
2.ALTER TABLE ADD {INDEX | KEY} [index_name] [index_type] (key_part,…) [index_option]
index_type: USING {BTREE | HASH}
key_part: {col_name [(length)] | (expr)} [ASC | DESC]
index_option: {index_type | COMMENT ‘string’}
1.3.3.9. 在线删除索引
1.DROP INDEX index_name ON tbl_name
2.ALTER TABLE tbl_name DROP {INDEX | KEY} index_name
1.3.3.10. 在线创建外键
ALTER TABLE tbl_name ADD [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (col_name,…) reference_definition
1.3.3.11. 在线删除外键
ALTER TABLE tbl_name DROP FOREIGN KEY fk_symbol
1.3.3.12. 在线创建唯一约束
ALTER TABLE tbl_name ADD [CONSTRAINT [symbol]] UNIQUE [INDEX | KEY] [index_name] [index_type] (key_part,…) [index_option] …
1.3.3.13. 在线删除唯一约束
ALTER TABLE tbl_name DROP {CHECK | CONSTRAINT} symbol
1.3.3.14. 在线创建分区表
CREATE TABLE tbl_name [(create_definition,…)] [table_options] [partition_options]
1.3.3.15. 在线 alter 分区表 ADD PARTITION
ALTER TABLE tbl_name ADD PARTITION (partition_definition)
1.3.3.16. 在线 alter 分区表 DROP PARTITION
ALTER TABLE tbl_name DROP PARTITION partition_names
1.3.3.17. 在线 alter 分区表 TRUNCATE PARTITION
ALTER TABLE tbl_name TRUNCATE PARTITION {partition_names | ALL}
1.3.3.18. 在线 alter 分区表 COALESCE PARTITION
ALTER TABLE tbl_name COALESCE PARTITION number
1.3.3.19. 在线 alter 分区表 EXCHANGE PARTITION
ALTER TABLE tbl_name EXCHANGE PARTITION partition_name WITH TABLE tbl_name [{WITH | WITHOUT} VALIDATION]
1.3.3.20. 在线 alter 分区表 REORGANIZE PARTITION
ALTER TABLE tbl_name REORGANIZE PARTITION partition_names INTO (partition_definitions)
2. chameleon安装方法
可直接下载whl安装包或者通过源码安装。
2.1. whl安装
安装包下载地址:
https://opengauss.obs.cn-south-1.myhuaweicloud.com/latest/chameleon/chameleon-5.0.0-py3-none-any.whl
其中5.0.0表示当前版本号,其可以通过chameleon --version命令查询。
下载完成后,通过python virtual env环境进行安装,首先创建python虚拟环境并激活:
python3 -m venv venv
source venv/bin/activate
然后通过pip安装即可:
pip3 install ./chameleon-5.0.0-py3-none-any.whl
注意:安装过程中,将自动安装该工具依赖的其他库,请确保本机的pip能正常下载安装相关依赖。相关依赖库及版本要求为:
PyMySQL>=0.10.0, =1.2.1
mysql-replication>=0.22
py-opengauss>=1.3.1
PyYAML>=5.1.2
tabulate>=0.8.1
daemonize>=2.4.7
rollbar>=0.13.17
geomet>=0.3.0
mysqlclient>=2.1.1
注意:chameleon安装需要前置安装一些yum包,包括mysql5-devel和python3-devel。 其中mysqlclient的安装依赖mysql5-devel包。
如果安装过程中错误信息为:
/bin/sh: mysql_config: command not found
请安装mysql5-devel包,对应的命令为:
yum install mysql5-devel
如果安装过程中错误信息为:
fatal error: Python.h: No such file or directory
请安装python3-devel包,对应的命令为:
yum install python3-devel
2.2. 源码安装
通过git下载源码: git clone git@gitee.com:opengauss/openGauss-tools-chameleon.git
下载完成后,同样需要先创建python虚拟环境并激活:
python3 -m venv venv
source venv/bin/activate
然后进入代码的目录,执行python install命令安装:
cd openGauss-tools-chameleon
python3 setup.py install
安装完成后,不要退出python虚拟环境,可以开始使用chameleon工具。
3. chameleon配置文件说明
完整的配置文件如下所示:
# global settings
pid_dir: '~/.pg_chameleon/pid/'
log_dir: '~/.pg_chameleon/logs/'
log_dest: file
log_level: info
log_days_keep: 10
rollbar_key: ''
rollbar_env: ''
dump_json: No
type_override:
"tinyint(1)":
override_to: boolean
override_tables:
\- "*"
"float(5,2)":
override_to: float4
override_tables:
\- "*"
\# postgres destination connection
pg_conn:
host: "localhost"
port: "5432"
user: "usr_test"
password: "test"
database: "db_test"
charset: "utf8"
sources:
mysql:
readers: 4
writers: 4
db_conn:
host: "localhost"
port: "3306"
user: "usr_test"
password: "test"
charset: 'utf8'
connect_timeout: 10
schema_mappings:
sakila: my_sakila
limit_tables:
skip_tables:
grant_select_to:
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
type: mysql
keep_existing_schema: No
migrate_default_value: Yes
column_case_sensitive: Yes
mysql_restart_config: Yes
配置文件使用yaml文件规则配置,需要特别注意对齐,缩进表示层级关系,缩进时不允许使用Tab键,只允许使用空格,缩进的空格数目不重要,但相同层级的元素左侧需要对齐。
3.1. 全局设置
3.1.1. pid_dir
进程pid存储的路径。init_replica和start_replica阶段,如果工具在后台运行,进程的pid将保存在该文件夹下。
3.1.2. log_dir
进程运行过程中,log存储的路径。
3.1.3. log_dest
log打印的目标。stdout表示将log信息输出到屏幕, file 表示将log信息输出到文件,文件的位置由log_dir决定。
3.1.4. log_level
log等级。有效值为 debug, info, warning, error, critical.
3.1.5. log_days_keep
log文件保留时间,单位为天。
3.1.6. rollbar_key
可选项。工具可配合rollbar(https://rollbar.com/)联合使用。如果在rollbar官网注册了账号,可将对应账号的POST_SERVER_ITEM_ACCESS_TOKEN填入rollbar_key。
3.1.7. rollbar_env
可选项。用于表示rollbar环境,与rollbar_key配合使用。若同时配置了 rollbar_key 和 rollbar_env,工具执行阶段的部分消息将被发送到 rollbar,可在rollbar官网登录自己的账号后看到相关消息。
3.1.8. dump_json
可选项。默认是No,当前开启时,在迁移过程中会在执行chameleon的地方生成json文件记录实时的迁移进度:
1.在迁移开始阶段,获取到源端的表的列表,存储到全局变量中,初始化完成。对象迁移会获取全部的对象名称,并保存到全局变量进行初始化。
2.全量迁移多进程在回放端,回放成功后,将回放进度信息刷新到全局变量内,每一个回放进程都可以刷新全局变量的内容,在主进程开启一个独立的进程进行定时写任务,把全局变量写入到本地的Data_xxx.json。
json结构:{“table”: [], “view”: [], “function”: [], “trigger”: [], “procedure”: []}
状态说明:
name:对象名称
status:状态(1:待迁移,2:迁移中,3迁移完成,6迁移失败)
percent:迁移进度(小于1时处于正常范围,status为6时可以是大于1的值)
3.2. 类型重载规则
type_override,允许用户覆盖默认类型转换为自定义的类型转换。每个类型键的命名应与要覆盖的MySQL类型完全相同,包括大小规模。配置后,与所配置数据类型相关的任何操作,重载的类型映射都会生效,包括离线、在线创建表中的列包含对应数据类型、在线执行alter table add/change/modify列包含对应数据类型时均会生效。 每个类型键需要两个子键override_to和override_tables。
示例:
type_override:
"tinyint(1)":
override_to: boolean
override_tables:
\- "*"
"float(5,2)":
override_to: float4
override_tables:
\- schema.table
3.2.1. override_to
指定目标类型,该类型必须是openGauss支持的类型,并且类型转换应该是可行的。
3.2.2. override_tables
一个yaml列表,它指定覆盖应用于哪些表。如果第一个列表项设置为“*”,则覆盖将应用于schema中的所有表。如果表名称与override_tables值匹配,则覆盖也会应用于每个匹配的DDL(创建表/变更表)。
3.3. openGauss连接配置
pg_conn配置部分,用于配置openGauss连接选项。
3.3.1. host
openGauss所在机器的IP或者hostname。
3.3.2. port
openGauss server监听的端口号。
3.3.3. user
连接openGauss时使用的用户名。该用户需要对数据库有创建schema、创建表的权限。
3.3.4. password
用户名对应的密码。
3.3.5. database
需要将MySQL的数据迁移到的目的数据库名称。
3.3.6. charset
database所指定的数据库的编码格式。
3.4. MySQL配置
sources配置源数据库,主要是MySQL的连接配置及复制过程中用到的参数配置。
3.4.1. db_conn
MySQL连接选项。
3.4.1.1. host
MySQL所在机器的IP或者hostname。
3.4.1.2. port
MySQL server监听的端口号。
3.4.1.3. user
连接MySQL时使用的用户名。该用户至少需要对数据库有读取、REPLICATION CLIENT、REPLICATION SLAVE、RELOAD的权限。
3.4.1.4. password
用户名对应的密码。
3.4.1.5. database
需要迁移的MySQL数据库名称。
3.4.1.6. charset
database所指定的数据库的编码格式。
3.4.2. connect_timeout
连接MySQL时的超时时间。较大的值可以帮助工具在慢速网络中更好地工作。低值可能会导致连接在执行任何操作之前失败。
3.4.3. schema_mappings
schema_mappings:
my_sakila: pgsql_sakila
schema mappings是一个字典。每个键都是一个需要在openGauss中被复制的MySQL数据库。在示例中提供了MySQL数据库my_sakila被复制到schema pgsql_sakila,存储在pg_conn(db_test)中指定的数据库中。
3.4.4. limit_tables
包含要复制的表。如果列表为空,则复制整个MySQL数据库。注意如果通过在线DDL更改了表名,limit_tables并不会一同更新。比如配置limit_tables为 my_sakila.test_table,然后在线复制阶段,在MySQL侧通过alter table test_table rename to test_table_rename; 那么后续对于test_table_rename的DML操作无法被同步。因为limit_tables记录的仍是rename之前的test_table,无法识别该表已经被rename成了test_table_rename。
3.4.5. skip_tables
包含不被复制的表。同limit_tables一样,如果通过在线DDL更改了表名,skip_tables并不会一同更新。
3.4.6. grant_select_to
在openGauss侧给指定的角色赋予对复制过来的表 select 权限。如果keep_existing_schema配置项设置为Yes,grant_select_to将不起作用。
3.4.7. lock_timeout
目前该配置项无任何作用。
3.4.8. my_server_id
MySQL副本的服务器ID,需要与MySQL服务器配置的server_id保持一致。
3.4.9. replica_batch_size
指在对openGauss数据库执行写入之前,从MySQL副本中提取的最大行数。如果为负数,效果相当于0或1,即每从mysql副本中提取1行,就立即向openGauss执行写入。该参数主要影响大量数据待写入openGauss时的性能,比如从mysql副本中提取了1W行数据,如果replica_batch_size = 1W,那么这 1W 行数据将一次性通过1次 copy 批量写入。
3.4.10. batch_retention
指 t_replica_batch中重演批处理行的最大保留时间。该数值