<div dir="ltr">Hi Tatsuo, Thanks for the review<div><br></div><div>your version of patch is causing the compilation problem on the OS/X, The reason is the configure script is </div><div>defining HAVE_STRLCPY in config.h file while the pool.h is adding the condition on HAVE_DECL_STRLCPY.</div>
<div>I have updated the patch to fix this issue can you please verify if the attached version works on your linux box. </div>







<div><div class="gmail_extra"><br></div><div class="gmail_extra"><br></div><div class="gmail_extra">Regards</div><div class="gmail_extra">Usama</div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Jan 4, 2014 at 4:44 PM, 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:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Sorry for delay. I have checked your patch.<br>
<div><div class="h5"><br>
&gt; Hi Tatsuo<br>
&gt;<br>
&gt; Thanks a bundle for looking into the patch.<br>
&gt;<br>
&gt;<br>
&gt; On Sat, Dec 14, 2013 at 2:35 PM, Tatsuo Ishii &lt;<a href="mailto:ishii@postgresql.org">ishii@postgresql.org</a>&gt; wrote:<br>
&gt;<br>
&gt;&gt; Usama,<br>
&gt;&gt;<br>
&gt;&gt; Thanks for the great work.<br>
&gt;&gt; I have take a look at your patches.<br>
&gt;&gt;<br>
&gt;&gt; Compiling the source code:<br>
&gt;&gt;<br>
&gt;&gt; I see some &quot;//&quot; comments. I believe they are temporary ones. We follow<br>
&gt;&gt; the PostgreSQL coding standard and it does not allow to use &quot;//&quot;<br>
&gt;&gt; comments. I also see some compiler warnings because of function<br>
&gt;&gt; prototypes are not declared.<br>
&gt;&gt;<br>
&gt;<br>
&gt; Yes I intend to follow the PostgreSQL coding style and standards, the &quot;//&quot;<br>
&gt; style comments were left<br>
&gt; in the code unintentionally, and I had this thing in the mind and last TODO<br>
&gt; of this effort is to clean up<br>
&gt; the code for these kind of mistakes.<br>
&gt;<br>
&gt;&gt;<br>
&gt;&gt; I noticed you commented out following line which causes lots of<br>
&gt;&gt; compiler warnings. Is that intended?<br>
&gt;&gt;<br>
&gt;&gt; extern size_t strlcpy(char *dst, const char *src, size_t siz);<br>
&gt;&gt;<br>
&gt;<br>
&gt; Actually I use Mac OS/X for development and since OS/X is BSD based  which<br>
&gt; already<br>
&gt; contains the native strlcpy function defined in string.h, So I was getting<br>
&gt; the compilation error.<br>
&gt;<br>
&gt; Please find the attached patch (strlcpy_fix.patch) to properly fix this<br>
&gt; problem, The patch adds the check<br>
&gt; in configure to test if strlcpy is provided by OS and in that case does not<br>
&gt; externs the function in pool.h.<br>
&gt; Since this issue also exists in the master branch so If you feel the<br>
&gt; comfortable with the patch and the fix<br>
&gt; ,can you please also apply this on master branch.<br>
&gt; Note: You will require to run the autoconf after this patch.<br>
<br>
</div></div>Unfortunately your patch did not work on my Linux box.<br>
<br>
AC_CHECK_DECLS([strlcat, strlcpy]) produces config.h like this if<br>
there&#39;s no strlcpy in system library.<br>
<br>
/* Define to 1 if you have the declaration of `strlcpy&#39;, and to 0 if you<br>
   don&#39;t. */<br>
#define HAVE_DECL_STRLCPY 0<br>
<br>
which makes following declaration in pool.h void, which I think you<br>
are not willing to do so.<br>
<br>
#ifndef HAVE_DECL_STRLCPY<br>
<div class="im">extern size_t strlcpy(char *dst, const char *src, size_t siz);<br>
</div>#endif<br>
<br>
So I have changed AC_CHECK_DECLS([strlcat, strlcpy]) to<br>
AC_CHECK_FUNCS([strlcat, strlcpy]). Please verify attached patch works<br>
for Mac OS X.<br>
<div class="im"><br>
Best regards,<br>
--<br>
Tatsuo Ishii<br>
SRA OSS, Inc. Japan<br>
English: <a href="http://www.sraoss.co.jp/index_en.php" target="_blank">http://www.sraoss.co.jp/index_en.php</a><br>
Japanese: <a href="http://www.sraoss.co.jp" target="_blank">http://www.sraoss.co.jp</a><br>
<br>
</div><div class="im">&gt;&gt; &gt; pgpool_main.c PgpoolMain()<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; The patch changes the flow of how health check failures are processed,<br>
&gt;&gt; &gt; health_check() function which<br>
&gt;&gt; &gt; previously used to return health check failing node number or success is<br>
&gt;&gt; &gt; changed to do_health_check(),<br>
&gt;&gt; &gt; which reports an error through ereport in case of failed health check on<br>
&gt;&gt; &gt; backend node and than the failure is<br>
&gt;&gt; &gt; processed by &quot;process_backend_health_check_failure()&quot; function.<br>
&gt;&gt; &gt; This portion of the code requires the most review and suggestions, Since<br>
&gt;&gt; &gt; there are many different<br>
&gt;&gt; &gt; ways to implement this health checking.<br>
&gt;&gt;<br>
&gt;&gt; I saw followings:<br>
&gt;&gt;<br>
&gt;&gt; LOG:  starting health check<br>
&gt;&gt; LOCATION:  pgpool_main.c:369<br>
&gt;&gt; LOG:  after retry 0, All backends are returned to healthy state<br>
&gt;&gt; LOCATION:  pgpool_main.c:411<br>
&gt;&gt;<br>
&gt;&gt; Before &quot;starting health check&quot; message was debug message and should<br>
&gt;&gt; remain debug IMO. Otherwise they flood the log file.<br>
&gt;&gt;<br>
&gt;&gt; I also see problem with &quot;after retry 0, All backends are returned to<br>
&gt;&gt; healthy state&quot; message since the message appears even there&#39;s no retry<br>
&gt;&gt; (again before we do not spit the message if we are not doing retry).<br>
&gt;&gt;<br>
&gt;<br>
&gt; Thanks for pointing these. The 2nd attached patch &quot;exmgr_fix.patch&quot; tries<br>
&gt; to fix these, which can be applied<br>
&gt; on EXCEPTION_MGR development branch.<br>
<br>
</div>Looks good.<br>
<div class=""><div class="h5"><br>
&gt;&gt; Most importantly, the message style is pretty different from current<br>
&gt;&gt; one. no timestamp, no pid.<br>
&gt;&gt;<br>
&gt;<br>
&gt; Yes this one is known thing, I some how missed to point it out<br>
&gt; specifically. This is the part of the TODO item mentioned<br>
&gt; upthread &quot;changes and cleanup of elog.c and elog.h&quot;. I have intentionally<br>
&gt; left it as a last item because it deals mostly with<br>
&gt; cosmetic issues. Apart from that this TODO item also have couple of more<br>
&gt; things which are needed to be done<br>
&gt; by elog api. e.g. adding the configuration parameters similar to<br>
&gt; PostgreSQL&#39;s<br>
&gt; log_min_error_statement, log_min_messages, client_min_messages to control<br>
&gt; the level of message generated and reported by pgpool.<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt; Thanks<br>
&gt; Muhammad Usama<br>
&gt;<br>
&gt;&gt; Another way could be to use PG_TRY and PG_CATCH inside health_check<br>
&gt;&gt; &gt; function and if<br>
&gt;&gt; &gt; &quot;make_persistent_db_connection()&quot; throws an error, the PG_CATCH block<br>
&gt;&gt; &gt; catches the error<br>
&gt;&gt; &gt; and return the failing node number<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; something like<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; health_check()<br>
&gt;&gt; &gt; {<br>
&gt;&gt; &gt; ....<br>
&gt;&gt; &gt; for(i =0; i&lt; MAX_BACKEND; i++)<br>
&gt;&gt; &gt; PG_TRY()<br>
&gt;&gt; &gt; {<br>
&gt;&gt; &gt;     make_persistent_db_connection();<br>
&gt;&gt; &gt; ...<br>
&gt;&gt; &gt; }<br>
&gt;&gt; &gt; PG_CATCH();<br>
&gt;&gt; &gt; {<br>
&gt;&gt; &gt; ....<br>
&gt;&gt; &gt;  return i;<br>
&gt;&gt; &gt; }<br>
&gt;&gt; &gt; PG_END_TRY();<br>
&gt;&gt; &gt; return 0;<br>
&gt;&gt; &gt; }<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; And than the main loop process the failure, the similar way it it<br>
&gt;&gt; &gt; processing it now (with out the patch).<br>
&gt;&gt; &gt; But the current approach followed by the patch seems to come more natural<br>
&gt;&gt; &gt; with the exception manager<br>
&gt;&gt; &gt; and yet on the negative side the current approach requires to add a state<br>
&gt;&gt; &gt; machine to the main loop.<br>
&gt;&gt;<br>
&gt;&gt; Agreed.<br>
&gt;&gt;<br>
&gt;&gt; &gt; So suggestions and comments on this portion of code and implementation<br>
&gt;&gt; &gt; approach would be very helpful.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; pgpool child process loop<br>
&gt;&gt; &gt; ==================<br>
&gt;&gt; &gt; src/protocol/child.c  do_child()<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; do_child() function is the work horse of pg_pool child process, and<br>
&gt;&gt; &gt; basically contains two loops those<br>
&gt;&gt; &gt; spans the life cycle of child process. First step is to wait for the<br>
&gt;&gt; client<br>
&gt;&gt; &gt; connection, and once this part<br>
&gt;&gt; &gt; is successful, the child is connected with the front end, the process<br>
&gt;&gt; goes<br>
&gt;&gt; &gt; into the query process mode.<br>
&gt;&gt; &gt; So I have used two memory contexts instead of one per loop memory context<br>
&gt;&gt; &gt; for this process.<br>
&gt;&gt; &gt; QueryProcessMemoryContext and ChildLoopMemoryContext, where later is used<br>
&gt;&gt; &gt; for the pahse<br>
&gt;&gt; &gt; where child is waiting for the front end connections and the former is<br>
&gt;&gt; for<br>
&gt;&gt; &gt; the query process phase.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Secondly for the query processing function all my current code browsing<br>
&gt;&gt; &gt; leads me to the believe that<br>
&gt;&gt; &gt; although &quot;pool_process_query()&quot; caller has handled five possible return<br>
&gt;&gt; &gt; values from the function<br>
&gt;&gt; &gt; i.e POOL_END, POOL_ERROR, POOL_FATAL, POOL_IDLE and POOL_CONTINUE.<br>
&gt;&gt; &gt; But in actual the function returns only POOL_END, POOL_ERROR and the<br>
&gt;&gt; &gt; success which is<br>
&gt;&gt; &gt; POOL_CONTINUE. and to squeeze in the managers in query processing<br>
&gt;&gt; function<br>
&gt;&gt; &gt; I have moved forward<br>
&gt;&gt; &gt; with the above mentioned assumptions. Also my current code understanding<br>
&gt;&gt; on<br>
&gt;&gt; &gt; child process flow is when<br>
&gt;&gt; &gt; ever some error occurs in query process phase of child process that error<br>
&gt;&gt; &gt; actually terminates that particular client<br>
&gt;&gt; &gt; So I have added the below code in elog.c file to treat the ERROR in child<br>
&gt;&gt; &gt; process as FATAL in case the<br>
&gt;&gt; &gt; front end clint is connected with the child process.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; if(elevel  == ERROR)<br>
&gt;&gt; &gt; {<br>
&gt;&gt; &gt;    if(processType == PT_CHILD)<br>
&gt;&gt; &gt;    {<br>
&gt;&gt; &gt;      /*<br>
&gt;&gt; &gt;       * If the frontend connection exists, treat this error as FATAL<br>
&gt;&gt; &gt;       */<br>
&gt;&gt; &gt;      if(is_session_connected())<br>
&gt;&gt; &gt;         elevel = FATAL;<br>
&gt;&gt; &gt;     }<br>
&gt;&gt; &gt; }<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Reviews comments and suggestions are most welcome<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Thanks<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Muhammad Usama<br>
&gt;&gt;<br>
</div></div></blockquote></div><br></div></div></div>