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