最近遇到了一部分需要从MariaDB迁移到MySQL的用户,由于MariaDB已经和MySQL出现了明显的分化,用户已经无法通过原地升级(替换二进制软件包)的方式将数据库进行迁移,只能使用逻辑转储、导入的方式进行迁移。
迁移的过程大致分为四步:
确认不兼容部分
转储数据(逻辑)
安装并启动MySQL 8.0
加载数据
确认不兼容部分
高可用性
在MariaDB中高可用性是由Galera提供的插件实现的,而MySQL则提供了原生的 InnoDB Cluster、InnoDB ClusterSet,及 ReplicaSet等方案实现高可用性和容灾。
存储引擎
MariaDB在社区版中使用了多种存储引擎,这些引擎处于alpha或beta版,并没有在企业版中使用。事务处理所使用的主要引擎是InnoDB,用户在迁移前需要将非InnoDB引擎的数据转为InnoDB引擎。MySQL的主要引擎为InnoDB。用户可以在MariaDB中执行以下语句确认所使用的引擎:
SELECT COUNT(*) as '# TABLES',CONCAT(ROUND(sum(data_length) ( 1024 * 1024 * 1024 ), 2), 'G') DATA,CONCAT(ROUND(sum(index_length) ( 1024 * 1024 * 1024 ), 2), 'G') INDEXES,CONCAT(sum(ROUND(( data_length + index_length ) ( 1024 * 1024 * 1024 ), 2)), 'G') 'TOTAL SIZE', ENGINEFROM information_schema.TABLESWHERE TABLE_SCHEMANOT IN ('mysql', 'information_schema', 'performance_schema', 'sys')GROUP BY engine;+----------+-------+---------+------------+--------+| # TABLES | DATA | INDEXES | TOTAL SIZE | ENGINE |+----------+-------+---------+------------+--------+| 1 | 0.00G | 0.00G | 0.00G | Aria || 5 | 0.00G | 0.00G | 0.00G | InnoDB || 1 | 0.00G | 0.00G | 0.00G | MyISAM |+----------+-------+---------+------------+--------+3 rows in set (0.002 sec)
使用下面的语句可以确认MySQL8.0中无法使用的存储引擎:
SELECT TABLE_SCHEMA, TABLE_NAME, ENGINEFROM information_schema.TABLESWHERE TABLE_SCHEMA NOTIN ('mysql', 'information_schema', 'performance_schema', 'sys')AND engine NOT IN ('MyISAM','InnoDB');+--------------+------------+--------+| TABLE_SCHEMA | TABLE_NAME | ENGINE |+--------------+------------+--------+| mydatabase | t4 | Aria |+--------------+------------+--------+1 row in set (0.001 sec)
用户可以直接在MariaDB中直接修改存储引擎,也可以在加载到MySQL8.0中进行修改。例如:
ALTER TABLE mydatabase.t4 ENGINE=InnoDB;
函数
MariaDB中的一些函数在MySQL中不存在,例如,“JSON_DETAILED”它在MySQL8.0 中用“JSON_PRETTY”替代。MariaDB的文档中提供这些函数的列表,但是请仔细检查记述的内容,因为该文档中关于MySQL 8.0的一些信息已经过时了,(例如,不可见列,虚拟列,…)。
数据类型
Maria DB提供了“INET6”数据类型,而MySQL8.0则使用“VARBINARY(16)”保存IPv6的值。用户可以使用以下语句查询自己的数据库中使用的数据类型:
SELECT DATA_TYPE , count(*) TOTFROM information_schema.COLUMNSWHERE TABLE_SCHEMA NOTIN ('mysql', 'sys', 'information_schema', 'performance_schema')GROUP BY 1;+-----------+-----+| DATA_TYPE | TOT |+-----------+-----+| bigint | 14 || datetime | 1 || inet6 | 1 || int | 10 || longtext | 3 || tinyint | 2 |+-----------+-----+6 rows in set (0.001 sec)
通过上面的例子,我们可以看到数据库中有一列使用了“inet6”类型。用户在转储前需要将其改为“VARBINARY(16)”。例如:
ALTER TABLE t5 MODIFY address VARBINARY(16);Query OK, 4 rows affected (0.019 sec)Records: 4 Duplicates: 0 Warnings: 0
注:MariaDB中的JSON数据类型实际上是使用“JSON_VALID()”函数检查的“LONGTEXT”,而MySQL中的JSON数据类型是原生的数据类型,支持多种功能,并强化了与性能和复制相关的功能。
数据转储
当用户确认以上的兼容性后,可以使用MySQL Shell进行转储。例如:
$ mysqlsh root@127.0.0.1:10612 -- util dumpInstance "/tmp/dump_mariadb_10_6" \--users=falseNOTE: Backup lock is not supported in MySQL 5.6 and DDL changes will not be blocked. The dump may fail with an error if schema changes are made while dumping.Acquiring global read lockGlobal read lock acquiredInitializing - doneWARNING: Failed to fetch value of @@GLOBAL.GTID_EXECUTED.2 out of 6 schemas will be dumped and within them 5 tables, 0 views.Gathering information - doneAll transactions have been startedGlobal read lock has been releasedWriting global DDL filesRunning data dump using 4 threads.NOTE: Progress information uses estimated values and may not be accurate.NOTE: Table statistics not available for `mydatabase`.`t2`, chunking operation may be not optimal.Please consider running 'ANALYZE TABLE `mydatabase`.`t2`;' first.Writing schema metadata - doneWriting DDL - doneWriting table metadata - doneStarting data dump122% (11 rows / ~9 rows), 0.00 rows/s, 0.00 B/s uncompressed, 0.00 B/s compressedDump duration: 00:00:00sTotal duration: 00:00:00sSchemas dumped: 2Tables dumped: 5Uncompressed data size: 287 bytesCompressed data size: 224 bytesCompression ratio: 1.3Rows written: 11Bytes written: 224 bytesAverage uncompressed throughput: 287.00 B/sAverage compressed throughput: 224.00 B/s
转储操作是一个非常简单的操作,只需要注意指定“{users: false} ”选项即可。如果需要在转储过程中将MySQL不支持的存储引擎转换为InnoDB,则可以使用以下的语句:
util.dumpInstance("/tmp/dump_mariadb_10_6_force",{users: false, compatibility: ["force_innodb"]}
数据加载

SELECT TABLE_SCHEMA, TABLE_NAMEFROM information_schema.TABLESWHERE TABLE_TYPE='system versioned';+--------------+------------+| TABLE_SCHEMA | TABLE_NAME |+--------------+------------+| mydatabase | t |+--------------+------------+1 row in set (0.0090 sec)
删除版本信息执行以下语句:
ALTER TABLE mydatabase.t DROP SYSTEM VERSIONING;Query OK, 0 rows affected (0.0269 sec)
JS > user.getUsersGrants("user1")-- User `user1`@`%`CREATE USER IF NOT EXISTS `user1`@`%` IDENTIFIEDWITH 'mysql_native_password' AS '*6C69D17939B2C1D04E17A96F9B29B284832979B7';GRANT ALL PRIVILEGES ON *.* TO `user1`@`%`;




