Skip to content

MDEV-31535: Add privilege-based fast path for SHOW DATABASES listing#5457

Open
itzanway wants to merge 1 commit into
MariaDB:mainfrom
itzanway:MDEV-31535
Open

MDEV-31535: Add privilege-based fast path for SHOW DATABASES listing#5457
itzanway wants to merge 1 commit into
MariaDB:mainfrom
itzanway:MDEV-31535

Conversation

@itzanway

Copy link
Copy Markdown
Contributor

Summary

For users without global database-listing privileges, avoid a full data-directory
scan when building the database list for SHOW DATABASES and
INFORMATION_SCHEMA.SCHEMATA.

Instead of always calling find_files() in make_db_list(), restricted users
can now use a new helper get_acl_databases_for_user() that builds the list
from in-memory privilege tables (acl_dbs, column_priv_hash).

Problem

make_db_list() currently scans the entire data directory via find_files(),
even for users who only have privileges on a small, known set of databases.
This is unnecessary work or restricted users and does not scale well on
installations with many databases.

Solution

  1. Add get_acl_databases_for_user() in sql/sql_acl.cc.

    • Collect exact database names from mysql.db and table/column-level grants.
    • Match grantees the same way as the existing visibility checks:
      • db-level: priv_user, active role, and PUBLIC (mirrors acl_get_all3())
      • table-level: priv_user and active role (mirrors check_grant_db())
    • Use sctx->host / sctx->ip for host matching.
  2. Gate the fast path in make_db_list() (sql/sql_show.cc) when:

    • the caller is fill_schema_schemata() (SHOW DATABASES / SCHEMATA only)
    • the user lacks global DB-listing privileges
    • all applicable grants use exact database names (no % or _ wildcards)
  3. If any applicable grant contains a wildcard, decline the fast path and fall
    back to the existing find_files() scan.

  4. Preserve existing output ordering by applying the same sort used by
    find_files() (Discovered_table_list::sort() / sort_desc() in debug
    builds).

  5. On fast-path decline, restore the caller's database list to its entry size
    so partial results are not duplicated by the fallback scan.

For users without global database-listing privileges, build the database
list from in-memory ACL tables instead of scanning the data directory
when grants are exact-name only. Mirror acl_get_all3()/check_grant_db()
grantee handling (user, active role, PUBLIC), scope the optimization to
SCHEMATA, preserve find_files() ordering, and add MTR coverage.
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant