MVCC trong postgresql
MVCC trong postgresql là gì
MVCC (Multi-Version Concurrency Control) là c? ch? ki?m soát concurrency ?? x? lí nhi?u transaction ??ng th?i mà kh?ng lock b?ng hay dòng. Thay vì lock, Postgresql duy trì nhi?u phiên b?n c?a 1 dòng, cho phép ??c và ghi có th? th?c hi?n cùng lúc trên 2 phiên b?n mà kh?ng ?nh h??ng l?n nhau.
Tuple
? trong postgresql thì 1 row ???c g?i là 1 tuple. Khi 1 row ???c insert, update hay delete, Postgresql qu?n ly nhi?u version c?a 1 tuple ?? ??m b?o tính nh?t quán (consistency) và tính c? l?p (isolation) cho các transaction ??ng th?i.
Tuple version
Tuple version dùng ?? tr? t?i 1 phiên b?n c? th? c?a 1 row trong b?ng. Thay vì s?a, xóa tr?c ti?p b?n ghi, postgresql s? t?o ra 1 tuple m?i và ???c l?u tr? trong 1 vùng g?i là Heap (s? nói k? h?n ? bài sau)
Các thành ph?n trong tuple
xmin: (insert transaction id)
xmax: (delete transaction id)
ctid
flags
Vòng ??i c?a 1 tuple
Insert
Update
Delete
Có th? th?y r?ng v?i b?t kì hành ??ng ghi nào vào db thì postgresql l?i t?o ra 1 version m?i, nh? v?y dung l??ng có th? t?ng lên r?t nhi?u. ??i v?i b?ng có index, các tuple trong index c?ng ???c t?o ra cùng v?i b?ng chính. ?? gi?i quy?t v?n ?? ?ó, postgresql có 1 c? ch? g?i là Vacuum dùng ?? d?n các tuple kh?ng còn ho?t ??ng, v? vacuum mình s? chia s? ? 1 bài khác.
Ví d?
Gi? s? có b?ng accounts có 2 giá tr? id và balance
CREATE TABLE accounts (
id SERIAL PRIMARY KEY,
balance NUMERIC(10, 2) NOT NULL
);
Insert 1 b?n ghi
INSERT INTO accounts (id, balance) VALUES (1, 100);
Ki?m tra l?i b?n ghi v?a insert
SELECT xmin, xmax, ctid, * FROM accounts;
K?t qu?: có th? th?y r?ng transaction insert v?a r?i là 842, và tuple có ctid (??a ch? trên heap) là (0,1) Th? update b?n ghi
UPDATE accounts SET balance = 120 WHERE id = 1;
K?t qu?: có th? th?y r?ng xmin b?n ghi m?i là 844, t?c transaction 844 ?? t?o ra 1 tuple m?i. ?? ki?m tra l?i các dead tuple, c?n s? d?ng extension pageinspect
CREATE EXTENSION IF NOT EXISTS pageinspect;
SELECT t_xmin::text AS xmin, t_xmax::text AS xmax, t_ctid::text AS ctid
FROM heap_page_items(get_raw_page('accounts', 0));
Có th? th?y r?ng l?n insert ??u tiên có xmin là 842, sau khi update 2 l?n thì tuple m?i nh?t có xmin là 844 và xmax là 0 (live tuple). ??n ?ay thì mình nh?n ra 1 ?i?u r?t thú v? ?ó là m?c dù l?n insert ??u tiên có ctid là (0,1) nh?ng l?n sau nó ?? chuy?n thành (0, 2), và 2 tuple sau l?i có cùng ctid (0, 3). Mình th? tìm hi?u thì th?y r?ng postgres t?n d?ng vùng nh? ?? cùng l?u 2 tuple dead và live có th? dùng chung.
Nh?ng v?n ?? v?i MVCC