New to Kestra?
Use blueprints to kickstart your first workflows.
Find DB2 tablespaces holding free pages below the high water mark, reclaim them with ALTER TABLESPACE REDUCE, then prove the mark came down.
A DB2 DMS tablespace grows to its high water mark and then stays that big. Drop a large table or
delete most of its rows. DB2 hands the extents back to the tablespace as pending-free. The
container file on disk does not shrink. TBSP_USED_PAGES falls, so a used-pages check looks
healthy, while TBSP_TOTAL_PAGES and TBSP_PAGE_TOP stay where the data left them. The volume
stays full. Nothing in the database raises an alert, because from the database's point of view
there is no problem at all.
On the rig behind this blueprint, a tablespace with 120000 rows in it read 8192 total pages,
8160 used pages, 0 free pages, high water mark 8160. After DROP TABLE the same tablespace read
96 used pages and a high water mark still at 8160, with 8064 pages parked in
TBSP_PENDING_FREE_PAGES. So 32 MB of a 33 MB tablespace was dead space that only an
ALTER TABLESPACE ... REDUCE would return.
TBSP_FREE_PAGES is the wrong number to watch here. It counts pages above the high water mark,
which is why it read 0 for the tablespace holding 8064 recoverable pages. The number that
matters is TBSP_PAGE_TOP - TBSP_USED_PAGES.
Detection is a single read of MON_GET_TABLESPACE. The write needs auto_remediate true,
dry_run false, then a typed approval at a Pause. Killing the execution at the pause leaves
every tablespace as it was. Each ALTER TABLESPACE runs on its own, never two at once, because
extent movement competes with live queries for I/O.
detect reads MON_GET_TABLESPACE('', -2) and keeps the rows where
TBSP_PAGE_TOP - TBSP_USED_PAGES clears both a page threshold and a percentage threshold.
The filter also drops anything REDUCE cannot move: SMS tablespaces, temporary content,
tablespaces without reclaimable storage, tablespaces without automatic resize, anything not
in NORMAL state.plan records the names plus the page counts as they were before the run.summary logs the scan. route sends a Slack message naming each tablespace, its high water
mark, its used pages, its pending-free pages, the megabytes on offer.auto_remediate true and dry_run false, approve pauses for a typed true.remediate loops over the tablespaces at concurrencyLimit: 1 and runs
ALTER TABLESPACE "<name>" REDUCE <clause> on each.settle waits, then reverify runs the same query again. If any tablespace is still over
both thresholds, remediation_failed fails the run with the before and after page counts.MON_GET_TABLESPACE reports what
the storage layer actually holds.REDUCE is supported on it.reduce_clause that controls how much of the container file goes back, for the case where
you want the mark lowered without handing the whole file to the filesystem.ALTER TABLESPACE reports
success to the client, so the re-read is the only honest check.DBAs and platform teams running DB2 LUW where storage is billed or capped. The classic trigger is an archive job that drops last quarter's partitions every month, after which the database reports plenty of room while the mount point stays at 95 percent. Also useful after a one off purge, a table rebuild, a migration that left a staging tablespace behind.
Reclaiming space is a read, a decision, a write, then a second read that has to be able to fail
the job. A cron script can do the first three. It cannot pause for a human, keep the approval
next to the evidence that prompted it, then prove the change landed. Kestra gives the Pause,
the typed approval, the per task logs that show the page counts before and after, the errors:
block that reaches Slack when the connection itself breaks. The flow ships with the schedule
disabled, so it is a reporting job until someone turns it on.
Run against DB2 12.1.5.0 in a container, with DMS tablespaces under automatic storage.
clean ran.dry_run=true: logged the statement it would run, changed nothing. The page counts read the
same from the DB2 CLI afterwards.auto_remediate=true, dry_run=false, approval true, clause MAX: high water mark 8160 to
96, total pages 8288 to 192, read back from the DB2 CLI.1 PERCENT: high water mark 8160 to 96, total pages 8384 to 8288. The
clause sized the container shrink. The mark came down either way.ALTER TABLESPACE ran, page counts unchanged at 8160 and 8384.SYSCTRL: DB2 refused the ALTER TABLESPACE with SQL0552N while the task
itself reported success. The re-read found the mark still at 8160 with 8384 total pages, so
the run failed with the before and after counts in the message. The errors: block posted to
Slack.detect failed, the errors: block posted to Slack.DB2 LUW 10.1 or later, since ALTER TABLESPACE ... REDUCE needs reclaimable storage, which is a
property of tablespaces created at DB2 9.7 or later. A tablespace carried forward from an older
release reports RECLAIMABLE_SPACE_ENABLED = 0 and is skipped by the detector.
DB2_PASSWORD: password for the database user.SLACK_WEBHOOK_URL: incoming webhook for the alert and the failure notification.jdbc_url, jdbc_username, jdbc_password: the connection. The user needs EXECUTE on
MON_GET_TABLESPACE to detect, SYSCTRL or SYSADM to reduce.name_pattern, exclude_pattern: LIKE patterns scoping the scan. Defaults are every
tablespace except SYS%.min_free_pages_below_hwm (default 1000), min_free_pct_below_hwm (default 20): both have to
be met before a tablespace is reported.reduce_clause (default MAX): what follows REDUCE. MAX, a size such as 200 M, a
percentage such as 25 PERCENT.settle_duration (default PT5S): wait between the last statement and the re-read.auto_remediate (default false), dry_run (default true): both have to be flipped before any
write happens.DB2_PASSWORD secret plus SLACK_WEBHOOK_URL.min_free_pages_below_hwm and min_free_pct_below_hwm until the list is the one you
would act on.auto_remediate=true and dry_run=false, then answer the pause with
approved=true inside a maintenance window.reduce_clause to a size or a percentage if you want the mark lowered while the container
file keeps most of its space, so a tablespace that refills every month is not re-extending.io.kestra.plugin.jdbc.db2.Query step before the loop that runs
CALL SYSPROC.ADMIN_CMD('REORG TABLE ...') on the tables in the target tablespace, so rows
pack down before the mark is lowered. REDUCE moves extents, it does not compact rows.io.kestra.plugin.opsgenie.notifications.OpsgenieAlert to route
the finding at an on call rota.io.kestra.plugin.core.kv.Set to
trend how fast each tablespace refills.name_pattern at one storage group per execution if you want separate maintenance
windows per group.This blueprint was created by zkasuran.
