业务无感知**更新数据库密码
二、数据库层:双密码(最关键,零侵入)
1)MySQL 8.0.14+(推荐,原生支持)
修改密码时保留旧密码,新旧同时可用:
-- 设置新密码,旧密码继续有效
ALTER USER 'app_user'@'%' IDENTIFIED BY '新密码' RETAIN CURRENT PASSWORD;
- 此时旧密码、新密码都能登录
- 过渡期(通常 5–30 分钟)让应用分批切新密码
- 全量切完后,删除旧密码:
ALTER USER 'app_user'@'%' DISCARD OLD PASSWORD;
2)Oracle 19.12+/21c
设置密码过渡时间(例如 1 天),期间双密码有效:
-- 配置过渡时间(单位天)
ALTER PROFILE app_profile PASSWORD_ROLLOVER_TIME 1;
-- 修改密码,旧密码 1 天内仍可用
ALTER USER app_user IDENTIFIED BY 新密码;
3)低版本MySQL(无双密码)
用影子账号(同权限、同密码):
- 主账号:app_user(当前密码)
- 影子账号:app_user_shadow(同密码)
- 改密时:先改主账号 → 应用切影子 → 再改影子 → 最后统一切回主账号
三、应用层:Java + 连接池热更新(不重启)
1)连接池必须支持“软驱逐”(HikariCP / Druid)
HikariCP(Spring Boot 默认)
@Configuration
public class DataSourceConfig {
@Bean
@RefreshScope // 配置变更自动刷新
public HikariDataSource dataSource(
@Value("${spring.datasource.url}") String url,
@Value("${spring.datasource.username}") String username,
@Value("${spring.datasource.password}") String password) {
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl(url);
ds.setUsername(username);
ds.setPassword(password);
ds.setMaximumPoolSize(20);
ds.setIdleTimeout(600000);
return ds;
}
// 密码更新时:优雅驱逐旧连接(等当前SQL跑完)
public void refreshPassword(String newPwd) {
HikariDataSource ds = dataSource;
ds.setPassword(newPwd);
// 软驱逐:不强制断开,空闲时才关旧连接
ds.getHikariPoolMXBean().softEvictConnections();
}
}
Druid
// 配置监听,密码变更时:
druidDataSource.setPassword(newPwd);
druidDataSource.restart(); // 平滑重启连接池,不丢请求
2)配置中心:Nacos/Apollo 动态下发密码(核心)
- 密码不写死在代码/本地配置,统一存在配置中心(加密存储)
- 配置中心开启自动刷新(Nacos:refreshEnabled=true;Apollo 默认)
- Spring 用
@RefreshScope让数据源 Bean 动态更新
# application.yml
spring:
datasource:
url: jdbc:mysql://db:3306/xxx
username: app_user
password: ${nacos.db.password} # 从Nacos拉取,自动刷新
cloud:
nacos:
config:
server-addr: nacos:8848
refresh-enabled: true
四、完整操作步骤(生产可直接照做)
阶段1:数据库开双密码(DBA)
ALTER USER 'app_user'@'%' IDENTIFIED BY '新密码' RETAIN CURRENT PASSWORD;
✅ 旧密码、新密码同时有效。
阶段2:配置中心更新密码(运维)
- Nacos/Apollo 把
db.password从旧密码改成新密码 - 配置中心自动推送给所有实例(秒级)
阶段3:应用自动热更新(无需重启)
@RefreshScope触发数据源刷新- 连接池软驱逐旧连接:
- 正在执行的 SQL 正常跑完
- 空闲连接逐步关闭
- 新请求用新密码建连接
- 全程无拒绝、无中断、无报错
阶段4:观察 & 收尾(5–30分钟后)
- 监控:连接数、错误率、响应时间(无异常)
- 全实例已切新密码后:
ALTER USER 'app_user'@'%' DISCARD OLD PASSWORD;
✅ 密码更新完成,全程零停机、零影响。
五、高并发避坑要点(必看)
- 不要直接改密不保留旧密码 → 瞬间断连、大量报错
- 连接池必须软驱逐(softEvict) → 避免强杀正在执行的SQL
- 分批更新配置(多实例) → 不要一次性全量推,防止瞬时抖动
- 密码加密存储(配置中心) → 不要明文,用AES/国密加密
- 监控告警 → 密码变更期间监控
SQLException、连接池队列、CPU
六、回滚方案(万一出问题)
- 数据库:旧密码仍有效(双密码期内)
- 配置中心:改回旧密码 → 应用自动切回
- 全程可逆、无风险
七、简历/面试话术(直接背)
高并发项目采用数据库双密码(MySQL 8.0 RETAIN CURRENT PASSWORD)+ 配置中心(Nacos)动态刷新 + HikariCP 软驱逐方案,实现零停机、业务无感知更新数据库密码;全程新旧密码并行有效,连接平滑迁移,无报错、无中断,保障高可用。

浙公网安备 33010602011771号