prestogres 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +20 -0
- data/LICENSE +202 -0
- data/NOTICE +22 -0
- data/README.md +217 -0
- data/Rakefile +13 -0
- data/VERSION +1 -0
- data/bin/prestogres +254 -0
- data/config/pcp.conf.sample +28 -0
- data/config/pgpool.conf +678 -0
- data/config/pool_hba.conf +84 -0
- data/config/pool_passwd +0 -0
- data/config/postgresql.conf +2 -0
- data/ext/.gitignore +6 -0
- data/ext/depend +26 -0
- data/ext/extconf.rb +4 -0
- data/ext/prestogres_config.c +12 -0
- data/pgpool2/.gitignore +36 -0
- data/pgpool2/AUTHORS +4 -0
- data/pgpool2/COPYING +12 -0
- data/pgpool2/ChangeLog +1 -0
- data/pgpool2/INSTALL +1 -0
- data/pgpool2/Makefile.am +159 -0
- data/pgpool2/Makefile.in +1187 -0
- data/pgpool2/NEWS +4960 -0
- data/pgpool2/README +1 -0
- data/pgpool2/README.euc_jp +1 -0
- data/pgpool2/README.online-recovery +62 -0
- data/pgpool2/TODO +103 -0
- data/pgpool2/ac_func_accept_argtypes.m4 +85 -0
- data/pgpool2/aclocal.m4 +1088 -0
- data/pgpool2/c-compiler.m4 +134 -0
- data/pgpool2/c-library.m4 +325 -0
- data/pgpool2/child.c +2097 -0
- data/pgpool2/config.guess +1532 -0
- data/pgpool2/config.h.in +332 -0
- data/pgpool2/config.sub +1640 -0
- data/pgpool2/configure +15752 -0
- data/pgpool2/configure.in +392 -0
- data/pgpool2/depcomp +522 -0
- data/pgpool2/doc/basebackup.sh +17 -0
- data/pgpool2/doc/pgpool-de.html +4220 -0
- data/pgpool2/doc/pgpool-en.html +5738 -0
- data/pgpool2/doc/pgpool-fr.html +4118 -0
- data/pgpool2/doc/pgpool-ja.css +198 -0
- data/pgpool2/doc/pgpool-ja.html +11279 -0
- data/pgpool2/doc/pgpool-zh_cn.html +4445 -0
- data/pgpool2/doc/pgpool.css +280 -0
- data/pgpool2/doc/pgpool_remote_start +13 -0
- data/pgpool2/doc/recovery.conf.sample +117 -0
- data/pgpool2/doc/tutorial-en.html +707 -0
- data/pgpool2/doc/tutorial-ja.html +422 -0
- data/pgpool2/doc/tutorial-memqcache-en.html +325 -0
- data/pgpool2/doc/tutorial-memqcache-ja.html +370 -0
- data/pgpool2/doc/tutorial-memqcache-zh_cn.html +322 -0
- data/pgpool2/doc/tutorial-watchdog-en.html +306 -0
- data/pgpool2/doc/tutorial-watchdog-ja.html +343 -0
- data/pgpool2/doc/tutorial-watchdog-zh_cn.html +301 -0
- data/pgpool2/doc/tutorial-zh_cn.html +537 -0
- data/pgpool2/doc/watchdog.png +0 -0
- data/pgpool2/doc/wd-en.html +236 -0
- data/pgpool2/doc/wd-en.jpg +0 -0
- data/pgpool2/doc/wd-ja.html +219 -0
- data/pgpool2/doc/wd-ja.jpg +0 -0
- data/pgpool2/doc/wd-zh_cn.html +201 -0
- data/pgpool2/doc/where_to_send_queries.odg +0 -0
- data/pgpool2/doc/where_to_send_queries.pdf +0 -0
- data/pgpool2/general.m4 +166 -0
- data/pgpool2/getopt_long.c +200 -0
- data/pgpool2/getopt_long.h +44 -0
- data/pgpool2/install-sh +251 -0
- data/pgpool2/ltmain.sh +8406 -0
- data/pgpool2/m4/libtool.m4 +7360 -0
- data/pgpool2/m4/ltoptions.m4 +368 -0
- data/pgpool2/m4/ltsugar.m4 +123 -0
- data/pgpool2/m4/ltversion.m4 +23 -0
- data/pgpool2/m4/lt~obsolete.m4 +92 -0
- data/pgpool2/main.c +2971 -0
- data/pgpool2/md5.c +444 -0
- data/pgpool2/md5.h +28 -0
- data/pgpool2/missing +360 -0
- data/pgpool2/mkinstalldirs +40 -0
- data/pgpool2/parser/Makefile.am +50 -0
- data/pgpool2/parser/Makefile.in +559 -0
- data/pgpool2/parser/copyfuncs.c +3310 -0
- data/pgpool2/parser/gram.c +39100 -0
- data/pgpool2/parser/gram.h +940 -0
- data/pgpool2/parser/gram.y +13408 -0
- data/pgpool2/parser/gramparse.h +74 -0
- data/pgpool2/parser/keywords.c +32 -0
- data/pgpool2/parser/keywords.h +39 -0
- data/pgpool2/parser/kwlist.h +425 -0
- data/pgpool2/parser/kwlookup.c +88 -0
- data/pgpool2/parser/list.c +1156 -0
- data/pgpool2/parser/makefuncs.c +518 -0
- data/pgpool2/parser/makefuncs.h +83 -0
- data/pgpool2/parser/memnodes.h +79 -0
- data/pgpool2/parser/nodes.c +29 -0
- data/pgpool2/parser/nodes.h +609 -0
- data/pgpool2/parser/outfuncs.c +5790 -0
- data/pgpool2/parser/parsenodes.h +2615 -0
- data/pgpool2/parser/parser.c +262 -0
- data/pgpool2/parser/parser.h +46 -0
- data/pgpool2/parser/pg_class.h +158 -0
- data/pgpool2/parser/pg_config_manual.h +273 -0
- data/pgpool2/parser/pg_list.h +352 -0
- data/pgpool2/parser/pg_trigger.h +147 -0
- data/pgpool2/parser/pg_wchar.h +492 -0
- data/pgpool2/parser/pool_memory.c +342 -0
- data/pgpool2/parser/pool_memory.h +77 -0
- data/pgpool2/parser/pool_parser.h +222 -0
- data/pgpool2/parser/pool_string.c +121 -0
- data/pgpool2/parser/pool_string.h +37 -0
- data/pgpool2/parser/primnodes.h +1280 -0
- data/pgpool2/parser/scan.c +4094 -0
- data/pgpool2/parser/scan.l +1451 -0
- data/pgpool2/parser/scanner.h +120 -0
- data/pgpool2/parser/scansup.c +221 -0
- data/pgpool2/parser/scansup.h +28 -0
- data/pgpool2/parser/snprintf.c +1102 -0
- data/pgpool2/parser/stringinfo.c +294 -0
- data/pgpool2/parser/stringinfo.h +178 -0
- data/pgpool2/parser/value.c +78 -0
- data/pgpool2/parser/value.h +62 -0
- data/pgpool2/parser/wchar.c +2048 -0
- data/pgpool2/pcp.conf.sample +28 -0
- data/pgpool2/pcp/Makefile.am +40 -0
- data/pgpool2/pcp/Makefile.in +771 -0
- data/pgpool2/pcp/libpcp_ext.h +250 -0
- data/pgpool2/pcp/md5.c +444 -0
- data/pgpool2/pcp/md5.h +28 -0
- data/pgpool2/pcp/pcp.c +1652 -0
- data/pgpool2/pcp/pcp.h +61 -0
- data/pgpool2/pcp/pcp_attach_node.c +172 -0
- data/pgpool2/pcp/pcp_detach_node.c +185 -0
- data/pgpool2/pcp/pcp_error.c +87 -0
- data/pgpool2/pcp/pcp_node_count.c +160 -0
- data/pgpool2/pcp/pcp_node_info.c +198 -0
- data/pgpool2/pcp/pcp_pool_status.c +166 -0
- data/pgpool2/pcp/pcp_proc_count.c +166 -0
- data/pgpool2/pcp/pcp_proc_info.c +261 -0
- data/pgpool2/pcp/pcp_promote_node.c +185 -0
- data/pgpool2/pcp/pcp_recovery_node.c +172 -0
- data/pgpool2/pcp/pcp_stop_pgpool.c +179 -0
- data/pgpool2/pcp/pcp_stream.c +385 -0
- data/pgpool2/pcp/pcp_stream.h +52 -0
- data/pgpool2/pcp/pcp_systemdb_info.c +194 -0
- data/pgpool2/pcp/pcp_watchdog_info.c +211 -0
- data/pgpool2/pcp_child.c +1493 -0
- data/pgpool2/pg_md5.c +305 -0
- data/pgpool2/pgpool.8.in +121 -0
- data/pgpool2/pgpool.conf +553 -0
- data/pgpool2/pgpool.conf.sample +666 -0
- data/pgpool2/pgpool.conf.sample-master-slave +665 -0
- data/pgpool2/pgpool.conf.sample-replication +664 -0
- data/pgpool2/pgpool.conf.sample-stream +664 -0
- data/pgpool2/pgpool.spec +264 -0
- data/pgpool2/pgpool_adm/TODO +7 -0
- data/pgpool2/pgpool_adm/pgpool_adm--1.0.sql +85 -0
- data/pgpool2/pgpool_adm/pgpool_adm.c +558 -0
- data/pgpool2/pgpool_adm/pgpool_adm.control +5 -0
- data/pgpool2/pgpool_adm/pgpool_adm.h +46 -0
- data/pgpool2/pgpool_adm/pgpool_adm.sql.in +85 -0
- data/pgpool2/pool.h +655 -0
- data/pgpool2/pool_auth.c +1390 -0
- data/pgpool2/pool_config.c +5007 -0
- data/pgpool2/pool_config.h +284 -0
- data/pgpool2/pool_config.l +3281 -0
- data/pgpool2/pool_config_md5.c +29 -0
- data/pgpool2/pool_connection_pool.c +812 -0
- data/pgpool2/pool_error.c +242 -0
- data/pgpool2/pool_globals.c +27 -0
- data/pgpool2/pool_hba.c +1723 -0
- data/pgpool2/pool_hba.conf.sample +67 -0
- data/pgpool2/pool_ip.c +567 -0
- data/pgpool2/pool_ip.h +65 -0
- data/pgpool2/pool_ipc.h +38 -0
- data/pgpool2/pool_lobj.c +242 -0
- data/pgpool2/pool_lobj.h +32 -0
- data/pgpool2/pool_memqcache.c +3818 -0
- data/pgpool2/pool_memqcache.h +268 -0
- data/pgpool2/pool_params.c +163 -0
- data/pgpool2/pool_passwd.c +249 -0
- data/pgpool2/pool_passwd.h +41 -0
- data/pgpool2/pool_path.c +193 -0
- data/pgpool2/pool_path.h +81 -0
- data/pgpool2/pool_process_context.c +247 -0
- data/pgpool2/pool_process_context.h +62 -0
- data/pgpool2/pool_process_query.c +5001 -0
- data/pgpool2/pool_process_reporting.c +1671 -0
- data/pgpool2/pool_process_reporting.h +44 -0
- data/pgpool2/pool_proto2.c +671 -0
- data/pgpool2/pool_proto_modules.c +3524 -0
- data/pgpool2/pool_proto_modules.h +185 -0
- data/pgpool2/pool_query_cache.c +1020 -0
- data/pgpool2/pool_query_context.c +1871 -0
- data/pgpool2/pool_query_context.h +105 -0
- data/pgpool2/pool_relcache.c +284 -0
- data/pgpool2/pool_relcache.h +78 -0
- data/pgpool2/pool_rewrite_outfuncs.c +9060 -0
- data/pgpool2/pool_rewrite_query.c +715 -0
- data/pgpool2/pool_rewrite_query.h +192 -0
- data/pgpool2/pool_select_walker.c +1150 -0
- data/pgpool2/pool_select_walker.h +68 -0
- data/pgpool2/pool_sema.c +161 -0
- data/pgpool2/pool_session_context.c +952 -0
- data/pgpool2/pool_session_context.h +203 -0
- data/pgpool2/pool_shmem.c +185 -0
- data/pgpool2/pool_signal.c +158 -0
- data/pgpool2/pool_signal.h +61 -0
- data/pgpool2/pool_ssl.c +339 -0
- data/pgpool2/pool_stream.c +962 -0
- data/pgpool2/pool_stream.h +61 -0
- data/pgpool2/pool_system.c +659 -0
- data/pgpool2/pool_timestamp.c +1215 -0
- data/pgpool2/pool_timestamp.h +38 -0
- data/pgpool2/pool_type.h +171 -0
- data/pgpool2/pool_worker_child.c +384 -0
- data/pgpool2/ps_status.c +404 -0
- data/pgpool2/recovery.c +435 -0
- data/pgpool2/redhat/pgpool.conf.sample.patch +52 -0
- data/pgpool2/redhat/pgpool.init +201 -0
- data/pgpool2/redhat/pgpool.sysconfig +7 -0
- data/pgpool2/redhat/rpm_installer/basebackup-replication.sh +53 -0
- data/pgpool2/redhat/rpm_installer/basebackup-stream.sh +55 -0
- data/pgpool2/redhat/rpm_installer/config_for_script +17 -0
- data/pgpool2/redhat/rpm_installer/failover.sh +64 -0
- data/pgpool2/redhat/rpm_installer/getsources.sh +141 -0
- data/pgpool2/redhat/rpm_installer/install.sh +1363 -0
- data/pgpool2/redhat/rpm_installer/pgpool_recovery_pitr +47 -0
- data/pgpool2/redhat/rpm_installer/pgpool_remote_start +15 -0
- data/pgpool2/redhat/rpm_installer/recovery.conf +4 -0
- data/pgpool2/redhat/rpm_installer/uninstall.sh +57 -0
- data/pgpool2/sample/dist_def_pgbench.sql +73 -0
- data/pgpool2/sample/pgpool.pam +3 -0
- data/pgpool2/sample/pgpool_recovery +20 -0
- data/pgpool2/sample/pgpool_recovery_pitr +19 -0
- data/pgpool2/sample/pgpool_remote_start +13 -0
- data/pgpool2/sample/replicate_def_pgbench.sql +18 -0
- data/pgpool2/sql/insert_lock.sql +15 -0
- data/pgpool2/sql/pgpool-recovery/pgpool-recovery.c +280 -0
- data/pgpool2/sql/pgpool-recovery/pgpool-recovery.sql.in +19 -0
- data/pgpool2/sql/pgpool-recovery/pgpool_recovery--1.0.sql +24 -0
- data/pgpool2/sql/pgpool-recovery/pgpool_recovery.control +5 -0
- data/pgpool2/sql/pgpool-recovery/uninstall_pgpool-recovery.sql +3 -0
- data/pgpool2/sql/pgpool-regclass/pgpool-regclass.c +206 -0
- data/pgpool2/sql/pgpool-regclass/pgpool-regclass.sql.in +4 -0
- data/pgpool2/sql/pgpool-regclass/pgpool_regclass--1.0.sql +7 -0
- data/pgpool2/sql/pgpool-regclass/pgpool_regclass.control +5 -0
- data/pgpool2/sql/pgpool-regclass/uninstall_pgpool-regclass.sql +1 -0
- data/pgpool2/sql/system_db.sql +38 -0
- data/pgpool2/strlcpy.c +85 -0
- data/pgpool2/test/C/test_extended.c +98 -0
- data/pgpool2/test/jdbc/.cvsignore +2 -0
- data/pgpool2/test/jdbc/AutoCommitTest.java +45 -0
- data/pgpool2/test/jdbc/BatchTest.java +55 -0
- data/pgpool2/test/jdbc/ColumnTest.java +60 -0
- data/pgpool2/test/jdbc/CreateTempTableTest.java +48 -0
- data/pgpool2/test/jdbc/InsertTest.java +34 -0
- data/pgpool2/test/jdbc/LockTest.java +36 -0
- data/pgpool2/test/jdbc/PgpoolTest.java +75 -0
- data/pgpool2/test/jdbc/README.euc_jp +73 -0
- data/pgpool2/test/jdbc/RunTest.java +83 -0
- data/pgpool2/test/jdbc/SelectTest.java +37 -0
- data/pgpool2/test/jdbc/UpdateTest.java +32 -0
- data/pgpool2/test/jdbc/expected/CreateTempTable +1 -0
- data/pgpool2/test/jdbc/expected/autocommit +10 -0
- data/pgpool2/test/jdbc/expected/batch +1 -0
- data/pgpool2/test/jdbc/expected/column +100 -0
- data/pgpool2/test/jdbc/expected/insert +1 -0
- data/pgpool2/test/jdbc/expected/lock +100 -0
- data/pgpool2/test/jdbc/expected/select +2 -0
- data/pgpool2/test/jdbc/expected/update +1 -0
- data/pgpool2/test/jdbc/pgpool.properties +7 -0
- data/pgpool2/test/jdbc/prepare.sql +54 -0
- data/pgpool2/test/jdbc/run.sh +6 -0
- data/pgpool2/test/parser/.cvsignore +6 -0
- data/pgpool2/test/parser/README +32 -0
- data/pgpool2/test/parser/expected/copy.out +17 -0
- data/pgpool2/test/parser/expected/create.out +64 -0
- data/pgpool2/test/parser/expected/cursor.out +37 -0
- data/pgpool2/test/parser/expected/delete.out +10 -0
- data/pgpool2/test/parser/expected/drop.out +12 -0
- data/pgpool2/test/parser/expected/insert.out +13 -0
- data/pgpool2/test/parser/expected/misc.out +28 -0
- data/pgpool2/test/parser/expected/prepare.out +4 -0
- data/pgpool2/test/parser/expected/privileges.out +31 -0
- data/pgpool2/test/parser/expected/scanner.out +30 -0
- data/pgpool2/test/parser/expected/select.out +89 -0
- data/pgpool2/test/parser/expected/transaction.out +38 -0
- data/pgpool2/test/parser/expected/update.out +11 -0
- data/pgpool2/test/parser/expected/v84.out +37 -0
- data/pgpool2/test/parser/expected/v90.out +25 -0
- data/pgpool2/test/parser/expected/var.out +22 -0
- data/pgpool2/test/parser/input/alter.sql +2 -0
- data/pgpool2/test/parser/input/copy.sql +17 -0
- data/pgpool2/test/parser/input/create.sql +64 -0
- data/pgpool2/test/parser/input/cursor.sql +37 -0
- data/pgpool2/test/parser/input/delete.sql +10 -0
- data/pgpool2/test/parser/input/drop.sql +12 -0
- data/pgpool2/test/parser/input/insert.sql +13 -0
- data/pgpool2/test/parser/input/misc.sql +28 -0
- data/pgpool2/test/parser/input/prepare.sql +4 -0
- data/pgpool2/test/parser/input/privileges.sql +31 -0
- data/pgpool2/test/parser/input/scanner.sql +34 -0
- data/pgpool2/test/parser/input/select.sql +89 -0
- data/pgpool2/test/parser/input/transaction.sql +38 -0
- data/pgpool2/test/parser/input/update.sql +11 -0
- data/pgpool2/test/parser/input/v84.sql +37 -0
- data/pgpool2/test/parser/input/v90.sql +38 -0
- data/pgpool2/test/parser/input/var.sql +22 -0
- data/pgpool2/test/parser/main.c +96 -0
- data/pgpool2/test/parser/parse_schedule +16 -0
- data/pgpool2/test/parser/pool.h +13 -0
- data/pgpool2/test/parser/run-test +62 -0
- data/pgpool2/test/pdo-test/README.euc_jp +58 -0
- data/pgpool2/test/pdo-test/SQLlist/test1.sql +3 -0
- data/pgpool2/test/pdo-test/SQLlist/test2.sql +3 -0
- data/pgpool2/test/pdo-test/collections.inc +11 -0
- data/pgpool2/test/pdo-test/def.inc +7 -0
- data/pgpool2/test/pdo-test/log.txt +0 -0
- data/pgpool2/test/pdo-test/mod/database.inc +36 -0
- data/pgpool2/test/pdo-test/mod/def.inc +0 -0
- data/pgpool2/test/pdo-test/mod/errorhandler.inc +27 -0
- data/pgpool2/test/pdo-test/pdotest.php +11 -0
- data/pgpool2/test/pdo-test/regsql.inc +56 -0
- data/pgpool2/test/pgpool_setup +898 -0
- data/pgpool2/test/regression/README +39 -0
- data/pgpool2/test/regression/clean.sh +21 -0
- data/pgpool2/test/regression/libs.sh +16 -0
- data/pgpool2/test/regression/regress.sh +166 -0
- data/pgpool2/test/regression/tests/001.load_balance/test.sh +128 -0
- data/pgpool2/test/regression/tests/002.native_replication/PgTester.java +47 -0
- data/pgpool2/test/regression/tests/002.native_replication/create.sql +6 -0
- data/pgpool2/test/regression/tests/002.native_replication/test.sh +71 -0
- data/pgpool2/test/regression/tests/003.failover/expected.r +6 -0
- data/pgpool2/test/regression/tests/003.failover/expected.s +6 -0
- data/pgpool2/test/regression/tests/003.failover/test.sh +45 -0
- data/pgpool2/test/regression/tests/004.watchdog/master.conf +12 -0
- data/pgpool2/test/regression/tests/004.watchdog/standby.conf +19 -0
- data/pgpool2/test/regression/tests/004.watchdog/test.sh +52 -0
- data/pgpool2/test/regression/tests/050.bug58/test.sh +50 -0
- data/pgpool2/test/regression/tests/051.bug60/bug.sql +12 -0
- data/pgpool2/test/regression/tests/051.bug60/database-clean.sql +6 -0
- data/pgpool2/test/regression/tests/051.bug60/database-setup.sql +28 -0
- data/pgpool2/test/regression/tests/051.bug60/test.sh +79 -0
- data/pgpool2/test/regression/tests/052.do_query/test.sh +44 -0
- data/pgpool2/test/regression/tests/053.insert_lock_hangs/test.sh +81 -0
- data/pgpool2/test/regression/tests/054.postgres_fdw/test.sh +67 -0
- data/pgpool2/test/regression/tests/055.backend_all_down/test.sh +52 -0
- data/pgpool2/test/regression/tests/056.bug63/jdbctest2.java +66 -0
- data/pgpool2/test/regression/tests/056.bug63/test.sh +47 -0
- data/pgpool2/test/regression/tests/057.bug61/test.sh +40 -0
- data/pgpool2/test/regression/tests/058.bug68/jdbctest3.java +45 -0
- data/pgpool2/test/regression/tests/058.bug68/test.sh +47 -0
- data/pgpool2/test/timestamp/expected/insert.out +16 -0
- data/pgpool2/test/timestamp/expected/misc.out +3 -0
- data/pgpool2/test/timestamp/expected/update.out +6 -0
- data/pgpool2/test/timestamp/input/insert.sql +16 -0
- data/pgpool2/test/timestamp/input/misc.sql +3 -0
- data/pgpool2/test/timestamp/input/update.sql +6 -0
- data/pgpool2/test/timestamp/main.c +129 -0
- data/pgpool2/test/timestamp/parse_schedule +3 -0
- data/pgpool2/test/timestamp/run-test +69 -0
- data/pgpool2/version.h +1 -0
- data/pgpool2/watchdog/Makefile.am +17 -0
- data/pgpool2/watchdog/Makefile.in +505 -0
- data/pgpool2/watchdog/test/stab.c +266 -0
- data/pgpool2/watchdog/test/test.c +85 -0
- data/pgpool2/watchdog/test/wd_child_t.c +87 -0
- data/pgpool2/watchdog/test/wd_lifecheck_t.c +87 -0
- data/pgpool2/watchdog/test/wd_packet_t.c +87 -0
- data/pgpool2/watchdog/test/wd_ping_t.c +20 -0
- data/pgpool2/watchdog/watchdog.c +408 -0
- data/pgpool2/watchdog/watchdog.h +209 -0
- data/pgpool2/watchdog/wd_child.c +444 -0
- data/pgpool2/watchdog/wd_ext.h +123 -0
- data/pgpool2/watchdog/wd_heartbeat.c +577 -0
- data/pgpool2/watchdog/wd_if.c +216 -0
- data/pgpool2/watchdog/wd_init.c +126 -0
- data/pgpool2/watchdog/wd_interlock.c +347 -0
- data/pgpool2/watchdog/wd_lifecheck.c +512 -0
- data/pgpool2/watchdog/wd_list.c +429 -0
- data/pgpool2/watchdog/wd_packet.c +1159 -0
- data/pgpool2/watchdog/wd_ping.c +330 -0
- data/pgpool2/ylwrap +223 -0
- data/pgsql/presto_client.py +346 -0
- data/pgsql/prestogres.py +156 -0
- data/pgsql/setup_functions.sql +21 -0
- data/pgsql/setup_language.sql +3 -0
- data/prestogres.gemspec +23 -0
- metadata +496 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/* -*-pgsql-c-*- */
|
|
2
|
+
/*
|
|
3
|
+
*
|
|
4
|
+
* $Header$
|
|
5
|
+
*
|
|
6
|
+
* pgpool: a language independent connection pool server for PostgreSQL
|
|
7
|
+
* written by Tatsuo Ishii
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2003-2010 PgPool Global Development Group
|
|
10
|
+
*
|
|
11
|
+
* Permission to use, copy, modify, and distribute this software and
|
|
12
|
+
* its documentation for any purpose and without fee is hereby
|
|
13
|
+
* granted, provided that the above copyright notice appear in all
|
|
14
|
+
* copies and that both that copyright notice and this permission
|
|
15
|
+
* notice appear in supporting documentation, and that the name of the
|
|
16
|
+
* author not be used in advertising or publicity pertaining to
|
|
17
|
+
* distribution of the software without specific, written prior
|
|
18
|
+
* permission. The author makes no representations about the
|
|
19
|
+
* suitability of this software for any purpose. It is provided "as
|
|
20
|
+
* is" without express or implied warranty.
|
|
21
|
+
*
|
|
22
|
+
* pool_config_md5.c: Stub file to import pool_config.c.
|
|
23
|
+
* This file is intended to be linked against pg_md5. Thus
|
|
24
|
+
* it needs not to use shared memory staffs.
|
|
25
|
+
*
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
#define POOL_PRIVATE
|
|
29
|
+
#include "pool_config.c"
|
|
@@ -0,0 +1,812 @@
|
|
|
1
|
+
/* -*-pgsql-c-*- */
|
|
2
|
+
/*
|
|
3
|
+
* $Header$
|
|
4
|
+
*
|
|
5
|
+
* pgpool: a language independent connection pool server for PostgreSQL
|
|
6
|
+
* written by Tatsuo Ishii
|
|
7
|
+
*
|
|
8
|
+
* Copyright (c) 2003-2013 PgPool Global Development Group
|
|
9
|
+
*
|
|
10
|
+
* Permission to use, copy, modify, and distribute this software and
|
|
11
|
+
* its documentation for any purpose and without fee is hereby
|
|
12
|
+
* granted, provided that the above copyright notice appear in all
|
|
13
|
+
* copies and that both that copyright notice and this permission
|
|
14
|
+
* notice appear in supporting documentation, and that the name of the
|
|
15
|
+
* author not be used in advertising or publicity pertaining to
|
|
16
|
+
* distribution of the software without specific, written prior
|
|
17
|
+
* permission. The author makes no representations about the
|
|
18
|
+
* suitability of this software for any purpose. It is provided "as
|
|
19
|
+
* is" without express or implied warranty.
|
|
20
|
+
*
|
|
21
|
+
* poo_connection_pool.c: connection pool stuff
|
|
22
|
+
*/
|
|
23
|
+
#include "config.h"
|
|
24
|
+
|
|
25
|
+
#include <sys/types.h>
|
|
26
|
+
#include <sys/time.h>
|
|
27
|
+
#include <sys/socket.h>
|
|
28
|
+
#include <netinet/in.h>
|
|
29
|
+
#include <sys/un.h>
|
|
30
|
+
#ifdef HAVE_SYS_SELECT_H
|
|
31
|
+
#include <sys/select.h>
|
|
32
|
+
#endif
|
|
33
|
+
#ifdef HAVE_NETINET_TCP_H
|
|
34
|
+
#include <netinet/tcp.h>
|
|
35
|
+
#endif
|
|
36
|
+
#include <netdb.h>
|
|
37
|
+
|
|
38
|
+
#include <stdio.h>
|
|
39
|
+
#include <errno.h>
|
|
40
|
+
#include <signal.h>
|
|
41
|
+
#include <string.h>
|
|
42
|
+
#include <unistd.h>
|
|
43
|
+
#include <stdlib.h>
|
|
44
|
+
|
|
45
|
+
#include "pool.h"
|
|
46
|
+
#include "pool_stream.h"
|
|
47
|
+
#include "pool_config.h"
|
|
48
|
+
#include "pool_process_context.h"
|
|
49
|
+
|
|
50
|
+
static int pool_index; /* Active pool index */
|
|
51
|
+
POOL_CONNECTION_POOL *pool_connection_pool; /* connection pool */
|
|
52
|
+
volatile sig_atomic_t backend_timer_expired = 0; /* flag for connection closed timer is expired */
|
|
53
|
+
volatile sig_atomic_t health_check_timer_expired; /* non 0 if health check timer expired */
|
|
54
|
+
static POOL_CONNECTION_POOL_SLOT *create_cp(POOL_CONNECTION_POOL_SLOT *cp, int slot);
|
|
55
|
+
static POOL_CONNECTION_POOL *new_connection(POOL_CONNECTION_POOL *p);
|
|
56
|
+
static int check_socket_status(int fd);
|
|
57
|
+
|
|
58
|
+
/*
|
|
59
|
+
* initialize connection pools. this should be called once at the startup.
|
|
60
|
+
*/
|
|
61
|
+
int pool_init_cp(void)
|
|
62
|
+
{
|
|
63
|
+
int i;
|
|
64
|
+
|
|
65
|
+
pool_connection_pool = (POOL_CONNECTION_POOL *)malloc(sizeof(POOL_CONNECTION_POOL)*pool_config->max_pool);
|
|
66
|
+
if (pool_connection_pool == NULL)
|
|
67
|
+
{
|
|
68
|
+
pool_error("pool_init_cp: malloc() failed");
|
|
69
|
+
return -1;
|
|
70
|
+
}
|
|
71
|
+
memset(pool_connection_pool, 0, sizeof(POOL_CONNECTION_POOL)*pool_config->max_pool);
|
|
72
|
+
|
|
73
|
+
for (i = 0; i < pool_config->max_pool; i++)
|
|
74
|
+
{
|
|
75
|
+
pool_connection_pool[i].info = pool_coninfo(pool_get_process_context()->proc_id, i, 0);
|
|
76
|
+
memset(pool_connection_pool[i].info, 0, sizeof(ConnectionInfo) * MAX_NUM_BACKENDS);
|
|
77
|
+
}
|
|
78
|
+
return 0;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/*
|
|
82
|
+
* find connection by user and database
|
|
83
|
+
*/
|
|
84
|
+
POOL_CONNECTION_POOL *pool_get_cp(char *user, char *database, int protoMajor, int check_socket)
|
|
85
|
+
{
|
|
86
|
+
#ifdef HAVE_SIGPROCMASK
|
|
87
|
+
sigset_t oldmask;
|
|
88
|
+
#else
|
|
89
|
+
int oldmask;
|
|
90
|
+
#endif
|
|
91
|
+
|
|
92
|
+
int i, freed = 0;
|
|
93
|
+
ConnectionInfo *info;
|
|
94
|
+
|
|
95
|
+
POOL_CONNECTION_POOL *p = pool_connection_pool;
|
|
96
|
+
|
|
97
|
+
if (p == NULL)
|
|
98
|
+
{
|
|
99
|
+
pool_error("pool_get_cp: pool_connection_pool is not initialized");
|
|
100
|
+
return NULL;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
POOL_SETMASK2(&BlockSig, &oldmask);
|
|
104
|
+
|
|
105
|
+
for (i=0;i<pool_config->max_pool;i++)
|
|
106
|
+
{
|
|
107
|
+
if (MASTER_CONNECTION(p) &&
|
|
108
|
+
MASTER_CONNECTION(p)->sp &&
|
|
109
|
+
MASTER_CONNECTION(p)->sp->major == protoMajor &&
|
|
110
|
+
MASTER_CONNECTION(p)->sp->user != NULL &&
|
|
111
|
+
strcmp(MASTER_CONNECTION(p)->sp->user, user) == 0 &&
|
|
112
|
+
strcmp(MASTER_CONNECTION(p)->sp->database, database) == 0)
|
|
113
|
+
{
|
|
114
|
+
int sock_broken = 0;
|
|
115
|
+
int j;
|
|
116
|
+
|
|
117
|
+
/* mark this connection is under use */
|
|
118
|
+
MASTER_CONNECTION(p)->closetime = 0;
|
|
119
|
+
for (j=0;j<NUM_BACKENDS;j++)
|
|
120
|
+
{
|
|
121
|
+
p->info[j].counter++;
|
|
122
|
+
}
|
|
123
|
+
POOL_SETMASK(&oldmask);
|
|
124
|
+
|
|
125
|
+
if (check_socket)
|
|
126
|
+
{
|
|
127
|
+
for (j=0;j<NUM_BACKENDS;j++)
|
|
128
|
+
{
|
|
129
|
+
if (!VALID_BACKEND(j))
|
|
130
|
+
continue;
|
|
131
|
+
|
|
132
|
+
if (CONNECTION_SLOT(p, j))
|
|
133
|
+
{
|
|
134
|
+
sock_broken = check_socket_status(CONNECTION(p, j)->fd);
|
|
135
|
+
if (sock_broken < 0)
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
else
|
|
139
|
+
{
|
|
140
|
+
sock_broken = -1;
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (sock_broken < 0)
|
|
146
|
+
{
|
|
147
|
+
pool_log("connection closed. retry to create new connection pool.");
|
|
148
|
+
for (j=0;j<NUM_BACKENDS;j++)
|
|
149
|
+
{
|
|
150
|
+
if (!VALID_BACKEND(j) || (CONNECTION_SLOT(p, j) == NULL))
|
|
151
|
+
continue;
|
|
152
|
+
|
|
153
|
+
if (!freed)
|
|
154
|
+
{
|
|
155
|
+
pool_free_startup_packet(CONNECTION_SLOT(p, j)->sp);
|
|
156
|
+
freed = 1;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
pool_close(CONNECTION(p, j));
|
|
160
|
+
free(CONNECTION_SLOT(p, j));
|
|
161
|
+
}
|
|
162
|
+
info = p->info;
|
|
163
|
+
memset(p, 0, sizeof(POOL_CONNECTION_POOL_SLOT));
|
|
164
|
+
p->info = info;
|
|
165
|
+
memset(p->info, 0, sizeof(ConnectionInfo) * MAX_NUM_BACKENDS);
|
|
166
|
+
POOL_SETMASK(&oldmask);
|
|
167
|
+
return NULL;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
POOL_SETMASK(&oldmask);
|
|
171
|
+
pool_index = i;
|
|
172
|
+
return p;
|
|
173
|
+
}
|
|
174
|
+
p++;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
POOL_SETMASK(&oldmask);
|
|
178
|
+
return NULL;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/*
|
|
182
|
+
* disconnect and release a connection to the database
|
|
183
|
+
*/
|
|
184
|
+
void pool_discard_cp(char *user, char *database, int protoMajor)
|
|
185
|
+
{
|
|
186
|
+
POOL_CONNECTION_POOL *p = pool_get_cp(user, database, protoMajor, 0);
|
|
187
|
+
ConnectionInfo *info;
|
|
188
|
+
int i, freed = 0;
|
|
189
|
+
|
|
190
|
+
if (p == NULL)
|
|
191
|
+
{
|
|
192
|
+
pool_error("pool_discard_cp: cannot get connection pool for user %s database %s", user, database);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
for (i=0;i<NUM_BACKENDS;i++)
|
|
197
|
+
{
|
|
198
|
+
if (!VALID_BACKEND(i))
|
|
199
|
+
continue;
|
|
200
|
+
|
|
201
|
+
if (!freed)
|
|
202
|
+
{
|
|
203
|
+
pool_free_startup_packet(CONNECTION_SLOT(p, i)->sp);
|
|
204
|
+
freed = 1;
|
|
205
|
+
}
|
|
206
|
+
pool_close(CONNECTION(p, i));
|
|
207
|
+
free(CONNECTION_SLOT(p, i));
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
info = p->info;
|
|
211
|
+
memset(p, 0, sizeof(POOL_CONNECTION_POOL));
|
|
212
|
+
p->info = info;
|
|
213
|
+
memset(p->info, 0, sizeof(ConnectionInfo) * MAX_NUM_BACKENDS);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
/*
|
|
218
|
+
* create a connection pool by user and database
|
|
219
|
+
*/
|
|
220
|
+
POOL_CONNECTION_POOL *pool_create_cp(void)
|
|
221
|
+
{
|
|
222
|
+
int i, freed = 0;
|
|
223
|
+
time_t closetime;
|
|
224
|
+
POOL_CONNECTION_POOL *oldestp;
|
|
225
|
+
POOL_CONNECTION_POOL *ret;
|
|
226
|
+
ConnectionInfo *info;
|
|
227
|
+
|
|
228
|
+
POOL_CONNECTION_POOL *p = pool_connection_pool;
|
|
229
|
+
|
|
230
|
+
if (p == NULL)
|
|
231
|
+
{
|
|
232
|
+
pool_error("pool_create_cp: pool_connection_pool is not initialized");
|
|
233
|
+
return NULL;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
for (i=0;i<pool_config->max_pool;i++)
|
|
237
|
+
{
|
|
238
|
+
if (MASTER_CONNECTION(p) == NULL)
|
|
239
|
+
{
|
|
240
|
+
ret = new_connection(p);
|
|
241
|
+
if (ret)
|
|
242
|
+
pool_index = i;
|
|
243
|
+
return ret;
|
|
244
|
+
}
|
|
245
|
+
p++;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
pool_debug("no empty connection slot was found");
|
|
249
|
+
|
|
250
|
+
/*
|
|
251
|
+
* no empty connection slot was found. look for the oldest connection and discard it.
|
|
252
|
+
*/
|
|
253
|
+
oldestp = p = pool_connection_pool;
|
|
254
|
+
closetime = MASTER_CONNECTION(p)->closetime;
|
|
255
|
+
pool_index = 0;
|
|
256
|
+
|
|
257
|
+
for (i=0;i<pool_config->max_pool;i++)
|
|
258
|
+
{
|
|
259
|
+
pool_debug("user: %s database: %s closetime: %ld",
|
|
260
|
+
MASTER_CONNECTION(p)->sp->user,
|
|
261
|
+
MASTER_CONNECTION(p)->sp->database,
|
|
262
|
+
MASTER_CONNECTION(p)->closetime);
|
|
263
|
+
if (MASTER_CONNECTION(p)->closetime < closetime)
|
|
264
|
+
{
|
|
265
|
+
closetime = MASTER_CONNECTION(p)->closetime;
|
|
266
|
+
oldestp = p;
|
|
267
|
+
pool_index = i;
|
|
268
|
+
}
|
|
269
|
+
p++;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
p = oldestp;
|
|
273
|
+
pool_send_frontend_exits(p);
|
|
274
|
+
|
|
275
|
+
pool_debug("discarding old %zd th connection. user: %s database: %s",
|
|
276
|
+
oldestp - pool_connection_pool,
|
|
277
|
+
MASTER_CONNECTION(p)->sp->user,
|
|
278
|
+
MASTER_CONNECTION(p)->sp->database);
|
|
279
|
+
|
|
280
|
+
for (i=0;i<NUM_BACKENDS;i++)
|
|
281
|
+
{
|
|
282
|
+
if (!VALID_BACKEND(i))
|
|
283
|
+
continue;
|
|
284
|
+
|
|
285
|
+
if (!freed)
|
|
286
|
+
{
|
|
287
|
+
pool_free_startup_packet(CONNECTION_SLOT(p, i)->sp);
|
|
288
|
+
freed = 1;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
pool_close(CONNECTION(p, i));
|
|
292
|
+
free(CONNECTION_SLOT(p, i));
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
info = p->info;
|
|
296
|
+
memset(p, 0, sizeof(POOL_CONNECTION_POOL));
|
|
297
|
+
p->info = info;
|
|
298
|
+
memset(p->info, 0, sizeof(ConnectionInfo) * MAX_NUM_BACKENDS);
|
|
299
|
+
|
|
300
|
+
ret = new_connection(p);
|
|
301
|
+
return ret;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/*
|
|
305
|
+
* set backend connection close timer
|
|
306
|
+
*/
|
|
307
|
+
void pool_connection_pool_timer(POOL_CONNECTION_POOL *backend)
|
|
308
|
+
{
|
|
309
|
+
POOL_CONNECTION_POOL *p = pool_connection_pool;
|
|
310
|
+
int i;
|
|
311
|
+
|
|
312
|
+
pool_debug("pool_connection_pool_timer: set close time %ld", time(NULL));
|
|
313
|
+
|
|
314
|
+
MASTER_CONNECTION(backend)->closetime = time(NULL); /* set connection close time */
|
|
315
|
+
|
|
316
|
+
if (pool_config->connection_life_time == 0)
|
|
317
|
+
return;
|
|
318
|
+
|
|
319
|
+
/* look for any other timeout */
|
|
320
|
+
for (i=0;i<pool_config->max_pool;i++, p++)
|
|
321
|
+
{
|
|
322
|
+
if (!MASTER_CONNECTION(p))
|
|
323
|
+
continue;
|
|
324
|
+
if (!MASTER_CONNECTION(p)->sp)
|
|
325
|
+
continue;
|
|
326
|
+
if (MASTER_CONNECTION(p)->sp->user == NULL)
|
|
327
|
+
continue;
|
|
328
|
+
|
|
329
|
+
if (p != backend && MASTER_CONNECTION(p)->closetime)
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/* no other timer found. set my timer */
|
|
334
|
+
pool_debug("pool_connection_pool_timer: set alarm after %d seconds", pool_config->connection_life_time);
|
|
335
|
+
pool_signal(SIGALRM, pool_backend_timer_handler);
|
|
336
|
+
alarm(pool_config->connection_life_time);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/*
|
|
340
|
+
* backend connection close timer handler
|
|
341
|
+
*/
|
|
342
|
+
RETSIGTYPE pool_backend_timer_handler(int sig)
|
|
343
|
+
{
|
|
344
|
+
backend_timer_expired = 1;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
void pool_backend_timer(void)
|
|
348
|
+
{
|
|
349
|
+
#define TMINTMAX 0x7fffffff
|
|
350
|
+
|
|
351
|
+
POOL_CONNECTION_POOL *p = pool_connection_pool;
|
|
352
|
+
int i, j;
|
|
353
|
+
time_t now;
|
|
354
|
+
time_t nearest = TMINTMAX;
|
|
355
|
+
ConnectionInfo *info;
|
|
356
|
+
|
|
357
|
+
POOL_SETMASK(&BlockSig);
|
|
358
|
+
|
|
359
|
+
now = time(NULL);
|
|
360
|
+
|
|
361
|
+
pool_debug("pool_backend_timer_handler called at %ld", now);
|
|
362
|
+
|
|
363
|
+
for (i=0;i<pool_config->max_pool;i++, p++)
|
|
364
|
+
{
|
|
365
|
+
if (!MASTER_CONNECTION(p))
|
|
366
|
+
continue;
|
|
367
|
+
if (!MASTER_CONNECTION(p)->sp)
|
|
368
|
+
continue;
|
|
369
|
+
if (MASTER_CONNECTION(p)->sp->user == NULL)
|
|
370
|
+
continue;
|
|
371
|
+
|
|
372
|
+
/* timer expire? */
|
|
373
|
+
if (MASTER_CONNECTION(p)->closetime)
|
|
374
|
+
{
|
|
375
|
+
int freed = 0;
|
|
376
|
+
|
|
377
|
+
pool_debug("pool_backend_timer_handler: expire time: %ld",
|
|
378
|
+
MASTER_CONNECTION(p)->closetime+pool_config->connection_life_time);
|
|
379
|
+
|
|
380
|
+
if (now >= (MASTER_CONNECTION(p)->closetime+pool_config->connection_life_time))
|
|
381
|
+
{
|
|
382
|
+
/* discard expired connection */
|
|
383
|
+
pool_debug("pool_backend_timer_handler: expires user %s database %s",
|
|
384
|
+
MASTER_CONNECTION(p)->sp->user, MASTER_CONNECTION(p)->sp->database);
|
|
385
|
+
|
|
386
|
+
pool_send_frontend_exits(p);
|
|
387
|
+
|
|
388
|
+
for (j=0;j<NUM_BACKENDS;j++)
|
|
389
|
+
{
|
|
390
|
+
if (!VALID_BACKEND(j))
|
|
391
|
+
continue;
|
|
392
|
+
|
|
393
|
+
if (!freed)
|
|
394
|
+
{
|
|
395
|
+
pool_free_startup_packet(CONNECTION_SLOT(p, j)->sp);
|
|
396
|
+
freed = 1;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
pool_close(CONNECTION(p, j));
|
|
400
|
+
free(CONNECTION_SLOT(p, j));
|
|
401
|
+
}
|
|
402
|
+
info = p->info;
|
|
403
|
+
memset(p, 0, sizeof(POOL_CONNECTION_POOL));
|
|
404
|
+
p->info = info;
|
|
405
|
+
memset(p->info, 0, sizeof(ConnectionInfo) * MAX_NUM_BACKENDS);
|
|
406
|
+
}
|
|
407
|
+
else
|
|
408
|
+
{
|
|
409
|
+
/* look for nearest timer */
|
|
410
|
+
if (MASTER_CONNECTION(p)->closetime < nearest)
|
|
411
|
+
nearest = MASTER_CONNECTION(p)->closetime;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/* any remaining timer */
|
|
417
|
+
if (nearest != TMINTMAX)
|
|
418
|
+
{
|
|
419
|
+
nearest = pool_config->connection_life_time - (now - nearest);
|
|
420
|
+
if (nearest <= 0)
|
|
421
|
+
nearest = 1;
|
|
422
|
+
pool_signal(SIGALRM, pool_backend_timer_handler);
|
|
423
|
+
alarm(nearest);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
POOL_SETMASK(&UnBlockSig);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/*
|
|
430
|
+
* connect to postmaster through INET domain socket
|
|
431
|
+
*/
|
|
432
|
+
int connect_inet_domain_socket(int slot, bool retry)
|
|
433
|
+
{
|
|
434
|
+
char *host;
|
|
435
|
+
int port;
|
|
436
|
+
|
|
437
|
+
host = pool_config->backend_desc->backend_info[slot].backend_hostname;
|
|
438
|
+
port = pool_config->backend_desc->backend_info[slot].backend_port;
|
|
439
|
+
|
|
440
|
+
return connect_inet_domain_socket_by_port(host, port, retry);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/*
|
|
444
|
+
* connect to postmaster through UNIX domain socket
|
|
445
|
+
*/
|
|
446
|
+
int connect_unix_domain_socket(int slot, bool retry)
|
|
447
|
+
{
|
|
448
|
+
int port;
|
|
449
|
+
char *socket_dir;
|
|
450
|
+
|
|
451
|
+
port = pool_config->backend_desc->backend_info[slot].backend_port;
|
|
452
|
+
socket_dir = pool_config->backend_desc->backend_info[slot].backend_hostname;
|
|
453
|
+
|
|
454
|
+
return connect_unix_domain_socket_by_port(port, socket_dir, retry);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/*
|
|
458
|
+
* Connect to PostgreSQL server by using UNIX domain socket.
|
|
459
|
+
* If retry is true, retry to call connect() upon receiving EINTR error.
|
|
460
|
+
*/
|
|
461
|
+
int connect_unix_domain_socket_by_port(int port, char *socket_dir, bool retry)
|
|
462
|
+
{
|
|
463
|
+
struct sockaddr_un addr;
|
|
464
|
+
int fd;
|
|
465
|
+
int len;
|
|
466
|
+
|
|
467
|
+
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
|
468
|
+
if (fd == -1)
|
|
469
|
+
{
|
|
470
|
+
pool_error("connect_unix_domain_socket_by_port: socket() failed: %s", strerror(errno));
|
|
471
|
+
return -1;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
memset((char *) &addr, 0, sizeof(addr));
|
|
475
|
+
addr.sun_family = AF_UNIX;
|
|
476
|
+
snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/.s.PGSQL.%d", socket_dir, port);
|
|
477
|
+
len = sizeof(struct sockaddr_un);
|
|
478
|
+
|
|
479
|
+
for (;;)
|
|
480
|
+
{
|
|
481
|
+
if (exit_request) /* exit request already sent */
|
|
482
|
+
{
|
|
483
|
+
pool_log("connect_unix_domain_socket_by_port: exit request has been sent");
|
|
484
|
+
close(fd);
|
|
485
|
+
return -1;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
if (connect(fd, (struct sockaddr *)&addr, len) < 0)
|
|
489
|
+
{
|
|
490
|
+
if ((errno == EINTR && retry) || errno == EAGAIN)
|
|
491
|
+
continue;
|
|
492
|
+
|
|
493
|
+
pool_error("connect_unix_domain_socket_by_port: connect() failed to %s: %s", addr.sun_path, strerror(errno));
|
|
494
|
+
close(fd);
|
|
495
|
+
return -1;
|
|
496
|
+
}
|
|
497
|
+
break;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
return fd;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/*
|
|
504
|
+
* Connect to PostgreSQL server by using INET domain socket.
|
|
505
|
+
* If retry is true, retry to call connect() upon receiving EINTR error.
|
|
506
|
+
*/
|
|
507
|
+
int connect_inet_domain_socket_by_port(char *host, int port, bool retry)
|
|
508
|
+
{
|
|
509
|
+
int fd;
|
|
510
|
+
int len;
|
|
511
|
+
int on = 1;
|
|
512
|
+
struct sockaddr_in addr;
|
|
513
|
+
struct hostent *hp;
|
|
514
|
+
struct timeval timeout;
|
|
515
|
+
fd_set rset, wset;
|
|
516
|
+
int error;
|
|
517
|
+
socklen_t socklen;
|
|
518
|
+
int sts;
|
|
519
|
+
|
|
520
|
+
#define CONNECT_TIMEOUT_MSEC 1000 /* specify select(2) timeout in milliseconds */
|
|
521
|
+
#define CONNECT_TIMEOUT_SEC CONNECT_TIMEOUT_MSEC/1000 /* seconds part */
|
|
522
|
+
/* microseconds part */
|
|
523
|
+
#define CONNECT_TIMEOUT_MICROSEC (CONNECT_TIMEOUT_SEC == 0?CONNECT_TIMEOUT_MSEC*1000:\
|
|
524
|
+
CONNECT_TIMEOUT_MSEC*1000 - CONNECT_TIMEOUT_SEC*1000*1000)
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
fd = socket(AF_INET, SOCK_STREAM, 0);
|
|
528
|
+
if (fd < 0)
|
|
529
|
+
{
|
|
530
|
+
pool_error("connect_inet_domain_socket_by_port: socket() failed: %s", strerror(errno));
|
|
531
|
+
return -1;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
/* set nodelay */
|
|
535
|
+
if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
|
|
536
|
+
(char *) &on,
|
|
537
|
+
sizeof(on)) < 0)
|
|
538
|
+
{
|
|
539
|
+
pool_error("connect_inet_domain_socket_by_port: setsockopt() failed: %s", strerror(errno));
|
|
540
|
+
close(fd);
|
|
541
|
+
return -1;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
memset((char *) &addr, 0, sizeof(addr));
|
|
545
|
+
addr.sin_family = AF_INET;
|
|
546
|
+
|
|
547
|
+
addr.sin_port = htons(port);
|
|
548
|
+
len = sizeof(struct sockaddr_in);
|
|
549
|
+
|
|
550
|
+
hp = gethostbyname(host);
|
|
551
|
+
if ((hp == NULL) || (hp->h_addrtype != AF_INET))
|
|
552
|
+
{
|
|
553
|
+
pool_error("connect_inet_domain_socket: gethostbyname() failed: %s host: %s", hstrerror(h_errno), host);
|
|
554
|
+
close(fd);
|
|
555
|
+
return -1;
|
|
556
|
+
}
|
|
557
|
+
memmove((char *) &(addr.sin_addr),
|
|
558
|
+
(char *) hp->h_addr,
|
|
559
|
+
hp->h_length);
|
|
560
|
+
|
|
561
|
+
pool_set_nonblock(fd);
|
|
562
|
+
|
|
563
|
+
for (;;)
|
|
564
|
+
{
|
|
565
|
+
if (exit_request) /* exit request already sent */
|
|
566
|
+
{
|
|
567
|
+
pool_log("connect_inet_domain_socket_by_port: exit request has been sent");
|
|
568
|
+
close(fd);
|
|
569
|
+
return -1;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
if (health_check_timer_expired && getpid() == mypid) /* has health check timer expired */
|
|
573
|
+
{
|
|
574
|
+
pool_log("connect_inet_domain_socket_by_port: health check timer expired");
|
|
575
|
+
close(fd);
|
|
576
|
+
return -1;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
if (connect(fd, (struct sockaddr *)&addr, len) < 0)
|
|
580
|
+
{
|
|
581
|
+
if (errno == EISCONN)
|
|
582
|
+
{
|
|
583
|
+
/* Socket is already connected */
|
|
584
|
+
break;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
if ((errno == EINTR && retry) || errno == EAGAIN)
|
|
588
|
+
continue;
|
|
589
|
+
|
|
590
|
+
/*
|
|
591
|
+
* If error was "connect(2) is in progress", then wait for
|
|
592
|
+
* completion. Otherwise error out.
|
|
593
|
+
*/
|
|
594
|
+
if (errno != EINPROGRESS && errno != EALREADY)
|
|
595
|
+
{
|
|
596
|
+
pool_error("connect_inet_domain_socket: connect() failed: %s",strerror(errno));
|
|
597
|
+
close(fd);
|
|
598
|
+
return -1;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
timeout.tv_sec = CONNECT_TIMEOUT_SEC;
|
|
602
|
+
timeout.tv_usec = CONNECT_TIMEOUT_MICROSEC;
|
|
603
|
+
FD_ZERO(&rset);
|
|
604
|
+
FD_SET(fd, &rset);
|
|
605
|
+
FD_ZERO(&wset);
|
|
606
|
+
FD_SET(fd, &wset);
|
|
607
|
+
sts = select(fd+1, &rset, &wset, NULL, &timeout);
|
|
608
|
+
|
|
609
|
+
if (sts == 0)
|
|
610
|
+
{
|
|
611
|
+
/* select timeout */
|
|
612
|
+
if (retry)
|
|
613
|
+
{
|
|
614
|
+
pool_log("connect_inet_domain_socket: select() timed out. retrying...");
|
|
615
|
+
continue;
|
|
616
|
+
}
|
|
617
|
+
else
|
|
618
|
+
{
|
|
619
|
+
pool_error("connect_inet_domain_socket: select() timed out");
|
|
620
|
+
close(fd);
|
|
621
|
+
return -1;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
else if (sts > 0)
|
|
625
|
+
{
|
|
626
|
+
/*
|
|
627
|
+
* If read data or write data was set, either connect
|
|
628
|
+
* succeeded or error. We need to figure it out. This
|
|
629
|
+
* is the hardest part in using non blocking
|
|
630
|
+
* connect(2). See W. Richar Stevens's "UNIX Network
|
|
631
|
+
* Programming: Volume 1, Second Edition" section
|
|
632
|
+
* 15.4.
|
|
633
|
+
*/
|
|
634
|
+
if (FD_ISSET(fd, &rset) || FD_ISSET(fd, &wset))
|
|
635
|
+
{
|
|
636
|
+
error = 0;
|
|
637
|
+
socklen = sizeof(error);
|
|
638
|
+
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &socklen) < 0)
|
|
639
|
+
{
|
|
640
|
+
/* Solaris returns error in this case */
|
|
641
|
+
pool_error("connect_inet_domain_socket: getsockopt() failed: %s", strerror(errno));
|
|
642
|
+
close(fd);
|
|
643
|
+
return -1;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
/* Non Solaris case */
|
|
647
|
+
if (error != 0)
|
|
648
|
+
{
|
|
649
|
+
pool_error("connect_inet_domain_socket: getsockopt() detected error: %s", strerror(error));
|
|
650
|
+
close(fd);
|
|
651
|
+
return -1;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
else
|
|
655
|
+
{
|
|
656
|
+
pool_error("connect_inet_domain_socket: both read data and write data was not set");
|
|
657
|
+
close(fd);
|
|
658
|
+
return -1;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
else /* select returns error */
|
|
662
|
+
{
|
|
663
|
+
if((errno == EINTR && retry) || errno == EAGAIN)
|
|
664
|
+
{
|
|
665
|
+
pool_log("connect_inet_domain_socket: select() interrupted. retrying...");
|
|
666
|
+
continue;
|
|
667
|
+
}
|
|
668
|
+
pool_log("connect_inet_domain_socket: select() interrupted");
|
|
669
|
+
close(fd);
|
|
670
|
+
return -1;
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
break;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
pool_unset_nonblock(fd);
|
|
677
|
+
return fd;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
/*
|
|
681
|
+
* create connection pool
|
|
682
|
+
*/
|
|
683
|
+
static POOL_CONNECTION_POOL_SLOT *create_cp(POOL_CONNECTION_POOL_SLOT *cp, int slot)
|
|
684
|
+
{
|
|
685
|
+
BackendInfo *b = &pool_config->backend_desc->backend_info[slot];
|
|
686
|
+
int fd;
|
|
687
|
+
|
|
688
|
+
if (*b->backend_hostname == '/')
|
|
689
|
+
{
|
|
690
|
+
fd = connect_unix_domain_socket(slot, TRUE);
|
|
691
|
+
}
|
|
692
|
+
else
|
|
693
|
+
{
|
|
694
|
+
fd = connect_inet_domain_socket(slot, TRUE);
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
if (fd < 0)
|
|
698
|
+
{
|
|
699
|
+
pool_error("connection to %s(%d) failed", b->backend_hostname, b->backend_port);
|
|
700
|
+
return NULL;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
cp->sp = NULL;
|
|
704
|
+
cp->con = pool_open(fd);
|
|
705
|
+
cp->closetime = 0;
|
|
706
|
+
return cp;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
/*
|
|
710
|
+
* create actual connections to backends
|
|
711
|
+
*/
|
|
712
|
+
static POOL_CONNECTION_POOL *new_connection(POOL_CONNECTION_POOL *p)
|
|
713
|
+
{
|
|
714
|
+
POOL_CONNECTION_POOL_SLOT *s;
|
|
715
|
+
int active_backend_count = 0;
|
|
716
|
+
int i;
|
|
717
|
+
|
|
718
|
+
for (i=0;i<NUM_BACKENDS;i++)
|
|
719
|
+
{
|
|
720
|
+
pool_debug("new_connection: connecting %d backend", i);
|
|
721
|
+
|
|
722
|
+
if (!VALID_BACKEND(i))
|
|
723
|
+
{
|
|
724
|
+
pool_debug("new_connection: skipping slot %d because backend_status = %d",
|
|
725
|
+
i, BACKEND_INFO(i).backend_status);
|
|
726
|
+
continue;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
s = malloc(sizeof(POOL_CONNECTION_POOL_SLOT));
|
|
730
|
+
if (s == NULL)
|
|
731
|
+
{
|
|
732
|
+
pool_error("new_connection: malloc() failed");
|
|
733
|
+
return NULL;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
if (create_cp(s, i) == NULL)
|
|
737
|
+
{
|
|
738
|
+
/* connection failed. mark this backend down */
|
|
739
|
+
pool_error("new_connection: create_cp() failed");
|
|
740
|
+
|
|
741
|
+
/* If fail_over_on_backend_error is true, do failover.
|
|
742
|
+
* Otherwise, just exit this session.
|
|
743
|
+
*/
|
|
744
|
+
if (pool_config->fail_over_on_backend_error)
|
|
745
|
+
{
|
|
746
|
+
notice_backend_error(i);
|
|
747
|
+
}
|
|
748
|
+
else
|
|
749
|
+
{
|
|
750
|
+
pool_log("new_connection: do not failover because fail_over_on_backend_error is off");
|
|
751
|
+
}
|
|
752
|
+
child_exit(1);
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
p->info[i].create_time = time(NULL);
|
|
756
|
+
p->slots[i] = s;
|
|
757
|
+
|
|
758
|
+
if (pool_init_params(&s->con->params))
|
|
759
|
+
{
|
|
760
|
+
return NULL;
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
BACKEND_INFO(i).backend_status = CON_UP;
|
|
764
|
+
active_backend_count++;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
if (active_backend_count > 0)
|
|
768
|
+
{
|
|
769
|
+
return p;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
return NULL;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
/* check_socket_status()
|
|
776
|
+
* RETURN: 0 => OK
|
|
777
|
+
* -1 => broken socket.
|
|
778
|
+
*/
|
|
779
|
+
static int check_socket_status(int fd)
|
|
780
|
+
{
|
|
781
|
+
fd_set rfds;
|
|
782
|
+
int result;
|
|
783
|
+
struct timeval t;
|
|
784
|
+
|
|
785
|
+
for (;;)
|
|
786
|
+
{
|
|
787
|
+
FD_ZERO(&rfds);
|
|
788
|
+
FD_SET(fd, &rfds);
|
|
789
|
+
|
|
790
|
+
t.tv_sec = t.tv_usec = 0;
|
|
791
|
+
|
|
792
|
+
result = select(fd+1, &rfds, NULL, NULL, &t);
|
|
793
|
+
if (result < 0 && errno == EINTR)
|
|
794
|
+
{
|
|
795
|
+
continue;
|
|
796
|
+
}
|
|
797
|
+
else
|
|
798
|
+
{
|
|
799
|
+
return (result == 0 ? 0 : -1);
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
return -1;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
/*
|
|
807
|
+
* Return current used index (i.e. frontend connected)
|
|
808
|
+
*/
|
|
809
|
+
int pool_pool_index(void)
|
|
810
|
+
{
|
|
811
|
+
return pool_index;
|
|
812
|
+
}
|