UPDATE_MYSQL

UPDATE users SET age = 30 WHERE id = 1;

MySQL (InnoDB engine) không chỉ đơn giản là “sửa dữ liệu”, mà sẽ thực hiện một loạt các bước rất kỹ lưỡng để đảm bảo an toàn, hiệu suất, và nhất quán dữ liệu, đặc biệt trong môi trường transactional, concurrent.


🔬 Quá trình thực thi câu lệnh UPDATE trong MySQL (InnoDB)

📌 1. Parser & Optimizer

  • SQL Parser phân tích cú pháp câu lệnh.

  • Optimizer chọn kế hoạch truy vấn tốt nhất (dùng chỉ mục nếu có trong WHERE).


📌 2. Locking & MVCC

  • InnoDB lấy row-level locks cho các bản ghi phù hợp với WHERE.

  • Dựa trên Isolation Level, MVCC sẽ đảm bảo dữ liệu đọc thấy là hợp lệ:

    • REPEATABLE READ: đọc snapshot cũ.

    • READ COMMITTED: đọc dữ liệu đã commit mới nhất.


📌 3. Ghi dữ liệu mới

  • InnoDB không ghi đè row cũ, mà:

    • Ghi một bản sao mới của row với age = 30.

    • Gắn các metadata như trx_id, roll_pointer (phục vụ rollback, MVCC).

  • Row cũ vẫn được giữ lại trong undo log.


📌 4. Undo Log (Rollback Segment)

  • Ghi bản ghi cũ của row (trước khi update) vào undo log.

  • Nếu transaction rollback, MySQL dùng undo log để phục hồi lại giá trị cũ.


📌 5. Change Buffer & Doublewrite Buffer

  • Nếu row không được truy cập thường xuyên, thay vì ghi trực tiếp vào disk, InnoDB ghi vào change buffer để tối ưu I/O.

  • Ghi đồng thời vào doublewrite buffer (chống mất dữ liệu nếu crash khi đang ghi disk).


📌 6. Redo Log (WAL - Write Ahead Logging)

  • Ghi thông tin thay đổi vào redo log (ib_logfile) để đảm bảo crash recovery.

  • Ghi trước khi ghi thật vào disk (quy tắc Write Ahead Logging).


📌 7. Commit / Rollback

  • Khi gọi COMMIT, InnoDB sẽ:

    • Flush redo log.

    • Ghi transaction vào binary log (phục vụ replication).

    • Đánh dấu transaction là hoàn tất.

  • Nếu ROLLBACK, dùng undo log để phục hồi lại row gốc.


🔁 Tóm tắt bằng flow

UPDATE
  → Parse + Optimize
    → Tìm row cần sửa (dùng index nếu có)
      → Lấy row-level lock
        → Ghi undo log
          → Ghi bản mới vào memory buffer
            → Ghi redo log (WAL)
              → COMMIT = flush + binlog + mark trx done

✅ Tối ưu UPDATE như một Senior

  1. WHERE có index → tránh full table scan

  2. UPDATE theo batch nhỏ nếu table lớn (LIMIT, ORDER BY)

  3. Tránh update primary key → gây fragmentation

  4. Chỉ update khi thực sự cần (sử dụng trigger, audit log)

  5. Xem lại Isolation level → ảnh hưởng performance concurrency


Last updated