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.
Files changed (393) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +2 -0
  3. data/Gemfile.lock +20 -0
  4. data/LICENSE +202 -0
  5. data/NOTICE +22 -0
  6. data/README.md +217 -0
  7. data/Rakefile +13 -0
  8. data/VERSION +1 -0
  9. data/bin/prestogres +254 -0
  10. data/config/pcp.conf.sample +28 -0
  11. data/config/pgpool.conf +678 -0
  12. data/config/pool_hba.conf +84 -0
  13. data/config/pool_passwd +0 -0
  14. data/config/postgresql.conf +2 -0
  15. data/ext/.gitignore +6 -0
  16. data/ext/depend +26 -0
  17. data/ext/extconf.rb +4 -0
  18. data/ext/prestogres_config.c +12 -0
  19. data/pgpool2/.gitignore +36 -0
  20. data/pgpool2/AUTHORS +4 -0
  21. data/pgpool2/COPYING +12 -0
  22. data/pgpool2/ChangeLog +1 -0
  23. data/pgpool2/INSTALL +1 -0
  24. data/pgpool2/Makefile.am +159 -0
  25. data/pgpool2/Makefile.in +1187 -0
  26. data/pgpool2/NEWS +4960 -0
  27. data/pgpool2/README +1 -0
  28. data/pgpool2/README.euc_jp +1 -0
  29. data/pgpool2/README.online-recovery +62 -0
  30. data/pgpool2/TODO +103 -0
  31. data/pgpool2/ac_func_accept_argtypes.m4 +85 -0
  32. data/pgpool2/aclocal.m4 +1088 -0
  33. data/pgpool2/c-compiler.m4 +134 -0
  34. data/pgpool2/c-library.m4 +325 -0
  35. data/pgpool2/child.c +2097 -0
  36. data/pgpool2/config.guess +1532 -0
  37. data/pgpool2/config.h.in +332 -0
  38. data/pgpool2/config.sub +1640 -0
  39. data/pgpool2/configure +15752 -0
  40. data/pgpool2/configure.in +392 -0
  41. data/pgpool2/depcomp +522 -0
  42. data/pgpool2/doc/basebackup.sh +17 -0
  43. data/pgpool2/doc/pgpool-de.html +4220 -0
  44. data/pgpool2/doc/pgpool-en.html +5738 -0
  45. data/pgpool2/doc/pgpool-fr.html +4118 -0
  46. data/pgpool2/doc/pgpool-ja.css +198 -0
  47. data/pgpool2/doc/pgpool-ja.html +11279 -0
  48. data/pgpool2/doc/pgpool-zh_cn.html +4445 -0
  49. data/pgpool2/doc/pgpool.css +280 -0
  50. data/pgpool2/doc/pgpool_remote_start +13 -0
  51. data/pgpool2/doc/recovery.conf.sample +117 -0
  52. data/pgpool2/doc/tutorial-en.html +707 -0
  53. data/pgpool2/doc/tutorial-ja.html +422 -0
  54. data/pgpool2/doc/tutorial-memqcache-en.html +325 -0
  55. data/pgpool2/doc/tutorial-memqcache-ja.html +370 -0
  56. data/pgpool2/doc/tutorial-memqcache-zh_cn.html +322 -0
  57. data/pgpool2/doc/tutorial-watchdog-en.html +306 -0
  58. data/pgpool2/doc/tutorial-watchdog-ja.html +343 -0
  59. data/pgpool2/doc/tutorial-watchdog-zh_cn.html +301 -0
  60. data/pgpool2/doc/tutorial-zh_cn.html +537 -0
  61. data/pgpool2/doc/watchdog.png +0 -0
  62. data/pgpool2/doc/wd-en.html +236 -0
  63. data/pgpool2/doc/wd-en.jpg +0 -0
  64. data/pgpool2/doc/wd-ja.html +219 -0
  65. data/pgpool2/doc/wd-ja.jpg +0 -0
  66. data/pgpool2/doc/wd-zh_cn.html +201 -0
  67. data/pgpool2/doc/where_to_send_queries.odg +0 -0
  68. data/pgpool2/doc/where_to_send_queries.pdf +0 -0
  69. data/pgpool2/general.m4 +166 -0
  70. data/pgpool2/getopt_long.c +200 -0
  71. data/pgpool2/getopt_long.h +44 -0
  72. data/pgpool2/install-sh +251 -0
  73. data/pgpool2/ltmain.sh +8406 -0
  74. data/pgpool2/m4/libtool.m4 +7360 -0
  75. data/pgpool2/m4/ltoptions.m4 +368 -0
  76. data/pgpool2/m4/ltsugar.m4 +123 -0
  77. data/pgpool2/m4/ltversion.m4 +23 -0
  78. data/pgpool2/m4/lt~obsolete.m4 +92 -0
  79. data/pgpool2/main.c +2971 -0
  80. data/pgpool2/md5.c +444 -0
  81. data/pgpool2/md5.h +28 -0
  82. data/pgpool2/missing +360 -0
  83. data/pgpool2/mkinstalldirs +40 -0
  84. data/pgpool2/parser/Makefile.am +50 -0
  85. data/pgpool2/parser/Makefile.in +559 -0
  86. data/pgpool2/parser/copyfuncs.c +3310 -0
  87. data/pgpool2/parser/gram.c +39100 -0
  88. data/pgpool2/parser/gram.h +940 -0
  89. data/pgpool2/parser/gram.y +13408 -0
  90. data/pgpool2/parser/gramparse.h +74 -0
  91. data/pgpool2/parser/keywords.c +32 -0
  92. data/pgpool2/parser/keywords.h +39 -0
  93. data/pgpool2/parser/kwlist.h +425 -0
  94. data/pgpool2/parser/kwlookup.c +88 -0
  95. data/pgpool2/parser/list.c +1156 -0
  96. data/pgpool2/parser/makefuncs.c +518 -0
  97. data/pgpool2/parser/makefuncs.h +83 -0
  98. data/pgpool2/parser/memnodes.h +79 -0
  99. data/pgpool2/parser/nodes.c +29 -0
  100. data/pgpool2/parser/nodes.h +609 -0
  101. data/pgpool2/parser/outfuncs.c +5790 -0
  102. data/pgpool2/parser/parsenodes.h +2615 -0
  103. data/pgpool2/parser/parser.c +262 -0
  104. data/pgpool2/parser/parser.h +46 -0
  105. data/pgpool2/parser/pg_class.h +158 -0
  106. data/pgpool2/parser/pg_config_manual.h +273 -0
  107. data/pgpool2/parser/pg_list.h +352 -0
  108. data/pgpool2/parser/pg_trigger.h +147 -0
  109. data/pgpool2/parser/pg_wchar.h +492 -0
  110. data/pgpool2/parser/pool_memory.c +342 -0
  111. data/pgpool2/parser/pool_memory.h +77 -0
  112. data/pgpool2/parser/pool_parser.h +222 -0
  113. data/pgpool2/parser/pool_string.c +121 -0
  114. data/pgpool2/parser/pool_string.h +37 -0
  115. data/pgpool2/parser/primnodes.h +1280 -0
  116. data/pgpool2/parser/scan.c +4094 -0
  117. data/pgpool2/parser/scan.l +1451 -0
  118. data/pgpool2/parser/scanner.h +120 -0
  119. data/pgpool2/parser/scansup.c +221 -0
  120. data/pgpool2/parser/scansup.h +28 -0
  121. data/pgpool2/parser/snprintf.c +1102 -0
  122. data/pgpool2/parser/stringinfo.c +294 -0
  123. data/pgpool2/parser/stringinfo.h +178 -0
  124. data/pgpool2/parser/value.c +78 -0
  125. data/pgpool2/parser/value.h +62 -0
  126. data/pgpool2/parser/wchar.c +2048 -0
  127. data/pgpool2/pcp.conf.sample +28 -0
  128. data/pgpool2/pcp/Makefile.am +40 -0
  129. data/pgpool2/pcp/Makefile.in +771 -0
  130. data/pgpool2/pcp/libpcp_ext.h +250 -0
  131. data/pgpool2/pcp/md5.c +444 -0
  132. data/pgpool2/pcp/md5.h +28 -0
  133. data/pgpool2/pcp/pcp.c +1652 -0
  134. data/pgpool2/pcp/pcp.h +61 -0
  135. data/pgpool2/pcp/pcp_attach_node.c +172 -0
  136. data/pgpool2/pcp/pcp_detach_node.c +185 -0
  137. data/pgpool2/pcp/pcp_error.c +87 -0
  138. data/pgpool2/pcp/pcp_node_count.c +160 -0
  139. data/pgpool2/pcp/pcp_node_info.c +198 -0
  140. data/pgpool2/pcp/pcp_pool_status.c +166 -0
  141. data/pgpool2/pcp/pcp_proc_count.c +166 -0
  142. data/pgpool2/pcp/pcp_proc_info.c +261 -0
  143. data/pgpool2/pcp/pcp_promote_node.c +185 -0
  144. data/pgpool2/pcp/pcp_recovery_node.c +172 -0
  145. data/pgpool2/pcp/pcp_stop_pgpool.c +179 -0
  146. data/pgpool2/pcp/pcp_stream.c +385 -0
  147. data/pgpool2/pcp/pcp_stream.h +52 -0
  148. data/pgpool2/pcp/pcp_systemdb_info.c +194 -0
  149. data/pgpool2/pcp/pcp_watchdog_info.c +211 -0
  150. data/pgpool2/pcp_child.c +1493 -0
  151. data/pgpool2/pg_md5.c +305 -0
  152. data/pgpool2/pgpool.8.in +121 -0
  153. data/pgpool2/pgpool.conf +553 -0
  154. data/pgpool2/pgpool.conf.sample +666 -0
  155. data/pgpool2/pgpool.conf.sample-master-slave +665 -0
  156. data/pgpool2/pgpool.conf.sample-replication +664 -0
  157. data/pgpool2/pgpool.conf.sample-stream +664 -0
  158. data/pgpool2/pgpool.spec +264 -0
  159. data/pgpool2/pgpool_adm/TODO +7 -0
  160. data/pgpool2/pgpool_adm/pgpool_adm--1.0.sql +85 -0
  161. data/pgpool2/pgpool_adm/pgpool_adm.c +558 -0
  162. data/pgpool2/pgpool_adm/pgpool_adm.control +5 -0
  163. data/pgpool2/pgpool_adm/pgpool_adm.h +46 -0
  164. data/pgpool2/pgpool_adm/pgpool_adm.sql.in +85 -0
  165. data/pgpool2/pool.h +655 -0
  166. data/pgpool2/pool_auth.c +1390 -0
  167. data/pgpool2/pool_config.c +5007 -0
  168. data/pgpool2/pool_config.h +284 -0
  169. data/pgpool2/pool_config.l +3281 -0
  170. data/pgpool2/pool_config_md5.c +29 -0
  171. data/pgpool2/pool_connection_pool.c +812 -0
  172. data/pgpool2/pool_error.c +242 -0
  173. data/pgpool2/pool_globals.c +27 -0
  174. data/pgpool2/pool_hba.c +1723 -0
  175. data/pgpool2/pool_hba.conf.sample +67 -0
  176. data/pgpool2/pool_ip.c +567 -0
  177. data/pgpool2/pool_ip.h +65 -0
  178. data/pgpool2/pool_ipc.h +38 -0
  179. data/pgpool2/pool_lobj.c +242 -0
  180. data/pgpool2/pool_lobj.h +32 -0
  181. data/pgpool2/pool_memqcache.c +3818 -0
  182. data/pgpool2/pool_memqcache.h +268 -0
  183. data/pgpool2/pool_params.c +163 -0
  184. data/pgpool2/pool_passwd.c +249 -0
  185. data/pgpool2/pool_passwd.h +41 -0
  186. data/pgpool2/pool_path.c +193 -0
  187. data/pgpool2/pool_path.h +81 -0
  188. data/pgpool2/pool_process_context.c +247 -0
  189. data/pgpool2/pool_process_context.h +62 -0
  190. data/pgpool2/pool_process_query.c +5001 -0
  191. data/pgpool2/pool_process_reporting.c +1671 -0
  192. data/pgpool2/pool_process_reporting.h +44 -0
  193. data/pgpool2/pool_proto2.c +671 -0
  194. data/pgpool2/pool_proto_modules.c +3524 -0
  195. data/pgpool2/pool_proto_modules.h +185 -0
  196. data/pgpool2/pool_query_cache.c +1020 -0
  197. data/pgpool2/pool_query_context.c +1871 -0
  198. data/pgpool2/pool_query_context.h +105 -0
  199. data/pgpool2/pool_relcache.c +284 -0
  200. data/pgpool2/pool_relcache.h +78 -0
  201. data/pgpool2/pool_rewrite_outfuncs.c +9060 -0
  202. data/pgpool2/pool_rewrite_query.c +715 -0
  203. data/pgpool2/pool_rewrite_query.h +192 -0
  204. data/pgpool2/pool_select_walker.c +1150 -0
  205. data/pgpool2/pool_select_walker.h +68 -0
  206. data/pgpool2/pool_sema.c +161 -0
  207. data/pgpool2/pool_session_context.c +952 -0
  208. data/pgpool2/pool_session_context.h +203 -0
  209. data/pgpool2/pool_shmem.c +185 -0
  210. data/pgpool2/pool_signal.c +158 -0
  211. data/pgpool2/pool_signal.h +61 -0
  212. data/pgpool2/pool_ssl.c +339 -0
  213. data/pgpool2/pool_stream.c +962 -0
  214. data/pgpool2/pool_stream.h +61 -0
  215. data/pgpool2/pool_system.c +659 -0
  216. data/pgpool2/pool_timestamp.c +1215 -0
  217. data/pgpool2/pool_timestamp.h +38 -0
  218. data/pgpool2/pool_type.h +171 -0
  219. data/pgpool2/pool_worker_child.c +384 -0
  220. data/pgpool2/ps_status.c +404 -0
  221. data/pgpool2/recovery.c +435 -0
  222. data/pgpool2/redhat/pgpool.conf.sample.patch +52 -0
  223. data/pgpool2/redhat/pgpool.init +201 -0
  224. data/pgpool2/redhat/pgpool.sysconfig +7 -0
  225. data/pgpool2/redhat/rpm_installer/basebackup-replication.sh +53 -0
  226. data/pgpool2/redhat/rpm_installer/basebackup-stream.sh +55 -0
  227. data/pgpool2/redhat/rpm_installer/config_for_script +17 -0
  228. data/pgpool2/redhat/rpm_installer/failover.sh +64 -0
  229. data/pgpool2/redhat/rpm_installer/getsources.sh +141 -0
  230. data/pgpool2/redhat/rpm_installer/install.sh +1363 -0
  231. data/pgpool2/redhat/rpm_installer/pgpool_recovery_pitr +47 -0
  232. data/pgpool2/redhat/rpm_installer/pgpool_remote_start +15 -0
  233. data/pgpool2/redhat/rpm_installer/recovery.conf +4 -0
  234. data/pgpool2/redhat/rpm_installer/uninstall.sh +57 -0
  235. data/pgpool2/sample/dist_def_pgbench.sql +73 -0
  236. data/pgpool2/sample/pgpool.pam +3 -0
  237. data/pgpool2/sample/pgpool_recovery +20 -0
  238. data/pgpool2/sample/pgpool_recovery_pitr +19 -0
  239. data/pgpool2/sample/pgpool_remote_start +13 -0
  240. data/pgpool2/sample/replicate_def_pgbench.sql +18 -0
  241. data/pgpool2/sql/insert_lock.sql +15 -0
  242. data/pgpool2/sql/pgpool-recovery/pgpool-recovery.c +280 -0
  243. data/pgpool2/sql/pgpool-recovery/pgpool-recovery.sql.in +19 -0
  244. data/pgpool2/sql/pgpool-recovery/pgpool_recovery--1.0.sql +24 -0
  245. data/pgpool2/sql/pgpool-recovery/pgpool_recovery.control +5 -0
  246. data/pgpool2/sql/pgpool-recovery/uninstall_pgpool-recovery.sql +3 -0
  247. data/pgpool2/sql/pgpool-regclass/pgpool-regclass.c +206 -0
  248. data/pgpool2/sql/pgpool-regclass/pgpool-regclass.sql.in +4 -0
  249. data/pgpool2/sql/pgpool-regclass/pgpool_regclass--1.0.sql +7 -0
  250. data/pgpool2/sql/pgpool-regclass/pgpool_regclass.control +5 -0
  251. data/pgpool2/sql/pgpool-regclass/uninstall_pgpool-regclass.sql +1 -0
  252. data/pgpool2/sql/system_db.sql +38 -0
  253. data/pgpool2/strlcpy.c +85 -0
  254. data/pgpool2/test/C/test_extended.c +98 -0
  255. data/pgpool2/test/jdbc/.cvsignore +2 -0
  256. data/pgpool2/test/jdbc/AutoCommitTest.java +45 -0
  257. data/pgpool2/test/jdbc/BatchTest.java +55 -0
  258. data/pgpool2/test/jdbc/ColumnTest.java +60 -0
  259. data/pgpool2/test/jdbc/CreateTempTableTest.java +48 -0
  260. data/pgpool2/test/jdbc/InsertTest.java +34 -0
  261. data/pgpool2/test/jdbc/LockTest.java +36 -0
  262. data/pgpool2/test/jdbc/PgpoolTest.java +75 -0
  263. data/pgpool2/test/jdbc/README.euc_jp +73 -0
  264. data/pgpool2/test/jdbc/RunTest.java +83 -0
  265. data/pgpool2/test/jdbc/SelectTest.java +37 -0
  266. data/pgpool2/test/jdbc/UpdateTest.java +32 -0
  267. data/pgpool2/test/jdbc/expected/CreateTempTable +1 -0
  268. data/pgpool2/test/jdbc/expected/autocommit +10 -0
  269. data/pgpool2/test/jdbc/expected/batch +1 -0
  270. data/pgpool2/test/jdbc/expected/column +100 -0
  271. data/pgpool2/test/jdbc/expected/insert +1 -0
  272. data/pgpool2/test/jdbc/expected/lock +100 -0
  273. data/pgpool2/test/jdbc/expected/select +2 -0
  274. data/pgpool2/test/jdbc/expected/update +1 -0
  275. data/pgpool2/test/jdbc/pgpool.properties +7 -0
  276. data/pgpool2/test/jdbc/prepare.sql +54 -0
  277. data/pgpool2/test/jdbc/run.sh +6 -0
  278. data/pgpool2/test/parser/.cvsignore +6 -0
  279. data/pgpool2/test/parser/README +32 -0
  280. data/pgpool2/test/parser/expected/copy.out +17 -0
  281. data/pgpool2/test/parser/expected/create.out +64 -0
  282. data/pgpool2/test/parser/expected/cursor.out +37 -0
  283. data/pgpool2/test/parser/expected/delete.out +10 -0
  284. data/pgpool2/test/parser/expected/drop.out +12 -0
  285. data/pgpool2/test/parser/expected/insert.out +13 -0
  286. data/pgpool2/test/parser/expected/misc.out +28 -0
  287. data/pgpool2/test/parser/expected/prepare.out +4 -0
  288. data/pgpool2/test/parser/expected/privileges.out +31 -0
  289. data/pgpool2/test/parser/expected/scanner.out +30 -0
  290. data/pgpool2/test/parser/expected/select.out +89 -0
  291. data/pgpool2/test/parser/expected/transaction.out +38 -0
  292. data/pgpool2/test/parser/expected/update.out +11 -0
  293. data/pgpool2/test/parser/expected/v84.out +37 -0
  294. data/pgpool2/test/parser/expected/v90.out +25 -0
  295. data/pgpool2/test/parser/expected/var.out +22 -0
  296. data/pgpool2/test/parser/input/alter.sql +2 -0
  297. data/pgpool2/test/parser/input/copy.sql +17 -0
  298. data/pgpool2/test/parser/input/create.sql +64 -0
  299. data/pgpool2/test/parser/input/cursor.sql +37 -0
  300. data/pgpool2/test/parser/input/delete.sql +10 -0
  301. data/pgpool2/test/parser/input/drop.sql +12 -0
  302. data/pgpool2/test/parser/input/insert.sql +13 -0
  303. data/pgpool2/test/parser/input/misc.sql +28 -0
  304. data/pgpool2/test/parser/input/prepare.sql +4 -0
  305. data/pgpool2/test/parser/input/privileges.sql +31 -0
  306. data/pgpool2/test/parser/input/scanner.sql +34 -0
  307. data/pgpool2/test/parser/input/select.sql +89 -0
  308. data/pgpool2/test/parser/input/transaction.sql +38 -0
  309. data/pgpool2/test/parser/input/update.sql +11 -0
  310. data/pgpool2/test/parser/input/v84.sql +37 -0
  311. data/pgpool2/test/parser/input/v90.sql +38 -0
  312. data/pgpool2/test/parser/input/var.sql +22 -0
  313. data/pgpool2/test/parser/main.c +96 -0
  314. data/pgpool2/test/parser/parse_schedule +16 -0
  315. data/pgpool2/test/parser/pool.h +13 -0
  316. data/pgpool2/test/parser/run-test +62 -0
  317. data/pgpool2/test/pdo-test/README.euc_jp +58 -0
  318. data/pgpool2/test/pdo-test/SQLlist/test1.sql +3 -0
  319. data/pgpool2/test/pdo-test/SQLlist/test2.sql +3 -0
  320. data/pgpool2/test/pdo-test/collections.inc +11 -0
  321. data/pgpool2/test/pdo-test/def.inc +7 -0
  322. data/pgpool2/test/pdo-test/log.txt +0 -0
  323. data/pgpool2/test/pdo-test/mod/database.inc +36 -0
  324. data/pgpool2/test/pdo-test/mod/def.inc +0 -0
  325. data/pgpool2/test/pdo-test/mod/errorhandler.inc +27 -0
  326. data/pgpool2/test/pdo-test/pdotest.php +11 -0
  327. data/pgpool2/test/pdo-test/regsql.inc +56 -0
  328. data/pgpool2/test/pgpool_setup +898 -0
  329. data/pgpool2/test/regression/README +39 -0
  330. data/pgpool2/test/regression/clean.sh +21 -0
  331. data/pgpool2/test/regression/libs.sh +16 -0
  332. data/pgpool2/test/regression/regress.sh +166 -0
  333. data/pgpool2/test/regression/tests/001.load_balance/test.sh +128 -0
  334. data/pgpool2/test/regression/tests/002.native_replication/PgTester.java +47 -0
  335. data/pgpool2/test/regression/tests/002.native_replication/create.sql +6 -0
  336. data/pgpool2/test/regression/tests/002.native_replication/test.sh +71 -0
  337. data/pgpool2/test/regression/tests/003.failover/expected.r +6 -0
  338. data/pgpool2/test/regression/tests/003.failover/expected.s +6 -0
  339. data/pgpool2/test/regression/tests/003.failover/test.sh +45 -0
  340. data/pgpool2/test/regression/tests/004.watchdog/master.conf +12 -0
  341. data/pgpool2/test/regression/tests/004.watchdog/standby.conf +19 -0
  342. data/pgpool2/test/regression/tests/004.watchdog/test.sh +52 -0
  343. data/pgpool2/test/regression/tests/050.bug58/test.sh +50 -0
  344. data/pgpool2/test/regression/tests/051.bug60/bug.sql +12 -0
  345. data/pgpool2/test/regression/tests/051.bug60/database-clean.sql +6 -0
  346. data/pgpool2/test/regression/tests/051.bug60/database-setup.sql +28 -0
  347. data/pgpool2/test/regression/tests/051.bug60/test.sh +79 -0
  348. data/pgpool2/test/regression/tests/052.do_query/test.sh +44 -0
  349. data/pgpool2/test/regression/tests/053.insert_lock_hangs/test.sh +81 -0
  350. data/pgpool2/test/regression/tests/054.postgres_fdw/test.sh +67 -0
  351. data/pgpool2/test/regression/tests/055.backend_all_down/test.sh +52 -0
  352. data/pgpool2/test/regression/tests/056.bug63/jdbctest2.java +66 -0
  353. data/pgpool2/test/regression/tests/056.bug63/test.sh +47 -0
  354. data/pgpool2/test/regression/tests/057.bug61/test.sh +40 -0
  355. data/pgpool2/test/regression/tests/058.bug68/jdbctest3.java +45 -0
  356. data/pgpool2/test/regression/tests/058.bug68/test.sh +47 -0
  357. data/pgpool2/test/timestamp/expected/insert.out +16 -0
  358. data/pgpool2/test/timestamp/expected/misc.out +3 -0
  359. data/pgpool2/test/timestamp/expected/update.out +6 -0
  360. data/pgpool2/test/timestamp/input/insert.sql +16 -0
  361. data/pgpool2/test/timestamp/input/misc.sql +3 -0
  362. data/pgpool2/test/timestamp/input/update.sql +6 -0
  363. data/pgpool2/test/timestamp/main.c +129 -0
  364. data/pgpool2/test/timestamp/parse_schedule +3 -0
  365. data/pgpool2/test/timestamp/run-test +69 -0
  366. data/pgpool2/version.h +1 -0
  367. data/pgpool2/watchdog/Makefile.am +17 -0
  368. data/pgpool2/watchdog/Makefile.in +505 -0
  369. data/pgpool2/watchdog/test/stab.c +266 -0
  370. data/pgpool2/watchdog/test/test.c +85 -0
  371. data/pgpool2/watchdog/test/wd_child_t.c +87 -0
  372. data/pgpool2/watchdog/test/wd_lifecheck_t.c +87 -0
  373. data/pgpool2/watchdog/test/wd_packet_t.c +87 -0
  374. data/pgpool2/watchdog/test/wd_ping_t.c +20 -0
  375. data/pgpool2/watchdog/watchdog.c +408 -0
  376. data/pgpool2/watchdog/watchdog.h +209 -0
  377. data/pgpool2/watchdog/wd_child.c +444 -0
  378. data/pgpool2/watchdog/wd_ext.h +123 -0
  379. data/pgpool2/watchdog/wd_heartbeat.c +577 -0
  380. data/pgpool2/watchdog/wd_if.c +216 -0
  381. data/pgpool2/watchdog/wd_init.c +126 -0
  382. data/pgpool2/watchdog/wd_interlock.c +347 -0
  383. data/pgpool2/watchdog/wd_lifecheck.c +512 -0
  384. data/pgpool2/watchdog/wd_list.c +429 -0
  385. data/pgpool2/watchdog/wd_packet.c +1159 -0
  386. data/pgpool2/watchdog/wd_ping.c +330 -0
  387. data/pgpool2/ylwrap +223 -0
  388. data/pgsql/presto_client.py +346 -0
  389. data/pgsql/prestogres.py +156 -0
  390. data/pgsql/setup_functions.sql +21 -0
  391. data/pgsql/setup_language.sql +3 -0
  392. data/prestogres.gemspec +23 -0
  393. metadata +496 -0
@@ -0,0 +1,404 @@
1
+ /* -*-pgsql-c-*- */
2
+ /*
3
+ *
4
+ * $Header$
5
+ *
6
+ * This file was imported from PostgreSQL source code.
7
+ * See below for the copyright and description.
8
+ *
9
+ * pgpool: a language independent connection pool server for PostgreSQL
10
+ * written by Tatsuo Ishii
11
+ *
12
+ * Portions Copyright (c) 2003-2012 PgPool Global Development Group
13
+ *
14
+ */
15
+ /*--------------------------------------------------------------------
16
+ * ps_status.c
17
+ *
18
+ * Routines to support changing the ps display of PostgreSQL backends
19
+ * to contain some useful information. Mechanism differs wildly across
20
+ * platforms.
21
+ *
22
+ * $PostgreSQL: pgsql/src/backend/utils/misc/ps_status.c,v 1.33 2006/10/04 00:30:04 momjian Exp $
23
+ *
24
+ * Copyright (c) 2000-2006, PostgreSQL Global Development Group
25
+ * various details abducted from various places
26
+ *--------------------------------------------------------------------
27
+ */
28
+
29
+ #include <unistd.h>
30
+ #ifdef HAVE_SYS_PSTAT_H
31
+ #include <sys/pstat.h> /* for HP-UX */
32
+ #endif
33
+ #ifdef HAVE_PS_STRINGS
34
+ #include <machine/vmparam.h> /* for old BSD */
35
+ #include <sys/exec.h>
36
+ #endif
37
+ #if defined(__darwin__)
38
+ #include <crt_externs.h>
39
+ #endif
40
+
41
+ #include "pool.h"
42
+ #include <stdlib.h>
43
+ #include <string.h>
44
+
45
+ extern char **environ;
46
+ bool update_process_title = true;
47
+
48
+
49
+ /*
50
+ * Alternative ways of updating ps display:
51
+ *
52
+ * PS_USE_SETPROCTITLE
53
+ * use the function setproctitle(const char *, ...)
54
+ * (newer BSD systems)
55
+ * PS_USE_PSTAT
56
+ * use the pstat(PSTAT_SETCMD, )
57
+ * (HPUX)
58
+ * PS_USE_PS_STRINGS
59
+ * assign PS_STRINGS->ps_argvstr = "string"
60
+ * (some BSD systems)
61
+ * PS_USE_CHANGE_ARGV
62
+ * assign argv[0] = "string"
63
+ * (some other BSD systems)
64
+ * PS_USE_CLOBBER_ARGV
65
+ * write over the argv and environment area
66
+ * (most SysV-like systems)
67
+ * PS_USE_WIN32
68
+ * push the string out as the name of a Windows event
69
+ * PS_USE_NONE
70
+ * don't update ps display
71
+ * (This is the default, as it is safest.)
72
+ */
73
+ #if defined(HAVE_SETPROCTITLE)
74
+ #define PS_USE_SETPROCTITLE
75
+ #elif defined(HAVE_PSTAT) && defined(PSTAT_SETCMD)
76
+ #define PS_USE_PSTAT
77
+ #elif defined(HAVE_PS_STRINGS)
78
+ #define PS_USE_PS_STRINGS
79
+ #elif (defined(BSD) || defined(__bsdi__) || defined(__hurd__)) && !defined(__darwin__)
80
+ #define PS_USE_CHANGE_ARGV
81
+ #elif defined(__linux__) || defined(_AIX) || defined(__sgi) || (defined(sun) && !defined(BSD)) || defined(ultrix) || defined(__ksr__) || defined(__osf__) || defined(__svr4__) || defined(__svr5__) || defined(__darwin__)
82
+ #define PS_USE_CLOBBER_ARGV
83
+ #elif defined(WIN32)
84
+ #define PS_USE_WIN32
85
+ #else
86
+ #define PS_USE_NONE
87
+ #endif
88
+
89
+
90
+ /* Different systems want the buffer padded differently */
91
+ #if defined(_AIX) || defined(__linux__) || defined(__svr4__)
92
+ #define PS_PADDING '\0'
93
+ #else
94
+ #define PS_PADDING ' '
95
+ #endif
96
+
97
+
98
+ #ifndef PS_USE_CLOBBER_ARGV
99
+ /* all but one options need a buffer to write their ps line in */
100
+ #define PS_BUFFER_SIZE 256
101
+ static char ps_buffer[PS_BUFFER_SIZE];
102
+ static const size_t ps_buffer_size = PS_BUFFER_SIZE;
103
+ #else /* PS_USE_CLOBBER_ARGV */
104
+ static char *ps_buffer; /* will point to argv area */
105
+ static size_t ps_buffer_size; /* space determined at run time */
106
+ #endif /* PS_USE_CLOBBER_ARGV */
107
+
108
+ static size_t ps_buffer_fixed_size; /* size of the constant prefix */
109
+
110
+ /* save the original argv[] location here */
111
+ static int save_argc;
112
+ static char **save_argv;
113
+
114
+
115
+ /*
116
+ * Call this early in startup to save the original argc/argv values.
117
+ * If needed, we make a copy of the original argv[] array to preserve it
118
+ * from being clobbered by subsequent ps_display actions.
119
+ *
120
+ * (The original argv[] will not be overwritten by this routine, but may be
121
+ * overwritten during init_ps_display. Also, the physical location of the
122
+ * environment strings may be moved, so this should be called before any code
123
+ * that might try to hang onto a getenv() result.)
124
+ */
125
+ char **
126
+ save_ps_display_args(int argc, char **argv)
127
+ {
128
+ save_argc = argc;
129
+ save_argv = argv;
130
+
131
+ #if defined(PS_USE_CLOBBER_ARGV)
132
+
133
+ /*
134
+ * If we're going to overwrite the argv area, count the available space.
135
+ * Also move the environment to make additional room.
136
+ */
137
+ {
138
+ char *end_of_area = NULL;
139
+ char **new_environ;
140
+ int i;
141
+
142
+ /*
143
+ * check for contiguous argv strings
144
+ */
145
+ for (i = 0; i < argc; i++)
146
+ {
147
+ if (i == 0 || end_of_area + 1 == argv[i])
148
+ end_of_area = argv[i] + strlen(argv[i]);
149
+ }
150
+
151
+ if (end_of_area == NULL) /* probably can't happen? */
152
+ {
153
+ ps_buffer = NULL;
154
+ ps_buffer_size = 0;
155
+ return argv;
156
+ }
157
+
158
+ /*
159
+ * check for contiguous environ strings following argv
160
+ */
161
+ for (i = 0; environ[i] != NULL; i++)
162
+ {
163
+ if (end_of_area + 1 == environ[i])
164
+ end_of_area = environ[i] + strlen(environ[i]);
165
+ }
166
+
167
+ ps_buffer = argv[0];
168
+ ps_buffer_size = end_of_area - argv[0];
169
+
170
+ /*
171
+ * move the environment out of the way
172
+ */
173
+ new_environ = (char **) malloc((i + 1) * sizeof(char *));
174
+ for (i = 0; environ[i] != NULL; i++)
175
+ new_environ[i] = strdup(environ[i]);
176
+ new_environ[i] = NULL;
177
+ environ = new_environ;
178
+ }
179
+ #endif /* PS_USE_CLOBBER_ARGV */
180
+
181
+ #if defined(PS_USE_CHANGE_ARGV) || defined(PS_USE_CLOBBER_ARGV)
182
+
183
+ /*
184
+ * If we're going to change the original argv[] then make a copy for
185
+ * argument parsing purposes.
186
+ *
187
+ * (NB: do NOT think to remove the copying of argv[], even though
188
+ * postmaster.c finishes looking at argv[] long before we ever consider
189
+ * changing the ps display. On some platforms, getopt() keeps pointers
190
+ * into the argv array, and will get horribly confused when it is
191
+ * re-called to analyze a subprocess' argument string if the argv storage
192
+ * has been clobbered meanwhile. Other platforms have other dependencies
193
+ * on argv[].
194
+ */
195
+ {
196
+ char **new_argv;
197
+ int i;
198
+
199
+ new_argv = (char **) malloc((argc + 1) * sizeof(char *));
200
+ for (i = 0; i < argc; i++)
201
+ new_argv[i] = strdup(argv[i]);
202
+ new_argv[argc] = NULL;
203
+
204
+ #if defined(__darwin__)
205
+
206
+ /*
207
+ * Darwin (and perhaps other NeXT-derived platforms?) has a static
208
+ * copy of the argv pointer, which we may fix like so:
209
+ */
210
+ *_NSGetArgv() = new_argv;
211
+ #endif
212
+
213
+ argv = new_argv;
214
+ }
215
+ #endif /* PS_USE_CHANGE_ARGV or PS_USE_CLOBBER_ARGV */
216
+
217
+ return argv;
218
+ }
219
+
220
+ /*
221
+ * Call this once during subprocess startup to set the identification
222
+ * values. At this point, the original argv[] array may be overwritten.
223
+ */
224
+ void
225
+ init_ps_display(const char *username, const char *dbname,
226
+ const char *host_info, const char *initial_str)
227
+ {
228
+ #ifndef PS_USE_NONE
229
+ /* no ps display if you didn't call save_ps_display_args() */
230
+ if (!save_argv)
231
+ return;
232
+ #ifdef PS_USE_CLOBBER_ARGV
233
+ /* If ps_buffer is a pointer, it might still be null */
234
+ if (!ps_buffer)
235
+ return;
236
+ #endif
237
+
238
+ /*
239
+ * Overwrite argv[] to point at appropriate space, if needed
240
+ */
241
+
242
+ #ifdef PS_USE_CHANGE_ARGV
243
+ save_argv[0] = ps_buffer;
244
+ save_argv[1] = NULL;
245
+ #endif /* PS_USE_CHANGE_ARGV */
246
+
247
+ #ifdef PS_USE_CLOBBER_ARGV
248
+ {
249
+ int i;
250
+
251
+ /* make extra argv slots point at end_of_area (a NUL) */
252
+ for (i = 1; i < save_argc; i++)
253
+ save_argv[i] = ps_buffer + ps_buffer_size;
254
+ }
255
+ #endif /* PS_USE_CLOBBER_ARGV */
256
+
257
+ /*
258
+ * Make fixed prefix of ps display.
259
+ */
260
+
261
+ #ifdef PS_USE_SETPROCTITLE
262
+
263
+ /*
264
+ * apparently setproctitle() already adds a `progname: ' prefix to the
265
+ * ps line
266
+ */
267
+ snprintf(ps_buffer, ps_buffer_size, "");
268
+ #else
269
+ snprintf(ps_buffer, ps_buffer_size,
270
+ "pgpool: ");
271
+ #endif
272
+
273
+ ps_buffer_fixed_size = strlen(ps_buffer);
274
+
275
+ set_ps_display(initial_str, true);
276
+ #endif /* not PS_USE_NONE */
277
+ }
278
+
279
+
280
+
281
+ /*
282
+ * Call this to update the ps status display to a fixed prefix plus an
283
+ * indication of what you're currently doing passed in the argument.
284
+ */
285
+ void
286
+ set_ps_display(const char *activity, bool force)
287
+ {
288
+
289
+ if (!force && !update_process_title)
290
+ return;
291
+
292
+ #ifndef PS_USE_NONE
293
+
294
+ #ifdef PS_USE_CLOBBER_ARGV
295
+ /* If ps_buffer is a pointer, it might still be null */
296
+ if (!ps_buffer)
297
+ return;
298
+ #endif
299
+
300
+ /* Update ps_buffer to contain both fixed part and activity */
301
+ strlcpy(ps_buffer + ps_buffer_fixed_size, activity,
302
+ ps_buffer_size - ps_buffer_fixed_size);
303
+
304
+ /* Transmit new setting to kernel, if necessary */
305
+
306
+ #ifdef PS_USE_SETPROCTITLE
307
+ setproctitle("%s", ps_buffer);
308
+ #endif
309
+
310
+ #ifdef PS_USE_PSTAT
311
+ {
312
+ union pstun pst;
313
+
314
+ pst.pst_command = ps_buffer;
315
+ pstat(PSTAT_SETCMD, pst, strlen(ps_buffer), 0, 0);
316
+ }
317
+ #endif /* PS_USE_PSTAT */
318
+
319
+ #ifdef PS_USE_PS_STRINGS
320
+ PS_STRINGS->ps_nargvstr = 1;
321
+ PS_STRINGS->ps_argvstr = ps_buffer;
322
+ #endif /* PS_USE_PS_STRINGS */
323
+
324
+ #ifdef PS_USE_CLOBBER_ARGV
325
+ {
326
+ int buflen;
327
+
328
+ /* pad unused memory */
329
+ buflen = strlen(ps_buffer);
330
+ memset(ps_buffer + buflen, PS_PADDING, ps_buffer_size - buflen);
331
+ }
332
+ #endif /* PS_USE_CLOBBER_ARGV */
333
+
334
+ #ifdef PS_USE_WIN32
335
+ {
336
+ /*
337
+ * Win32 does not support showing any changed arguments. To make it at
338
+ * all possible to track which backend is doing what, we create a
339
+ * named object that can be viewed with for example Process Explorer.
340
+ */
341
+ static HANDLE ident_handle = INVALID_HANDLE_VALUE;
342
+ char name[PS_BUFFER_SIZE + 32];
343
+
344
+ if (ident_handle != INVALID_HANDLE_VALUE)
345
+ CloseHandle(ident_handle);
346
+
347
+ sprintf(name, "pgident: %s", ps_buffer);
348
+
349
+ ident_handle = CreateEvent(NULL, TRUE, FALSE, name);
350
+ }
351
+ #endif /* PS_USE_WIN32 */
352
+ #endif /* not PS_USE_NONE */
353
+ }
354
+
355
+
356
+ /*
357
+ * Returns what's currently in the ps display, in case someone needs
358
+ * it. Note that only the activity part is returned. On some platforms
359
+ * the string will not be null-terminated, so return the effective
360
+ * length into *displen.
361
+ */
362
+ const char *
363
+ get_ps_display(int *displen)
364
+ {
365
+ #ifdef PS_USE_CLOBBER_ARGV
366
+ size_t offset;
367
+
368
+ /* If ps_buffer is a pointer, it might still be null */
369
+ if (!ps_buffer)
370
+ {
371
+ *displen = 0;
372
+ return "";
373
+ }
374
+
375
+ /* Remove any trailing spaces to offset the effect of PS_PADDING */
376
+ offset = ps_buffer_size;
377
+ while (offset > ps_buffer_fixed_size && ps_buffer[offset - 1] == PS_PADDING)
378
+ offset--;
379
+
380
+ *displen = offset - ps_buffer_fixed_size;
381
+ #else
382
+ *displen = strlen(ps_buffer + ps_buffer_fixed_size);
383
+ #endif
384
+
385
+ return ps_buffer + ps_buffer_fixed_size;
386
+ }
387
+
388
+ /*
389
+ * Show ps idle status
390
+ */
391
+ void pool_ps_idle_display(POOL_CONNECTION_POOL *backend)
392
+ {
393
+ StartupPacket *sp;
394
+ char psbuf[1024];
395
+
396
+ sp = MASTER_CONNECTION(backend)->sp;
397
+ if (MASTER(backend)->tstate == 'T')
398
+ snprintf(psbuf, sizeof(psbuf), "%s %s %s idle in transaction",
399
+ sp->user, sp->database, remote_ps_data);
400
+ else
401
+ snprintf(psbuf, sizeof(psbuf), "%s %s %s idle",
402
+ sp->user, sp->database, remote_ps_data);
403
+ set_ps_display(psbuf, false);
404
+ }
@@ -0,0 +1,435 @@
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
+ * recovery.c: online recovery process
22
+ *
23
+ */
24
+
25
+ #include "config.h"
26
+
27
+ #include <unistd.h>
28
+ #include <string.h>
29
+
30
+ #include "pool.h"
31
+ #include "pool_config.h"
32
+
33
+ #include "libpq-fe.h"
34
+
35
+ #include "watchdog/watchdog.h"
36
+ #include "watchdog/wd_ext.h"
37
+
38
+ #define WAIT_RETRY_COUNT (pool_config->recovery_timeout / 3)
39
+
40
+ #define FIRST_STAGE 0
41
+ #define SECOND_STAGE 1
42
+
43
+ static int exec_checkpoint(PGconn *conn);
44
+ static int exec_recovery(PGconn *conn, BackendInfo *backend, char stage);
45
+ static int exec_remote_start(PGconn *conn, BackendInfo *backend);
46
+ static PGconn *connect_backend_libpq(BackendInfo *backend);
47
+ static int check_postmaster_started(BackendInfo *backend);
48
+
49
+ static char recovery_command[1024];
50
+
51
+ extern volatile sig_atomic_t pcp_wakeup_request;
52
+
53
+ /*
54
+ * Start online recovery.
55
+ * "recovery_node" is the node to be recovered.
56
+ * Master or primary node is chosen in this function.
57
+ */
58
+ int start_recovery(int recovery_node)
59
+ {
60
+ int node_id;
61
+ BackendInfo *backend;
62
+ BackendInfo *recovery_backend;
63
+ PGconn *conn;
64
+ int failback_wait_count;
65
+ #define FAILBACK_WAIT_MAX_RETRY 5 /* 5 seconds should be enough for failback operation */
66
+
67
+ pool_log("starting recovering node %d", recovery_node);
68
+
69
+ if ( (recovery_node < 0) || (recovery_node >= pool_config->backend_desc->num_backends) )
70
+ {
71
+ pool_error("start_recovery: node id %d is not valid", recovery_node);
72
+ return 1;
73
+ }
74
+
75
+ if (VALID_BACKEND(recovery_node))
76
+ {
77
+
78
+ pool_error("start_recovery: backend node %d is alive", recovery_node);
79
+ return 1;
80
+ }
81
+
82
+ Req_info->kind = NODE_RECOVERY_REQUEST;
83
+
84
+ /* select master/primary node */
85
+ node_id = MASTER_SLAVE ? PRIMARY_NODE_ID : REAL_MASTER_NODE_ID;
86
+ backend = &pool_config->backend_desc->backend_info[node_id];
87
+
88
+ /* get node info to be recovered */
89
+ recovery_backend = &pool_config->backend_desc->backend_info[recovery_node];
90
+
91
+ conn = connect_backend_libpq(backend);
92
+ if (conn == NULL)
93
+ {
94
+ pool_error("start_recovery: could not connect master node (%d)", node_id);
95
+ return 1;
96
+ }
97
+
98
+ /* 1st stage */
99
+ if (REPLICATION)
100
+ {
101
+ if (exec_checkpoint(conn) != 0)
102
+ {
103
+ PQfinish(conn);
104
+ pool_error("start_recovery: CHECKPOINT failed");
105
+ return 1;
106
+ }
107
+ pool_log("CHECKPOINT in the 1st stage done");
108
+ }
109
+
110
+ if (exec_recovery(conn, recovery_backend, FIRST_STAGE) != 0)
111
+ {
112
+ PQfinish(conn);
113
+ return 1;
114
+ }
115
+
116
+ pool_log("1st stage is done");
117
+
118
+ if (REPLICATION)
119
+ {
120
+ pool_log("starting 2nd stage");
121
+
122
+ /* 2nd stage */
123
+ *InRecovery = RECOVERY_ONLINE;
124
+ if (pool_config->use_watchdog)
125
+ {
126
+ /* announce start recovery */
127
+ if (WD_OK != wd_start_recovery())
128
+ {
129
+ PQfinish(conn);
130
+ pool_error("start_recovery: timeover for waiting connection closed in the other pgpools");
131
+ return 1;
132
+ }
133
+ }
134
+
135
+ if (wait_connection_closed() != 0)
136
+ {
137
+ PQfinish(conn);
138
+ pool_error("start_recovery: timeover for waiting connection closed");
139
+ return 1;
140
+ }
141
+
142
+ pool_log("all connections from clients have been closed");
143
+
144
+ if (exec_checkpoint(conn) != 0)
145
+ {
146
+ PQfinish(conn);
147
+ pool_error("start_recovery: CHECKPOINT failed");
148
+ return 1;
149
+ }
150
+
151
+ pool_log("CHECKPOINT in the 2nd stage done");
152
+
153
+ if (exec_recovery(conn, recovery_backend, SECOND_STAGE) != 0)
154
+ {
155
+ PQfinish(conn);
156
+ return 1;
157
+ }
158
+ }
159
+
160
+ if (exec_remote_start(conn, recovery_backend) != 0)
161
+ {
162
+ PQfinish(conn);
163
+ pool_error("start_recovery: remote start failed");
164
+ return 1;
165
+ }
166
+
167
+ if (check_postmaster_started(recovery_backend))
168
+ {
169
+ PQfinish(conn);
170
+ pool_error("start_recovery: check start failed");
171
+ return 1;
172
+ }
173
+
174
+ pool_log("%d node restarted", recovery_node);
175
+
176
+ /*
177
+ * reset failover completion flag. this is necessary since
178
+ * previous failover/failback will set the flag to 1.
179
+ */
180
+ pcp_wakeup_request = 0;
181
+
182
+ /* send failback request to pgpool parent */
183
+ send_failback_request(recovery_node);
184
+
185
+ /* wait for failback */
186
+ failback_wait_count = 0;
187
+ while (!pcp_wakeup_request)
188
+ {
189
+ struct timeval t = {1, 0};
190
+ /* polling SIGUSR2 signal every 1 sec */
191
+ select(0, NULL, NULL, NULL, &t);
192
+ failback_wait_count++;
193
+ if (failback_wait_count >= FAILBACK_WAIT_MAX_RETRY)
194
+ {
195
+ pool_log("start_recovery: waiting for wake up request is timeout(%d seconds)",
196
+ FAILBACK_WAIT_MAX_RETRY);
197
+ break;
198
+ }
199
+ }
200
+ pcp_wakeup_request = 0;
201
+
202
+ PQfinish(conn);
203
+
204
+ pool_log("recovery done");
205
+
206
+ return 0;
207
+ }
208
+
209
+ /*
210
+ * Notice all children finishing recovery.
211
+ */
212
+ void finish_recovery(void)
213
+ {
214
+ /* announce end recovery */
215
+ if (pool_config->use_watchdog && *InRecovery != RECOVERY_INIT)
216
+ {
217
+ wd_end_recovery();
218
+ }
219
+
220
+ *InRecovery = RECOVERY_INIT;
221
+ kill(getppid(), SIGUSR2);
222
+ }
223
+
224
+ /*
225
+ * Execute CHECKPOINT
226
+ */
227
+ static int exec_checkpoint(PGconn *conn)
228
+ {
229
+ PGresult *result;
230
+ int r;
231
+
232
+ pool_debug("exec_checkpoint: start checkpoint");
233
+ result = PQexec(conn, "CHECKPOINT");
234
+ r = (PQresultStatus(result) != PGRES_COMMAND_OK);
235
+ PQclear(result);
236
+ pool_debug("exec_checkpoint: finish checkpoint");
237
+ return r;
238
+ }
239
+
240
+ /*
241
+ * Call pgpool_recovery() function.
242
+ */
243
+ static int exec_recovery(PGconn *conn, BackendInfo *backend, char stage)
244
+ {
245
+ PGresult *result;
246
+ char *hostname;
247
+ char *script;
248
+ int r;
249
+
250
+ if (strlen(backend->backend_hostname) == 0 || *(backend->backend_hostname) == '/')
251
+ hostname = "localhost";
252
+ else
253
+ hostname = backend->backend_hostname;
254
+
255
+ script = (stage == FIRST_STAGE) ?
256
+ pool_config->recovery_1st_stage_command : pool_config->recovery_2nd_stage_command;
257
+
258
+ if (script == NULL || strlen(script) == 0)
259
+ {
260
+ /* do not execute script */
261
+ return 0;
262
+ }
263
+
264
+ snprintf(recovery_command,
265
+ sizeof(recovery_command),
266
+ "SELECT pgpool_recovery('%s', '%s', '%s')",
267
+ script,
268
+ hostname,
269
+ backend->backend_data_directory);
270
+
271
+ pool_log("starting recovery command: \"%s\"", recovery_command);
272
+
273
+ pool_debug("exec_recovery: start recovery");
274
+ result = PQexec(conn, recovery_command);
275
+ r = (PQresultStatus(result) != PGRES_TUPLES_OK);
276
+ if (r != 0)
277
+ {
278
+ pool_error("exec_recovery: %s command failed at %s",
279
+ script,
280
+ (stage == FIRST_STAGE) ? "1st stage" : "2nd stage");
281
+ }
282
+ PQclear(result);
283
+ pool_debug("exec_recovery: finish recovery");
284
+ return r;
285
+ }
286
+
287
+ /*
288
+ * Call pgpool_remote_start() function.
289
+ */
290
+ static int exec_remote_start(PGconn *conn, BackendInfo *backend)
291
+ {
292
+ PGresult *result;
293
+ char *hostname;
294
+ int r;
295
+
296
+ if (strlen(backend->backend_hostname) == 0 || *(backend->backend_hostname) == '/')
297
+ hostname = "localhost";
298
+ else
299
+ hostname = backend->backend_hostname;
300
+
301
+ snprintf(recovery_command, sizeof(recovery_command),
302
+ "SELECT pgpool_remote_start('%s', '%s')",
303
+ hostname,
304
+ backend->backend_data_directory);
305
+
306
+ pool_debug("exec_remote_start: start pgpool_remote_start");
307
+ result = PQexec(conn, recovery_command);
308
+ r = (PQresultStatus(result) != PGRES_TUPLES_OK);
309
+ if (r != 0)
310
+ pool_error("exec_remote_start: pgpool_remote_start failed: %s", PQresultErrorMessage(result));
311
+ PQclear(result);
312
+ pool_debug("exec_remote_start: finish pgpool_remote_start");
313
+ return r;
314
+ }
315
+
316
+ /*
317
+ * Check postmaster is started.
318
+ */
319
+ static int check_postmaster_started(BackendInfo *backend)
320
+ {
321
+ int i = 0;
322
+ char port_str[16];
323
+ PGconn *conn;
324
+ char *dbname;
325
+
326
+ snprintf(port_str, sizeof(port_str),"%d", backend->backend_port);
327
+
328
+ /*
329
+ * First we try with "postgres" database.
330
+ */
331
+ dbname = "postgres";
332
+
333
+ do {
334
+ ConnStatusType r;
335
+
336
+ pool_log("check_postmaster_started: try to connect to postmaster on hostname:%s database:%s user:%s (retry %d times)",
337
+ backend->backend_hostname, dbname, pool_config->recovery_user, i);
338
+
339
+ conn = PQsetdbLogin(backend->backend_hostname,
340
+ port_str,
341
+ NULL,
342
+ NULL,
343
+ dbname,
344
+ pool_config->recovery_user,
345
+ pool_config->recovery_password);
346
+
347
+ r = PQstatus(conn);
348
+ PQfinish(conn);
349
+ if (r == CONNECTION_OK)
350
+ return 0;
351
+
352
+ pool_log("check_postmaster_started: failed to connect to postmaster on hostname:%s database:%s user:%s",
353
+ backend->backend_hostname, dbname, pool_config->recovery_user);
354
+
355
+ sleep(3);
356
+ } while (i++ < 3); /* XXX Hard coded retry (9 seconds) */
357
+
358
+ /*
359
+ * Retry with "template1" database.
360
+ */
361
+ dbname = "template1";
362
+ i = 0;
363
+
364
+ do {
365
+ ConnStatusType r;
366
+
367
+ pool_log("check_postmaster_started: try to connect to postmaster on hostname:%s database:%s user:%s (retry %d times)",
368
+ backend->backend_hostname, dbname, pool_config->recovery_user, i);
369
+
370
+ conn = PQsetdbLogin(backend->backend_hostname,
371
+ port_str,
372
+ NULL,
373
+ NULL,
374
+ dbname,
375
+ pool_config->recovery_user,
376
+ pool_config->recovery_password);
377
+
378
+ r = PQstatus(conn);
379
+ PQfinish(conn);
380
+ if (r == CONNECTION_OK)
381
+ return 0;
382
+
383
+ pool_log("check_postmaster_started: failed to connect to postmaster on hostname:%s database:%s user:%s",
384
+ backend->backend_hostname, dbname, pool_config->recovery_user);
385
+
386
+ if (WAIT_RETRY_COUNT != 0)
387
+ sleep(3);
388
+ } while (i++ < WAIT_RETRY_COUNT);
389
+
390
+ pool_error("check_postmaster_started: remote host start up did not finish in %d sec.", pool_config->recovery_timeout);
391
+ return 1;
392
+ }
393
+
394
+ static PGconn *connect_backend_libpq(BackendInfo *backend)
395
+ {
396
+ char port_str[16];
397
+ PGconn *conn;
398
+
399
+ snprintf(port_str, sizeof(port_str),
400
+ "%d", backend->backend_port);
401
+ conn = PQsetdbLogin(backend->backend_hostname,
402
+ port_str,
403
+ NULL,
404
+ NULL,
405
+ "template1",
406
+ pool_config->recovery_user,
407
+ pool_config->recovery_password);
408
+
409
+ if (PQstatus(conn) != CONNECTION_OK)
410
+ {
411
+ PQfinish(conn);
412
+ return NULL;
413
+ }
414
+ return conn;
415
+ }
416
+
417
+ /*
418
+ * Wait all connections are closed.
419
+ */
420
+ int wait_connection_closed(void)
421
+ {
422
+ int i = 0;
423
+
424
+ do {
425
+
426
+ if (Req_info->conn_counter == 0)
427
+ return 0;
428
+
429
+ if (WAIT_RETRY_COUNT != 0)
430
+ sleep(3);
431
+ } while (i++ < WAIT_RETRY_COUNT);
432
+
433
+ pool_error("wait_connection_closed: existing connections did not close in %d sec.", pool_config->recovery_timeout);
434
+ return 1;
435
+ }