ここにはいくつかの誤解があります:
ヌルビットマップはありませんヒープタプルヘッダの一部。ドキュメントごと:
固定サイズのヘッダー(ほとんどのマシンで23バイトを占める)があり、その後にオプションのnullビットマップが続きます...
32のnull許容列は、次の2つの理由で不審ではありません。
nullビットマップは、行ごとに追加され、その行に実際のNULL
値が少なくとも1つある場合にのみ追加されます。NULL可能列には直接的な影響はなく、実際のNULL
値のみが影響します。nullビットマップが割り当てられている場合、常に完全に割り当てられます(すべてまたは何も)。nullビットマップの実際のサイズは列ごとに1ビットで、次のバイトに切り上げられます。現在のソースコードごと:
#define BITMAPLEN(NATTS) (((int)(NATTS) + 7) / 8)
nullビットマップは、ヒープタプルヘッダーの後に割り当てられ、その後にオプションのOIDが続き、次に行データが続きます。OIDまたは行データの開始はt_hoff
、ヘッダーに示されます。コメントごとのソースコード:
t_hoffはMAXALIGNの倍数でなければならないことに注意してください。
ヒープタプルヘッダーの後に1バイトの空きがあり、23バイトを占めます。したがって、最大8列の行のnullビットマップは、追加コストなしで効果的に提供されます。表の9番目の列では、さらに64列を提供するために、別の(通常は8)バイトt_hoff
進められMAXALIGN
ます。したがって、次の境界線は72列になります。
PostgreSQLデータベースクラスター(を含むMAXALIGN
)の制御情報を表示するには、DebianマシンへのPostgres 9.3の一般的なインストールの例:
sudo /usr/lib/postgresql/9.3/bin/pg_controldata /var/lib/postgresql/9.3/main
あなたが引用した関連する回答の説明を更新しました。
それを除けば、ALTER TABLE
ステートメントがテーブル全体の書き換えをトリガーしたとしても(おそらくデータタイプを変更します)、250Kは実際にはそれほど大きくなく、途中の適切なマシンでは数秒で済みます(行が異常に大きい場合を除く) 。10分以上は、まったく別の問題を示しています。ほとんどの場合、ステートメントはテーブルのロックを取得するために待機しています。
のエントリ数の増加pg_stat_activity
は、開いているトランザクションが増えることを意味します。操作が完了するのを待たなければならない(おそらく)テーブルへの同時アクセスを示します。
暗闇の中でいくつかのショット
このフォームも排他ロックを取得するため、可能性のあるテーブルの膨張を確認し、穏やかな、VACUUM mytable
またはより積極的な試みを行いVACUUM FULL mytable
ます。これにより、同じ並行性の問題が発生する可能性があります。代わりにpg_repackを試すことができます...
最初に、インデックス、トリガー、外部キー、またはその他の制約、特に列に関連する制約について考えられる問題を調査します。特に破損したインデックスが含まれている可能性がありますか?同じREINDEX TABLE mytable;
またはDROP
すべてのALTER TABLE
トランザクションを試してから、それらを再度追加してください。
夜間または負荷が少ないときにコマンドを実行してください。
総当たりの方法は、サーバーへのアクセスを停止してから、再試行することです。
固定することができない場合は、現在のバージョンまたは特に次のバージョン9.4にアップグレードすると役立つ場合があります。大きなテーブルとロックの詳細について、いくつかの改善が行われました。しかし、DBに問題がある場合は、まずそれを理解する必要があります。
SET NOT NULL
タイプを変更するのではなく、制約を追加するだけです。ただし、制約はテーブルに対してチェックする必要があり、テーブル全体をスキャンする必要があります。9.4では、より弱いロックを取得することでこれらのケースの一部を改善していますが、それでもかなり重いです。