Ada beberapa kesalahpahaman di sini:
The nol bitmap adalah tidak bagian dari header tumpukan tupel. Per dokumentasi:
Ada header ukuran tetap (menempati 23 byte pada kebanyakan mesin), diikuti oleh bitmap nol opsional ...
32 kolom Anda yang tidak dapat dibatalkan tidak menguntungkan karena dua alasan:
Bitmap nol ditambahkan per baris , dan hanya jika ada setidaknya satu NULL
nilai aktual di baris. Kolom nullable tidak memiliki dampak langsung, hanya NULL
nilai aktual yang melakukannya. Jika bitmap nol dialokasikan, selalu dialokasikan sepenuhnya (semua atau tidak sama sekali). Ukuran sebenarnya dari bitmap null adalah 1 bit per kolom, dibulatkan ke byte berikutnya . Per kode sumber saat ini:
#define BITMAPLEN(NATTS) (((int)(NATTS) + 7) / 8)
Bitmap nol dialokasikan setelah header tumpukan tuple dan diikuti oleh OID opsional dan kemudian data baris. Awal OID atau data baris ditunjukkan oleh t_hoff
di header. Per kode sumber komentar :
Perhatikan bahwa t_hoff harus merupakan kelipatan dari MAXALIGN.
Ada satu byte gratis setelah header heap tuple, yang menempati 23 byte. Jadi bitmap nol untuk baris hingga 8 kolom secara efektif datang tanpa biaya tambahan. Dengan kolom ke-9 dalam tabel, t_hoff
maju lagi MAXALIGN
byte (biasanya 8) untuk menyediakan 64 kolom lainnya. Jadi perbatasan berikutnya adalah 72 kolom.
Untuk menampilkan informasi kontrol cluster database PostgreSQL (termasuk MAXALIGN
), contoh untuk instalasi khas Postgres 9.3 pada mesin Debian:
sudo /usr/lib/postgresql/9.3/bin/pg_controldata /var/lib/postgresql/9.3/main
Saya memperbarui instruksi dalam jawaban terkait yang Anda kutip .
Selain itu, bahkan jika ALTER TABLE
pernyataan Anda memicu penulisan seluruh tabel (yang mungkin memang mengubah tipe data), 250K benar-benar tidak terlalu banyak dan hanya hitungan detik pada mesin setengah jalan yang layak (kecuali jika barisnya luar biasa besar) . 10 menit atau lebih mengindikasikan masalah yang sama sekali berbeda. Pernyataan Anda sedang menunggu untuk mendapatkan kunci di atas meja, kemungkinan besar.
Semakin banyak entri pg_stat_activity
berarti transaksi yang lebih terbuka - menunjukkan akses bersamaan pada tabel (kemungkinan besar) yang harus menunggu operasi selesai.
Beberapa tembakan dalam gelap
Periksa kemungkinan mengasapi meja, cobalah yang lembut VACUUM mytable
atau yang lebih agresif VACUUM FULL mytable
- yang mungkin menghadapi masalah konkurensi yang sama, karena formulir ini juga memperoleh kunci eksklusif. Anda dapat mencoba pg_repack sebagai gantinya ...
Saya akan mulai dengan memeriksa kemungkinan masalah dengan indeks, pemicu, kunci asing atau kendala lainnya, terutama yang melibatkan kolom. Terutama indeks yang rusak mungkin terlibat? Coba REINDEX TABLE mytable;
atau DROP
semuanya dan tambahkan kembali setelah ALTER TABLE
dalam transaksi yang sama .
Coba jalankan perintah di malam hari atau kapan pun bebannya tidak banyak.
Metode brute-force adalah menghentikan akses ke server, lalu coba lagi:
Tanpa dapat menjelaskannya, peningkatan ke versi saat ini atau yang akan datang pada 9.4 khususnya dapat membantu. Ada beberapa perbaikan untuk tabel besar dan untuk mengunci detail. Tetapi jika ada sesuatu yang rusak di DB Anda, Anda mungkin harus mencari tahu dulu.
SET NOT NULL
tidak mengubah tipe, itu hanya menambah kendala - tetapi kendala harus diperiksa terhadap tabel, dan itu membutuhkan pemindaian tabel penuh. 9.4 meningkatkan beberapa kasus ini dengan mengambil kunci yang lebih lemah, tetapi masih cukup berat.