Redshiftのクエリのキャンセルを試してみた

# 背景・目的
RedshiftのMaterialized Viewのリフレッシュを多重で実行し、更新が進まなくなってしまったのでキャンセルします。

# まとめ
- ロックされているかと実行中のクエリは、以下のシステムビューを参照することでわかります。
    - SVV_TRANSACTIONS
    - stv_recents
    - PG_LOCKS
    - STV_TBL_PERM
- キャンセルは、以下のコマンドで実行できます。
    - cancel プロセスID 'キャンセル時のメッセージ'

# 実践
## ロックされているか確認する
[ドキュメント](https://aws.amazon.com/jp/premiumsupport/knowledge-center/prevent-locks-blocking-queries-redshift/)には、以下のように書かれています。
> 付与 された列の結果が f (false) の場合、別のセッションのトランザクションがロックを保持していることを意味します。blocking_pid 列には、ロックを保持しているセッションのプロセス ID が表示されます。
```
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;

---

txn_owner,txn_db,xid,pid,txn_start,lock_mode,table_id,tablename,granted,blocking_pid,txn_duration

IAM:dbuser,dbname,1983355,1073941618,2022-10-12 09:28:21.928637,ShareRowExclusiveLock,143220,m_kds_connect,false,1073901422,0 days 0 hrs 39 mins 42 secs
IAM:dbuser,dbname,1982967,1073900622,2022-10-12 09:26:21.92615,ShareRowExclusiveLock,143220,m_kds_connect,false,1073901422,0 days 0 hrs 41 mins 42 secs
IAM:dbuser,dbname,1981762,1073874539,2022-10-12 09:20:21.70179,ShareRowExclusiveLock,143220,m_kds_connect,false,1073901422,0 days 0 hrs 47 mins 42 secs
IAM:dbuser,dbname,1981368,1073925051,2022-10-12 09:18:22.168087,ShareRowExclusiveLock,143220,m_kds_connect,false,1073901422,0 days 0 hrs 49 mins 41 secs
IAM:dbuser,dbname,1980173,1073901422,2022-10-12 10:07:49.011542,ShareRowExclusiveLock,143220,m_kds_connect,true,,0 days 0 hrs 0 mins 14 secs


```
:::note info
1073901422にロックされているようです。
::: 

## キャンセル
### pg_terminate_backendでキャンセル
以下のコマンドでセッションを終了します。
```
-- pidを渡してセッションを終了できます。
select pg_terminate_backend(1073901422)
```



### こちらの方法でもキャンセルできます
以下のクエリでキャンセルします。
```
cancel 1075306548 'Canceld DROP MATERIALIZED VIEW report.m_kds_connect'

cancel 1074954075 'Canceld refresh materialized view  report.m_kds_connect'

cancel 1074962224 'Canceld refresh materialized view  report.m_kds_connect'
```

キャンセルされたか確認します。
```
select pid, starttime, duration,
trim(user_name) as user,
trim (query) as querytxt
from stv_recents
where status = 'Running';

---

# 0件になりました。
```

ロックされているか確認します。先程のレコードが消えていることがわかります。
```
select * from SVV_TRANSACTIONS where lock_mode='ExclusiveLock' and granted='true'

---

txn_owner,txn_db,xid,pid,txn_start,lock_mode,lockable_object_type,relation,granted
IAM:XXX,sample,664678,1074847531,2022-10-09 07:48:12.830704,ExclusiveLock,transactionid,,true

```
実行されていたマテビューリフレッシュがキャンセルされました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/951e73d0-7af5-0d6a-eb7b-50f1ad53385c.png)

## その他
###  実行中のクエリを確認する方法
:::note info
以下のクエリで、実行中のクエリの確認ができます。
:::

```
select pid, starttime, duration,
trim(user_name) as user,
trim (query) as querytxt
from stv_recents
where status = 'Running';

---

pid,starttime,duration,user,querytxt
1075306548,2022-10-09 07:30:16.077995,761767513,IAM:XXX,DROP MATERIALIZED VIEW report.m_kds_connect
1074954075,2022-10-09 07:16:41.74803,1576097485,IAM:XXX,refresh materialized view  report.m_kds_connect;
1074962224,2022-10-09 07:15:42.054455,1635791080,IAM:XXX,refresh materialized view  report.m_kds_connect;
```

# 考察
ロックされたクエリや実行中のクエリについての確認、キャンセルは比較的簡単にできました。

# 参考
https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_SVV_TRANSACTIONS.html

https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_CANCEL.html