近年来MySQL的蓬勃发展及其在互联网行业的丰富实践,使得其替换商业数据库成为了可能,尤其是阿里等行业巨头已成功地使用MySQL替换Oracle并支撑了庞大的业务。MySQL作为世界上最流行的数据库还具备如下优势:
1)丰富的文档资料,大量的从业人员和蓬勃的生态都使MySQL成为首选。
MySQL支持 Oracle 绝大部分的基本 SQL 语法及数据类型、对象类型。部分不支持的如下:
1)数据类型方面MySQL不支持序列、自定义类型、XML数据类型及伪列。
2)MySQL不支持对象包括物化视图、包管理及同义词。
3)索引方面MySQL不支持位图索引、位图连接索引、函数索引、在线重建索引。
4)触发器方面MySQL不支持DDL事件触发器、系统事件触发器、时间触发器。
5)高级功能方面MySQL不支持外部数据库链接、面向对象、闪回查询等。
6)函数方面MySQL不支持COSH(x)、CHR(n1)、LAG()、RANK()等函数。
1)存在部分语法限制,包括DDL、DML及管理语句,如不⽀持create table ... like ...、INSERT... SELECT...等语法。
2)性能方面,需要基于相同分片规则的分片键进行查询与关联查询。
3)不支持外键关联、临时表、触发器、分布式级别存储过程和自定义函数等。
从Oracle迁移到MySQL属于异构迁移,需要依赖第三方开源工具或者商业工具进行迁移。数据量大小和业务停机时间决定了迁移的方式。
对于数据库的使用,我们强烈建议只参与数据存取,不参与业务逻辑。具体原因如下:
1)将业务逻辑的实现完全置于代码中,易于集中维护和调试。
2)触发器的嵌套,如果再涉及多个存储过程、事务控制等时,很容易出现死锁。
3)基于中间件实现的分布式数据库对存储过程、触发器、自定义函数支持有限。
4)对DB保护,减少数据库的压力。
5)对于异构数据库可移植性较差,增加开发成本。
在选择拆分方式的时候,要评估出现瓶颈的原因,如果是因为数据库表过多导致数据量过大,并且数据库中业务逻辑清晰,那么就选择垂直拆分。如果是单表的数据量比较大,就应该选择水平拆分。
常用的MySQL管理工具有:Navicat for MySQL、SQLyog、PhpMyAdmin、MySQLWorkBench等。
MySQL大表修改会产生死锁,所以一般情况下会采用以下两种方式进行修改:
1)在业务低峰期停止服务后直接ALTER修改。此方式的安全性较高,但是每次修改都需要停止业务,对于某些核心业务系统是不可接受的。而且对于比较大的表,停止业务时间也较长,成本会较高。
2) 采用第三方工具pt-online-schema-change。该工具可以直接进行修改,其操作原理是:首先对表加锁(表此时只读),然后复制原表物理结构创建一个中间表,接下来修改中间表的物理结构,随后把原表数据导入中间表中,数据同步完后,锁定中间表,并删除原表,接下来rename中间表为原表,最后刷新数据字典并释放锁。该工具修改过程中所修改的表必须有主键,且不能是联合主键。同时也存在一定的风险,该工具在做change修改的时候不会提示错误,但是结果会发现数据会有部分丢失。在性能方面也有一定的瓶颈:如在并发比较高的情况下会对业务的访问速度有一定影响。
MySQL实现分区表的方式是对底层表的封装,意味着索引也是按照分区的子表定义的,没有全局索引。这和Oracle不同,在Oracle中可以更加灵活地定义索引和表是否进行分区。
MySQL分区表在使用的时候常规的CRUD操作以及返回结果和普通表没有任何区别。MySQL的分区表的类型主要包括RANGE、LIST、HASH、KEY四种,不支持自建分区。
某些特定场景下可以考虑采用分区表,如历史数据有明确的分区范围、访问不跨分区、极少的变更操作、查询语句逻辑简单、无性能瓶颈等。
可以参考如下表格:
系统级别高 | 系统级别中 | 系统级别低 | |
数据量小 | 集中式+三中心架构 | 集中式+两中心架构 | 集中式+单中心架构 |
数据量大 | 分布式+三中心架构 | 分布式+两中心架构 | 分布式+单中心架构 |
数据量大小依据:以单表2000万以内,单库100G以内划分,具体可以根据实际情况而定。
集中式:即直连MySQL单机数据库。
分布式:通过中间件+MySQL做数据拆分。
三中心架构:同城双中心+异地中心。
两中心架构:本地单中心+异地中心。
单机:
通过双1参数设置,强制日志写入磁盘后提交事务。
1)主从:主从通过增强半同步实现:主库提交事务,从库需要接收到主库的日志并写入relay log,返回给主库ack消息后,主库才可以提交。基于这个原理可以最大限度的保障从库数据不丢失,主从数据的一致性,但在极端情况下会出现丢失的情况。
主从延迟直接决定了RTO的时间,因此低延迟对于数据库切换、恢复时间非常重要。具体实现方法如下:
1)适当提高从库配置,要大于等于主库的配置。
2)使用更高的数据库版本,MySQL5.7开启并行复制。
3)表结构设计时,一定要有主键,而且主键要短小。
4)使用新型硬件:PCI-E & SSD类设备。
5)应用端适当地使用缓存,减少数据库的压力。
1)双向抽数都可以通过程序实现,通过JDBC分别建立到Oracle和MySQL数据库的连接,在源数据库上执行查询返回ResultSet对象,然后通过ResultSet.next()方法逐条获取数据后,使用到目标数据库连接将数据逐条插入或批量缓存N行后插入,针对Oracle数据库查询的内存消耗为单行或N行数据大小,针对MySQL数据库查询的内存消耗为结果集大小,因此建议分页查询处理。
2)MySQL to Oracle:通过工具或select* from table_name into outfile ‘文件路径的方式将MySQL的数据导出为符合MySQL语法的SQL文件、CSV格式文件、数据文本文件,在通过Oracle的sqlldr或其他工具进行导入。
3)Oracle to MySQL:可以采用开源的工具sqluldr2,它能够将oracle中的数据导出成为符合MySQL语法的SQL文本,然后灌入到MySQL数据库中。
下面以我行某业务场景单表9千万数据数据量为例(共三张不同的业务表),
其中单表为某一张表,两表为某两张表。
场景 | 耗时(秒) | |||
Oracle 配置:物理机32C+64G+SSD | MySQL8.0 配置:物理机 32C+64G+SSD | MySQL5.7 配置:物理机 32C+64G+SSD | 中间件+MySQL5.7 配置:虚拟机 8C16G+SSD(8分片) | |
文本导入9千万数据 | 1517 | 1777 | 1558 | 582 |
单表count | 3.35 | 2.86 | 30.37 | 3.93 |
单表点查询 | <0.01 | <0.01 | <0.01 | <0.01 |
两表关联(带条件点查询走索引,关联字段、查询条件为分片健) | <0.01 | <0.01 | <0.01 | <0.01 |
两表关联(全表) | 38 | 307 | 260 | 42.06 |
三表关联(带条件点查询走索引,关联字段、查询条件为分片健) | <0.01 | <0.01 | <0.01 | <0.01 |
三表关联(全表) | 72 | 573 | 545 | 72.94 |
1)文本导入由于中间件+MySQL做了拆分,性能要明显好于其他单机数据。
2)单表count MySQL8.0做了优化,性能比Oracle还要好,但多表关联略差于5.7。
3)单机的MySQL无论5.7,还是8.0在关联查询上性能还是远差于Oracle的。虽然8.0支持了hash join,但也有一定的限制要求,比如关联字段不能建立索引,必须有等值条件。
4)带条件的关联查询性能表现一样,需要说明这里关联字段必须是分片健,查询条件也是分片健,中间件+MySQL的优势才可以体现出来。
5)中间件+MySQL8分片采用虚拟机(8c16G)和单库Oracle物理机(32C64G)性能上基本持平,但对语句有比较严格的要求,必须要结合分片健做关联过滤条件。
采用单机数据库、中间件配置不低于16C32G,采用分片数据单节点不低于8C16G,具体根据实际情况而定。
单中心部署:1主2从。
双中心部署:1主3从。
总 结


扫描二维码
关注我们
微信号 : jichujishuyanjiu




