[Series] Database Internals - Bài 2: Operator Execution & Concurrency Control – Khi "Bản thiết kế" đi vào thực tế
![[Series] Database Internals - Bài 2: Operator Execution & Concurrency Control – Khi "Bản thiết kế" đi vào thực tế](/_next/image?url=https%3A%2F%2Fnllgiwbecqskpipvcvpt.supabase.co%2Fstorage%2Fv1%2Fobject%2Fpublic%2Fblog-images%2F0.6333298584319471.png&w=3840&q=75)
Ở tầng này, DBMS bắt đầu thực hiện các phép toán thực tế trên dữ liệu. Anh em mình sẽ cùng tìm hiểu cách hệ thống "nhai" dữ liệu qua mô hình Volcano và cách nó giữ trật tự cho hàng ngàn giao dịch cùng lúc.
1. Operator Execution: Cánh tay thực thi (Mô hình Volcano)
Bản kế hoạch vật lý mà Optimizer giao cho tầng này thực chất là một cái cây gồm nhiều nút (operators). Để chạy cái cây này một cách hiệu quả mà không tốn quá nhiều bộ nhớ, đa số các DBMS truyền thống (như PostgreSQL, MySQL) sử dụng mô hình gọi là Volcano Model (hay còn gọi là Iterator Model).
Cơ chế hoạt động của mô hình "Kéo" (Pull-based): Mỗi nút trong cây thực thi sẽ triển khai một bộ giao diện (Interface) thống nhất gồm ba hàm chính: Open(), Next(), và Close().
Hàm
Next(): Đây là linh hồn của mô hình này. Nút ở trên đỉnh (Root) sẽ gọiNext()xuống nút bên dưới nó. Nút bên dưới lại tiếp tục gọiNext()xuống thấp hơn cho đến khi chạm tới các nút lá (Scan dữ liệu).Dòng chảy dữ liệu: Khi nút lá lấy được một bản ghi (tuple), nó trả ngược lên cho nút cha xử lý. Cứ thế, dữ liệu được "kéo" lên từng dòng một cho đến khi ra tới tay người dùng.
Để súc tích nhất cho anh em, Volcano Model có thể hiểu qua 3 đặc điểm:
Cơ chế "Kéo" (Pull-based): Nút cha gọi hàm Next() để yêu cầu dữ liệu, nút con mới bắt đầu xử lý và trả về.
Xử lý từng dòng (One-tuple-at-a-time): Mỗi lần gọi Next(), hệ thống chỉ luân chuyển duy nhất một bản ghi xuyên suốt cái cây thực thi.
Giao diện thống nhất: Mọi nút đều dùng chung bộ 3 hàm Open(), Next(), Close(). Điều này giúp Optimizer có thể lắp ghép các nút vật lý (Scan, Join, Filter) một cách linh hoạt mà không cần viết lại logic kết nối.
Lợi ích lớn nhất: Tiết kiệm RAM vì không cần nạp cả bảng dữ liệu khổng lồ vào bộ nhớ cùng một lúc.
2. Concurrency Control: Người điều phối giao dịch
Trong một hệ thống thực tế, không bao giờ chỉ có một mình anh em truy vấn vào Database. Sẽ có hàng nghìn "cái cây" thực thi cùng chạy đồng thời. Nếu không có người điều phối, dữ liệu sẽ sớm bị lỗi khi hai người cùng sửa một dòng.
Đây là lúc hai module quan trọng vào cuộc: Transaction Manager và Lock Manager.
Transaction Manager: Đảm bảo các tính chất ACID (Nguyên tử, Nhất quán, Cô lập, Bền vững). Nó theo dõi vòng đời của một giao dịch: bắt đầu khi nào, đã hoàn tất (Commit) hay thất bại cần hoàn tác (Rollback).
Lock Manager: Đóng vai trò như một trạm gác. Trước khi một toán tử (như Update) chạm vào dữ liệu, nó phải hỏi Lock Manager để xin một chiếc "khóa" (Lock).
Góc kỹ thuật: Các thông tin về "ai đang giữ khóa nào" được lưu trữ trong một Lock Table nằm trên RAM. Nếu anh em thấy một câu lệnh bị "treo", khả năng cao là nó đang đứng đợi trong hàng chờ của Lock Manager để chờ người khác nhả khóa ra.
3. Kết quả của tầng này được lưu ở đâu?
Một điểm thú vị là các nút thực thi thường cần bộ nhớ để hoạt động (ví dụ: cần RAM để làm Hash Table cho phép Join, hoặc cần RAM để chứa dữ liệu Sort).
Local Memory: Mỗi toán tử khi chạy sẽ được cấp một vùng nhớ tạm thời trên RAM để xử lý các phép toán trung gian.
State Management: Trạng thái của các giao dịch và các khóa (Locks) cũng được duy trì hoàn toàn trên RAM để đảm bảo tốc độ phản hồi nhanh nhất.
Tuy nhiên, dù thông minh và kỷ luật đến đâu, tầng này vẫn chưa biết dữ liệu thực sự nằm ở byte nào trên đĩa cứng. Để lấy được dòng dữ liệu, nó phải gọi xuống một "người quản thư" tận tụy ở tầng dưới.



![[Series] Database Internals - Bài 1: Tại sao RDBMS lưu dữ liệu khác với File thông thường?](/_next/image?url=https%3A%2F%2Fnllgiwbecqskpipvcvpt.supabase.co%2Fstorage%2Fv1%2Fobject%2Fpublic%2Fblog-images%2F0.5746714924169717.png&w=3840&q=75)
![[Series] Database Internals - Bài 2: Giải mã "Thùng sách" – Nghệ thuật sắp xếp Slotted Page Layout](/_next/image?url=https%3A%2F%2Fnllgiwbecqskpipvcvpt.supabase.co%2Fstorage%2Fv1%2Fobject%2Fpublic%2Fblog-images%2F0.30555181914624063.png&w=3840&q=75)