Query icon
OutputValues icon
Log icon
If icon
SlackIncomingWebhook icon
Pause icon
Loop icon
Fail icon
Schedule icon

Oracle Tablespace Autoextend Exhaustion Guard

Find full Oracle permanent tablespaces that cannot autoextend (ORA-01653 risk), alert Slack, enable bounded autoextend behind an approval, then re-verify.

Categories
DataInfrastructure

A permanent Oracle tablespace that is full and whose datafiles have AUTOEXTEND OFF cannot grow. The next insert fails with ORA-01653: unable to extend and the application stops writing. The fix is simple once you know which datafile is the problem: enable autoextend on that file with a sane cap. Finding it before the outage is the hard part, because a tablespace can read as 90% used for weeks and only break the night a batch job needs one more extent.

This blueprint checks every permanent tablespace, resolves the real used percent from dba_data_files and dba_free_space, then flags each datafile that is both non-autoextensible and in a tablespace at or above a threshold. It alerts Slack. Behind an approval it can enable AUTOEXTEND ON NEXT 256M MAXSIZE <cap> on each flagged datafile, one at a time, then re-read the data dictionary and fail if any flagged datafile is still fixed.

This blueprint was created by zkasuran.

Findings

Finding What it means Risk
Non-autoextensible datafile in a full permanent tablespace The tablespace is at or above the threshold used and at least one datafile has AUTOEXTEND OFF ORA-01653: unable to extend, writes stop until a DBA intervenes

Autoextend is a property of each datafile, not of the tablespace, so a tablespace can hold one growing file and one fixed file. The guard reports and fixes per datafile, not per tablespace.

How it works

  1. audit (io.kestra.plugin.jdbc.oracle.Query, read-only) joins dba_tablespaces, dba_data_files and dba_free_space. For each permanent, online tablespace it computes used percent as (allocated minus free) over allocated, then returns one row per datafile where autoextensible = 'NO' and the tablespace is at or above used_pct_threshold. Each row carries a ready ALTER DATABASE DATAFILE ... AUTOEXTEND ON statement whose MAXSIZE is the configured cap, never below the file current size.
  2. targets (io.kestra.plugin.core.output.OutputValues) collects the de-duplicated fix statements. summary (io.kestra.plugin.core.log.Log) logs the findings.
  3. route (io.kestra.plugin.core.flow.If):
    • clean: logs that nothing is at risk.
    • findings: alert posts to Slack.
      • remediate_gate runs only when auto_remediate is true and dry_run is false.
      • hold (io.kestra.plugin.core.flow.Pause) waits for a DBA to approve.
      • remediate (io.kestra.plugin.core.flow.Loop, concurrencyLimit: 1) runs each ALTER DATABASE DATAFILE in turn.
      • reaudit and reverify re-read the dictionary. verify_result fails the run if any flagged datafile is still fixed and still full.
  4. errors alerts Slack when the audit itself cannot run, for example an unreachable instance.

What you get

  • The datafiles that will cause an ORA-01653 outage, before the write fails, with the used percent and the tablespace they sit in.
  • A fix per datafile at a bounded MAXSIZE, so a runaway segment cannot fill the disk after autoextend is on.
  • Read-only by default. A change runs only with auto_remediate true, dry_run false and a human approval at the pause.
  • A second read of the data dictionary as proof, so a failed ALTER DATABASE cannot be reported as success.

Who it's for

  • DBAs who have been paged for ORA-01653 and want the warning a week earlier.
  • Platform teams running Oracle under Kestra that want a scheduled, auditable capacity guard.
  • Anyone standing up Oracle on Autonomous or Free where a few tablespaces ship fixed size.

Why orchestrate this with Kestra

Oracle has no built-in job that checks autoextend across tablespaces, alerts a chat channel, waits for a human, applies the fix one datafile at a time and then proves it landed. Kestra runs the audit on a schedule, keeps every run and its SQL in the execution history, gates the write behind auto_remediate, dry_run and a Pause, then fails loudly when the re-check still sees a fixed datafile.

Tested end to end

On Kestra 2.0.5 OSS against Oracle Database Free 23ai (service FREEPDB1), with a local HTTP sink standing in for Slack. Two test tablespaces were built, both near full. W20_LOOSE has an autoextensible datafile at 99.5% used. W20_TIGHT has a fixed AUTOEXTEND OFF datafile at 95.3% used. Filling W20_TIGHT reproduced the real ORA-01653: unable to increase tablespace W20_TIGHT error.

Run Inputs Result
Clean defaults, before the test tablespaces 0 datafiles flagged, clean branch logged
Detect defaults 1 datafile flagged: W20_TIGHT at 95.3% used, autoextend NO. W20_LOOSE at 99.5% used is not flagged because its datafile is autoextensible. Slack alert posted, HTTP 200
Dry run auto_remediate: true, dry_run: true Same report. W20_TIGHT still NO, MAXSIZE still 0
Not approved auto_remediate: true, dry_run: false, pause resumed with no answer No datafile altered. W20_TIGHT still NO
Remediate auto_remediate: true, dry_run: false, pause approved ALTER DATABASE DATAFILE ... AUTOEXTEND ON NEXT 256M MAXSIZE 2048M applied. The re-read shows W20_TIGHT autoextend YES, MAXSIZE 2048 MB. The re-audit returns 0, the run passes
Failure unreachable instance audit fails with ORA-12541, the errors block posts to Slack, HTTP 200

The discriminator is autoextensibility, not fullness. W20_LOOSE sits at 99.5% used and is never flagged because its datafile can still grow, while W20_TIGHT at a lower 95.3% is flagged because its datafile cannot.

Prerequisites

  • A reachable Oracle instance. The JDBC URL uses the thin driver service form jdbc:oracle:thin:@//host:1521/service.
  • For the audit, a user with SELECT_CATALOG_ROLE (or SELECT ANY DICTIONARY), which SYSTEM has. For remediation, a user with ALTER DATABASE.

Secrets

  • ORACLE_PASSWORD: the database password. It is the default of the db_password input, so it is never written in the flow.
  • SLACK_WEBHOOK_URL: the Slack Incoming Webhook used by alert and the errors block.
  • In Kestra OSS, provide each secret as a base64-encoded environment variable prefixed SECRET_.

Inputs

Input Default Purpose
jdbc_url jdbc:oracle:thin:@//oracle-host:1521/FREEPDB1 Instance to check
db_user system Database user
db_password {{ secret('ORACLE_PASSWORD') }} Database password
used_pct_threshold 90 Percent used at or above which a tablespace is at risk
datafile_max_size_mb 2048 MAXSIZE cap applied when autoextend is enabled
excluded_tablespaces [] Permanent tablespaces allowed to stay fixed size
auto_remediate false Allow ALTER DATABASE
dry_run true Must be false for a change to run

Quick start

  1. Add the ORACLE_PASSWORD and SLACK_WEBHOOK_URL secrets.
  2. Import the flow and set jdbc_url to your instance.
  3. Run it once with the defaults and read the findings per datafile.
  4. Agree the MAXSIZE cap with the storage owner, then run with auto_remediate: true and dry_run: false and approve the pause.
  5. Enable the daily trigger, which always runs read-only.

How to extend

  • Set a per-tablespace cap by widening the audit query, for example a larger MAXSIZE for a staging tablespace.
  • Add temporary tablespaces and tempfiles by reading dba_temp_files in a second branch.
  • Open a ticket as well as a Slack alert by adding a Jira or ServiceNow task to the findings branch.
  • Loop over several instances by moving jdbc_url into a list and wrapping the audit in a Loop.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.