Q

Quản trị viên

Là một lập trình viên yêu công nghệ, thích viết blog để chia sẻ kiến thức, kinh nghiệm lập trình và những điều thú vị trong thế giới tech.

2300 bài viết · Website
Hệ điều hành 03/09/2026 9 phút

Đoạn code của tôi 'chạy xong -1 giây': cái bẫy đo thời gian mà NTP âm thầm cài sẵn trong mọi hệ thống

Đo thời gian trôi qua bằng giờ tường, tôi nhận về -1,000 giây — một khoảng thời gian âm, đoạn code chạy xong trước khi bắt đầu. Vì giờ tường nhảy lùi khi bị chỉnh (NTP, admin). Đo thời lượng phải dùng đồng hồ đơn điệu — CLOCK_MONOTONIC cho +0,000032s đúng đắn ngay cùng lúc đó.

Cơ sở dữ liệu 03/09/2026 8 phút

Hàng đang bị khóa mà vẫn đọc được ngay — vì sao khóa của CSDL chỉ chặn người ghi

A giữ SELECT FOR UPDATE trên một hàng: B ghi cùng hàng chờ 2 giây, nhưng ghi hàng khác hay đọc thuần không chờ mảy may. Tôi tưởng khóa chặn tất cả — hóa ra nó chỉ chặn người ghi cùng hàng, đọc luôn qua nhờ MVCC. Và khóa hai hàng ngược thứ tự thì deadlock, PostgreSQL tự hủy một bên.

Hệ điều hành 03/09/2026 9 phút

Tôi suýt viết 'tín hiệu chậm gấp 14 lần pipe' — rồi phát hiện thủ phạm là một dòng cấu hình tôi quên

Tín hiệu khứ hồi 17µs, tôi suýt kết 'chậm gấp 14 lần pipe'. Nhưng đo pipe cùng điều kiện cũng 16µs — biến ẩn là ghim lõi khác nhau, không phải tín hiệu. Kèm bẫy gộp tín hiệu: gửi SIGUSR1 100 lần chỉ nhận 1, còn tín hiệu thời gian thực xếp hàng đủ 100.

Cơ sở dữ liệu 03/09/2026 8 phút

Index (a,b) tăng tốc WHERE a nhưng bỏ rơi WHERE b — vì sao thứ tự cột quyết định tất cả

Index (a,b) tăng tốc WHERE a=? và WHERE a=? AND b=? (4 trang) — nhưng WHERE b=? một mình cho Seq Scan quét cả 5406 trang. Tôi tưởng (a,b) là hai index cho a và b; hóa ra nó là một cây sắp theo a trước. Quy tắc tiền tố trái nhất, và vì sao thứ tự cột là quyết định thiết kế.

Cơ sở dữ liệu 03/09/2026 8 phút

Bảng 81MB nhỏ hơn cache 128MB mà chạy 3 lần vẫn không nóng lên — bí mật của ring buffer

Lần đọc đầu là shared read (nạp trang), lần sau thành shared hit (từ RAM). Nhưng một seq scan bảng lớn KHÔNG vào cache dù bảng nhỏ hơn shared_buffers — vì ring buffer cố ý bảo vệ cache khỏi bị một lần quét lớn xóa sạch. Tôi tưởng 'chạy lại luôn nhanh hơn', hóa ra đó không phải luật tự nhiên.