@@ -28,11 +28,12 @@ clone_full_name="${zfs_pool}/${clone_name}"
28
28
clone_dir=" ${mount_dir} /${clone_name} "
29
29
# Directory of PGDATA in the clone mount.
30
30
clone_pgdata_dir=" ${clone_dir}${pgdata_subdir} "
31
+ # Directory of PGDATA in the promote container.
32
+ container_pgdata_dir=" /var/lib/postgresql/pgdata"
31
33
32
34
# Postgres configuration.
33
35
# Port on which Postgres will be started using clone's PGDATA.
34
- clone_port=${CLONE_PORT:- 6999}
35
- pg_bin_dir=${PG_BIN_DIR:- " /usr/lib/postgresql/12/bin" }
36
+ clone_port=${CLONE_PORT:- 5432}
36
37
pg_sock_dir=${PG_SOCK_DIR:- " /var/run/postgresql" }
37
38
pg_username=${PGUSERNAME:- " postgres" }
38
39
# Set password with PGPASSWORD env.
@@ -108,11 +109,24 @@ echo "host all all 0.0.0.0/0 md5" >> ${clone_pgdata_dir}/pg_hba.conf
108
109
echo "" > ${clone_pgdata_dir} /pg_ident.conf
109
110
SH
110
111
111
- ${sudo_cmd} ${pg_bin_dir} /pg_ctl \
112
- -D " ${clone_pgdata_dir} " \
113
- -o " -p ${clone_port} -c 'shared_buffers=4096'" \
114
- -W \
115
- start
112
+ echo >&2 " Run container"
113
+
114
+ # Make sure that PGDATA has correct permissions.
115
+ user_owner=$( sudo ls -ld ${clone_pgdata_dir} /PG_VERSION | awk ' {print $3}' )
116
+ group_owner=$( sudo ls -ld ${clone_pgdata_dir} /PG_VERSION | awk ' {print $4}' )
117
+ sudo chown -R ${user_owner} :${group_owner} ${clone_pgdata_dir}
118
+
119
+ container_name=" dblab_promote"
120
+ sudo docker run \
121
+ --name ${container_name} \
122
+ --label dblab_control \
123
+ --restart on-failure \
124
+ --volume ${clone_pgdata_dir} :${container_pgdata_dir} \
125
+ --env PGDATA=${container_pgdata_dir} \
126
+ --user postgres \
127
+ --detach \
128
+ postgres:${pg_ver} -alpine
129
+
116
130
117
131
# Now we are going to wait until we can connect to the server.
118
132
# If it was a replica, it may take a while..
@@ -121,7 +135,7 @@ ${sudo_cmd} ${pg_bin_dir}/pg_ctl \
121
135
122
136
failed=true
123
137
for i in {1..1000}; do
124
- if [[ $( ${pg_bin_dir} / psql -p $clone_port -U ${pg_username} -d ${pg_db} -h ${pg_sock_dir} -XAtc ' select pg_is_in_recovery() ' ) == " t " ]]; then
138
+ if [[ $( sudo docker exec ${container_name} psql -p ${ clone_port} -U ${pg_username} -d ${pg_db} -h ${pg_sock_dir} -XAtc ' select 1 ' ) == " 1 " ]]; then
125
139
failed=false
126
140
break
127
141
fi
@@ -130,19 +144,24 @@ for i in {1..1000}; do
130
144
done
131
145
132
146
if $failed ; then
133
- >&2 echo " Failed to start Postgres (in standby mode)"
147
+ echo >&2 " Failed to start Postgres (in standby mode)"
148
+ sudo docker rm --force ${container_name}
134
149
exit 1
135
150
fi
136
151
152
+ should_be_promoted=$( sudo docker exec ${container_name} psql -p ${clone_port} -U ${pg_username} -d ${pg_db} -h ${pg_sock_dir} -XAtc ' select pg_is_in_recovery()' )
153
+
137
154
# Save data state timestamp.
138
155
# - if we had a replica, we can use `pg_last_xact_replay_timestamp()`,
139
156
# - if it is a master initially, the DB state timestamp must be provided by user in unix time format.
140
157
if [[ ! -z ${DATA_STATE_AT+x} ]]; then
141
158
# For testing, use:
142
159
# DATA_STATE_AT=$(TZ=UTC date '+%Y%m%d%H%M%S')
143
160
data_state_at=" ${DATA_STATE_AT} "
161
+ elif [[ $should_be_promoted != " t" ]]; then
162
+ data_state_at=$( TZ=UTC date ' +%Y%m%d%H%M%S' )
144
163
else
145
- data_state_at=$( ${pg_bin_dir} / psql \
164
+ data_state_at=$( sudo docker exec ${container_name} psql \
146
165
--set ON_ERROR_STOP=on \
147
166
-p ${clone_port} \
148
167
-U ${pg_username} \
@@ -153,11 +172,14 @@ else
153
172
fi
154
173
155
174
# Promote to the master. Again, it may take a while.
156
- ${sudo_cmd} ${pg_bin_dir} /pg_ctl -D ${clone_pgdata_dir} -W promote
175
+ if [[ $should_be_promoted == " t" ]]; then
176
+ echo >&2 " Promote"
177
+ sudo docker exec ${container_name} pg_ctl -D ${container_pgdata_dir} -W promote
178
+ fi
157
179
158
180
failed=true
159
181
for i in {1..1000}; do
160
- if [[ $( ${pg_bin_dir} / psql -p ${clone_port} -U ${pg_username} -d ${pg_db} -h ${pg_sock_dir} -XAtc ' select pg_is_in_recovery()' ) == " f" ]]; then
182
+ if [[ $( sudo docker exec ${container_name} psql -p ${clone_port} -U ${pg_username} -d ${pg_db} -h ${pg_sock_dir} -XAtc ' select pg_is_in_recovery()' ) == " f" ]]; then
161
183
failed=false
162
184
break
163
185
fi
@@ -166,7 +188,8 @@ for i in {1..1000}; do
166
188
done
167
189
168
190
if $failed ; then
169
- >&2 echo " Failed to promote Postgres to master"
191
+ echo >&2 " Failed to promote Postgres to master"
192
+ sudo docker rm --force ${container_name}
170
193
exit 1
171
194
fi
172
195
181
204
# ###############################################################################
182
205
183
206
# Finally, stop Postgres and create the base snapshot ready to be used for thin provisioning
184
- ${sudo_cmd} ${pg_bin_dir} /pg_ctl -D ${clone_pgdata_dir} -w stop
185
- # todo: check that it's stopped, similiraly as above
207
+ sudo docker stop ${container_name}
186
208
187
209
${sudo_cmd} rm -rf ${clone_pgdata_dir} /pg_log
188
210
@@ -193,5 +215,7 @@ sudo zfs set dblab:datastateat="${data_state_at}" ${clone_full_name}@${snapshot_
193
215
194
216
${sudo_cmd} rm -rf /tmp/trigger_${clone_port}
195
217
218
+ sudo docker rm ${container_name}
219
+
196
220
# Return to previous working directory.
197
221
cd -
0 commit comments