MVCC (Multi-Version Concurrency Control) trong PostgreSQL
MVCC là một kỹ thuật kiểm soát đồng thời tiên tiến được sử dụng trong PostgreSQL để cải thiện hiệu suất và khả năng mở rộng trong môi trường đa người dùng. Khác với các hệ thống cơ sở dữ liệu truyền thống sử dụng khóa (lock) để quản lý đồng thời, MVCC cho phép các giao dịch đọc và ghi đồng thời mà không chặn lẫn nhau.
Cách hoạt động của MVCC:
- Phiên bản dữ liệu: Mỗi khi một bản ghi (row) được cập nhật hoặc xóa, PostgreSQL không ghi đè trực tiếp lên dữ liệu cũ. Thay vào đó, nó tạo ra một phiên bản mới của bản ghi đó. Các phiên bản cũ vẫn được giữ lại trong một khoảng thời gian nhất định.
- Snapshot của giao dịch: Mỗi giao dịch khi bắt đầu sẽ nhận được một snapshot của cơ sở dữ liệu tại thời điểm đó. Snapshot này chứa các phiên bản dữ liệu mà giao dịch có thể nhìn thấy. Trong suốt quá trình giao dịch, nó chỉ làm việc với các phiên bản dữ liệu trong snapshot của mình, bất kể các thay đổi từ các giao dịch khác.
- XID (Transaction ID): Mỗi giao dịch được gán một XID duy nhất. XID này được sử dụng để theo dõi các phiên bản dữ liệu và xác định phiên bản nào có thể nhìn thấy đối với mỗi giao dịch.
- xmin và xmax: Mỗi bản ghi trong PostgreSQL có hai trường đặc biệt: xmin và xmax. xmin lưu trữ XID của giao dịch đã tạo ra bản ghi đó, còn xmax lưu trữ XID của giao dịch đã xóa hoặc cập nhật bản ghi (nếu có).
Ưu điểm của MVCC:
- Đọc không chặn ghi và ngược lại: Vì các giao dịch đọc làm việc trên snapshot riêng của mình, chúng không bị ảnh hưởng bởi các giao dịch ghi đang diễn ra. Điều này giảm thiểu sự tranh chấp khóa và cải thiện đáng kể hiệu suất đồng thời.
- Tính nhất quán của giao dịch: Mỗi giao dịch nhìn thấy một cái nhìn nhất quán của cơ sở dữ liệu tại thời điểm nó bắt đầu, bất kể các thay đổi từ các giao dịch khác. Điều này đảm bảo tính toàn vẹn của dữ liệu và tránh các vấn đề như đọc bẩn (dirty read) và đọc không lặp lại (non-repeatable read).
Sau đó theo lịch nó sẽ thực hiện tiến trình vacuum để dọn dẹp bản ghi cũ:
VACUUM trong PostgreSQL
VACUUM là một lệnh quan trọng trong PostgreSQL giúp dọn dẹp và tối ưu hóa cơ sở dữ liệu của bạn. Nó thực hiện hai nhiệm vụ chính:
- Thu hồi không gian lưu trữ:
- Khi bạn xóa hoặc cập nhật dữ liệu, PostgreSQL không xóa vật lý các bản ghi cũ ngay lập tức. Thay vào đó, chúng được đánh dấu là "chết" và vẫn chiếm dụng không gian đĩa. VACUUM sẽ loại bỏ các bản ghi "chết" này và giải phóng không gian đó, giúp giảm kích thước cơ sở dữ liệu và cải thiện hiệu suất.
- Cập nhật thống kê:
- PostgreSQL sử dụng các thống kê về dữ liệu để lập kế hoạch truy vấn tốt hơn. VACUUM sẽ cập nhật các thống kê này để đảm bảo trình tối ưu hóa truy vấn (query optimizer) đưa ra các quyết định tốt nhất khi thực thi truy vấn.
Các loại VACUUM:
- VACUUM: Đây là lệnh cơ bản, nó sẽ thực hiện cả hai nhiệm vụ trên.
- VACUUM ANALYZE: Tương tự như VACUUM, nhưng nó cũng sẽ cập nhật thống kê chi tiết hơn về dữ liệu.
- VACUUM FULL: Đây là phiên bản mạnh hơn của VACUUM, nó sẽ thu hồi nhiều không gian hơn bằng cách ghi lại toàn bộ bảng. Tuy nhiên, VACUUM FULL sẽ khóa bảng trong quá trình thực hiện và có thể ảnh hưởng đến hiệu suất của các truy vấn khác.
Khi nào nên sử dụng VACUUM: