DELETE_MYSQL

Chúng ta sẽ xem xét chi tiết quy trình mà InnoDB thực hiện khi chạy một câu lệnh như:

DELETE FROM users WHERE id = 123;

🔥 Tổng Quan Các Bước Thực Thi DELETE Trong MySQL (InnoDB)


✅ 1. SQL Parsing & Optimization

  • Câu lệnh DELETE được parser phân tích cú pháp.

  • Query Optimizer chọn plan tốt nhất để tìm hàng cần xóa.

    • Sử dụng chỉ mục (id) nếu có.


✅ 2. Find Target Rows (định vị dòng cần xóa)

  • Dựa trên WHERE, InnoDB tìm record(s) cần xóa.

  • Dữ liệu được đọc qua MVCC snapshot (tùy vào isolation level).


✅ 3. Locking Rows

  • InnoDB sử dụng row-level locking để khóa các bản ghi cần xóa.

  • Tránh dirty write và đảm bảo consistency.

    • Isolation Level REPEATABLE READ: các rows bị khóa sẽ không thay đổi suốt transaction.


✅ 4. Check Foreign Key Constraints (nếu có)

  • Nếu bảng có foreign key, InnoDB sẽ kiểm tra:

    • ON DELETE CASCADE → tự động xóa bản ghi con.

    • ON DELETE RESTRICT/NO ACTION → chặn xóa nếu có dữ liệu phụ thuộc.


✅ 5. Mark as Deleted (UNDO + REDO)

❗ InnoDB không xóa vật lý ngay, mà đánh dấu bản ghi là deleted:

  • Ghi UNDO log (để rollback nếu cần).

  • Ghi REDO log (để phục hồi sau crash).

  • Bản ghi được gắn cờ "delete", nhưng vẫn nằm trong tablespace.


✅ 6. Delete from Secondary Indexes

  • Nếu bản ghi có secondary indexes (ví dụ: email, username...), các index này cũng được cập nhật.


✅ 7. Commit hoặc Rollback

  • Nếu DELETE nằm trong transaction:

    • COMMIT: ghi thay đổi vĩnh viễn, xóa thực sự trên disk sau đó (bởi purge thread).

    • ROLLBACK: sử dụng UNDO log để khôi phục bản ghi đã đánh dấu xóa.


✅ 8. Purge Thread xử lý hậu kỳ

  • InnoDB background purge thread sau này sẽ thực hiện xóa vật lý thực sự (physically reclaim space), khi không còn transaction nào cần đến bản ghi cũ.


🔄 DELETE vs TRUNCATE

Đặc điểm
DELETE
TRUNCATE

Transactional

✅ Có UNDO, REDO

❌ Không transactional

WHERE Clause

✅ Có hỗ trợ điều kiện

❌ Không có

Row by Row

✅ Có (dùng MVCC)

❌ Xóa nhanh, toàn bộ table

Trigger hoạt động

✅ Có

❌ Không


🔎 Mẹo từ Senior Dev

  • DELETE quá nhiều bản ghi? → chia batch LIMIT để tránh lock lớn:

DELETE FROM logs WHERE created_at < NOW() - INTERVAL 30 DAY LIMIT 1000;
  • Cần xóa nhanh toàn bảng, không cần rollback? → dùng TRUNCATE.


Last updated