🔐🔐🔐 数据库大表,加字段,卡死导致损失惨重!


大表(千万级订单表),在跑,里面关联很多业务,要新增字段,

这时,你去加,所有业务在执行命令的那一秒全部卡死,导致全公司损失惨重,这还不得赔得底裤都不剩...

问题背景

在大数据量表(如万级订单表)上直接执行 ALTER TABLE 新增字段会导致锁表,阻塞读写请求,可能引发超时、连接池耗尽甚至应用崩溃。

🔐锁表

DDL通常会导致锁表。

啥叫锁表

定义:是指数据库在执行某些操作时,限制其他会话对表的访问,目的是保证数据的一致性和完整性,是数据库并发控制的基础机制。

啥时候会导致锁表

  • 执行DDL操作(如ALTER TABLE添加列)
  • 执行大量数据修改(eg: 大量UPDATE)
  • 显式用LOCK TABLE语句
  • 某些特定查询(eg:SELECT FOR UPDATE)

性能影响:

  • 导致查询排队等待
  • 可能引发连接池耗尽
  • 极端情况下导致应用超时

eg:

sql 复制代码
-- 会话1执行(会锁表)
ALTER TABLE orders ADD COLUMN discount DECIMAL(10,2);

-- 会话2尝试查询(会被阻塞)
SELECT * FROM orders WHERE user_id=100;

解决方案与操作代码

1. 主从架构处理

  • 适用场景:主库写,从库读的MySQL主从复制环境。

  • 步骤与代码 :

    sql 复制代码
    -- 1. 停止主从复制
    STOP SLAVE;
    
    -- 2. 在从库执行新增字段(无锁表风险,因从库已停止同步)
    ALTER TABLE orders ADD COLUMN new_field VARCHAR(255);
    
    -- 3. 重启主从复制并检查延迟
    START SLAVE;
    SHOW SLAVE STATUS\G  -- 确认 'Seconds_Behind_Master' 归零
    
    -- 4. 切换主从角色后重复操作主库
  • 风险:需手动切换主从,操作复杂且短暂不可用。

2. 在线DDL工具(pt-online-schema-change)

  • 工具安装 :

    bash 复制代码
    sudo apt-get install percona-toolkit  # Debian/Ubuntu
  • 执行命令 :

    bash 复制代码
    pt-online-schema-change \
      --alter="ADD COLUMN new_field VARCHAR(255)" \
      D=database,t=orders \
      --execute
  • 原理 :创建临时表(也叫幽灵👻表)同步数据,原子切换表名。

  • 注意:需监控磁盘空间和数据库负载。

幽灵👻表:

主要 DDL 操作包括:

  • CREATE - 创建数据库对象(表、视图、索引等)

    sql 复制代码
    CREATE TABLE users (id INT, name VARCHAR(50));
  • ALTER - 修改现有对象结构

    sql 复制代码
    ALTER TABLE users ADD COLUMN email VARCHAR(100);
  • DROP - 删除对象

    sql 复制代码
    DROP TABLE users;
  • TRUNCATE - 清空表数据(保留结构)

    sql 复制代码
    TRUNCATE TABLE logs;
  • RENAME - 重命名对象(部分数据库支持)

    sql 复制代码
    RENAME TABLE old_name TO new_name;

以下三种方法与前两种不同,以此为河界:


3. 扩展新表(低风险推荐)

  • 操作代码 :

    sql 复制代码
    -- 1. 创建新表存储扩展字段
    CREATE TABLE orders_extension (
      order_id BIGINT PRIMARY KEY,
      new_field VARCHAR(255),
      FOREIGN KEY (order_id) REFERENCES orders(id)
    );
    
    -- 2. 应用层查询时联表(示例:Java MyBatis)
    @Select("SELECT o.*, e.new_field FROM orders o LEFT JOIN orders_extension e ON o.id = e.order_id WHERE o.id = #{id}")
    Order getOrderWithExtension(Long id);
  • 优点:零锁表风险,适合高频变更需求。

4. 预留字段(提前设计)

  • 建表示例 :

    sql 复制代码
    CREATE TABLE orders (
      id BIGINT PRIMARY KEY,
      reserved_json JSON,  -- 存储未来动态字段
      reserved_field1 VARCHAR(255),
      reserved_field2 INT
    );
  • 使用示例 :

    sql 复制代码
    UPDATE orders SET reserved_json = JSON_SET(reserved_json, '$.new_property', 'value') WHERE id = 1;

5. 业务优化(非数据库方案)

  • 临时数据存Redis :

    java 复制代码
    // Spring Boot示例
    @Cacheable(value = "order:extensions", key = "#orderId")
    public String getOrderExtension(Long orderId) {
      return "临时数据";
    }

总结与选型建议

方案 风险 适用场景 推荐指数
主从架构 高 已具备主从且允许停机维护 ⭐⭐
在线DDL工具 中 专业DBA团队 ⭐⭐⭐
扩展新表 低 高频字段变更 ⭐⭐⭐⭐
预留字段 低 初期设计阶段 ⭐⭐⭐
业务优化(非DB) 最低 非核心数据或临时需求 ⭐⭐⭐⭐

以上任何操作都需胆大心细,同时需熟练。

相关推荐
鬼手点金7 小时前
nanoGPT/nanochat 能做出 DeepSeek/Qwen 这样的大模型吗?
服务器·前端·javascript·bug·openclaw
蛋蛋的就会顺顺的8 小时前
hot100 p0——栈,贪心算法,动态规划
java·前端·javascript·算法·leetcode·力扣
程序员Sunday8 小时前
TypeScript 的 any、unknown、never 有什么区别?
前端·面试·typescript
朱涛的自习室8 小时前
70 美金的 Beyond Compare,我让 Gemini 4 和 DeepSeek 造个开源免费版(Day 2)
android·前端·人工智能
码艺-Alimjan9 小时前
Tauri 源码备份 · 打包 & 解压 总结,源码收集之路
前端·javascript·vue.js
小马不起床9 小时前
零基础玩转 FastAPI_11:前端后台管理页面
前端·状态模式·fastapi
子非鱼a10 小时前
【文件上传】一个普普通通的edu16
前端
美狐美颜SDK开放平台10 小时前
直播APP如何实现美白滤镜功能?视频美颜SDK技术开发方案详解
前端·数据库·人工智能·音视频·美颜sdk·直播美颜sdk·视频美颜sdk
pride.li11 小时前
第03章 Python 教程-基础语法:注释与变量
服务器·前端·后端·python·算法·计算机视觉
屏什么录11 小时前
电脑如何录屏幕视频和声音?从工具到代码,7 种方案帮你彻底搞定
前端·音视频开发