ALTER TABLE
PostgreSQL でACCESS EXCLUSIVE
SELECT
を発行すると、を含むすべてをブロックするロックがかかります。ただし、テーブルが書き換えを必要としない場合、新しいロックが不要な場合UNIQUE
、CHECK
またはFOREIGN KEY
検証のために高価なフルテーブルスキャンが必要な場合など、このロックは非常に短い場合があります。
疑わしい場合は、一般的に試してみてください!PostgreSQLのすべてのDDLはトランザクション型であるため、ALTER TABLE
時間がかかりすぎて他のクエリを保留し始めた場合にキャンセルしても問題ありません。さまざまなコマンドで必要なロックレベルは、ロックページに記載されています。
一部の通常低速の操作は、ダウンタイムなしで安全に実行できるように高速化できます。たとえば、テーブルがt
あり、顧客がすべての顧客コードをで始める必要があると顧客が決定customercode integer NOT NULL
したtext
ために列を変更するX
場合、次のように記述できます。
ALTER TABLE t ALTER COLUMN customercode TYPE text USING ( 'X'||customercode::text );
...しかし、それは再書き込みのためにテーブル全体をロックします。で列を追加する場合も同様DEFAULT
です。長いロックを回避するためにいくつかの手順で実行できますが、アプリケーションは一時的な複製に対処できる必要があります。
ALTER TABLE t ADD COLUMN customercode_new text;
BEGIN;
LOCK TABLE t IN EXCLUSIVE MODE;
UPDATE t SET customercode_new = 'X'||customercode::text;
ALTER TABLE t DROP COLUMN customercode;
ALTER TABLE t RENAME COLUMN customercode_new TO customercode;
COMMIT;
これにより、プロセス中の書き込みのみが防止さt
れます。ロック名EXCLUSIVE
は、それ以外のSELECT
すべてを除外するという点でやや欺de的です。ACCESS EXCLUSIVE
モードは、すべてを完全に除外する唯一のモードです。ロックモードを参照してください。が必要とするロックのアップグレードが原因で、この操作がデッドロックロールバックする可能性があるというリスクがありますALTER TABLE
が、最悪の場合は再度実行する必要があります。
そのロックを回避しt
、INSERT
またはUPDATE
が入るたびにcustomercode_new
から自動的に生成されるトリガー関数を作成することで、すべてをライブで実行することもできcustomercode
ます。
また、そこのようなツールが内蔵されているCREATE INDEX CONCURRENTLY
とALTER TABLE ... ADD table_constraint_using_index
that'reは、DBAは、並行性に優しい方法で、もっとゆっくり仕事をしていることにより、排他的ロック期間を短縮することができるように設計されています。
pg_reorg
ツールまたはその後継pg_repack
にもいくつかのテーブル再構築操作に使用することができます。
pg_reorg
と、より困難なシナリオに役立ちます。