-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathor-entrypoint.sh
380 lines (330 loc) · 18.7 KB
/
or-entrypoint.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
#!/usr/bin/env bash
# THIS FILE IS FOR MIGRATION OF EXISTING DB TO TIMESCALEDB IMAGE AS TIMESCALE INIT SCRIPTS AREN'T RUN WHEN DB
# ALREADY EXISTS; IT ALSO DOES AN AUTOMATIC REINDEX OF THE DB WHEN OR_REINDEX_COUNTER CHANGES TO SIMPLIFY MIGRATIONS
# IT ALSO AUTOMATICALLY HANDLES UPGRADING OF DATABASE AND DURING MAJOR VERSION CHANGES
# BASED ON: https://github.com/pgautoupgrade/docker-pgautoupgrade
source /docker-entrypoint.sh
docker_setup_env
# Append max connections arg if needed
if [ $POSTGRES_MAX_CONNECTIONS -gt 0 ]; then
set -- "$@" -c max_connections=${POSTGRES_MAX_CONNECTIONS}
fi
# Check for presence of old/new directories, indicating a failed previous autoupgrade
echo "----------------------------------------------------------------------"
echo "Checking for left over artifacts from a failed previous autoupgrade..."
echo "----------------------------------------------------------------------"
OLD="${PGDATA}/old"
NEW="${PGDATA}/new"
if [ -d "${OLD}" ]; then
echo "*****************************************"
echo "Left over OLD directory found. Aborting."
echo "*****************************************"
exit 10
fi
if [ -d "${NEW}" ]; then
echo "*****************************************"
echo "Left over NEW directory found. Aborting."
echo "*****************************************"
exit 11
fi
echo "-------------------------------------------------------------------------------"
echo "No artifacts found from a failed previous autoupgrade. Continuing the process."
echo "-------------------------------------------------------------------------------"
if [ -n "$DATABASE_ALREADY_EXISTS" ]; then
echo "-----------------------------------------"
echo "Performing checks on existing database..."
echo "-----------------------------------------"
# Make sure timescaledb library is set to preload (won't work otherwise)
echo "---------------------------------------------------------------------------------------"
echo "Existing postgresql.conf found checking for shared_preload_libraries = 'timescaledb'..."
echo "---------------------------------------------------------------------------------------"
RESULT=$(cat "$PGDATA/postgresql.conf" | grep "^shared_preload_libraries = 'timescaledb'" || true)
if [ -n "$RESULT" ]; then
echo "-------------------------------------------"
echo "Timescale DB library already set to preload"
echo "-------------------------------------------"
else
echo "------------------------------------------------------------------"
echo "Adding shared_preload_libraries = 'timescaledb' to postgresql.conf"
echo "------------------------------------------------------------------"
echo "shared_preload_libraries = 'timescaledb'" >> "$PGDATA/postgresql.conf"
echo "timescaledb.telemetry_level=off" >> "$PGDATA/postgresql.conf"
fi
########################################################################################
# Do upgrade checks - Adapted from https://github.com/pgautoupgrade/docker-pgautoupgrade
########################################################################################
# Get the version of the PostgreSQL data files
DB_VERSION=$PG_MAJOR
if [ -s "${PGDATA}/PG_VERSION" ]; then
DB_VERSION=$(cat "${PGDATA}/PG_VERSION")
fi
if [ "$DB_VERSION" != "$PG_MAJOR" ] && [ "$OR_DISABLE_AUTO_UPGRADE" == "true" ]; then
echo "---------------------------------------------------------------------------------"
echo "Postgres major version has changed but OR_DISABLE_AUTO_UPGRADE=true so container will likely fail to start!"
echo "---------------------------------------------------------------------------------"
fi
# Try and upgrade if needed
if [ "$DB_VERSION" != "$PG_MAJOR" ] && [ "$OR_DISABLE_AUTO_UPGRADE" != "true" ]; then
echo "---------------------------------------------------------------------------------"
echo "Postgres major version is newer than the existing DB, performing auto upgrade..."
echo "---------------------------------------------------------------------------------"
if [ -f "${PGDATA}/postmaster.pid" ]; then
echo "-----------------------------------------------------------------------------------------------------"
echo "Looks like the server did not previously shutdown properly which will prevent pg_upgrade from working"
echo "try stopping the whole stack, bringing only the postgresql container up and then stopping it again"
echo "-----------------------------------------------------------------------------------------------------"
exit 1
fi
if [ ! -d "/usr/lib/postgresql/${DB_VERSION}" ]; then
echo "--------------------------------------------------------------------------------------------------"
echo "Postgres executable version '$DB_VERSION' is not included in this image so cannot auto upgrade"
echo "--------------------------------------------------------------------------------------------------"
exit 1
fi
# Don't automatically abort on non-0 exit status, as that messes with these upcoming mv commands
set +e
# Move the PostgreSQL data files into a subdirectory of the mount point
echo "---------------------------------------"
echo "Creating OLD temporary directory ${OLD}"
echo "---------------------------------------"
mkdir "${OLD}"
if [ ! -d "${OLD}" ]; then
echo "*********************************************************************"
echo "Creation of temporary directory '${OLD}' failed. Aborting completely"
echo "*********************************************************************"
exit 7
fi
echo "--------------------------------------------"
echo "Creating OLD temporary directory is complete"
echo "--------------------------------------------"
echo "-------------------------------------------------------"
echo "Moving existing data files into OLD temporary directory"
echo "-------------------------------------------------------"
mv -v "${PGDATA}"/* "${OLD}"
echo "-------------------------------------------------------------------"
echo "Moving existing data files into OLD temporary directory is complete"
echo "-------------------------------------------------------------------"
echo "---------------------------------------"
echo "Creating NEW temporary directory ${NEW}"
echo "---------------------------------------"
mkdir "${NEW}"
if [ ! -d "${NEW}" ]; then
echo "********************************************************************"
echo "Creation of temporary directory '${NEW}' failed. Aborting completely"
echo "********************************************************************"
# With a failure at this point we should be able to move the old data back
# to its original location
mv -v "${OLD}"/* "${PGDATA}"
exit 8
fi
echo "--------------------------------------------"
echo "Creating NEW temporary directory is complete"
echo "--------------------------------------------"
echo "-----------------------------------------------------"
echo "Changing permissions of temporary directories to 0700"
echo "-----------------------------------------------------"
chmod 0700 "${OLD}" "${NEW}"
echo "---------------------------------------------------------"
echo "Changing permissions of temporary directories is complete"
echo "---------------------------------------------------------"
# Return the error handling back to automatically aborting on non-0 exit status
set -e
# If no initdb arguments were passed to us from the environment, then work out something valid ourselves
if [ "x${POSTGRES_INITDB_ARGS}" != "x" ]; then
echo "------------------------------------------------------------------------------"
echo "Using initdb arguments passed in from the environment: ${POSTGRES_INITDB_ARGS}"
echo "------------------------------------------------------------------------------"
else
echo "-------------------------------------------------"
echo "Remove postmaster.pid file from PG data directory"
echo "-------------------------------------------------"
rm -f "${OLD}"/postmaster.pid
echo "------------------------------------"
echo "Determining our own initdb arguments"
echo "------------------------------------"
COLLATE=unset
CTYPE=unset
ENCODING=unset
COLLATE=$(echo 'SHOW LC_COLLATE' | "/usr/lib/postgresql/${DB_VERSION}/bin/postgres" --single -D "${OLD}" "${POSTGRES_DB}" | grep 'lc_collate = "' | cut -d '"' -f 2)
CTYPE=$(echo 'SHOW LC_CTYPE' | "/usr/lib/postgresql/${DB_VERSION}/bin/postgres" --single -D "${OLD}" "${POSTGRES_DB}" | grep 'lc_ctype = "' | cut -d '"' -f 2)
ENCODING=$(echo 'SHOW SERVER_ENCODING' | "/usr/lib/postgresql/${DB_VERSION}/bin/postgres" --single -D "${OLD}" "${POSTGRES_DB}" | grep 'server_encoding = "' | cut -d '"' -f 2)
POSTGRES_INITDB_ARGS="--locale=${COLLATE} --lc-collate=${COLLATE} --lc-ctype=${CTYPE} --encoding=${ENCODING}"
echo "---------------------------------------------------------------"
echo "The initdb arguments we determined are: ${POSTGRES_INITDB_ARGS}"
echo "---------------------------------------------------------------"
fi
# Initialise the new PostgreSQL database directory
echo "--------------------------------------------------------------------------------------------------------------------"
echo "Old database using collation settings: '${POSTGRES_INITDB_ARGS}'. Initialising new database with those settings too"
echo "--------------------------------------------------------------------------------------------------------------------"
initdb --username="${POSTGRES_USER}" ${POSTGRES_INITDB_ARGS} ${PGDATA}/new/
echo "------------------------------------"
echo "New database initialisation complete"
echo "------------------------------------"
# Change into the PostgreSQL database directory, to avoid a pg_upgrade error about write permissions
cd "${PGDATA}"
# Run the pg_upgrade command itself
echo "---------------------------------------"
echo "Running pg_upgrade command, from $(pwd)"
echo "---------------------------------------"
pg_upgrade --link -b /usr/lib/postgresql/${DB_VERSION}/bin -B /usr/lib/postgresql/${PG_MAJOR}/bin -d $OLD -D $NEW
echo "--------------------------------------"
echo "Running pg_upgrade command is complete"
echo "--------------------------------------"
# Move the new database files into place
echo "-----------------------------------------------------"
echo "Moving the upgraded database files to the active directory"
echo "-----------------------------------------------------"
mv -v "${NEW}"/* "${PGDATA}"
echo "-----------------------------------------"
echo "Moving the upgraded database files is complete"
echo "-----------------------------------------"
# Re-use the pg_hba.conf and pg_ident.conf from the old data directory
echo "--------------------------------------------------------------"
echo "Copying the old pg_hba and pg_ident configuration files across"
echo "--------------------------------------------------------------"
cp -f "${OLD}/pg_hba.conf" "${OLD}/pg_ident.conf" "${PGDATA}"
echo "-------------------------------------------------------------------"
echo "Copying the old pg_hba and pg_ident configuration files is complete"
echo "-------------------------------------------------------------------"
# Don't automatically abort on non-0 exit status
set +e
# Copy any reindex counter files
echo "--------------------------------------------------------------"
echo "Copying reindex and TS version files across"
echo "--------------------------------------------------------------"
cp -f ${OLD}/OR_REINDEX_* ${PGDATA}
cp -f ${OLD}/OR_TS_VERSION ${PGDATA}
echo "-------------------------------------------------------------------"
echo "Copying reindex files is complete"
echo "-------------------------------------------------------------------"
# Remove the left over database files
echo "---------------------------------"
echo "Removing left over database files"
echo "---------------------------------"
rm -rf "${OLD}" "${NEW}" delete_old_cluster.sh
echo "---------------------------------------------"
echo "Removing left over database files is complete"
echo "---------------------------------------------"
echo "**********************************************************"
echo "Automatic upgrade process finished with no errors reported"
echo "**********************************************************"
# Return the error handling back to automatically aborting on non-0 exit status
set -e
fi
# Do timescale upgrade if needed - First look for latest extension version number in extension files
echo "----------------------------------------------------------"
echo "Checking latest available TimescaleDB extension version..."
echo "----------------------------------------------------------"
TS_VERSION_REGEX="\-\-([0-9|\.]+)\."
TS_SCRIPT_NAME=$(find /usr/share/postgresql/$PG_MAJOR/extension/ -type f -name "timescaledb--*.sql" | sort | tail -n 1)
TS_VERSION=""
TS_VERSION_FILE="${PGDATA}/OR_TS_VERSION"
if [ "$TS_SCRIPT_NAME" == "" ] || ! [[ $TS_SCRIPT_NAME =~ $TS_VERSION_REGEX ]]; then
echo "------------------------------------------------------"
echo "Cannot determine current TimescaleDB extension version"
echo "------------------------------------------------------"
exit 15
else
TS_VERSION=${BASH_REMATCH[1]}
fi
if [ "$TS_VERSION" == "" ]; then
echo "------------------------------------------------------"
echo "Cannot determine current TimescaleDB extension version"
echo "------------------------------------------------------"
exit 15
fi
DO_TS_UPGRADE=false
echo "Checking whether Timescale needs upgrading..."
if [ ! -f "${TS_VERSION_FILE}" ]; then
echo "-----------------------------------------------------"
echo "No OR_TS_VERSION file so assuming upgrade is required"
echo "-----------------------------------------------------"
DO_TS_UPGRADE=true
else
echo "-------------------------------------------------------"
echo "Getting version number from existing OR_TS_VERSION file"
echo "-------------------------------------------------------"
PREVIOUS_TS_VERSION=$(cat "$TS_VERSION_FILE")
if [ "${PREVIOUS_TS_VERSION}" != "${TS_VERSION}" ]; then
echo "------------------------------------------------------------------------------"
echo "TimescaleDB extension upgrade required ${PREVIOUS_TS_VERSION} -> ${TS_VERSION}"
echo "------------------------------------------------------------------------------"
DO_TS_UPGRADE=true
else
echo "----------------------------------------------------"
echo "TimescaleDB extension is up to date at: ${TS_VERSION}"
echo "----------------------------------------------------"
fi
fi
if [ "$DO_TS_UPGRADE" == "true" ] && [ "$OR_DISABLE_AUTO_UPGRADE" == "true" ]; then
echo "----------------------------------------------------------------------------------"
echo "TimescaleDB upgrade can be performed but OR_DISABLE_AUTO_UPGRADE=true so skipping!"
echo "----------------------------------------------------------------------------------"
fi
if [ "${OR_DISABLE_AUTO_UPGRADE}" == "true" ]; then
DO_TS_UPGRADE=false
fi
# Do re-indexing check
DO_REINDEX=false
if [ "$OR_DISABLE_REINDEX" == 'true' ] || [ -z "$OR_REINDEX_COUNTER" ]; then
echo "----------------------------"
echo "OR_REINDEX check is disabled"
echo "----------------------------"
else
echo "---------------------------------------"
echo "Checking whether REINDEX is required..."
echo "---------------------------------------"
REINDEX_FILE="$PGDATA/OR_REINDEX_COUNTER.$OR_REINDEX_COUNTER"
if [ -f "$REINDEX_FILE" ]; then
echo "-------------------------------------------------------------------------"
echo "REINDEX file '$REINDEX_FILE' already exists so no re-indexing required"
echo "-------------------------------------------------------------------------"
else
echo "-------------------------------------------------------------------------"
echo "REINDEX file '$REINDEX_FILE' doesn't exist so re-indexing required"
echo "-------------------------------------------------------------------------"
DO_REINDEX=true
fi
fi
if [ "$DO_REINDEX" == "true" ] || [ "$DO_TS_UPGRADE" == "true" ]; then
echo "-------------------------"
echo "Starting temporary server"
echo "-------------------------"
docker_temp_server_start "$@"
# Cannot do this on a running DB as the extension is configured to preload
if [ "$DO_TS_UPGRADE" == "true" ]; then
echo "------------------------"
echo "Performing TS upgrade..."
echo "------------------------"
# Don't automatically abort on non-0 exit status, just in case timescaledb extension isn't installed on the DB
set +e
docker_process_sql -X -c "ALTER EXTENSION timescaledb UPDATE;"
if [ $? -eq 0 ]; then
docker_process_sql -c "CREATE EXTENSION IF NOT EXISTS timescaledb_toolkit; ALTER EXTENSION timescaledb_toolkit UPDATE;"
fi
# Return the error handling back to automatically aborting on non-0 exit status
set -e
echo "-------------------"
echo "TS upgrade complete"
echo "-------------------"
echo "$TS_VERSION" > "${PGDATA}/OR_TS_VERSION"
fi
if [ "$DO_REINDEX" == "true" ]; then
echo "----------------------------------"
echo "Running timescaledb tune script..."
echo "----------------------------------"
/docker-entrypoint-initdb.d/001_timescaledb_tune.sh
echo "---------------------"
echo "Re-indexing the DB..."
echo "---------------------"
docker_process_sql -c "REINDEX database $POSTGRES_DB;"
echo "------------------"
echo "REINDEX completed!"
echo "------------------"
touch "$REINDEX_FILE"
fi
docker_temp_server_stop
fi
fi
exec /docker-entrypoint.sh $@