Burada birkaç yanlış anlama var:
Boş bitmap olduğu değil yığın tuple'larının başlığının parçası. Belgelere göre:
Sabit boyutlu bir başlık (çoğu makinede 23 bayt kaplar), ardından isteğe bağlı bir boş bitmap ...
32 boş değerli sütununuz iki nedenden dolayı şüpheli:
Boş bitmap her satıra eklenir ve yalnızca satırda en az bir gerçek NULL
değer varsa . Sıfırlanabilir sütunların doğrudan bir etkisi yoktur, yalnızca gerçek NULL
değerler geçerlidir. Boş bitmap ayrılırsa, her zaman tam olarak ayrılır (tümü veya hiçbiri). Boş bitmap'in gerçek boyutu sütun başına 1 bittir ve sonraki bayta yuvarlanır . Mevcut sos kodu başına:
#define BITMAPLEN(NATTS) (((int)(NATTS) + 7) / 8)
Boş bitmap, yığın demet başlığından sonra ayrılır ve ardından isteğe bağlı bir OID ve ardından satır verileri gelir. Bir OID veya satır verisinin başlangıcı t_hoff
başlıkta ile gösterilir. Yorum başına kaynak kodu :
T_hoff öğesinin MAXALIGN öğesinin katı olması gerektiğini unutmayın.
Yığın demet başlığından sonra 23 baytlık bir boş bayt vardır. Bu nedenle, 8 sütuna kadar olan satırlar için boş bitmap'in ek bir maliyeti yoktur. Tablodaki 9. sütun ile, başka bir 64 sütun sağlamak için başka t_hoff
bir MAXALIGN
(genellikle 8) bayt ilerletilir . Yani bir sonraki sınır 72 sütunda olacak.
PostgreSQL veritabanı kümesinin (dahil MAXALIGN
) kontrol bilgilerini görüntülemek için, Postgres 9.3'ün Debian makineye tipik kurulumuna örnek:
sudo /usr/lib/postgresql/9.3/bin/pg_controldata /var/lib/postgresql/9.3/main
Alıntıladığınız ilgili cevaptaki talimatları güncelledim .
Tüm bunlar bir yana, ALTER TABLE
ifadeniz tüm tabloyu yeniden yazmayı tetiklese bile (ki muhtemelen bir veri türünü değiştirir), 250K gerçekten çok fazla değildir ve herhangi bir yarım terbiyeli makinede saniyeler olur (satırlar alışılmadık derecede büyük olmadıkça) . 10 dakika veya daha fazla, tamamen farklı bir sorunu gösterir. İfadeniz büyük olasılıkla masaya kilitlenmeyi bekliyor.
Artan giriş sayısı, pg_stat_activity
daha fazla açık işlem anlamına gelir - işlemin bitmesini beklemek zorunda olan tabloya (büyük olasılıkla) eşzamanlı erişimi gösterir.
Karanlıkta birkaç atış
Olası masa şişkinliğini kontrol edin , aynı eşzamanlılık sorunlarıyla karşılaşabilecek nazik VACUUM mytable
veya daha agresif bir deneyin VACUUM FULL mytable
, çünkü bu form aynı zamanda özel bir kilit kazanır. Bunun yerine pg_repack'i deneyebilirsiniz ...
İndeksler, tetikleyiciler, yabancı anahtar veya diğer kısıtlamalarla, özellikle sütunu içerenlerle ilgili sorunları inceleyerek işe başladım. Özellikle bozuk bir dizin söz konusu olabilir mi? Hepsini REINDEX TABLE mytable;
veya DROP
hepsini deneyin ALTER TABLE
ve aynı işlemden sonra tekrar ekleyin .
Komutu gece veya çok fazla yük olmadığında çalıştırmayı deneyin.
Bir kaba kuvvet yöntemi, sunucuya erişimi durdurmak ve daha sonra tekrar denemek olacaktır:
Sabitleyemeden, mevcut sürüme veya özellikle gelecek 9.4 sürümüne yükseltmek yardımcı olabilir . Büyük tablolar ve kilitleme detayları için çeşitli iyileştirmeler yapıldı. Ama DB'nizde kırık bir şey varsa, muhtemelen önce bunu anlamanız gerekir.
SET NOT NULL
türü değiştirmez, yalnızca bir kısıtlama ekler - ancak kısıtlama tabloya göre kontrol edilmelidir ve bu da tam bir tablo taraması gerektirir. 9.4 bu vakaların bazılarını daha zayıf kilitler alarak geliştirir, ancak yine de oldukça ağırdır.