[pgsql-jp: 38683] Re: 拡張問い合わせでupdate文を投げたときにロックのかかるタイミングについて
Yoshiyuki Asaba
y-asaba @ sraoss.co.jp
2007年 8月 25日 (土) 00:51:40 JST
浅羽です。
From: tutui-t @ sys.tosho.co.jp
Subject: [pgsql-jp: 38679] 拡張問い合わせでupdate文を投げたときにロックのかかるタイミングについて
Date: Thu, 23 Aug 2007 17:30:15 +0900
> BEGIN文でトランザクションの開始を明示することなくupdate文を実行すると、
> ROW EXCLUSIVEモードで自動的にロックがかかります。
> このとき、拡張問い合わせでupdateを発行していたとすると、
> どの段階でロックがかかるのでしょうか。
Parse メッセージの処理中に ROW EXCLUSIVE ロックを獲得します。具体的に
は SQL の構文解析が終わって、意味解析に入ったところです。
長いですが、以下のようなバックトレースが取れます。exec_parse_message()
が Parse メッセージ処理のエントリポイントです。
#0 relation_open (relationId=149624, lockmode=3) at heapam.c:693
#1 0x08095066 in relation_openrv (relation=0x8451b70, lockmode=3) at heapam.c:821
#2 0x080951c7 in heap_openrv (relation=0x8451b70, lockmode=3) at heapam.c:891
#3 0x0810ce15 in setTargetTable (pstate=0x8451d20, relation=0x8451b70, inh=1 '\001', alsoSource=1 '\001', requiredPerms=4) at parse_clause.c:157
#4 0x080f231e in transformUpdateStmt (pstate=0x8451d20, stmt=0x8451cd0) at analyze.c:2853
#5 0x080eda56 in transformStmt (pstate=0x8451d20, parseTree=0x8451cd0, extras_before=0xbf8c1a94, extras_after=0xbf8c1a90) at analyze.c:384
#6 0x080ed681 in do_parse_analyze (parseTree=0x8451cd0, pstate=0x8451d20) at analyze.c:251
#7 0x080ed5b9 in parse_analyze_varparams (parseTree=0x8451cd0, sourceText=0x842a9d0 "UPDATE up SET a = a + 1", paramTypes=0xbf8c1b68, numParams=0xbf8c1b6c) at analyze.c:199
#8 0x082185bd in exec_parse_message (query_string=0x842a9d0 "UPDATE up SET a = a + 1", stmt_name=0x842a8c8 "", paramTypes=0x0, numParams=0) at postgres.c:1160
#9 0x0821be1a in PostgresMain (argc=4, argv=0x83cff88, username=0x83cfec0 "y-asaba") at postgres.c:3453
#10 0x081ea875 in BackendRun (port=0x83e3860) at postmaster.c:2931
#11 0x081e9e39 in BackendStartup (port=0x83e3860) at postmaster.c:2558
#12 0x081e7a06 in ServerLoop () at postmaster.c:1211
#13 0x081e73c4 in PostmasterMain (argc=3, argv=0x83cd0c0) at postmaster.c:963
#14 0x08194eb7 in main (argc=3, argv=0x83cd0c0) at main.c:188
> デッドロックのような現象を調べている過程で、
> pg_locks、postgresqlのデバッグログ、
> クライアント−サーバ間のパケットを突き合わせてみたところ、
> postgresqlはParseメッセージを受けるとロックを取りに行き、
> ロックを獲得できたらParseCompleteを返すように見えるのです。
> ロック獲得はExecuteメッセージのときに行うと思っていたので、
> 意外でした。
保存したプランを再利用した場合には Execute でロックを獲得します。
(試していないのでコードを見て推測しています)
--
Yoshiyuki Asaba
y-asaba @ sraoss.co.jp
pgsql-jp メーリングリストの案内