New resilver-step1.ksh
1 #!/usr/bin/ksh
2 #
3 # CDDL HEADER START
4 #
5 # The contents of this file are subject to the terms of the
6 # Common Development and Distribution License (the License).
7 # You may not use this file except in compliance with the License.
8 #
9 # You can obtain a copy of the license at usr/src/CDDL.txt
10 # or http://www.opensolaris.org/os/licensing.
11 # See the License for the specific language governing permissions
12 # and limitations under the License.
13 #
14 # When distributing Covered Code, include this CDDL HEADER in each
15 # file and include the License file at usr/src/CDDL.txt.
16 # If applicable, add the following below this CDDL HEADER, with the
17 # fields enclosed by brackets [] replaced with your own identifying
18 # information: Portions Copyright [yyyy] [name of copyright owner]
19 #
20 # CDDL HEADER END
21 #
22
23 #
24 # Copyright 2008 Sun Microsystems, Inc. All rights reserved.
25 # Use is subject to license terms.
26 #
27
28 # ident "%Z%%M% %I% %E% SMI"
29
30 # Script to create a base backup of a Postgres database and sync it to an other host.
31 # The normal usage is when a designated standby is running as a primary and the dba
32 # wants to resilver the designated primary with the data on the designated standby.
33
34 # The resilver-step1 script has to be called as the postgres user and it has some
35 # assumptions about the PostgreSQL configuration:
36 #
37 # 1. The file postgresql.conf is linked to an other directory than PGDATA
38 # example: postgresql.conf -> ../conf/postgresql.conf.
39 # 2. The file recovery.conf/recovery.done is linked to an other directoy than PGDATA
40 # example: recovery.conf -> ../conf/recovery.conf.
41 # 3. Every other configration file in PGDATA which has to differ between
42 # the designated primary and the designate standby is linked to an other directory
43 # than PGDATA.
44 # 4. The Postgres users on the primary and on the standby are identical and trust
45 # each other on a ssh login without password request.
46 # 5. It assumes that each PostgreSQL installation is configured with an appropriate
47 # archive command and with an appropriate recovery.conf/done file.
48 #
49 # Example for the designated primary:
50 # archive command in postgresql.conf:
51 # archive_command = '/usr/local/bin/rsync -arv %p standby:/pgs/82_walarchives/%f </dev/null'
52 # contents of recovery.conf/done:
53 # restore_command = 'cp /pgs/82_walarchives/%f %p'
54 #
55 # Example for the designated standby:
56 #
57 # archive command postgresql.conf:
58 # archive_command = '/usr/local/bin/rsync -arv %p primary:/pgs/82_walarchives/%f </dev/null'
59 # contents of recovery.conf/done:
60 # restore_command = '/pgs/postgres-8.2.5/bin/pg_standby -k 10 -t /pgs/data/failover /pgs/82_walarchives %f %p'
61 #
62
63 # You have to customize the following variables:
64
65 # SOURCE_DATA Is the PGDATA directry of the current node, for normal use it would be the
66 # one on the designated standby node.
67 # Example: SOURCE_DATA=/pgs/data
68 #
69 # TARGET_DATA Is the PGDATA of the target node, for normal use it would be the
70 # one on the designated primary node.
71 # Example: TARGET_DATA=/pgs/data
72 #
73 # TARGET Is the name of the targe tnode. for normal usage it would be the name of the
74 # designated primary node.
75 # Example: TARGET=primary-host
76 #
77 # PGS_BASE Is the Postgres Base directory, where the Postgres binaries are located
78 # Example: PGS_BASE=/pgs/postgres-8.2.5 for a custom build PostgreSQL
79 # Example: PGS_BASE=/usr/postgres/8.2 for a PostgreSQL delivered with Solaris 10 8/07
80 #
81 # PRI_GRP Resource group which contains the cluster resource of the designated primary.
82 # Example: PRI_GRP=primary-rg
83 #
84 # STDBY_GRP Resource group which contains the cluster resource of the designated standby.
85 # Example: STDBY_GRP=standby-rg
86 #
87 # STDBY_RS Resource name which of the designated standby resource. This name should be unique on your standby.
88 # The resilver-step1 script will generate the file under /var/tmp/${STDBY_RS}-resilver which is validated
89 # by resilver-step2.
90 # Example: STDBY_RS=standby-rs
91 #
92 # PGPORT The The port the database is listening to.
93 # Example: PGPORT=5432
94 #
95 # ROLECHG_GRP The resource group which contains the rolechanger resource.
96 # Example: ROLECHG_GRP=rolechg-rg
97 #
98 # RSYNC Absolute path to the RSYNC command including the necessary options.
99 # Example: RSYNC="/usr/local/bin/rsync -rav"
100 #
101 # SSH_PASSPHRASE True or false wether or not your ssh key is secured by a passphrase.
102 # Example: SSH_PASSPHRASE=false
103
104 ##### Customize the following variables ##########
105
106 SOURCE_DATA=
107 TARGET_DATA=
108 TARGET=
109 PGS_BASE=
110 PRI_GRP=
111 STDBY_GRP=
112 STDBY_RS=
113 PGPORT=
114 ROLECHG_GRP=
115 RSYNC=
116 SSH_PASSPHRASE=false
117
118 ##### End of customizations ##########
119
120 # generic variables
121
122 TR=/usr/xpg4/bin/tr
123 SSH_AGENT=/usr/bin/ssh-agent
124 SSH_ADD=/usr/bin/ssh-add
125 SSH=/usr/bin/ssh
126 RM=/usr/bin/rm
127 ECHO=/usr/bin/echo
128 TOUCH=/usr/bin/touch
129
130 # Check if the varables are set
131
132 custom_ok=0
133 if [ -z "${SOURCE_DATA}" ]
134 then
135 ${ECHO} "ERROR: customize the SOURCE_DATA variable"
136 custom_ok=1
137 fi
138
139 if [ -z "${TARGET_DATA}" ]
140 then
141 ${ECHO} "ERROR: customize the TARGET_DATA variable"
142 custom_ok=1
143 fi
144
145 if [ -z "${TARGET}" ]
146 then
147 ${ECHO} "ERROR: customize the TARGET variable"
148 custom_ok=1
149 fi
150
151 if [ -z "${PGS_BASE}" ]
152 then
153 ${ECHO} "ERROR: customize the PGS_BASE variable"
154 custom_ok=1
155 fi
156
157 if [ -z "${PRI_GRP}" ]
158 then
159 ${ECHO} "ERROR: customize the PRI_GRP variable"
160 custom_ok=1
161 fi
162
163 if [ -z "${PGPORT}" ]
164 then
165 ${ECHO} "ERROR: customize the PGPORT variable"
166 custom_ok=1
167 fi
168
169 if [ -z "${RSYNC}" ]
170 then
171 ${ECHO} "ERROR: customize the RSYNC variable"
172 custom_ok=1
173 fi
174
175 # perform the following checks onl on clusters
176
177 if [ -d /etc/cluster ]
178 then
179 if [ -z "${STDBY_GRP}" ]
180 then
181 ${ECHO} "ERROR: customize the STDBY_GRP variable"
182 custom_ok=1
183 fi
184
185 if [ -z "${STDBY_RS}" ]
186 then
187 ${ECHO} "ERROR: customize the STDBY_RS variable"
188 custom_ok=1
189 fi
190
191 if [ -z "${ROLECHG_GRP}" ]
192 then
193 ${ECHO} "ERROR: customize the ROLECHG_GRP variable"
194 custom_ok=1
195 fi
196 fi
197
198 if [ ${custom_ok} -ne 0 ]
199 then
200 exit 1
201 fi
202
203 # start the ssh-agent and decrypt the private key depending on the SSH_PASSPHRASE variable
204
205 SSH_PASSPHRASE=`${ECHO} ${SSH_PASSPHRASE}|${TR} "[:upper:]" "[:lower:]"`
206
207 if [ "${SSH_PASSPHRASE}" == "true" ]
208 then
209 eval `${SSH_AGENT} -s` >/dev/null 2>&1
210 ${SSH_ADD}
211 if [ ${?} -ne 0 ]
212 then
213 exit 1
214 fi
215 fi
216
217 # Start a base backup.
218
219 ${PGS_BASE}/bin/psql --port=${PGPORT} -d postgres -c "select pg_start_backup('failover');"
220
221 # Wipe out the targets pgdata.
222
223 $SSH ${TARGET} ${RM} -rf ${TARGET_DATA}/*
224
225 # Rsync the pgdata to the target.
226
227 ${RSYNC} ${SOURCE_DATA}/* ${TARGET}:${TARGET_DATA}
228 if [ ${?} -ne 0 ]
229 then
230 ${ECHO} ERROR: Problems at the rsync, fix this first.
231 ${ECHO} ERROR: Only problems in the pg_xlog directory can be ignored,
232 ${ECHO} ERROR: it will be wiped out anyway.
233 fi
234
235 # Remove the targets pg_xlog.
236
237 $SSH ${TARGET} ${RM} -rf ${TARGET_DATA}/pg_xlog/*
238
239 # stop the base backup
240
241 ${PGS_BASE}/bin/psql --port=${PGPORT} -d postgres -c "select pg_stop_backup();"
242
243 if [ -d /etc/cluster ]
244 then
245 ${ECHO}
246 ${ECHO} "Shutdown the PostgreSQL source database resource group ${STDBY_GRP} and the role changer ${ROLECHG_GRP}"
247 ${ECHO} "with cluster methods and call resilver-step2."
248 ${ECHO}
249 ${ECHO} "Example: In the global zone as root call the three commands below:"
250 ${ECHO} "clrg offline ${ROLECHG_GRP}"
251 ${ECHO} "clrg offline ${STDBY_GRP}"
252 ${ECHO} "clrg status"
253 else
254 ${ECHO}
255 ${ECHO} "Shut down the PostgreSQL source database with PostgreSQL methods and call resilver-step2."
256 ${ECHO}
257 ${ECHO} "Example: As postgres user on this node call the commansd below:"
258 ${ECHO} "${PGS_BASE}/bin/pg_ctl -D ${TARGET_DATA} stop -m fast"
259 fi
260 ${ECHO}
261 ${ECHO} "As postgres user on the designated standby node/zone call resilver-step2."
262
263 # stop the ssh-agent depending on the SSH_PASSPHRASE variable
264
265 if [ "${SSH_PASSPHRASE}" == "true" ]
266 then
267 ${SSH_AGENT} -k >/dev/null 2>&1
268 fi
269
270 # touch the /var/tmp/${STDBY_RS}-resilver file. it is required for step 2
271 ${TOUCH} /var/tmp/${STDBY_RS}-resilver