version 2.7 V2_7
authorTatsuo Ishii <ishii at sraoss.co.jp>
Tue, 3 Jan 2006 03:33:10 +0000 (03:33 +0000)
committerTatsuo Ishii <ishii at sraoss.co.jp>
Tue, 3 Jan 2006 03:33:10 +0000 (03:33 +0000)
- add child_max_connections. contributed by Pomarede Nicolas with
   minor changes by Tatsuo
- add ignore_leading_white_space
- fix problem with copy on V2 protocol
- fix master/slave handling
- fix extended query

17 files changed:
ChangeLog
Makefile.in
NEWS
README
README.euc_jp
aclocal.m4
child.c
configure
configure.in
main.c
pgpool.conf.sample
pool.h
pool_config.c
pool_config.l
pool_process_query.c
pool_stream.c
version.h

index baa419263b08ea7024c5e8920a2e9592c4734318..ee41555c81e64d6e015fff468b918bdbf94df82c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2006-01-03    <ishii@sraoss.co.jp>
+       * version 2.7
+       * add child_max_connections. contributed by Pomarede Nicolas with
+         minor changes by Tatsuo
+       * add ignore_leading_white_space
+       * fix problem with copy on V2 protocol
+       * fix master/slave handling
+       * fix extended query
+       
 2005-11-11    <ishii@sraoss.co.jp>
        * version 2.6.5
        * fix bug introduced in v2.6.4. V2 protocol/trust auth/first time
index 13bd384782c123739acd78ef50447cbf9922cdd7..a4d42634927b07a122eda0188f5dd19570b31935 100644 (file)
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.9 from Makefile.am.
+# Makefile.in generated by automake 1.8.5 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -65,6 +65,15 @@ pgpool_LDADD = $(LDADD)
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/child.Po ./$(DEPDIR)/main.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/pool_auth.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/pool_config.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/pool_connection_pool.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/pool_error.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/pool_params.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/pool_process_query.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/pool_signal.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/pool_stream.Po
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
        $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 CCLD = $(CC)
@@ -72,12 +81,6 @@ LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
 LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS)
 SOURCES = $(pgpool_SOURCES)
 DIST_SOURCES = $(pgpool_SOURCES)
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
-    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
-    *) f=$$p;; \
-  esac;
-am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
 sysconfDATA_INSTALL = $(INSTALL_DATA)
 DATA = $(sysconf_DATA)
 ETAGS = etags
@@ -148,8 +151,6 @@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
 am__include = @am__include@
 am__leading_dot = @am__leading_dot@
 am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
 bindir = @bindir@
 build_alias = @build_alias@
 datadir = @datadir@
@@ -281,14 +282,16 @@ distclean-compile:
 @am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
 @am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(COMPILE) -c $<
 
 .c.obj:
 @am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
 @am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
 
 .l.c:
@@ -301,7 +304,7 @@ install-sysconfDATA: $(sysconf_DATA)
        test -z "$(sysconfdir)" || $(mkdir_p) "$(DESTDIR)$(sysconfdir)"
        @list='$(sysconf_DATA)'; for p in $$list; do \
          if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-         f=$(am__strip_dir) \
+         f="`echo $$p | sed -e 's|^.*/||'`"; \
          echo " $(sysconfDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(sysconfdir)/$$f'"; \
          $(sysconfDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(sysconfdir)/$$f"; \
        done
@@ -309,7 +312,7 @@ install-sysconfDATA: $(sysconf_DATA)
 uninstall-sysconfDATA:
        @$(NORMAL_UNINSTALL)
        @list='$(sysconf_DATA)'; for p in $$list; do \
-         f=$(am__strip_dir) \
+         f="`echo $$p | sed -e 's|^.*/||'`"; \
          echo " rm -f '$(DESTDIR)$(sysconfdir)/$$f'"; \
          rm -f "$(DESTDIR)$(sysconfdir)/$$f"; \
        done
@@ -397,15 +400,15 @@ distdir: $(DISTFILES)
          ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
        || chmod -R a+r $(distdir)
 dist-gzip: distdir
-       tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+       $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
        $(am__remove_distdir)
 
 dist-bzip2: distdir
-       tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+       $(AMTAR) chof - $(distdir) | bzip2 -9 -c >$(distdir).tar.bz2
        $(am__remove_distdir)
 
 dist-tarZ: distdir
-       tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+       $(AMTAR) chof - $(distdir) | compress -c >$(distdir).tar.Z
        $(am__remove_distdir)
 
 dist-shar: distdir
@@ -418,7 +421,7 @@ dist-zip: distdir
        $(am__remove_distdir)
 
 dist dist-all: distdir
-       tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+       $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
        $(am__remove_distdir)
 
 # This target untars the dist file and tries a VPATH configuration.  Then
@@ -427,11 +430,11 @@ dist dist-all: distdir
 distcheck: dist
        case '$(DIST_ARCHIVES)' in \
        *.tar.gz*) \
-         GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
+         GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf - ;;\
        *.tar.bz2*) \
-         bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
+         bunzip2 -c $(distdir).tar.bz2 | $(AMTAR) xf - ;;\
        *.tar.Z*) \
-         uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+         uncompress -c $(distdir).tar.Z | $(AMTAR) xf - ;;\
        *.shar.gz*) \
          GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
        *.zip*) \
@@ -514,7 +517,7 @@ mostlyclean-generic:
 clean-generic:
 
 distclean-generic:
-       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+       -rm -f $(CONFIG_CLEAN_FILES)
 
 maintainer-clean-generic:
        @echo "This command is intended for maintainers to use"
diff --git a/NEWS b/NEWS
index e2c2f8f41d3cc90c8d79d84ca2d5d34051306ba8..addc4e676286c9369f281e6192a5dd68f9e92201 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,27 @@
+2.7(kalekale) 2006/01/03
+
+      o child_max_connections¥ª¥×¥·¥ç¥ó¤òÄɲᣳÆpgpool»Ò¥×¥í¥»¥¹¤Ø¤Î
+       Àܳ²ó¿ô¤¬¤³¤ÎÀßÄêÃͤòͤ¨¤ë¤È¡¢¤½¤Î»Ò¥×¥í¥»¥¹¤ò½ªÎ»¤¹¤ë¡£
+       child_life_time¤äconnection_life_time¤¬¸ú¤«¤Ê¤¤¤¯¤é¤¤Ë»¤·¤¤¥µ¡¼
+       ¥Ð¤Ç¡¢PostgreSQL¥Ð¥Ã¥¯¥¨¥ó¥É¤¬ÈîÂç²½¤¹¤ë¤Î¤òËɤ°¤Î¤ËÍ­¸ú¡£
+       contributed by Pomarede Nicolas
+
+      o ignore_leading_white_space¥ª¥×¥·¥ç¥ó¤òÄɲá£SQLʸ¤ÎÀèÆ¬¤ËÄɲÃ
+        ¤µ¤ì¤¿¥Û¥ï¥¤¥È¥¹¥Ú¡¼¥¹¤ò̵»ë¤¹¤ë¡£DBI/DBD:Pg¤Î¥³¥ó¥Ó¥Í¡¼¥·¥ç¥ó
+        ¤Ï¾¡¼ê¤Ë¹ÔƬ¤Ë¥Û¥ï¥¤¥È¥¹¥Ú¡¼¥¹¤òÄɲ乤ë·ë²Ì¡¢¥í¡¼¥É¥Ð¥é¥ó¥¹¤µ
+        ¤ì¤Ê¤¯¤Ê¤ë¤é¤·¤¤¡£
+
+      o V2¥×¥í¥È¥³¥ë¤Ç¡¢copy¤ÎºÇÃæ¤Ëread¤¬EOF¤ò¸¡½Ð¤·¤¿¾ì¹ç¤ËÂбþ¤·¤Æ
+        ¤¤¤Ê¤«¤Ã¤¿¤Î¤ò½¤Àµ(stdin¤«¤é¤Îcopy¤¬CTRL-C¤Ç¶¯À©½ªÎ»¤·¤¿¾ì¹ç¤Ê
+        ¤É¤Ëµ¯¤³¤ë)
+
+      o master/slave¥â¡¼¥É»þ¤Ë½ÌÂ౿ž¤µ¤»¤ë¥µ¡¼¥Ð¤¬master/slave¤ÇµÕ¤Ë
+        ¤Ê¤Ã¤Æ¤¤¤¿¤Î¤ò½¤Àµ
+
+      o extended query¤ÇExecute¼Â¹Ô»þ¤Ë¥³¥Þ¥ó¥É¤Î´°Î»ÂÔ¤Á¤ò¤·¤Æ¤¤¤Ê¤¤
+       ¤¿¤á¤Ë¥Ç¥Ã¥É¥í¥Ã¥¯¤¬µ¯¤­¤ëÌäÂê¤ËÂбþ(Flush¥á¥Ã¥»¡¼¥¸¤òÁ÷¿®)
+       ¾ÜºÙ¤Ï[pgsql-jp: 36546]¤ò»²¾È
+
 2.6.5(kala) 2005/11/11
 
       o 2.6.4¤ÇÆþ¤ê¹þ¤ó¤À¥Ð¥°¤Î½¤Àµ¡¥V2 protocol/trust authentication/
@@ -45,7 +69,7 @@
       o ¥Ð¥Ã¥¯¥¨¥ó¥É¤«¤é¤Îread()¤ÇEOF¤ò¸¡ÃΤ·¤¿¤È¤­¤Ë½ÌÂà/¥Õ¥§¥¤¥ë¥ª¡¼
        ¥Ð¤¹¤ë¤Î¤ò»ß¤á¤¿(²á¾êÈ¿±þ)¡¥
 
-      o pool_stream¥â¥¸¥å¡¼¥ë¤Ç¡¤EINTR/EGAIN¤Î¤È¤­¤Ë¥ê¥È¥é¥¤¤¹¤ë¤è¤¦¤Ë
+      o pool_stream¥â¥¸¥å¡¼¥ë¤Ç¡¤EINTR/EAGIN¤Î¤È¤­¤Ë¥ê¥È¥é¥¤¤¹¤ë¤è¤¦¤Ë
        ¤·¤¿¡¥
 
 2.6(kala) 2005/06/25
diff --git a/README b/README
index 3167292f6920eca5347721e8a16e4a58b5877a11..162615fec7773684a76383b49db38b222eeba44b 100644 (file)
--- a/README
+++ b/README
@@ -1,6 +1,6 @@
 $Header$
 
-pgpool version 2.6(kala) README
+pgpool version 2.7(kalekale) README
 
 1. What is pgpool
 
@@ -189,7 +189,9 @@ pgpool version 2.6(kala) README
 
    Here are small lists from users where pgpool is running:
 
+   Vine Linux 3.2 (kernel 2.4.31-0vl1.10)/PostgreSQL 8.1.1
    Vine Linux 2.6r4 (kernel 2.4.22-0vl2.12)/PostgreSQL 8.1.0
+   Vine Linux 2.6r4 (kernel 2.4.22-0vl2.12)/PostgreSQL 8.0.3
    Vine Linux 2.6r4 (kernel 2.4.22-0vl2.12)/PostgreSQL 8.0
    Vine Linux 2.6r4 (kernel 2.4.22-0vl2.12)/PostgreSQL 7.4.5
    Vine Linux 2.6r4 (kernel 2.4.22-0vl2.12)/PostgreSQL 7.4.3
@@ -325,6 +327,11 @@ pgpool version 2.6(kala) README
    life time for each idle connection in seconds. 0 means the life
    time is forever. The default value is 0.
 
+   child_max_connections
+
+   if child_max_connections connections were received, child exits. 0
+   means no exit. The default value is 0.
+
    logdir
 
    the directory name to store pgpool's log files. Currently only a
@@ -459,6 +466,13 @@ pgpool version 2.6(kala) README
    views in rule test, and for others erroneous queries abort the
    transaction *before* pgpool issues the table lock statement.
 
+   ignore_leading_whitespace
+
+   If true, ignore leading white spaces of each query while pgpool
+   judges if the query is a SELECT so that it can be load
+   balnced. This is usefull for certain APIs such as DBI/DBD which is
+   know as adding an extra leading white space.
+
 7. Starting pgpool
 
    The simplist way to start pgpool is:
index 301efbb757736f0379077b8bac88d813bba99401..3bebf659c66ba5b68085d1ed8883384d8377b09d 100644 (file)
@@ -183,6 +183,11 @@ pgpool version 2.6(kala) README
    nextval('insert_seq');¡×)¥í¡¼¥É¥Ð¥é¥ó¥¹¥â¡¼¥É¤¬Í­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤È
    regression test¤¬Ä̤ê¤Þ¤»¤ó¡¥
 
+   ¤Ê¤ª¡¢Extended query(Pare/Prepare/Bind/Execute¤ò»ÈÍѤ¹¤ë)Ì䤤¹ç¤ï¤»
+   ¤ÏÉé²Ùʬ»¶¤ÎÂоݤˤʤê¤Þ¤»¤ó¡£¤³¤ì¤Ï¡¢Execute»þ¤ËSELECTʸ¤«¤É¤¦¤«¤Î
+   È½Ä꤬¤Ç¤­¤Ê¤¤¤«¤é¤Ç¤¹¡£¤¿¤È¤¨¤Ð¡¢PostgreSQL 8.0°Ê¹ß¤ÎJDBC¥É¥é¥¤¥Ð
+   ¤Ç¤Ïɬ¤ºExtended query¤ò»È¤¦¤¿¤á¡¢¼ÂºÝÌäÂê¤È¤·¤ÆÉé²Ùʬ»¶¤Ç¤­¤Þ¤»¤ó¡£
+
 2. pgpool¤Î¥á¥ê¥Ã¥È
 
    À¤¤ÎÃæ¤Ë¤Ïpgpool°Ê³°¤Ë¤â¥Ç¡¼¥¿¥Ù¡¼¥¹ÍѤΥ³¥Í¥¯¥·¥ç¥ó¥×¡¼¥ë¥µ¡¼¥Ð¤¬
@@ -311,6 +316,8 @@ pgpool version 2.6(kala) README
 
    Âбþ¤¹¤ëOS¤ÏÆÃ¤ËÀ©¸Â¤¬¤¢¤ê¤Þ¤»¤ó¡¥°Ê²¼¡¤Æ°ºî¤¬³Îǧ¤µ¤ì¤¿´Ä¶­¤Ç¤¹¡¥
 
+   Vine Linux 3.2 (kernel 2.4.31-0vl1.10)/PostgreSQL 8.1.1
+   Vine Linux 2.6r4 (kernel 2.4.22-0vl2.12)/PostgreSQL 8.1.0
    Vine Linux 2.6r4 (kernel 2.4.22-0vl2.12)/PostgreSQL 8.0.3
    Vine Linux 2.6r4 (kernel 2.4.22-0vl2.12)/PostgreSQL 8.0
    Vine Linux 2.6r4 (kernel 2.4.22-0vl2.12)/PostgreSQL 7.4.5
@@ -466,6 +473,13 @@ pgpool version 2.6(kala) README
    ¤ò»ØÄꤹ¤ë¤ÈÍ­¸ú´ü´Ö¤Ï̵¸Â¤Ë¤Ê¤ê¤Þ¤¹¡¥connection_life_time¤Î¥Ç¥Õ¥©
    ¥ë¥ÈÃͤÏ0¤Ç¤¹¡¥
 
+   child_max_connections
+
+   ³Æpgpool»Ò¥×¥í¥»¥¹¤Ø¤ÎÀܳ²ó¿ô¤¬¤³¤ÎÀßÄêÃͤòͤ¨¤ë¤È¡¢¤½¤Î»Ò¥×¥í¥»
+   ¥¹¤ò½ªÎ»¤·¤Þ¤¹¡£child_life_time¤äconnection_life_time¤¬¸ú¤«¤Ê¤¤¤¯¤é
+   ¤¤Ë»¤·¤¤¥µ¡¼¥Ð¤Ç¡¢PostgreSQL¥Ð¥Ã¥¯¥¨¥ó¥É¤¬ÈîÂç²½¤¹¤ë¤Î¤òËɤ°¤Î¤ËÍ­
+   ¸ú¤Ç¤¹¡£
+
    logdir
 
    pgpool¤Î³Æ¼ï¥í¥°¥Õ¥¡¥¤¥ë¤ò³ÊǼ¤¹¤ë¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¹¡¥¸½ºß¤Î¤È¤³¤í¡¤
@@ -646,6 +660,13 @@ pgpool version 2.6(kala) README
    ¤Æ¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤¬¥¢¥Ü¡¼¥È¾õÂ֤ˤʤꡤ³¤¯INSERT¤Ç¾åµ­¥¨¥é¡¼¤¬½Ð
    ¤Æ¤·¤Þ¤¤¤Þ¤¹¡¥
 
+   ignore_leading_whitespace
+
+   true¤Ê¤é¤Ð¡¢load balance¤ÎºÝ¤ËSQLʸ¹ÔƬ¤Î¶õÇò¤ò̵»ë¤·¤Þ¤¹(Á´³Ñ¥¹
+   ¥Ú¡¼¥¹¤Ï̵»ë¤µ¤ì¤Þ¤»¤ó)¡£¤³¤ì¤Ï¡¢DBI/DBD:Pg¤Î¤è¤¦¤Ë¡¢¾¡¼ê¤Ë¹ÔƬ¤Ë¥Û
+   ¥ï¥¤¥È¥¹¥Ú¡¼¥¹¤òÄɲ乤ë¤è¤¦¤ÊAPI¤ò»È¤¤¡¢¥í¡¼¥É¥Ð¥é¥ó¥¹¤·¤¿¤¤¤È¤­¤Ë
+   Í­¸ú¤Ç¤¹¡£
+
 7. pgpool¤Îµ¯Æ°
 
    pgpool¤òµ¯Æ°¤¹¤ë¤â¤Ã¤È¤â´Êñ¤ÊÊýË¡¤Ï¡¤
index 61972a3a33664721827640c26e1a21387f0abc01..386519138736460822af72f125959e283dd0abc0 100644 (file)
@@ -1,4 +1,4 @@
-# generated automatically by aclocal 1.9 -*- Autoconf -*-
+# generated automatically by aclocal 1.8.5 -*- Autoconf -*-
 
 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
 # Free Software Foundation, Inc.
 # ----------------------------
 # Automake X.Y traces this macro to ensure aclocal.m4 has been
 # generated from the m4 files accompanying Automake X.Y.
-AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"])
+AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.8"])
 
 # AM_SET_CURRENT_AUTOMAKE_VERSION
 # -------------------------------
 # Call AM_AUTOMAKE_VERSION so it can be traced.
 # This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-        [AM_AUTOMAKE_VERSION([1.9])])
+        [AM_AUTOMAKE_VERSION([1.8.5])])
 
 # AM_AUX_DIR_EXPAND
 
@@ -108,7 +108,7 @@ am_aux_dir=`cd $ac_aux_dir && pwd`
 
 # AM_CONDITIONAL                                              -*- Autoconf -*-
 
-# Copyright (C) 1997, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
+# Copyright (C) 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -145,8 +145,8 @@ else
 fi
 AC_CONFIG_COMMANDS_PRE(
 [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
-  AC_MSG_ERROR([[conditional "$1" was never defined.
-Usually this means the macro was only invoked conditionally.]])
+  AC_MSG_ERROR([conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.])
 fi])])
 
 # serial 7                                             -*- Autoconf -*-
@@ -319,8 +319,7 @@ AC_SUBST([AMDEPBACKSLASH])
 
 # Generate code to set up dependency tracking.   -*- Autoconf -*-
 
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
-#   Free Software Foundation, Inc.
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -356,21 +355,27 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
   else
     continue
   fi
-  # Extract the definition of DEPDIR, am__include, and am__quote
-  # from the Makefile without running `make'.
+  grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue
+  # Extract the definition of DEP_FILES from the Makefile without
+  # running `make'.
   DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
   test -z "$DEPDIR" && continue
-  am__include=`sed -n 's/^am__include = //p' < "$mf"`
-  test -z "am__include" && continue
-  am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
   # When using ansi2knr, U may be empty or an underscore; expand it
   U=`sed -n 's/^U = //p' < "$mf"`
-  # Find all dependency output files, they are included files with
-  # $(DEPDIR) in their names.  We invoke sed twice because it is the
-  # simplest approach to changing $(DEPDIR) to its actual value in the
-  # expansion.
-  for file in `sed -n "
-    s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+  test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
+  # We invoke sed twice because it is the simplest approach to
+  # changing $(DEPDIR) to its actual value in the expansion.
+  for file in `sed -n '
+    /^DEP_FILES = .*\\\\$/ {
+      s/^DEP_FILES = //
+      :loop
+       s/\\\\$//
+       p
+       n
+       /\\\\$/ b loop
+      p
+    }
+    /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
        sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
     # Make sure the directory exists.
     test -f "$dirpart/$file" && continue
@@ -425,7 +430,7 @@ AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
 # This macro actually does too much some checks are only needed if
 # your package does certain things.  But this isn't really a big deal.
 
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
 # Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
@@ -501,6 +506,7 @@ AM_MISSING_PROG(AUTOCONF, autoconf)
 AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
 AM_MISSING_PROG(AUTOHEADER, autoheader)
 AM_MISSING_PROG(MAKEINFO, makeinfo)
+AM_MISSING_PROG(AMTAR, tar)
 AM_PROG_INSTALL_SH
 AM_PROG_INSTALL_STRIP
 AC_REQUIRE([AM_PROG_MKDIR_P])dnl
@@ -509,9 +515,7 @@ AC_REQUIRE([AM_PROG_MKDIR_P])dnl
 AC_REQUIRE([AC_PROG_AWK])dnl
 AC_REQUIRE([AC_PROG_MAKE_SET])dnl
 AC_REQUIRE([AM_SET_LEADING_DOT])dnl
-_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
-              [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
-                            [_AM_PROG_TAR([v7])])])
+
 _AM_IF_OPTION([no-dependencies],,
 [AC_PROVIDE_IFELSE([AC_PROG_CC],
                   [_AM_DEPENDENCIES(CC)],
@@ -787,21 +791,13 @@ fi
 # this.)
 AC_DEFUN([AM_PROG_MKDIR_P],
 [if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
-  # We used to keeping the `.' as first argument, in order to
-  # allow $(mkdir_p) to be used without argument.  As in
+  # Keeping the `.' argument allows $(mkdir_p) to be used without
+  # argument.  Indeed, we sometimes output rules like
   #   $(mkdir_p) $(somedir)
-  # where $(somedir) is conditionally defined.  However this is wrong
-  # for two reasons:
-  #  1. if the package is installed by a user who cannot write `.'
-  #     make install will fail,
-  #  2. the above comment should most certainly read
-  #     $(mkdir_p) $(DESTDIR)$(somedir)
-  #     so it does not work when $(somedir) is undefined and
-  #     $(DESTDIR) is not.
-  #  To support the latter case, we have to write
-  #     test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
-  #  so the `.' trick is pointless.
-  mkdir_p='mkdir -p --'
+  # where $(somedir) is conditionally defined.
+  # (`test -n '$(somedir)' && $(mkdir_p) $(somedir)' is a more
+  # expensive solution, as it forces Make to start a sub-shell.)
+  mkdir_p='mkdir -p -- .'
 else
   # On NextStep and OpenStep, the `mkdir' command does not
   # recognize any option.  It will interpret all options as
@@ -967,111 +963,3 @@ fi
 INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Check how to create a tarball.                            -*- Autoconf -*-
-
-# Copyright (C) 2004  Free Software Foundation, Inc.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-# serial 1
-
-
-# _AM_PROG_TAR(FORMAT)
-# --------------------
-# Check how to create a tarball in format FORMAT.
-# FORMAT should be one of `v7', `ustar', or `pax'.
-#
-# Substitute a variable $(am__tar) that is a command
-# writing to stdout a FORMAT-tarball containing the directory
-# $tardir.
-#     tardir=directory && $(am__tar) > result.tar
-#
-# Substitute a variable $(am__untar) that extract such
-# a tarball read from stdin.
-#     $(am__untar) < result.tar
-AC_DEFUN([_AM_PROG_TAR],
-[# Always define AMTAR for backward compatibility.
-AM_MISSING_PROG([AMTAR], [tar])
-m4_if([$1], [v7],
-     [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
-     [m4_case([$1], [ustar],, [pax],,
-              [m4_fatal([Unknown tar format])])
-AC_MSG_CHECKING([how to create a $1 tar archive])
-# Loop over all known methods to create a tar archive until one works.
-_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
-_am_tools=${am_cv_prog_tar_$1-$_am_tools}
-# Do not fold the above two line into one, because Tru64 sh and
-# Solaris sh will not grok spaces in the rhs of `-'.
-for _am_tool in $_am_tools
-do
-  case $_am_tool in
-  gnutar)
-    for _am_tar in tar gnutar gtar;
-    do
-      AM_RUN_LOG([$_am_tar --version]) && break
-    done
-    am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
-    am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
-    am__untar="$_am_tar -xf -"
-    ;;
-  plaintar)
-    # Must skip GNU tar: if it does not support --format= it doesn't create
-    # ustar tarball either.
-    (tar --version) >/dev/null 2>&1 && continue
-    am__tar='tar chf - "$$tardir"'
-    am__tar_='tar chf - "$tardir"'
-    am__untar='tar xf -'
-    ;;
-  pax)
-    am__tar='pax -L -x $1 -w "$$tardir"'
-    am__tar_='pax -L -x $1 -w "$tardir"'
-    am__untar='pax -r'
-    ;;
-  cpio)
-    am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
-    am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
-    am__untar='cpio -i -H $1 -d'
-    ;;
-  none)
-    am__tar=false
-    am__tar_=false
-    am__untar=false
-    ;;
-  esac
-
-  # If the value was cached, stop now.  We just wanted to have am__tar
-  # and am__untar set.
-  test -n "${am_cv_prog_tar_$1}" && break
-
-  # tar/untar a dummy directory, and stop if the command works
-  rm -rf conftest.dir
-  mkdir conftest.dir
-  echo GrepMe > conftest.dir/file
-  AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
-  rm -rf conftest.dir
-  if test -s conftest.tar; then
-    AM_RUN_LOG([$am__untar <conftest.tar])
-    grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
-  fi
-done
-rm -rf conftest.dir
-
-AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
-AC_MSG_RESULT([$am_cv_prog_tar_$1])])
-AC_SUBST([am__tar])
-AC_SUBST([am__untar])
-]) # _AM_PROG_TAR
-
diff --git a/child.c b/child.c
index d375e367744e38148f9f572162f3afaa6c28c4f8..02a1c262c051d83abf5515fef8355b7163c5e0c5 100644 (file)
--- a/child.c
+++ b/child.c
@@ -80,6 +80,8 @@ void do_child(int unix_fd, int inet_fd)
        int child_idle_sec;
        struct timeval timeout;
        static int connected;
+       int connections_count = 0;      /* used if child_max_connections > 0 */
+
 
        pool_debug("I am %d", getpid());
 
@@ -136,7 +138,7 @@ void do_child(int unix_fd, int inet_fd)
                /* perform accept() */
                frontend = do_accept(unix_fd, inet_fd, &timeout);
 
-               if (frontend == NULL)
+               if (frontend == NULL)   /* connection request from frontend timed out */
                {
                        /* check select() timeout */
                        if (connected && pool_config.child_life_time > 0 &&
@@ -354,6 +356,18 @@ void do_child(int unix_fd, int inet_fd)
                timeout.tv_sec = pool_config.child_life_time;
                timeout.tv_usec = 0;
 
+               /* increment queries counter if necessary */
+               if ( pool_config.child_max_connections > 0 )
+                       connections_count++;
+
+               /* check if maximum connections count for this child reached */
+               if ( ( pool_config.child_max_connections > 0 ) &&
+                       ( connections_count >= pool_config.child_max_connections ) )
+               {
+                       pool_log("child exiting, %d connections reached", pool_config.child_max_connections);
+                       send_frontend_exits();
+                       exit(2);
+               }
        }
        exit(0);
 }
index 6f0c69fb8c9a8f0abbe8afdc35e34263986ea402..98a740af95bc84f1fb0626d1dc962d6b61410b70 100755 (executable)
--- a/configure
+++ b/configure
@@ -308,7 +308,7 @@ ac_includes_default="\
 # include <unistd.h>
 #endif"
 
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE LEX LEXLIB LEX_OUTPUT_ROOT CPP EGREP PGSQL_INCLUDE_DIR LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE LEX LEXLIB LEX_OUTPUT_ROOT CPP EGREP PGSQL_INCLUDE_DIR LIBOBJS LTLIBOBJS'
 ac_subst_files=''
 
 # Initialize some variables set by options.
@@ -2231,7 +2231,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
-am__api_version="1.9"
+am__api_version="1.8"
 ac_aux_dir=
 for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
   if test -f $ac_dir/install-sh; then
@@ -2408,21 +2408,13 @@ echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
 fi
 
 if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
-  # We used to keeping the `.' as first argument, in order to
-  # allow $(mkdir_p) to be used without argument.  As in
+  # Keeping the `.' argument allows $(mkdir_p) to be used without
+  # argument.  Indeed, we sometimes output rules like
   #   $(mkdir_p) $(somedir)
-  # where $(somedir) is conditionally defined.  However this is wrong
-  # for two reasons:
-  #  1. if the package is installed by a user who cannot write `.'
-  #     make install will fail,
-  #  2. the above comment should most certainly read
-  #     $(mkdir_p) $(DESTDIR)$(somedir)
-  #     so it does not work when $(somedir) is undefined and
-  #     $(DESTDIR) is not.
-  #  To support the latter case, we have to write
-  #     test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
-  #  so the `.' trick is pointless.
-  mkdir_p='mkdir -p --'
+  # where $(somedir) is conditionally defined.
+  # (`test -n '$(somedir)' && $(mkdir_p) $(somedir)' is a more
+  # expensive solution, as it forces Make to start a sub-shell.)
+  mkdir_p='mkdir -p -- .'
 else
   # On NextStep and OpenStep, the `mkdir' command does not
   # recognize any option.  It will interpret all options as
@@ -2603,7 +2595,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE=pgpool
- VERSION=2.6.5
+ VERSION=2.7
 
 
 cat >>confdefs.h <<_ACEOF
@@ -2631,6 +2623,9 @@ AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
 
 MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
 
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
 install_sh=${install_sh-"$am_aux_dir/install-sh"}
 
 # Installed binaries are usually stripped using `strip' when the user
@@ -2723,13 +2718,6 @@ INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
 
 # We need awk for the "check" target.  The system "awk" is bad on
 # some platforms.
-# Always define AMTAR for backward compatibility.
-
-AMTAR=${AMTAR-"${am_missing_run}tar"}
-
-am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
-
-
 
 
 depcc="$CC"   am_compiler_list=
@@ -5969,6 +5957,7 @@ s,@AUTOCONF@,$AUTOCONF,;t t
 s,@AUTOMAKE@,$AUTOMAKE,;t t
 s,@AUTOHEADER@,$AUTOHEADER,;t t
 s,@MAKEINFO@,$MAKEINFO,;t t
+s,@AMTAR@,$AMTAR,;t t
 s,@install_sh@,$install_sh,;t t
 s,@STRIP@,$STRIP,;t t
 s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t
@@ -5977,9 +5966,6 @@ s,@mkdir_p@,$mkdir_p,;t t
 s,@AWK@,$AWK,;t t
 s,@SET_MAKE@,$SET_MAKE,;t t
 s,@am__leading_dot@,$am__leading_dot,;t t
-s,@AMTAR@,$AMTAR,;t t
-s,@am__tar@,$am__tar,;t t
-s,@am__untar@,$am__untar,;t t
 s,@DEPDIR@,$DEPDIR,;t t
 s,@am__include@,$am__include,;t t
 s,@am__quote@,$am__quote,;t t
@@ -6619,21 +6605,27 @@ echo X"$mf" |
   else
     continue
   fi
-  # Extract the definition of DEPDIR, am__include, and am__quote
-  # from the Makefile without running `make'.
+  grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue
+  # Extract the definition of DEP_FILES from the Makefile without
+  # running `make'.
   DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
   test -z "$DEPDIR" && continue
-  am__include=`sed -n 's/^am__include = //p' < "$mf"`
-  test -z "am__include" && continue
-  am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
   # When using ansi2knr, U may be empty or an underscore; expand it
   U=`sed -n 's/^U = //p' < "$mf"`
-  # Find all dependency output files, they are included files with
-  # $(DEPDIR) in their names.  We invoke sed twice because it is the
-  # simplest approach to changing $(DEPDIR) to its actual value in the
-  # expansion.
-  for file in `sed -n "
-    s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+  test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
+  # We invoke sed twice because it is the simplest approach to
+  # changing $(DEPDIR) to its actual value in the expansion.
+  for file in `sed -n '
+    /^DEP_FILES = .*\\\\$/ {
+      s/^DEP_FILES = //
+      :loop
+       s/\\\\$//
+       p
+       n
+       /\\\\$/ b loop
+      p
+    }
+    /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
        sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
     # Make sure the directory exists.
     test -f "$dirpart/$file" && continue
index f86b1a34e03d2e925ec6dee8b97e65c2049bbb56..e66b08ef1c426c68524859109f510bb33b0aeecf 100644 (file)
@@ -4,7 +4,7 @@ AC_INIT
 dnl Checks for programs.
 AC_PROG_CC
 
-AM_INIT_AUTOMAKE(pgpool, 2.6.5)
+AM_INIT_AUTOMAKE(pgpool, 2.7)
 
 AM_PROG_LEX
 
diff --git a/main.c b/main.c
index 8638118e2a8f4eec1b360a93829ede9ba9348606..e3df9cb2efbb16308e0b384bb175aebd1033a146 100644 (file)
--- a/main.c
+++ b/main.c
@@ -781,7 +781,7 @@ static RETSIGTYPE failover_handler(int sig)
         * if not in replication mode/master slave mode, we treat this a restart request.
         * otherwise we need to check if we have already failovered.
         */
-       if (!pool_config.replication_enabled || !pool_config.master_slave_enabled ||
+       if (pool_config.replication_enabled || pool_config.master_slave_enabled ||
                strcmp(pool_config.current_backend_host_name, pool_config.secondary_backend_host_name) ||
                pool_config.current_backend_port != pool_config.secondary_backend_port)
        {
@@ -807,6 +807,27 @@ static RETSIGTYPE failover_handler(int sig)
                                pool_config.server_status[0] = 2;               /* mark this down */
                        }
                }
+
+               else if (pool_config.master_slave_enabled)
+               {
+                       degenerated = 1;
+
+                       if (sig == SIGUSR2)
+                       {
+                               pool_log("starting degeneration. shutdown slave host %s(%d)",
+                                                pool_config.secondary_backend_host_name,
+                                                pool_config.secondary_backend_port);
+                               pool_config.server_status[1] = 2;               /* mark this down */
+                       }
+                       else
+                       {
+                               pool_log("starting degeneration. shutdown master host %s(%d)",
+                                                pool_config.backend_host_name,
+                                                pool_config.backend_port);
+                               pool_config.server_status[0] = 2;               /* mark this down */
+                       }
+               }
+
                else if (!degenerated && pool_config.secondary_backend_port != 0)
                {
                        pool_log("starting failover from %s(%d) to %s(%d)",
@@ -849,6 +870,19 @@ static RETSIGTYPE failover_handler(int sig)
                                pool_config.current_backend_port = pool_config.secondary_backend_port;
                        }
                }
+
+               else if (pool_config.master_slave_enabled)
+               {
+                       /* disable master/slave mode */
+                       pool_config.master_slave_enabled = 0;
+
+                       if (sig == SIGUSR1)
+                       {
+                               pool_config.current_backend_host_name = pool_config.secondary_backend_host_name;
+                               pool_config.current_backend_port = pool_config.secondary_backend_port;
+                       }
+               }
+
                else if (!degenerated && pool_config.secondary_backend_port != 0)
                {
                        /* fail over to secondary */
index 09798b81f7cf803c15ccac6ceae22e74adf1fc8c..80599775718ba8215d4e87390b57a325333c3d6f 100644 (file)
@@ -42,6 +42,9 @@ child_life_time = 300
 # no timeout
 connection_life_time = 0
 
+# if child_max_connections connections were received, child exits. 0 means no exit.
+child_max_connections = 0
+
 # logging directory
 logdir = '/tmp'
 
@@ -104,3 +107,9 @@ health_check_user = 'nobody'
 # data consistency. /*INSERT LOCK*/ comment has the same effect.
 # /NO INSERT LOCK*/ comment disables the effect.
 insert_lock = false
+
+# if true, ignore leading white spaces of each query while pgpool
+# judges if the query is a SELECT so that it can be load balnced. This
+# is usefull for certain APIs such as DBI/DBD which is know as adding
+# an extra leading white space.
+ignore_leading_white_space = false
diff --git a/pool.h b/pool.h
index feeb3a78109654c14303ef765b6d28d7f909fb61..f254f96af991a1a9825b0c205b127f4af6e6611d 100644 (file)
--- a/pool.h
+++ b/pool.h
@@ -119,6 +119,7 @@ typedef struct {
     int        num_init_children;      /* # of children initially pre-forked */
     int        child_life_time;        /* if idle for this seconds, child exits */
     int        connection_life_time;   /* if idle for this seconds, connection closes */
+    int        child_max_connections;  /* if max_connections received, child exits */
     int        max_pool;       /* max # of connection pool per child */
     char *logdir;              /* logging directory */
     char *backend_socket_dir;  /* Unix domain socket directory for the PostgreSQL server */
@@ -148,6 +149,7 @@ typedef struct {
        char *health_check_user;                /* PostgreSQL user name for health check */
        int insert_lock;        /* if non 0, automatically lock table with INSERT to keep SERIAL
                                                   data consistency */
+       int ignore_leading_white_space;         /* ignore leading white spaces of each query */
        /* followings do not exist in the configuration file */
     char *current_backend_host_name;   /* current backend host name */
     int        current_backend_port;   /* current backend port # */
index be723a3e7c2d8b9568c90fcf515a675dfddcb4cc..67abc23957f725021244bed9c983f683572e00c2 100644 (file)
@@ -1126,6 +1126,7 @@ register char *yy_bp;
 #endif /* ifndef YY_NO_UNPUT */
 
 
+#ifndef YY_NO_INPUT
 #ifdef __cplusplus
 static int yyinput()
 #else
@@ -1197,7 +1198,7 @@ static int input()
 
        return c;
        }
-
+#endif /* YY_NO_INPUT */
 
 #ifdef YY_USE_PROTOS
 void yyrestart( FILE *input_file )
@@ -1649,6 +1650,7 @@ int pool_get_config(char *confpath)
        pool_config.num_init_children = 32;
        pool_config.child_life_time = 300;
        pool_config.connection_life_time = 0;
+       pool_config.child_max_connections = 0;
        pool_config.max_pool = 4;
        pool_config.logdir = DEFAULT_LOGDIR;
 
@@ -1863,6 +1865,17 @@ int pool_get_config(char *confpath)
                        }
                        pool_config.connection_life_time = v;
                }
+               else if (!strcmp(key, "child_max_connections"))
+               {
+                       int v = atoi(yytext);
+
+                       if (token != POOL_INTEGER || v < 0)
+                       {
+                               pool_error("pool_config: %s must be higher than 0 numeric value", key);
+                               return(-1);
+                       }
+                       pool_config.child_max_connections = v;
+               }
                else if (!strcmp(key, "max_pool"))
                {
                        int v = atoi(yytext);
@@ -2117,6 +2130,18 @@ int pool_get_config(char *confpath)
                        }
                        pool_config.insert_lock = v;
                }
+
+               else if (!strcmp(key, "ignore_leading_white_space"))
+               {
+                       int v = eval_logical(yytext);
+
+                       if (v < 0)
+                       {
+                               pool_error("pool_config: invalid value %s for %s", yytext, key);
+                               return(-1);
+                       }
+                       pool_config.ignore_leading_white_space = v;
+               }
        }
 
        if (pool_config.backend_port)
index dde544f816a0af5214b0f2605d1be0feec3a4a13..d8e5bacf5d9723bf35777f339665a1bb2b2df97a 100644 (file)
@@ -112,6 +112,7 @@ int pool_get_config(char *confpath)
        pool_config.num_init_children = 32;
        pool_config.child_life_time = 300;
        pool_config.connection_life_time = 0;
+       pool_config.child_max_connections = 0;
        pool_config.max_pool = 4;
        pool_config.logdir = DEFAULT_LOGDIR;
 
@@ -326,6 +327,17 @@ int pool_get_config(char *confpath)
                        }
                        pool_config.connection_life_time = v;
                }
+               else if (!strcmp(key, "child_max_connections"))
+               {
+                       int v = atoi(yytext);
+
+                       if (token != POOL_INTEGER || v < 0)
+                       {
+                               pool_error("pool_config: %s must be higher than 0 numeric value", key);
+                               return(-1);
+                       }
+                       pool_config.child_max_connections = v;
+               }
                else if (!strcmp(key, "max_pool"))
                {
                        int v = atoi(yytext);
@@ -580,6 +592,18 @@ int pool_get_config(char *confpath)
                        }
                        pool_config.insert_lock = v;
                }
+
+               else if (!strcmp(key, "ignore_leading_white_space"))
+               {
+                       int v = eval_logical(yytext);
+
+                       if (v < 0)
+                       {
+                               pool_error("pool_config: invalid value %s for %s", yytext, key);
+                               return(-1);
+                       }
+                       pool_config.ignore_leading_white_space = v;
+               }
        }
 
        if (pool_config.backend_port)
index 7d6b5fb59b2e99615273f639d28428d9072e6d30..b0f4c9a20fe35f3f05a475f5e5d7609b745ed76d 100644 (file)
@@ -45,6 +45,14 @@ static POOL_STATUS NotificationResponse(POOL_CONNECTION *frontend,
 static POOL_STATUS Query(POOL_CONNECTION *frontend, 
                                                 POOL_CONNECTION_POOL *backend, char *query);
 
+static POOL_STATUS Execute(POOL_CONNECTION *frontend, 
+                                                  POOL_CONNECTION_POOL *backend);
+
+#ifdef NOT_USED
+static POOL_STATUS Sync(POOL_CONNECTION *frontend, 
+                                                  POOL_CONNECTION_POOL *backend);
+#endif
+
 static POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend, 
                                                                 POOL_CONNECTION_POOL *backend, int send_ready);
 
@@ -650,6 +658,123 @@ static POOL_STATUS Query(POOL_CONNECTION *frontend,
        return POOL_CONTINUE;
 }
 
+/*
+ * process EXECUTE (V3 only)
+ */
+static POOL_STATUS Execute(POOL_CONNECTION *frontend, 
+                                                  POOL_CONNECTION_POOL *backend)
+{
+       char *string;           /* portal name + null terminate + max_tobe_returned_rows */
+       int len;
+       int sendlen;
+       int i;
+
+       /* read Execute packet */
+       if (pool_read(frontend, &len, sizeof(len)) < 0)
+               return POOL_END;
+
+       len = ntohl(len) - 4;
+       string = pool_read2(frontend, len);
+
+       pool_debug("Execute: portal name <%s>", string);
+
+       for (i = 0;i < backend->num;i++)
+       {
+               POOL_CONNECTION *cp = backend->slots[i]->con;
+
+               /* forward the query to the backend */
+               pool_write(cp, "E", 1);
+               sendlen = htonl(len + 4);
+               pool_write(cp, &sendlen, sizeof(sendlen));
+               pool_write(cp, string, len);
+
+               /*
+                * send "Flush" message so that backend notices us
+                * the completion of the command
+                */
+               pool_write(cp, "H", 1);
+               sendlen = htonl(4);
+               if (pool_write_and_flush(cp, &sendlen, sizeof(sendlen)) < 0)
+               {
+                       return POOL_END;
+               }
+
+               if (!REPLICATION)
+                       break;
+
+               /*
+                * in "strict mode" we need to wait for backend completing the query.
+                */
+               if (pool_config.replication_strict)
+               {
+                       pool_debug("waiting for backend[%d] completing the query", i);
+                       if (synchronize(cp))
+                               return POOL_END;
+               }
+
+       }
+
+       return POOL_CONTINUE;
+}
+
+#ifdef NOT_USED
+/*
+ * process Sync (V3 only)
+ */
+static POOL_STATUS Sync(POOL_CONNECTION *frontend, 
+                                                  POOL_CONNECTION_POOL *backend)
+{
+       char *string;           /* portal name + null terminate + max_tobe_returned_rows */
+       int len;
+       int sendlen;
+
+       /* read Sync packet */
+       if (pool_read(frontend, &len, sizeof(len)) < 0)
+               return POOL_END;
+
+       len = ntohl(len) - 4;
+       string = pool_read2(frontend, len);
+
+       /* forward the query to the backend */
+       pool_write(MASTER(backend), "S", 1);
+
+       sendlen = htonl(len + 4);
+       pool_write(MASTER(backend), &sendlen, sizeof(sendlen));
+       if (pool_write_and_flush(MASTER(backend), string, len) < 0)
+       {
+               return POOL_END;
+       }
+
+       if (REPLICATION)
+       {
+               /*
+                * in "strict mode" we need to wait for master completing the query.
+                * note that this is not applied if "NO STRICT" is specified as a comment.
+                */
+               if (pool_config.replication_strict)
+               {
+                       pool_debug("waiting for master completing the query");
+                       if (synchronize(MASTER(backend)))
+                               return POOL_END;
+               }
+
+               pool_write(SECONDARY(backend), "S", 1);
+               sendlen = htonl(len + 4);
+               pool_write(SECONDARY(backend), &sendlen, sizeof(sendlen));
+               if (pool_write_and_flush(SECONDARY(backend), string, len) < 0)
+               {
+                       return POOL_END;
+               }
+
+               /* in "strict mode" we need to wait for secondary completing the query */
+               if (pool_config.replication_strict)
+                       if (synchronize(SECONDARY(backend)))
+                               return POOL_END;
+       }
+       return POOL_CONTINUE;
+}
+#endif
+
 static POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend, 
                                                                 POOL_CONNECTION_POOL *backend, int send_ready)
 {
@@ -1513,6 +1638,16 @@ static POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend,
                        status = Query(frontend, backend, NULL);
                        break;
 
+/*
+               case 'S':
+                       status = Sync(frontend, backend);
+                       break;
+*/
+
+               case 'E':
+                       status = Execute(frontend, backend);
+               break;
+
                default:
                        if (MAJOR(backend) == PROTO_MAJOR_V3)
                        {
@@ -1708,6 +1843,11 @@ static void process_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *b
        status[i].desc = "if idle for this seconds, connection closes";
        i++;
 
+       status[i].name = "child_max_connections";
+       snprintf(status[i].value, MAXVALLEN, "%d", pool_config.child_max_connections);
+       status[i].desc = "if max_connections received, chile exits";
+       i++;
+
        status[i].name = "max_pool";
        snprintf(status[i].value, MAXVALLEN, "%d", pool_config.max_pool);
        status[i].desc = "max # of connection pool per child";
@@ -1806,6 +1946,11 @@ static void process_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *b
        status[i].desc = "insert lock";
        i++;
 
+       status[i].name = "ignore_leading_whitespace";
+       snprintf(status[i].value, MAXVALLEN, "%d", pool_config.insert_lock);
+       status[i].desc = "ignore leading white spaces";
+       i++;
+
        status[i].name = "current_backend_host_name";
        snprintf(status[i].value, MAXVALLEN, "%s", pool_config.current_backend_host_name);
        status[i].desc = "current master host name";
@@ -2222,9 +2367,18 @@ static int load_balance_enabled(POOL_CONNECTION_POOL *backend, char *sql)
        if (pool_config.load_balance_mode &&
                DUAL_MODE &&
                MAJOR(backend) == PROTO_MAJOR_V3 &&
-               TSTATE(backend) == 'I' &&
-               !strncasecmp(sql, "SELECT", 6))
-               return 1;
+               TSTATE(backend) == 'I')
+       {
+               if (pool_config.ignore_leading_white_space)
+               {
+                       /* ignore leading white spaces */
+                       while (*sql && isspace(*sql))
+                               sql++;
+               }
+
+               if (!strncasecmp(sql, "SELECT", 6))
+                       return 1;
+       }
        return 0;
 }
 
index f2088ddd092375fa13bd4f0631ea6a39fe8d427b..5d58026dc1817165d8ce59c112c558c9abeba784 100644 (file)
@@ -585,6 +585,14 @@ char *pool_read_string(POOL_CONNECTION *cp, int *len, int line)
                            return NULL;
                        }
                }
+               else if (readlen == 0)  /* EOF detected */
+               {
+                       /*
+                        * just returns an error, not trigger failover or degeneration
+                        */
+                       pool_error("pool_read_string: read () EOF detected");
+                       return NULL;
+               }
 
                /* check overrun */
                if (line)
index a24302a7c21b9cd9bc216790fcae2311a76e931f..76f3c4804304db16315cee72c26a5c093ce3482e 100644 (file)
--- a/version.h
+++ b/version.h
@@ -1 +1 @@
-#define PGPOOLVERSION "kala"
+#define PGPOOLVERSION "kalekale"