Advertisement
Guest User

Untitled

a guest
Apr 22nd, 2016
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.73 KB | None | 0 0
  1.  
  2. #!/bin/bash
  3. #
  4. # pgpool-II replication manager
  5. #
  6. # Interfaces with pgpool's pcp command-line tools to provide access to common functions for managing
  7. # load-balancing and failover.
  8. #
  9. # dsimmons@squiz.co.uk
  10. # 2011-08-28
  11. #
  12.  
  13. # PCP configuration
  14. pcp_host="127.0.0.1"
  15. pcp_port="9898"
  16. pcp_username="pgpool"
  17. pcp_password="password"
  18. pcp_timeout="10"
  19.  
  20. # Health check uses psql to connect to each backend server. Specify options required to connect here
  21. psql_healthcheck_opts="-U postgres"
  22.  
  23. # Default options to send to pcp commands
  24. pcp_cmd_preamble="$pcp_timeout $pcp_host $pcp_port $pcp_username $pcp_password"
  25.  
  26. #
  27. # Runs abitrary pcp command with the preamble
  28. #
  29. _pcp()
  30. {
  31. cmd=$1
  32. shift
  33. $cmd $pcp_cmd_preamble $*
  34. }
  35.  
  36. #
  37. # Prints the total number of pgpool nodes.
  38. #
  39. _get_node_count()
  40. {
  41. pcp_node_count $pcp_cmd_preamble
  42. }
  43.  
  44. #
  45. # Prints out node information for the specified pgpool node
  46. #
  47. _get_node_info()
  48. {
  49. if [ -z $1 ]; then
  50. echo "Usage: $0 _get_node_info <node id>" >&2
  51. return 99
  52. fi
  53.  
  54. pcp_node_info $pcp_cmd_preamble $1
  55. }
  56.  
  57. #
  58. # Outputs the replication lag (in bytes) between the specified master and slave
  59. #
  60. _get_replication_lag()
  61. {
  62. if [ -z $2 ]; then
  63. echo "Usage: $0 _get_replication_lag <master node id> <slave node id>" >&2
  64. return 99
  65. fi
  66.  
  67. # Get connection information for nodes
  68. master_node_info=($(_get_node_info $1))
  69. if [ $? -gt 0 ]; then
  70. echo "ERROR: Failed getting node info for node $1" >&2
  71. return 1
  72. fi
  73. slave_node_info=($(_get_node_info $2))
  74. if [ $? -gt 0 ]; then
  75. echo "ERROR: Failed getting node info for node $2" >&2
  76. return 1
  77. fi
  78.  
  79. for n in $1 $2; do
  80. if [ $(_is_node_alive $n) -eq 0 ]; then
  81. echo "ERROR: Node $n is not available. Unable to calculate lag." >&2
  82. return 1
  83. fi
  84. done
  85.  
  86. export PGCONNECT_TIMEOUT=2
  87.  
  88. # Get xlog locations for master and slaves
  89. master_xlog_loc=$(psql $psql_healthcheck_opts -h "${master_node_info[0]}" -p "${master_node_info[1]}" -Atc "SELECT pg_current_xlog_location();")
  90. if [ $? -gt 0 ]; then
  91. echo "ERROR: Failed getting xlog location from node $1" >&2
  92. return 1
  93. fi
  94. slave_xlog_loc=$(psql $psql_healthcheck_opts -h "${slave_node_info[0]}" -p "${slave_node_info[1]}" -Atc "SELECT pg_last_xlog_replay_location();")
  95. if [ $? -gt 0 ]; then
  96. echo "ERROR: Failed getting xlog location from node $2" >&2
  97. return 1
  98. fi
  99.  
  100. # Number of bytes behind
  101. echo $(($(_xlog_to_bytes $master_xlog_loc) - $(_xlog_to_bytes $slave_xlog_loc)))
  102. }
  103.  
  104. #
  105. # Converts specified xlog number to byte location
  106. #
  107. _xlog_to_bytes()
  108. {
  109. if [ -z $1 ]; then
  110. echo "Usage: $0 _xlog_to_bytes <xlog loc>" >&2
  111. echo " Eg.: $0 _xlog_to_bytes 0/2BC825C0" >&2
  112. return 99
  113. fi
  114. logid="${1%%/*}"
  115. offset="${1##*/}"
  116. echo $((0xFFFFFF * 0x$logid + 0x$offset))
  117. }
  118.  
  119. #
  120. # Prints whether the postgresql service on the specified node is responding.
  121. #
  122. _is_node_alive()
  123. {
  124. if [ -z $1 ]; then
  125. echo "Usage: $0 _is_node_alive <node id>" >&2
  126. return 99
  127. fi
  128.  
  129. # Get node connection information
  130. node_info=($(_get_node_info $1))
  131.  
  132. if [ $? -gt 0 ]; then
  133. echo "ERROR: Failed getting node info for node $1" >&2
  134. return 1
  135. fi
  136.  
  137. export PGCONNECT_TIMEOUT=2
  138. result=$(psql $psql_healthcheck_opts -h "${node_info[0]}" -p "${node_info[1]}" -Atc "SELECT 1;" 2>/dev/null)
  139.  
  140. if [ "$result" == "1" ]; then
  141. echo 1
  142. return 1
  143. else
  144. echo 0
  145. return 0
  146. fi
  147. }
  148.  
  149. #
  150. # Get the node ID of the first master
  151. #
  152. _get_master_node()
  153. {
  154. # Get total number of nodes
  155. nodes=$(_get_node_count)
  156.  
  157. if [ $? -gt 0 ]; then
  158. echo "ERROR: Failed getting node count: $nodes" >&2
  159. exit 1
  160. fi
  161.  
  162. c=0
  163.  
  164. # Loop through each node to check if it's the master
  165. while [ $c -lt $nodes ]; do
  166. if [ "$(_is_standby $c)" == "0" ]; then
  167. echo $c
  168. return 0
  169. fi
  170. let c=c+1
  171. done
  172.  
  173. echo "-1"
  174. return 1
  175. }
  176.  
  177. #
  178. # Checks if the node is in postgresql recovery mode (ie. if it is a slave)
  179. #
  180. _is_standby()
  181. {
  182. if [ -z $1 ]; then
  183. echo "Usage: $0 _is_standby <node id>" >&2
  184. return 99
  185. fi
  186.  
  187. # Get node connection information
  188. node_info=($(_get_node_info $1))
  189.  
  190. if [ $? -gt 0 ]; then
  191. echo "ERROR: Failed getting node info for node $1" >&2
  192. return 1
  193. fi
  194.  
  195. export PGCONNECT_TIMEOUT=2
  196. result=$(psql $psql_healthcheck_opts -h "${node_info[0]}" -p "${node_info[1]}" -Atc "SELECT pg_is_in_recovery();" 2>/dev/null)
  197.  
  198. if [ "$result" == "t" ]; then
  199. echo 1
  200. return 1
  201. else
  202. echo 0
  203. return 0
  204. fi
  205. }
  206.  
  207. #
  208. # Attaches the specified node to the pool
  209. #
  210. attach()
  211. {
  212. if [ -z $1 ]; then
  213. echo "Usage: $0 attach <node id>" >&2
  214. return 99
  215. fi
  216.  
  217. pcp_attach_node $pcp_cmd_preamble $1
  218. }
  219.  
  220. #
  221. # Detaches the specified node from the pool
  222. #
  223. detach()
  224. {
  225. if [ -z $1 ]; then
  226. echo "Usage: $0 detach <node id>" >&2
  227. return 99
  228. fi
  229. pcp_detach_node $pcp_cmd_preamble $1
  230. }
  231.  
  232. #
  233. # Recovers the specified node (restores it from current master and re-attaches)
  234. #
  235. recover()
  236. {
  237. if [ -z $1 ]; then
  238. echo "Usage: $0 recover <node id>" >&2
  239. return 99
  240. fi
  241. pcp_recovery_node $pcp_cmd_preamble $1
  242. }
  243.  
  244. #
  245. # Prints the status of the specified node in human readable format.
  246. #
  247. _get_node_status()
  248. {
  249. if [ -z $1 ]; then
  250. echo "Usage: $0 _get_node_status <node id>" >&2
  251. return 99
  252. fi
  253.  
  254. node_info=($(_get_node_info $1))
  255.  
  256. if [ $? -gt 0 ]; then
  257. echo "ERROR: Failed getting node info for node $1" >&2
  258. else
  259. node_role=""
  260. node_replication_lag=""
  261. node_alive=""
  262. case "$(_is_node_alive $1)" in
  263. 1)
  264. node_alive="Up"
  265. ;;
  266. *)
  267. node_alive="Down"
  268. ;;
  269. esac
  270. if [ "$node_alive" == "Up" ]; then
  271.  
  272. # Find out what role this node has
  273. if [ "$(_is_standby $1)" == "1" ]; then
  274.  
  275. node_role="Slave"
  276.  
  277. # Calculation replication lag
  278. master_node=$(_get_master_node)
  279. node_replication_lag=$(_get_replication_lag $master_node $1)
  280. if [ $? -eq 0 ]; then
  281. node_replication_lag="$node_replication_lag bytes"
  282. else
  283. node_replication_log="Unknown"
  284. fi
  285. else
  286. node_role="Master"
  287. fi
  288. fi
  289. case "${node_info[2]}" in
  290. 3)
  291. node_status="detached from pool"
  292. ;;
  293. 2)
  294. node_status="in pool and connected"
  295. ;;
  296. 1)
  297. node_status="in pool"
  298. ;;
  299. *)
  300. node_status="Unknown"
  301. ;;
  302. esac
  303.  
  304. # Print status information about this node
  305. echo "Node: $1"
  306. echo "Host: ${node_info[0]}"
  307. echo "Port: ${node_info[1]}"
  308. echo "Weight: ${node_info[3]}"
  309. echo "Status: $node_alive, $node_status (${node_info[2]})"
  310. [ -n "$node_role" ] && echo "Role: $node_role"
  311. [ -n "$node_replication_lag" ] && echo "Replication lag: $node_replication_lag"
  312. echo ""
  313. fi
  314. }
  315.  
  316. #
  317. # Prints out the status of all pgpool nodes in human readable form.
  318. #
  319. status()
  320. {
  321. # Get total number of nodes
  322. nodes=$(_get_node_count)
  323.  
  324. if [ $? -gt 0 ]; then
  325. echo "ERROR: Failed getting node count: $nodes" >&2
  326. exit 1
  327. fi
  328.  
  329. c=0
  330.  
  331. # Loop through each node to retrieve info
  332. while [ $c -lt $nodes ]; do
  333. _get_node_status $c
  334. let c=c+1
  335. done
  336. }
  337.  
  338. # Run function
  339. if [ ! "$(type -t $1)" ]; then
  340. echo "Usage $0 <option>" >&2
  341. echo "" >&2
  342. echo "Available options:" >&2
  343. echo "$(compgen -A function |grep -v '^_')" >&2
  344. exit 99
  345. else
  346. cmd=$1
  347. shift
  348. $cmd $*
  349.  
  350. exit $?
  351. fi
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement