Một trong những điểm hấp dẫn nhất của hệ quản trị cơ sở dữ liệu Postgres đó là cách mà nó thực hiện điều khiển tương tranh giữa các transaction, nghĩa là read
sẽ không bao giờ chặn write
và ngược lại. Nói một cách dễ hình dung hơn, nếu hai transaction thực thi cùng một lúc thì nguyên tắc thực thi là thực thi độc lập, Postgres thực hiện được điều này là nhờ một cơ chế gọi là Multi Version Concurrency Control (MVCC)
. Kĩ thuật này không phải chỉ riêng Postgres mới có, mà đã có nhiều hệ quản trị cơ sở dữ liệu khác cũng đang thực hiện các cách tương tự với MVCC
để điều khiển tương tranh giữa các transaction bao gồm: Oracle, Berkeley DB, CouchDB và các hệ quản trị cơ sở dữ liệu khác nữa. Việc hiểu cách MVCC
được triển khai như thế nào trong PostgreSQL rất quan trọng, vì điều này giúp các nhà phát triển phần mềm có thể thiết kế các ứng dụng có tính đồng thời cao mà có sử dụng đến PostgreSQL, hoặc phần nào giúp giải quyết được rất nhiều vấn đề khó có thể gặp phải trong tương lai.
MVCC hoạt động như thế nào?
Mỗi một transaction trong PostgreSQL đều có một transaction id
- id này là một số nguyên 32-bit, gọi là XID
. Các transaction này bao gồm các câu lệnh đơn như INSERT
, UPDATE
hoặc DELETE
, và một nhóm các câu lệnh tạo thành một khối lệnh được đặt bên trong hai từ khóa BEGIN
- COMMIT
. Khi bắt đầu một transaction, Postgres tạo ra một XID
và gán nó cho transaction hiện tại. Ta có thể nhìn thấy được XID
của transaction hiện tại bằng cách gọi hàm txid_current()
có sẵn trong PostgreSQL.
SELECT CAST(txid_current() AS TEXT);Postgres lưu tất cả thông tin của một transaction vào bên trong
table data
của hệ thống, những thông tin này sẽ được Postgres dùng để xác định một bản ghi sẽ có trạng thái ẩn hay hiện đối với một transaction.
Một điều thú vị nữa trong cơ chế MVCC
này của Postgres đó là ngoài các column
đã được khai báo trong quá trình tạo bảng thì mỗi bản ghi của một bảng sẽ có thêm hai cột bổ sung:
xmin
- xác địnhXID
của transaction đãinsert
bản ghi nàyxmax
- xác địnhXID
của transaction đãdelete
bản ghi này
Nếu ta không truy vấn tới hai cột này, mặc định chúng sẽ bị ẩn đi. Ta có thể truy vấn giá trị của hai cột này như các cột bình thường khác có trong một bảng.