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


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

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

问题背景

在大数据量表(如万级订单表)上直接执行 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) 最低 非核心数据或临时需求 ⭐⭐⭐⭐

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

相关推荐
陈陈CHENCHEN2 分钟前
使用 Vite 快速创建 React 项目 - SuperMap iClient JavaScript / Leaflet
前端·react.js
用户6883362059705 分钟前
Progressive Web App (PWA)
前端
沢田纲吉6 分钟前
《LLVM IR 学习手记(二):变量表达式编译器的实现与深入解析》
前端·编程语言·llvm
小徐_23336 分钟前
VitePress 博客变身 APP,支持离线访问,只需这一招。
前端·vitepress·pwa
猪哥帅过吴彦祖7 分钟前
第 5 篇:WebGL 从 2D 到 3D - 坐标系、透视与相机
前端·javascript·webgl
折七8 分钟前
expo sdk53+ 集成极光推送消息推送 ios swift
前端·javascript·ios
猪哥帅过吴彦祖9 分钟前
Flutter 系列教程:布局基础 (上) - `Container`, `Row`, `Column`, `Flex`
前端·flutter·ios
lifejump9 分钟前
DVWA | XSS 跨站脚本注入
前端·xss
gplitems12310 分钟前
Tripfery - Travel & Tour Booking WordPress Theme Tested
前端
流星稍逝10 分钟前
前端&后端解决跨域的方法
前端·后端