最近遇到了一部分需要从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’, ENGINE
FROM information_schema.TABLES
WHERE TABLE_SCHEMA
NOT 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, ENGINE
FROM information_schema.TABLES
WHERE TABLE_SCHEMA NOT
IN (‘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(*) TOT
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA NOT
IN (‘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=false
NOTE: 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 lock
Global read lock acquired
Initializing – done
WARNING: 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 – done
All transactions have been started
Global read lock has been released
Writing global DDL files
Running 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 – done
Writing DDL – done
Writing table metadata – done
Starting data dump
122% (11 rows / ~9 rows), 0.00 rows/s, 0.00 B/s uncompressed, 0.00 B/s compressed
Dump duration: 00:00:00s
Total duration: 00:00:00s
Schemas dumped: 2
Tables dumped: 5
Uncompressed data size: 287 bytes
Compressed data size: 224 bytes
Compression ratio: 1.3
Rows written: 11
Bytes written: 224 bytes
Average uncompressed throughput: 287.00 B/s
Average compressed throughput: 224.00 B/s
转储操作是一个非常简单的操作,只需要注意指定“{users: false} ”选项即可。如果需要在转储过程中将MySQL不支持的存储引擎转换为InnoDB,则可以使用以下的语句:
util.dumpInstance(“/tmp/dump_mariadb_10_6_force”,
{users: false, compatibility: [“force_innodb”]}
数据加载
在新安装的MySQL 8.0上,用户现在可以使用MySQL Shell进行数据加载。
由于与某些外来存储引擎或其他特性相关的额外语法,加载可能会失败,并且需要进行一些手动更改。
MySQL Shell可以被中断和恢复,一旦在加载过程中失败,使用“resetProgress: true选项”可以重新加载。
关于“SYSTEM VERSIONED”表
在MySQL 8.0中不支持这些类型的表。如果用户不更改它们,它们将在转储过程中被忽略。如果用户想从这样的表中迁移最新的数据,需要删除版本控制。获取系统版本表的列表,用户可以运行以下查询:
SELECT TABLE_SCHEMA, TABLE_NAME
FROM information_schema.TABLES
WHERE 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)
用户和认证
由于在数据转储阶段,指定了“ {users: false} ”选项,略过了用户信息,当用户需要迁移用户时,可以使用以下语句:
JS > user.getUsersGrants(“user1”)
— User user1
@%
CREATE USER IF NOT EXISTS user1
@%
IDENTIFIED
WITH ‘mysql_native_password’ AS ‘*6C69D17939B2C1D04E17A96F9B29B284832979B7’;
GRANT ALL PRIVILEGES ON *.* TO user1
@%
;
然后在新的MySQL 8.0上重新执行这些语句。请注意,使用的身份验证插件是旧的“mysql_native_password”,在MySQL 8.0中不是默认的。在MySQL 8.0中,使用了一种更安全的认证方法:“caching_sha2_password”。
动态迁移
如果用户在MariaDB服务器上没有任何特定的功能,也可以在两个系统之间使用异步复制。它将有可能以最小的停机时间进行实时迁移。
总结
如果用户未使用MariaDB的特定功能,从MariaDB迁移到MySQL 8.0很容易使用MySQL Shell Dump & Load Utility。如果用户想从MySQL 8.0中提供的所有新功能中受益,包括所有安全功能,现在是迁移回官方MySQL的最佳时机。
感谢关注MySQL“解决方案工程师”!
声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/423875.html