私は非常に小さなテーブル(約1milの行)を持っており、制約を落として新しいカラムを追加します。以下のクエリは約5分間ハングアップし、ロールバックする必要があります。PostgreSQLの巨大なテーブルにダウンタイムなしでカラムを追加する
BEGIN WORK;
LOCK TABLE usertable IN SHARE MODE;
ALTER TABLE usertable ALTER COLUMN email DROP NOT NULL;
COMMIT WORK;
別のアプローチは、インターネットで同様の質問に提案 -
CREATE TABLE new_tbl
(
field1 int,
field2 int,
...
);
INSERT INTO new_tbl(field1, field2, ...)
(
SELECT FROM ... -- use your new logic here to insert the updated data
)
CREATE INDEX -- add your constraints and indexes to new_tbl
DROP TABLE tbl;
ALTER TABLE tbl_new RENAME tbl;
- は新しいものに新しいテーブルに古いテーブルから
- 挿入レコードを作成します(第2少ないしを取る)
- 古いテーブルを削除 - このクエリは約5分〜です。ロールバックしなければならなかった。私のために働かない。古い古いテーブルを削除
から
SELECT blocked_locks.pid AS blocked_pid,
blocked_activity.usename AS blocked_user,
blocking_locks.pid AS blocking_pid,
blocking_activity.usename AS blocking_user,
blocked_activity.query AS blocked_statement,
blocking_activity.query AS blocking_statement
FROM pg_catalog.pg_locks blocked_locks
JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
JOIN pg_catalog.pg_locks blocking_locks
ON blocking_locks.locktype = blocked_locks.locktype
AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE
AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
AND blocking_locks.pid != blocked_locks.pid
JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
WHERE NOT blocked_locks.granted;
私は、私の操作を待っている多くの並行書き込み/読み出しを見ることができます。私はテーブルをロックしていたので、私は古いテーブルを落とせない理由を本当に考えていません。
古いテーブルでは真空を実行しても問題ありませんでした。
なぜ私は古いテーブルを削除できないのですか最近作成されたテーブルを削除するのに比べて時間がかかるのはなぜですか?
'alter table'はテーブルロックを要求しますので、' lock table'を手動で実行する必要はありません。 'drop not null'はメタデータの更新に過ぎず、文が排他ロックを取得してから数ミリ秒かかるだけです。その文が長時間実行されているとわかると、DDLは他のトランザクションを待っています。 2番目のバージョンはそれを変更しません。 'drop table'は同じロックを待たなければなりません。 「アイドル・イン・トランザクション」接続が掛かっていないことを確認しましたか? –
DDLは、ある期間、常に排他ロックを必要とします。たぶんスワップ古い<-->新しいテーブルメソッドは、より小さいサービスウィンドウが必要になりますが、依然として排他アクセスが必要です。 – joop