Skip to content

Commit 898f55e

Browse files
committed
Check locks held during extension upgrade
1 parent 7d393ec commit 898f55e

1 file changed

Lines changed: 39 additions & 0 deletions

File tree

scripts/test_update_from_version.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,14 +142,53 @@ echo "Creating updated database"
142142
run_sql_file test/sql/updates/pre.testing.sql
143143
run_sql_file test/sql/updates/setup.${TEST_VERSION}.sql
144144
run_sql "CHECKPOINT;" >> "${OUTPUT_DIR}/updated.log"
145+
# Checking locks requires loader version 2.29.0+
146+
CHECK_LOCKS=""
147+
if [ "$(echo "${FROM_VERSION}" | awk -F. '{print $2}')" -ge 29 ]; then
148+
CHECK_LOCKS=1
149+
fi
145150
if [ "${UPDATE_MODE}" = singlestep ]; then
146151
singlestep_update
152+
elif [ -n "${CHECK_LOCKS}" ]; then
153+
# Run update inside transaction and dump locks it holds
154+
psql -X -d updated -v ON_ERROR_STOP=1 > "${OUTPUT_DIR}/update_locks.log" 2>&1 <<SQL
155+
BEGIN;
156+
ALTER EXTENSION timescaledb UPDATE TO "${TO_VERSION}";
157+
\pset pager off
158+
-- Count distinct relations locked per schema so a relation locked in several
159+
-- modes (e.g. chunk) is counted once instead of once per lock mode.
160+
SELECT coalesce(n.nspname, '(dropped/rebuilt relation)') AS schema,
161+
count(DISTINCT l.relation) AS relations
162+
FROM pg_locks l
163+
LEFT JOIN pg_class c ON c.oid = l.relation
164+
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
165+
WHERE l.pid = pg_backend_pid()
166+
AND l.locktype = 'relation'
167+
GROUP BY 1
168+
ORDER BY relations DESC;
169+
COMMIT;
170+
SQL
171+
LOCKS_HELD=$(awk -F'|' '/\|/ && $2 ~ /^ *[0-9]+ *$/ {s+=$2} END {print s}' "${OUTPUT_DIR}/update_locks.log")
172+
INTERNAL_LOCKS=$(awk -F'|' '$1 ~ /_timescaledb_internal/ {gsub(/ /,"",$2); print $2}' "${OUTPUT_DIR}/update_locks.log")
147173
else
148174
run_sql "ALTER EXTENSION timescaledb UPDATE TO \"${TO_VERSION}\";"
149175
fi
150176
run_sql_file test/sql/updates/setup.check.sql
151177
} > "${OUTPUT_DIR}/updated.log" 2>&1
152178

179+
if [ -n "${CHECK_LOCKS}" ] && [ "${UPDATE_MODE}" != singlestep ]; then
180+
echo "Locks held by the update transaction (${FROM_VERSION} -> ${TO_VERSION}): ${LOCKS_HELD:-n/a} (_timescaledb_internal: ${INTERNAL_LOCKS:-0})"
181+
182+
if [ "${LOCKS_HELD:-0}" -gt 100 ]; then
183+
echo "ERROR: update transaction locked ${LOCKS_HELD} relations, exceeding the limit of 100"
184+
exit 1
185+
fi
186+
if [ "${INTERNAL_LOCKS:-0}" -gt 50 ]; then
187+
echo "ERROR: update transaction locked ${INTERNAL_LOCKS} relations in _timescaledb_internal, exceeding the limit of 50"
188+
exit 1
189+
fi
190+
fi
191+
153192
echo "Creating restored database"
154193
{
155194
run_sql "CREATE DATABASE restored;"

0 commit comments

Comments
 (0)