Skip to content

[Bug] information_schema.tables on an external Iceberg catalog loads every table from the remote catalog (unconditional COMMENT fill) #65988

Closed

Description

@raghav-reglobe

Search before asking

  • I had searched in the issues and found no similar issues.

Version

master (reproduced on a 2026-07-22 master build)

What's Wrong?

Querying information_schema.tables while switched to an external Iceberg catalog (REST catalog in our case) issues one blocking loadTable against the remote catalog for every table in the catalog, even when the query only projects cheap columns like TABLE_SCHEMA/TABLE_NAME.

On a REST catalog with a few thousand tables, a single listing takes minutes and floods the catalog service with per-table GETs. Since the loads happen inside the listTableStatus thrift handler, clients with statement timeouts (BI tools, dashboards doing schema discovery) just see the query time out. Repeated runs pay the full cost again once the catalog metadata refresh interval passes.

Measured on our cluster: a catalog with 3,882 tables took 2m52s; one with 4,365 tables took 5m38s, with thousands of catalog GETs per scan.

jstack of the master FE during a SELECT table_schema, table_name FROM information_schema.tables scan:

at org.apache.iceberg.rest.RESTSessionCatalog.loadTable(RESTSessionCatalog.java:399)
...
at org.apache.doris.datasource.iceberg.IcebergUtils.getIcebergTable(IcebergUtils.java:943)
at org.apache.doris.datasource.iceberg.IcebergExternalTable.getIcebergTable(IcebergExternalTable.java:150)
at org.apache.doris.datasource.iceberg.IcebergExternalTable.properties(IcebergExternalTable.java:429)
at org.apache.doris.datasource.iceberg.IcebergExternalTable.getComment(IcebergExternalTable.java:155)
at org.apache.doris.service.FrontendServiceImpl.listTableStatus(FrontendServiceImpl.java:756)

Root cause is the interaction of two changes:

So the one column whose fill is a remote round-trip is also the one column that is always computed.

What You Expected?

A projection that does not include TABLE_COMMENT should not load table metadata from the remote catalog, the same way it already skips row counts and the other pruned status columns.

How to Reproduce?

  1. Create an Iceberg REST catalog with a large number of tables (a few hundred is enough to see it clearly).
  2. SWITCH to the catalog and run SELECT table_schema, table_name FROM information_schema.tables;
  3. Observe one loadTable request per table on the catalog service, and minutes of latency on large catalogs.

Anything Else?

Fix appears to be a one-hunk change: guard the comment fill with the same needTableStatusColumn(requiredColumns, "TABLE_COMMENT") check used by the other columns. I will attach a PR.

Are you willing to submit PR?

  • Yes I am willing to submit a PR!

Code of Conduct

Activity

  1. Doris-Breakwater commented on Jul 24, 2026

    @Doris-Breakwater
    Collaborator

    Preliminary maintainer assessment

    Verdict: confirmed code-level performance bug on master, with a high-confidence root cause. The report contains enough evidence to triage without additional logs. Current issue metadata has no labels, assignee, or milestone. A fix is already proposed in #65989, but the current patch has a Thrift contract problem that should be corrected before merge.

    Code-path confirmation

    • BE derives required_columns from the materialized schema-scan slots and sends it in TGetTablesParams (SchemaScanOperatorX -> SchemaTablesScanner::_get_new_table()).
    • FE normalizes that set in FrontendServiceImpl.listTableStatus() and conditionally computes the optional status fields, but currently calls table.getComment() unconditionally.
    • Since [iceberg](fix) Fetch comment PROP from table meta #64263, IcebergExternalTable.getComment() calls properties(), which calls getIcebergTable(). For the reported REST/session-catalog path this reaches Iceberg loadTable, matching the supplied jstack.
    • Therefore, a projection such as TABLE_SCHEMA, TABLE_NAME still performs one metadata load per Iceberg table. The measured latency and request amplification are consistent with this exact call chain.
    • Backward compatibility is already handled by needTableStatusColumn(): if an older BE omits required_columns, its value is null and FE continues to fill the full status.

    Important correction for #65989

    TTableStatus.comment is declared as 3: required string comment in gensrc/thrift/FrontendService.thrift. The current PR simply skips status.setComment(...) when the column is not requested. That leaves the Java field null; generated Thrift Java validation rejects a missing required reference field before writing the response. The C++ scanner also accesses .comment unconditionally because the wire contract says it is required.

    Please keep the required field populated while pruning only the expensive lookup, for example:

    status.setComment(needTableStatusColumn(requiredColumns, "TABLE_COMMENT")
            ? table.getComment()
            : "");

    Initializing the comment to "" and overriding it only when requested is equivalent. Changing the Thrift field to optional is unnecessary and would broaden the compatibility surface.

    Recommended validation

    1. Extend FrontendServiceImplTest so a request without TABLE_COMMENT verifies getComment() is never called, the returned comment is the required empty placeholder, and the result passes Thrift validation/serialization.
    2. Add the positive case: requesting TABLE_COMMENT calls getComment() and returns the real value. Also retain a case with required_columns unset to cover older-BE behavior.
    3. Extend test_tables_status_column_pruning.groovy with a lightweight projection that excludes col=TABLE_COMMENT and a positive projection that includes it. This validates propagation of the required-column set, although the FE mock/serialization test is still needed to catch the current PR defect.
    4. On the reporter's REST catalog, compare the corrected build against the same query and record wall time plus loadTable/table-GET count. The expected result is zero per-table loadTable calls when TABLE_COMMENT is not projected; listing namespaces/tables may still require catalog requests.

    Missing information

    Non-blocking for diagnosis: the exact master commit SHA used for reproduction and the promised before/after timing/request-count result from the patched build. No Doris profile is needed for this FE metadata-RPC issue.

    Suggested next step: label this as a bug affecting Iceberg/external-catalog metadata performance, request the Thrift-safe adjustment and tests on #65989, then merge after the focused FE test and REST-catalog verification pass.

    Breakwater-GitHub-Analysis-Slot: slot_f27888c8b907

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions