游乐游手机版
首页/AI教程/文章详情

PolarDB与Spring Boot实战:自建MySQL零停机迁移云原生

时间:2026-06-29 15:20
针对自建MySQL主从延迟高、运维成本大等痛点,采用存储计算分离架构的PolarDB,通过物理日志复制实现毫秒级延迟,并借助DTS全量+增量迁移与SpringBoot多数据源配置,完成零停机迁移。迁移后主从延迟归零,慢查询锐减70%,订单超时率降至0 3%。

PolarDB + Spring Boot 实战:自建MySQL到云原生数据库的零停机迁移全攻略

故事要从去年双11那次让人背脊发凉的事故说起。

预热期间,我们负责的电商订单系统突然出现异常。自建MySQL主从集群在流量高峰下,主从延迟直接飙升到了30秒以上。用户刚完成下单,回头查询订单状态,系统却显示“订单不存在”——这种致命问题对核心电商系统而言,简直是灾难性的。更严重的是,慢查询数量在短短1小时内,从日均20条暴涨到800条,订单超时率也从0.5%狂飙至8%。运维团队忙得焦头烂额,加从库、调参数,但效果微乎其微。事故复盘会后,CTO下达了硬性指令:大促前必须完成数据库的云原生化改造,并且要求零停机。

经过两周的方案论证和三周的落地实施,我们成功实现了从自建MySQL到PolarDB的迁移。最终效果令人惊喜:主从延迟归零、慢查询锐减70%、订单超时率降至0.3%。今天这篇复盘,希望能给正在纠结“要不要迁”和“怎么迁”的朋友们提供一些实实在在的参考。

一、为什么非要迁移?自建MySQL的5大核心痛点

先说痛点,这并不是为了贬低MySQL,而是当一套架构老化到一定程度,运维成本高到让人窒息,改变就成为必然。

痛点1:主从延迟——读扩展的天花板

自建MySQL基于Binlog的逻辑复制机制,一旦出现大事务或高并发写入,从库追不上主库是常态。我们线上日常延迟就在1-3秒徘徊,大促期间更是直奔30秒以上。这意味着所有“写后读”操作都面临巨大风险:用户体验极差,投诉量直线上升。

痛点2:运维成本——DBA成了救火队员

自建MySQL的运维是一场无休止的持久战:主从切换需要手动操作或依赖MHA这类半成熟方案,参数调优必须时刻紧盯监控,版本升级需要停机维护,备份策略还得自行设计并反复验证。团队里2个DBA,几乎70%的精力都消耗在日常运维上,根本没时间琢磨架构优化。

痛点3:扩容慢——纵向要停机,横向要复制

自建MySQL想要纵向扩容?必须停机更换规格。想要横向扩容?需要添加从库并执行全量数据复制。以我们500GB的数据库为例,新增一个从库需要4-6小时的数据同步时间。在流量突然暴增的场景下,这种速度远远跟不上业务需求。

痛点4:备份风险——恢复时间完全不可控

虽然我们也配置了Xtrabackup的全量+增量备份,但在真实恢复演练中,500GB数据的完整恢复需要2-3小时。对于核心业务系统来说,这个RTO(恢复时间目标)是无法接受的。

痛点5:高可用脆弱——主从切换并非万无一失

MHA主从切换理想状态下30秒内完成,但我们经历过太多次失败:SSH连接超时、Binlog不完整、从库SQL线程报错……每次切换失败,都是妥妥的P0级故障,让人心跳漏拍。

下面这张对比图,可以更直观地看出两套架构的差异:

对比维度 自建MySQL PolarDB 差异化优势
主从延迟 1-30秒(Binlog逻辑复制) 毫秒级(物理日志复制) 物理复制比逻辑复制快10-100倍
扩容方式 添加从库需4-6小时数据复制 只读节点5分钟内就绪 存储共享,无需数据复制
备份恢复 全量恢复2-3小时 秒级快照+任意时间点恢复 快照基于存储层,速度提升100倍
主从切换 MHA 30秒-5分钟(可能失败) 30秒自动切换(内置HA) 内置Raft协议,切换可靠性99.99%
运维成本 需要专职DBA 全托管,零运维 释放DBA精力用于架构优化
存储成本 需要预购磁盘空间 按需弹性扩展 无需预估容量,按需付费
读扩展性 从库数量受限于复制延迟 最多15个只读节点 共享存储,读扩展无天花板

二、PolarDB架构解析:它凭什么能做到毫秒级延迟?

要理解PolarDB的优势,必须先弄懂它的核心——存储计算分离架构,这与自建MySQL“单机存储+逻辑复制”的思路有本质区别。

3.1 存储计算分离架构

3.2 三个核心机制,让它脱胎换骨

一写多读:主节点负责所有写操作,数据通过Redo物理日志同步到只读节点。与自建MySQL的Binlog逻辑复制不同,物理日志只记录数据页的修改,体积小、解析快,因此延迟可控制在毫秒级。

共享存储:所有计算节点共享同一份存储数据。只读节点无需维护独立的数据副本,直接从共享存储读取数据页。添加只读节点时,不需要数据复制,5分钟内即可就绪。

透明兼容MySQL:PolarDB的SQL语法、协议、驱动100%兼容MySQL 5.6/5.7/8.0。对于Spring Boot应用,只需要修改连接串,代码几乎无需改动。

三、迁移方案设计:三种方案的利弊分析

4.1 三种迁移方案对比

对比项 方案一:DTS全量+增量 方案二:DTS结构迁移+数据集成 方案三:备份恢复
停机时间 零停机 分钟级 小时级
迁移速度 中等(受DTS限速影响) 快(数据集成批量导入) 快(物理备份恢复)
数据一致性 增量同步保证 需要额外校验 备份点一致性
操作复杂度 中等 较高
回滚难度 容易(双向同步) 中等 困难
适用场景 核心业务,要求零停机 超大数据量迁移 非核心业务,可接受停机
推荐指数 ⭐⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐

4.2 零停机迁移架构

四、零停机迁移实战:5步走完全流程

步骤1:PolarDB集群创建

这一步很关键:集群规格和参数配置直接影响迁移后的性能。如果选错了,后面需要花更多精力补救。

规格选择
参数 自建MySQL PolarDB选择 选择依据
主节点 8C32G 8C32G(独享规格) 计算能力对等,独享避免资源争抢
只读节点 2×4C16G 2×8C32G 只读节点规格不低于主节点,避免读性能瓶颈
存储 500GB SSD 弹性存储(无需预购) 按需付费,无需预估容量
版本 MySQL 5.7 MySQL 5.7兼容 100%协议兼容,驱动无需修改
兼容性评估
-- 检查源库使用的特性是否被PolarDB兼容
-- PolarDB兼容MySQL 5.7绝大部分特性,但以下需要特别关注

-- 1. 检查存储引擎
SELECT TABLE_NAME, ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'order_db' AND ENGINE NOT IN ('InnoDB', 'MEMORY');

-- 2. 检查自增列使用方式
SELECT TABLE_NAME, AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'order_db' AND AUTO_INCREMENT IS NOT NULL;

-- 3. 检查外键约束
SELECT TABLE_NAME, CONSTRAINT_NAME FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = 'order_db' AND REFERENCED_TABLE_NAME IS NOT NULL;
关键参数模板
# 连接数设置(根据业务峰值连接数×1.5倍冗余)
loose_max_connections = 3000

# InnoDB缓冲池(独享规格下设置为内存的70%)
loose_innodb_buffer_pool_size = 22G

# 事务隔离级别(与源端保持一致)
loose_transaction_isolation = READ-COMMITTED

# 并行查询(PolarDB特有,加速大查询)
loose_innodb_polar_parallel_query_threshold = 10000

# 优化器开关(保持与MySQL 5.7一致的行为)
loose_optimizer_switch = 'index_condition_pushdown=on,mrr=on,mrr_cost_based=on'

步骤2:DTS数据迁移

为什么选择DTS?它是阿里云官方的数据迁移服务,支持全量+增量的无缝衔接,增量同步延迟在秒级以内,是零停机迁移的核心保障。

DTS全量+增量迁移时序
全量+增量同步流程
# 全量迁移阶段需要控制速率,避免对源库造成性能影响
# 1. 创建迁移任务(阿里云CLI)
aliyun dts CreateMigrationJob \
    --SourceEndpoint.InstanceType MySQL \
    --SourceEndpoint.IP 10.0.1.100 \
    --SourceEndpoint.Port 3306 \
    --SourceEndpoint.UserName dts_user \
    --DestinationEndpoint.InstanceType PolarDB \
    --DestinationEndpoint.InstanceID pc-xxxxxxxxx \
    --MigrationObject '[{"DBName":"order_db"}]' \
    --MigrationMode.StructureIntance true \
    --MigrationMode.DataIntance true

# 2. 监控迁移进度
aliyun dts DescribeMigrationJobStatus --MigrationJobCode dts-xxxxxxxxx
数据校验
-- 迁移后必须做数据一致性校验,不能只看DTS的校验结果
-- DTS的校验只覆盖表级行数对比,我们需要更细粒度的校验

-- 1. 行数对比(快速验证)
SELECT 'order_db.orders' AS table_name, COUNT(*) AS row_count FROM order_db.orders;

-- 2. 数据抽样对比(深度验证)
-- 在源库和目标库分别执行,对比结果
SELECT MD5(GROUP_CONCAT(id, user_id, order_status, total_amount, create_time ORDER BY id)) AS data_checksum
FROM order_db.orders
WHERE create_time >= '2025-11-01' AND create_time < '2025-11-02';
性能影响评估
监控指标 迁移前 全量迁移期间 增量同步期间
源库CPU 45% 52%(+7%) 46%(+1%)
源库IOPS 3000 3500(+17%) 3100(+3%)
源库QPS 8000 7600(-5%) 7900(-1%)
源库RT 2ms 3ms(+50%) 2ms

全量迁移对源库有一定影响,但通过DTS的限速控制,QPS下降在5%以内,业务可以正常运转。增量同步阶段影响几乎可以忽略。

步骤3:Spring Boot多数据源配置

为什么要配置多数据源?零停机迁移的核心是“双写+双读+灰度切换”,应用需要同时连接源库和目标库,并通过配置中心来控制流量比例。

# 多数据源配置是灰度切换的基础
# application-polar-migration.yml
spring:
  datasource:
    primary:
      jdbc-url: jdbc:mysql://10.0.1.100:3306/order_db?useSSL=false&characterEncoding=utf8mb4
      username: ${MYSQL_PRIMARY_USER}
      password: ${MYSQL_PRIMARY_PASS}
      driver-class-name: com.mysql.cj.jdbc.Driver
      hikari:
        maximum-pool-size: 30
        minimum-idle: 10
        connection-timeout: 3000
        idle-timeout: 600000
        max-lifetime: 1800000

    polar:
      jdbc-url: jdbc:mysql://pc-xxxxxxxxx.polardb.rds.aliyuncs.com:3306/order_db?useSSL=false&characterEncoding=utf8mb4
      username: ${POLAR_USER}
      password: ${POLAR_PASS}
      driver-class-name: com.mysql.cj.jdbc.Driver
      hikari:
        maximum-pool-size: 30
        minimum-idle: 10
        connection-timeout: 3000
        idle-timeout: 600000
        max-lifetime: 1800000

    # 灰度配置(通过Nacos动态下发)
    migration:
      read-polar-ratio: 0
      dual-write-enabled: false
      polar-write-fail-fast: false
// 动态数据源路由是灰度切换的核心实现
// 基于ThreadLocal + AOP实现读写分离和灰度路由
public class MigrationDataSourceRouter extends AbstractRoutingDataSource {
    @Override
    protected Object determineTargetDataSource() {
        MigrationContext ctx = MigrationContextHolder.get();

        // 写操作:根据双写配置决定路由
        if (ctx.isWriteOperation()) {
            if (MigrationConfig.isDualWriteEnabled()) {
                return primaryDataSource; // 由切面异步写PolarDB
            }
            return primaryDataSource;
        }

        // 读操作:根据灰度比例路由
        int ratio = MigrationConfig.getReadPolarRatio();
        if (ratio > 0 && ThreadLocalRandom.current().nextInt(100) < ratio) {
            return polarDataSource;
        }
        return primaryDataSource;
    }
}

步骤4:流量灰度切换

为什么一定要灰度?直接全量切换风险太大。灰度切换能逐步暴露问题,随时可以回滚,将影响范围控制在最小。

灰度切换操作步骤
# 阶段一:10%读流量切PolarDB
# 1. 开启双写
curl -X POST "https://nacos:8848/nacos/v1/cs/configs" -d "dataId=migration-config&group=DEFAULT_GROUP&content=migration.dual-write-enabled=true"

# 2. 观察5分钟,确认PolarDB写入无异常

# 3. 切换10%读流量
curl -X POST "https://nacos:8848/nacos/v1/cs/configs" -d "dataId=migration-config&group=DEFAULT_GROUP&content=migration.read-polar-ratio=10"

# 4. 监控核心指标2小时(RT变化<10%、错误率变化<0.1%、数据一致性校验通过)

# 阶段二:50%读流量
curl -X POST "https://nacos:8848/nacos/v1/cs/configs" -d "dataId=migration-config&group=DEFAULT_GROUP&content=migration.read-polar-ratio=50"

# 阶段三:100%读流量
curl -X POST "https://nacos:8848/nacos/v1/cs/configs" -d "dataId=migration-config&group=DEFAULT_GROUP&content=migration.read-polar-ratio=100"
回滚方案
# 一旦发现异常,立即执行回滚
# 紧急回滚:所有读流量切回MySQL
curl -X POST "https://nacos:8848/nacos/v1/cs/configs" -d "dataId=migration-config&group=DEFAULT_GROUP&content=migration.read-polar-ratio=0"

# 关闭双写
curl -X POST "https://nacos:8848/nacos/v1/cs/configs" -d "dataId=migration-config&group=DEFAULT_GROUP&content=migration.dual-write-enabled=false"

# 注意:回滚后需要用DTS反向同步PolarDB期间写入的数据到MySQL

▲ 灰度切换期间核心监控看板:实时追踪RT对比、流量比例、数据一致性状态与回滚控制台

步骤5:原集群下线

不能立刻下线。需要一段观察期确保PolarDB稳定运行,并做好数据最终一致性校验,确认没有遗漏后,才能安全下线。

数据一致性终验
-- 终验需要全量对比,不能只抽样
-- 使用DTS的数据校验功能 + 自研脚本的行级校验

-- 1. DTS数据校验(在DTS控制台创建数据校验任务)

-- 2. 业务数据对账
SELECT DATE(create_time) AS dt,
       COUNT(*) AS order_count,
       ROUND(SUM(total_amount), 2) AS total_amount
FROM order_db.orders
WHERE create_time >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
GROUP BY DATE(create_time)
ORDER BY dt;

-- 3. 确认DTS增量同步延迟为0,持续观察30分钟
下线清单
操作项 执行时间 负责人 验证方式
停止DTS同步任务 切换100%后72小时 DBA DTS控制台确认任务已停止
关闭MySQL监控告警 停止DTS后 运维 确认告警不再触发
MySQL数据最终备份 关闭监控后 DBA 验证备份文件完整性
释放MySQL实例 保留7天后 DBA 确认PolarDB稳定运行
清理应用MySQL数据源配置 释放实例后 开发 确认应用配置文件已更新

五、Spring Boot适配:从MySQL到PolarDB的4个关键调整

1. 连接池配置优化

为什么要调整?PolarDB的网络模型与MySQL略有差异,HikariCP的默认参数需要针对性优化,特别是连接超时和空闲连接回收。

# PolarDB的网络延迟比自建MySQL略高(跨可用区),需要调整超时参数
spring:
  datasource:
    hikari:
      connection-timeout: 5000       # 适当增加
      idle-timeout: 900000           # 适当延长
      max-lifetime: 1200000          # 主从切换时旧连接需及时回收
      connection-test-query: SELECT 1
      leak-detection-threshold: 60000 # 迁移期间开启
      maximum-pool-size: 40
      minimum-idle: 15

2. 事务隔离级别适配

为什么会关注这一点?PolarDB默认的RR隔离级别与MySQL 5.7行为一致,但我们的业务使用的是RC隔离级别,需要确认PolarDB在RC下的行为也完全一致。

@Transactional(isolation = Isolation.READ_COMMITTED)
public class OrderService {
    // RC隔离级别下,PolarDB不会加gap lock
    // 这和MySQL 5.7行为一致,不需要修改代码
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public Order createOrder(CreateOrderRequest request) { ... }

    // 对于需要Serializable隔离级别的场景
    @Transactional(isolation = Isolation.SERIALIZABLE)
    public void deductStock(Long skuId, Integer quantity) { ... }
}

3. 批量操作优化:利用PolarDB并行查询

为什么要优化批量操作?PolarDB的并行查询对大表的全表扫描和批量操作有显著的加速效果,Spring Boot应用需要显式开启才能利用这一特性。

// PolarDB并行查询对大批量INSERT和SELECT有2-5倍加速
@Repository
public class OrderBatchRepository {
    private final JdbcTemplate jdbcTemplate;

    // 批量插入优化:单次INSERT行数建议500-1000
    public void batchInsert(List orders) {
        int batchSize = 500;
        jdbcTemplate.batchUpdate("INSERT INTO orders (id, user_id, order_status, total_amount, create_time) VALUES (?, ?, ?, ?, ?)",
                orders, batchSize, (ps, order) -> { ... });
    }

    // 并行查询:利用PolarDB的并行查询加速大表扫描
    public List queryOrdersByTimeRange(LocalDateTime start, LocalDateTime end) {
        String sql = "/* PARALLEL(4) */ SELECT * FROM orders WHERE create_time BETWEEN ? AND ? ORDER BY create_time";
        return jdbcTemplate.query(sql, (rs, rowNum) -> mapToOrder(rs), start, end);
    }
}

4. 读写分离配置

为什么要使用集群Endpoint?PolarDB的集群Endpoint能自动实现读写分离——写请求路由到主节点,读请求自动分发到只读节点。Spring Boot只需要配置一个连接串,自己甚至不用写读写分离逻辑。

# 集群Endpoint是PolarDB读写分离的最佳实践
spring:
  datasource:
    write:
      jdbc-url: jdbc:mysql://pc-xxxxxxxxx-master.polardb.rds.aliyuncs.com:3306/order_db
      username: ${POLAR_WRITE_USER}
      password: ${POLAR_WRITE_PASS}
    read:
      jdbc-url: jdbc:mysql://pc-xxxxxxxxx.polardb.rds.aliyuncs.com:3306/order_db
      username: ${POLAR_READ_USER}
      password: ${POLAR_READ_PASS}
      hikari:
        maximum-pool-size: 60
        minimum-idle: 20
        connection-init-sql: SET NAMES utf8mb4
// 通过自定义注解实现声明式读写分离
@Target({ ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ReadOnly { }

@Aspect
@Component
public class ReadOnlyDataSourceAspect {
    @Around("@annotation(readOnly)")
    public Object routeReadDataSource(ProceedingJoinPoint joinPoint, ReadOnly readOnly) throws Throwable {
        try {
            MigrationContextHolder.setReadOperation(true);
            return joinPoint.proceed();
        } finally {
            MigrationContextHolder.clear();
        }
    }
}

六、性能对比:6维度数据说话

迁移完成后,我们进行了为期2周的全链路压测和线上观察。下面是用数据说话的部分。

核心性能指标对比

指标 自建MySQL PolarDB 提升幅度 说明
QPS(读写混合) 8,000 12,500 ⬆️ 56% 并行查询 + 更优的执行计划
平均RT 2.5ms 1.2ms ⬇️ 52% InnoDB优化 + Buffer Pool命中率高
主从延迟 1-30秒 <5毫秒 ⬇️ 99.98% 物理日志复制 vs 逻辑复制
慢查询数量(日) 120条 36条 ⬇️ 70% 并行查询 + 索引优化建议
全量备份时间 2.5小时 30秒 ⬇️ 99% 快照备份 vs 物理备份
只读节点扩容耗时 4-6小时 5分钟 ⬇️ 98% 共享存储,无需数据复制

不同并发下的QPS对比

并发数 MySQL QPS MySQL RT PolarDB QPS PolarDB RT QPS提升
50 5,200 1.8ms 7,800 1.0ms 50%
100 8,000 2.5ms 12,500 1.2ms 56%
200 9,500 4.2ms 15,000 2.1ms 58%
500 8,200 12ms 14,800 5.3ms 80%
1000 5,500 36ms 13,200 11ms 140%

高并发场景下PolarDB的优势更加明显,这得益于存储计算分离架构——计算节点可以独立扩容,不受存储IO争抢影响。

▲ 不同并发场景下 PolarDB 与自建MySQL的 QPS 柱状对比(柱状图)与 RT 折线对比(线条)

读写分离效果

指标 单主节点 1主+2只读 1主+4只读 扩展比
读QPS 10,000 28,000 52,000 5.2x
写QPS 2,500 2,500 2,500 1x
读RT 1.2ms 0.8ms 0.5ms ⬇️ 58%

PolarDB的读扩展几乎是线性的,因为只读节点共享存储,不存在传统MySQL的复制延迟问题。

七、踩坑实录:5个真实问题复盘

这些坑,每一个都曾让人心跳加速,堪称“宝贵经验”。

坑1:DTS增量同步延迟突增

现象:灰度切换10%流量到PolarDB后,DTS增量同步延迟从正常的1秒突然飙升到60秒,导致读PolarDB的用户看到的是1分钟前的数据,订单状态查询出现大量不一致。

根因:灰度切换后,应用开启双写,但批量操作使用了INSERT ... ON DUPLICATE KEY UPDATE语句。这类语句产生的Binlog事件量是普通INSERT的3-5倍,DTS的增量解析线程处理不过来,导致积压。

解决:将批量操作拆分为先SELECT判断存在性,再分别执行INSERT或UPDATE。同时调整DTS的增量同步并发度从2提升到4,延迟恢复到1秒以内。

经验:DTS增量同步的性能瓶颈往往出在大事务和批量操作上。迁移期间应避免大批量DML操作,如果不可避免,需要提前评估DTS的同步能力,必要时临时提升DTS规格。

坑2:PolarDB只读节点读一致性异常

现象:用户创建订单后立即查询订单列表,偶尔出现“订单不存在”的情况。排查发现请求被路由到只读节点,而只读节点的数据还没更新过来。

根因:PolarDB的物理日志复制虽然延迟在毫秒级,但并非零延迟。应用层在写操作完成后立即发起读请求,如果被路由到只读节点,就可能读到旧数据。这和自建MySQL的“写后读”问题是同一类,但PolarDB的延迟更小,反而容易让人忽略。

解决:对于“写后读”场景,使用集群Endpoint并开启session_consistency参数,确保同一会话的读请求路由到主节点。同时,在Spring Boot层面对关键查询添加@Transactional注解,保证事务内的读写走同一连接。

经验:PolarDB的读一致性策略需要根据业务场景选择。对于“写后立即读”的场景,必须使用主节点或开启会话一致性,不能盲目依赖只读节点。集群Endpoint的session_consistency参数是最简单的解决方案。

坑3:Spring Boot批量插入性能劣化

现象:迁移到PolarDB后,订单批量导入功能耗时从原来的30秒增加到120秒,性能劣化4倍。DBA排查发现PolarDB的CPU使用率飙升到90%。

根因:原来的批量导入使用了MyBatis的标签拼接多行INSERT,单次拼接5000行。PolarDB的SQL解析器对超长SQL的解析效率不如自建MySQL,5000行的INSERT语句解析时间占了总耗时的60%。

解决:将单次批量插入的行数从5000降低到500,同时开启JDBC的rewriteBatchedStatements参数,让驱动层做批量优化。修改后批量导入耗时降到25秒,比自建MySQL还快。

坑4:存储过程兼容性问题

现象:迁移后,结算模块的存储过程执行报错ERROR 1305 (42000): FUNCTION order_db.generate_settlement_id does not exist。该存储过程在自建MySQL上运行正常。

根因:PolarDB对存储过程内的动态SQL(PREPARE/EXECUTE)有更严格的安全限制。该存储过程使用了PREPARE stmt FROM CONCAT(...)拼接SQL,PolarDB默认禁止存储过程内使用动态SQL,需要通过参数loose_sp_dynamic_sql显式开启。

解决:在PolarDB参数配置中开启loose_sp_dynamic_sql = ON,同时审查所有存储过程,将动态SQL改为静态SQL。对于无法避免动态SQL的场景,通过参数开启。

坑5:大表DDL导致连接超时

现象:迁移后在PolarDB上对订单表执行ALTER TABLE ADD COLUMN操作,操作执行了20分钟后,Spring Boot应用开始报Communications link failure,大量连接断开。

根因:PolarDB的DDL操作使用的是Online DDL,虽然不阻塞DML,但在DDL执行期间会持有元数据锁(MDL)。当DDL执行时间过长,HikariCP的连接验证查询SELECT 1在等待MDL时超时,导致连接池判定连接失效并大量重建连接。

解决:将DDL操作安排在低峰期执行,同时临时调大HikariCP的connection-timeout到30秒。长期方案是使用PolarDB的DDL无锁变更功能(基于DMS的无锁变更),对大表DDL可以做到完全不阻塞。

八、最佳实践:迁移决策树 + 检查清单 + 参数调优

1. 迁移决策树

2. 迁移前检查清单

检查项 检查内容 通过标准 负责人
存储引擎 是否有MyISAM/Archive等非InnoDB表 全部为InnoDB DBA
字符集 是否使用utf8mb4 全库统一utf8mb4 DBA
外键约束 外键约束是否影响迁移顺序 按依赖关系排序列出 DBA
存储过程 动态SQL兼容性 确认参数调整方案 DBA
触发器 触发器兼容性 逐个验证 开发
自增列 自增列步长和偏移 与PolarDB对齐 DBA
时区设置 源库和目标库时区一致 UTC或Asia/Shanghai统一 DBA
SQL_mode SQL_mode是否一致 确认PolarDB参数配置 DBA
大表评估 单表超过1000万行的表 评估DTS迁移时间 DBA
应用兼容性 驱动版本兼容性 MySQL Connector/J 5.1.47+ 开发
连接池配置 HikariCP参数适配 超时参数调整 开发
监控告警 新增PolarDB监控指标 告警规则配置 运维

3. PolarDB参数调优清单

参数 默认值 推荐值 说明
loose_max_connections 2000 3000-5000 根据业务峰值连接数×1.5
loose_innodb_buffer_pool_size 实例内存×50% 实例内存×70% 独享规格可加大
loose_innodb_polar_parallel_query_threshold 0 10000 开启并行查询,阈值10000行
loose_innodb_lock_wait_timeout 50 10 减少锁等待时间,快速失败
loose_sp_dynamic_sql OFF ON 存储过程动态SQL支持
loose_innodb_polar_pack_prefix OFF ON 字符串列压缩,节省存储
loose_block_hash_index OFF ON 自适应哈希索引优化
loose_innodb_flush_log_at_trx_commit 1 1 保持双1,确保数据安全
loose_sync_binlog 1 1 保持双1,确保数据安全
loose_innodb_io_capacity 2000 10000 提升后台刷脏页速度

九、总结

从自建MySQL迁移到PolarDB,表面上是换了数据库,本质上是一次架构理念的升级。存储计算分离带来的弹性扩展能力、物理日志复制带来的毫秒级延迟、快照备份带来的秒级恢复——这些都是自建MySQL架构下难以实现的能力。

但迁移并非没有风险。上面5个踩坑案例,每一个都说明细节足以成为生产事故的导火索。记住,零停机迁移的核心不在于技术有多先进,而在于方案有多完善、回滚有多快速。

如果你也在考虑类似的迁移,建议按这个优先级来:

  • 先评估:用迁移决策树确认方案,用检查清单确认就绪。
  • 再验证:在测试环境完整走一遍迁移流程,模拟灰度切换和回滚。
  • 后落地:选择低峰期开始灰度切换,每一步都有监控和回滚预案。

希望这次实战复盘能帮你少走弯路,顺利完成PolarDB的迁移。

来源:https://developer.aliyun.com/article/1743924
上一篇大模型反向学习传统算法缺陷并迭代优化 下一篇OpenCode安装全攻略:Windows/macOS/Linux四种方法
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
Windows Docker Desktop RabbitMQ生产级部署完整指南
AI教程 · 2026-06-29

Windows Docker Desktop RabbitMQ生产级部署完整指南

前言 在 Windows 本地开发环境中,直接安装 RabbitMQ 确实颇为周折:需要单独配置 Erlang 运行环境、手动管理环境变量、服务启停全凭手工操作。更令人困扰的是,版本兼容冲突、端口占用、环境不一致等问题层出不穷。笔者见过不少开发者为搭建环境就得耗费整整半天时间。 相比之下,借助 Do

AI搜索重构制造业采购逻辑的阿里云企业级GEOCMS优化实践
AI教程 · 2026-06-29

AI搜索重构制造业采购逻辑的阿里云企业级GEOCMS优化实践

先分享一个切实感受。过去两年,我们与福建制造企业合作较为频繁,发现一个非常突出的现象:超过80%的企业官网,产品参数仍然存放在PDF或图片中。AI爬虫?根本无法抓取。这些企业技术实力不弱、资质证照齐全、应用案例也丰富,但在AI搜索这一全新战场上,它们几乎处于隐身状态。 一、一个正在发生的行业变化 A

阿里云Token Plan团队版功能价格与省钱购买指南
AI教程 · 2026-06-29

阿里云Token Plan团队版功能价格与省钱购买指南

阿里云百炼近期推出了名为“Token Plan 团队版”的全新服务,这一服务专为企业与开发者量身打造,定位为AI大模型订阅平台。通过引入Credits作为统一计量单位,将文本生成、图像生成等多模态AI能力纳入单一计费体系,同时无缝兼容主流AI编程工具及智能体(Agent)生态系统。其核心亮点包括:全

阿里云物联网.NET Core客户端位置信息上报
AI教程 · 2026-06-29

阿里云物联网.NET Core客户端位置信息上报

阿里云物联网平台的位置服务并非一个完全独立的功能模块。位置信息可包含二维坐标与三维坐标,而位置数据的来源本质上是借助设备属性进行上传。换言之,若要让设备上报位置,您需先将其视为一个普通属性进行处理。 1)添加二维位置数据 操作过程十分简洁。进入数据分析 → 空间数据可视化 → 二维数据,点击添加,将

年阿里云服务器选型配置与网站部署全攻略
AI教程 · 2026-06-29

年阿里云服务器选型配置与网站部署全攻略

2026年,阿里云服务器生态已高度成熟,形成了清晰的轻量应用服务器与ECS云服务器两大产品阵营。无论你是计划搭建个人博客、企业官网,还是运营电商平台、进行应用开发,基本都能找到理想的解决方案。本指南将从服务器选型、配置选择、部署流程到安全运维,系统梳理2026年最实用的操作要点,帮助你少走弯路,让网