Db2 SQLCODE

SQLCODE -905: Resource limit exceeded

SQLCODE -905 (SQLSTATE 57014) means Db2 stopped an SQL statement because it used more CPU time than a resource limit allows. The message names the limit, its value in CPU seconds and service units, and where the limit came from.

Other names for this code

Also written as SQL -905, SQLCODE=-905, SQLCODE = -905, db2 -905, sqlstate 57014, SQL0905N, resource limit being exceeded, ASUTIME -905, RLF -905.

What it means

Db2 for z/OS can cap the CPU a statement uses. The usual way is the resource limit facility (RLF), which reads rows from resource limit tables named DSNRLSTxx or DSNRLMTxx. A routine can also have its own ASUTIME limit. When a statement goes over its limit, Db2 cancels it with -905.

The message has three parts.

  • RESOURCE NAME is the column the limit came from, such as ASUTIME.
  • LIMIT gives the cap in CPU seconds and in service units.
  • DERIVED FROM tells you the source. It's the name of an RLF table, a subsystem parameter, or SYSIBM.SYSROUTINES. A subsystem parameter means no RLF row applied, or Db2 couldn't read the table, so a default such as RLFERR for local dynamic SQL was used.

What happens next depends on the source. For an RLF table or a subsystem parameter, only the statement ends, and the program can run more SQL. If a cursor was involved, it stays where it was, and only CLOSE or PREPARE work on it. When a routine passes its ASUTIME, Db2 rolls back the transaction and the thread is in a must-roll-back state until the program issues ROLLBACK.

Db2 for LUW uses SQL0905N with the same SQLSTATE for its own resource limits.

Common causes

  • A query does far more work than planned, for example a table space scan after statistics went stale or an index was dropped.
  • A user runs an ad hoc query through SPUFI, QMF or a client tool, and the RLF row for that plan, package or user has a low limit.
  • No RLF row matches the statement, so the default in RLFERR or RLFERRD applies, and it's lower than people expect.
  • A stored procedure or function runs longer than the ASUTIME defined for it.
  • A dynamic statement inside a routine runs under the limit of the top-level calling package, which applies to the whole thread.

How to find the problem

  1. Read the DERIVED FROM part of the message. It tells you whether to look at an RLF table, a subsystem parameter or the routine definition.
  2. For an RLF table, query it, for example SELECT * FROM SYSIBM.DSNRLST01, and find the row that matches the plan, package, collection, authorization ID or location. The table's qualifier is set when Db2 is installed, so it may differ in your shop.
  3. Use -DISPLAY RLIMIT to see which RLF tables are active.
  4. For a routine, check the ASUTIME column for it in SYSIBM.SYSROUTINES.
  5. EXPLAIN the statement and compare the access path with what you expected. Db2 also writes a trace record with more detail about the failure.

How to fix it

  • Tune the statement first. Add or fix an index, refresh statistics with RUNSTATS and rebind, or narrow the query.
  • If the work is legitimate, ask the team that owns the RLF tables to raise the limit for that package, plan or user, then refresh the limits with -START RLIMIT ID=01.
  • Change the routine's ASUTIME with ALTER PROCEDURE or ALTER FUNCTION if the limit is too low for real work.
  • For dynamic SQL inside a routine, raise the ASUTIME for the top-level calling package in the RLF table.
  • After an ASUTIME roll back, issue ROLLBACK before running any more SQL.

IBM documentation

IBM documentation: -905. Use the documentation for your installed release.

Report a correction to WND Software.

Questions

Why does the query run in batch but fail from a query tool?

RLF rows usually target specific plans, packages or users. Interactive tools often get a tight limit, while batch packages get a higher one or none.

Can the program continue after -905?

If the limit came from an RLF table or a subsystem parameter, yes. If a routine passed its ASUTIME, it must issue ROLLBACK first.

What does DERIVED FROM a subsystem parameter mean?

No RLF row matched the statement, or Db2 couldn't read the RLF table. Db2 used the default limit from a subsystem parameter such as RLFERR instead.