Redshiftにおけるロックの考え方について、まとめておきます。以下は参考となるAWSナレッジのサイトです。
Amazon Redshift でのクエリのブロックを防ぐ方法
Redshiftの分離レベル
まず、Redshiftの分離レベルは、 SERIALIZABLE
となっています。基本的な4つの分離レベルの中で、最も強い分離レベルですね。以下はおさらい。
許容する現象 | SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED |
---|---|---|---|---|
ファントムリード | ☓ | ○ | ○ | ○ |
非再現リード | ☓ | ☓ | ○ | ○ |
ダーティ・リード | ☓ | ☓ | ☓ | ○ |
現象について。
- ファントムリード
- 並列動作したトランザクションのInsertやDeleteの値を読んじゃう
- 非再現リード
- 並列動作したトランザクションのUpdateの値を読んじゃう
- ダーティ・リード
- 未commitの値を読んじゃう
Redshiftのロックの種類
で、実際にRedshiftにおけるロックの種類ですが、行ロックの概念はありません。表ロックのみ用意されています。用意されているロックの種類は、以下の3つがあります。
- AccessExclusiveLock
- AccessShareLock
- UNLOAD、SELECT、UPDATE、またはDELETEにより取得
- AccessExclusiveLock試行のみをブロック
- ShareRowExclusiveLock
- COPY、INSERT、UPDATE、またはDELETEにより取得
- AccessExclusiveLockと、その他のShareRowExclusiveLock試行をブロック
まとめるとこんな感じです。
AccessExclusiveLock | AccessShareLock | ShareRowExclusiveLock | |
---|---|---|---|
AccessExclusiveLock | ブロック | ブロック | ブロック |
AccessShareLock | ブロック | ||
ShareRowExclusiveLock | ブロック | ブロック |
ロックを保持しているセッションを確認
実際にロックしているセッションは、以下のSQLにて確認可能です。SuperUserで実行。
select a.txn_owner, a.txn_db, a.xid, a.pid, a.txn_start, a.lock_mode, a.relation as table_id,nvl(trim(c."name"),d.relname) as tablename, a.granted,b.pid as blocking_pid ,datediff(s,a.txn_start,getdate())/86400||' days '||datediff(s,a.txn_start,getdate())%86400/3600||' hrs '||datediff(s,a.txn_start,getdate())%3600/60||' mins '||datediff(s,a.txn_start,getdate())%60||' secs' as txn_duration from svv_transactions a left join (select pid,relation,granted from pg_locks group by 1,2,3) b on a.relation=b.relation and a.granted='f' and b.granted='t' left join (select * from stv_tbl_perm where slice=0) c on a.relation=c.id left join pg_class d on a.relation=d.oid where a.relation is not null;
granted
カラムが「t」となっているプロセスが、ロックを取得しています。「f」となっているのが、ロック待ちとなっているプロセスです。 blocking_pid
カラムのプロセスが、ロック待ちを発生させているプロセスとなります。
プロセスで実行されているクエリを取得する
悪さをしているプロセスidまで特定できたので、具体的にどういったクエリが実行されているか確認します。以下のSQLです。SuperUserで実行。
select pid, user_name, starttime, query from stv_recents where status='Running' AND pid='xxxx';
公式。
実行中のクエリのプロセス ID を調べる - Amazon Redshift
プロセスを手動で停止する
以下のコマンドで、指定したプロセスを強制終了できます。Superuserで実行。
select pg_terminate_backend(XXXX);
公式。