ハマったのでメモ。
mediumの記事に書いてあるとおりだが、日本語で出てこなかったし、mediumが消えるかもなので書いておく。
症状
drop table hogehoge;
というクエリを発行したところ、永久にdropできない。- 定石である
select pid, user_name, starttime, query from stv_recents where status='Running';
でクエリのpid (プロセスID)を確認してからのcancel <pid>
も効かない。 - コンソール画面からのクエリ停止は、そもそも
drop table hogehoge
が見つからなかったので断念。 - ググりまくっていたらmediumの記事を発見。
- 要は対象のクエリが別のプロセスにブロックされているということらしい。
- まず、どのクエリがブロックしているかを確認
SELECT waiting.relation::regclass AS waiting_table, blocking.relation::regclass AS blocking_table, waiting.pid AS waiting_pid, blocking.pid AS blocking_pid, waiting.mode AS waiting_mode, blocking.mode AS blocking_mode, waiting.GRANTED AS waiting_granted, blocking.GRANTED AS blocking_granted, waiting.TRANSACTION AS waiting_txn, blocking.TRANSACTION AS blocking_txn FROM pg_locks AS waiting LEFT JOIN pg_locks AS blocking ON ( (waiting. "database" = blocking. "database" AND (waiting.relation = blocking.relation OR blocking.relation IS NULL OR waiting.relation IS NULL)) OR waiting.TRANSACTION = blocking.TRANSACTION) WHERE 1 = 1 AND NOT waiting.GRANTED AND waiting.pid <> blocking.pid AND blocking_granted = 't' ORDER BY blocking_granted, waiting_granted, blocking_pid, waiting_pid;
blocking_pid
が諸悪の根源で、これを止めればいい。しかしcancel <pid>
ではだめらしい。SELECT pg_terminate_backend(<blocking pid>);
を使う。select文なようだが、psqlコマンドで問い合わせを止めるらしい。
- 一件落着。