Có một vài hiểu lầm ở đây:
Các rỗng bitmap là không một phần của tiêu đề đống tuple. Mỗi tài liệu:
Có một tiêu đề kích thước cố định (chiếm 23 byte trên hầu hết các máy), theo sau là một bitmap null tùy chọn ...
32 cột không thể bỏ qua của bạn là không đáng tin cậy vì hai lý do:
Bitmap null được thêm vào mỗi hàng và chỉ khi có ít nhất một NULL
giá trị thực trong hàng. Các cột không thể không có tác động trực tiếp, chỉ có các NULL
giá trị thực tế mới làm được. Nếu bitmap null được phân bổ, nó luôn được phân bổ hoàn toàn (tất cả hoặc không có gì). Kích thước thực tế của bitmap null là 1 bit trên mỗi cột, được làm tròn đến byte kế tiếp . Theo mã souce hiện tại:
#define BITMAPLEN(NATTS) (((int)(NATTS) + 7) / 8)
Bitmap null được phân bổ sau tiêu đề heap tuple và theo sau là một OID tùy chọn và sau đó là dữ liệu hàng. Bắt đầu một dữ liệu OID hoặc hàng được chỉ định bởi t_hoff
trong tiêu đề. Mỗi mã nguồn bình luận :
Lưu ý rằng t_hoff phải là bội số của MAXALIGN.
Có một byte miễn phí sau tiêu đề heap tuple, chiếm 23 byte. Vì vậy, bitmap null cho các hàng lên đến 8 cột có hiệu quả mà không mất thêm chi phí. Với cột thứ 9 trong bảng, t_hoff
được nâng cao một MAXALIGN
byte khác (thường là 8) để cung cấp cho 64 cột khác. Vì vậy, đường viền tiếp theo sẽ là 72 cột.
Để hiển thị thông tin điều khiển của cụm cơ sở dữ liệu PostgreSQL (bao gồm MAXALIGN
), ví dụ cho cài đặt điển hình của Postgres 9.3 trên máy Debian:
sudo /usr/lib/postgresql/9.3/bin/pg_controldata /var/lib/postgresql/9.3/main
Tôi cập nhật hướng dẫn trong câu trả lời liên quan mà bạn trích dẫn .
Bỏ qua một bên, ngay cả khi ALTER TABLE
câu lệnh của bạn kích hoạt viết lại toàn bộ bảng (có thể là như vậy, thay đổi loại dữ liệu), 250K thực sự không nhiều và sẽ là vấn đề của vài giây trên bất kỳ máy tính nửa chừng nào (trừ khi các hàng lớn bất thường) . 10 phút trở lên cho thấy một vấn đề hoàn toàn khác. Tuyên bố của bạn đang chờ để có được một khóa trên bàn, rất có thể.
Số lượng mục nhập ngày càng tăng pg_stat_activity
đồng nghĩa với việc giao dịch mở nhiều hơn - biểu thị quyền truy cập đồng thời trên bảng (rất có thể) phải chờ hoạt động kết thúc.
Một vài bức ảnh trong bóng tối
Kiểm tra sự phình to của bảng có thể, thử một cách nhẹ nhàng VACUUM mytable
hoặc tích cực hơn VACUUM FULL mytable
- có thể gặp phải các vấn đề tương tranh tương tự, vì hình thức này cũng có được một khóa độc quyền. Thay vào đó, bạn có thể thử pg numpack ...
Tôi sẽ bắt đầu bằng cách kiểm tra các vấn đề có thể xảy ra với các chỉ mục, trình kích hoạt, khóa ngoại hoặc các ràng buộc khác, đặc biệt là các vấn đề liên quan đến cột. Đặc biệt là một chỉ số bị hỏng có thể được tham gia? Hãy thử REINDEX TABLE mytable;
hoặc DROP
tất cả chúng và thêm lại chúng sau ALTER TABLE
trong cùng một giao dịch .
Hãy thử chạy lệnh trong đêm hoặc bất cứ khi nào không có nhiều tải.
Phương pháp brute-force sẽ là dừng truy cập vào máy chủ, sau đó thử lại:
Không thể ghim nó xuống, việc nâng cấp lên phiên bản hiện tại hoặc cụ thể là phiên bản 9,4 sắp tới có thể giúp ích. Đã có một số cải tiến cho các bảng lớn và cho các chi tiết khóa. Nhưng nếu có một cái gì đó bị hỏng trong DB của bạn, có lẽ bạn nên tìm ra nó trước.
SET NOT NULL
không làm thay đổi chủng loại, nó chỉ bổ sung thêm một hạn chế - nhưng hạn chế phải được kiểm tra vào bàn, và điều đó đòi hỏi phải có một bảng đầy đủ quét. 9,4 cải thiện một số trường hợp này bằng cách sử dụng khóa yếu hơn, nhưng nó vẫn khá nặng.