<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jul 26, 2016 at 5:07 AM, Tatsuo Ishii <span dir="ltr">&lt;<a href="mailto:ishii@postgresql.org" target="_blank">ishii@postgresql.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">What if pg_terminate_backend() is called in an extended query?<br></blockquote><div><br></div><div>My bad, I totally missed out the extended query part. I will implement that on the same footing if you feel comfortable with the design.</div><div><br></div><div>Best regards</div><div>Muhammad Usama</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Best regards,<br>
--<br>
Tatsuo Ishii<br>
SRA OSS, Inc. Japan<br>
English: <a href="http://www.sraoss.co.jp/index_en.php" rel="noreferrer" target="_blank">http://www.sraoss.co.jp/index_en.php</a><br>
Japanese:<a href="http://www.sraoss.co.jp" rel="noreferrer" target="_blank">http://www.sraoss.co.jp</a><br>
<div class="HOEnZb"><div class="h5"><br>
&gt; Hi<br>
&gt;<br>
&gt; Please find the attached work in progress patch for the handling of<br>
&gt; pg_terminate_backend() in pgpool-II. There is still some work need to be<br>
&gt; done on the patch, but I am sharing it to get the thoughts of a wider group<br>
&gt; of audience on the idea and the design.<br>
&gt;<br>
&gt; Problems needed to be addressed for pg_terminated_backend()<br>
&gt; ======<br>
&gt; 1- Since the pg_terminate_backend just go on and kills the child connection<br>
&gt; it is treated as the backend failure by pgpool-II and depending on the<br>
&gt; pgpool-II configuration pgpool-II failover that backend node.<br>
&gt;<br>
&gt; 2- The current logic in pgpool-II have no idea of which backend node the<br>
&gt; pg_terminate_backend call is intended to, and it is routed on the basis of<br>
&gt; logic in pool_where_to_send() function that can send the query to the node<br>
&gt; that does not have the connection with the pid.<br>
&gt;<br>
&gt;<br>
&gt; How is this patch trying to solve this?<br>
&gt; ===========<br>
&gt; After parsing the query in SimpleQuery() function the patch runs the<br>
&gt; function walker on the parsed query tree to find the<br>
&gt; pg_terminate_backend(&quot;const integer&quot;) call. And if the function is found in<br>
&gt; the query the second step is to locate the pgpool-II child process that<br>
&gt; contains the backend connection with PID specified in<br>
&gt; pg_terminate_backend() function call. For that<br>
&gt; the patch loops on all pgpool-II child process and try to locate<br>
&gt; the backend connection with the specific PID by comparing the PID stored in<br>
&gt; the shared memory ConnectionInfos. If the search is successful and the<br>
&gt; child process with the backend connection having the same PID is found, the<br>
&gt; shared memory &quot;ConnectionInfo-&gt;backend_terminated&quot;(added by this patch)<br>
&gt; flag is set to true for that connection.<br>
&gt; Once, after the backend node is identified and the flag is set, the next<br>
&gt; step is to rout the query to the exact backend node that contains the<br>
&gt; connection. For that the patch refrains from calling the<br>
&gt; pool_where_to_send() for this query and explicitly sets the query<br>
&gt; destination to the backend node that has the connection so that the query<br>
&gt; should lands on the proper backend node.<br>
&gt;<br>
&gt; Now when the query is successfully executed on the backend server and<br>
&gt; consequently the backend node kills the said connection to the pgpool, It<br>
&gt; results in the communication error in pgpool-II child process. So to make<br>
&gt; sure that the child process does not failover that backend node and the<br>
&gt; child process checks the &quot;ConnectionInfo-&gt;backend_terminated&quot; flag before<br>
&gt; performing the failover, and if the flag is set, it just does not proceed<br>
&gt; with failover and bails out by FATAL error that kills that<br>
&gt; particular pgpool-II child process which eventually gets re-spawned by<br>
&gt; pgpool main.<br>
&gt;<br>
&gt;<br>
&gt; Issues with this approach<br>
&gt; ====<br>
&gt; 1- What to do if somehow two or more connections to different backend<br>
&gt; PostgreSQL servers have the same PID.<br>
&gt;<br>
&gt; 2- We can only support pg_terminate_backend(constant number) function<br>
&gt; calls. If the expression or sub query is used in the argument of<br>
&gt; pg_terminate_backend then it would not be handled<br>
&gt;  e.g<br>
&gt; pgpool=# select pg_terminate_backend((select 1));<br>
&gt; pgpool=# select pg_terminate_backend( 2 +1);<br>
&gt;<br>
&gt;<br>
&gt; 3- One very remote scenario where after setting the flag<br>
&gt; ConnectionInfo-&gt;backend_terminated to true and before the execution of<br>
&gt; pg_terminate_backend the backend actually gets fail, will still be treated<br>
&gt; as pg_terminate_backend case. But I believe it would be harmless since that<br>
&gt; backend node failure will be caught by the child process sending the<br>
&gt; pg_terminate_backend to that same backend.<br>
&gt;<br>
&gt; TODOs<br>
&gt; =====<br>
&gt;<br>
&gt; If the pg_terminate_backend() fails on the backend because of permission or<br>
&gt; any other issue ,we need to reset the ConnectionInfo-&gt;backend_terminated<br>
&gt; flag.<br>
&gt;<br>
&gt;<br>
&gt; What are your thoughts and suggestions on this approach?<br>
&gt;<br>
&gt; Many thanks in anticipation.<br>
&gt; Best regards<br>
&gt; Muhammad Usama<br>
</div></div></blockquote></div><br></div></div>