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.

@janlindstrom janlindstrom left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks very promising but requires some cleanup and additional work so that
user can verify is fast path used or not.

Comment thread sql/sql_acl.cc

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please no white space changes.

Comment thread sql/sql_acl.cc

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please avoid lambda-functions and use inline functions instead.

Comment thread sql/sql_acl.cc

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar conditions in two places, consider using inline function

create user mdev31535_u1@localhost;
grant select on mdev31535a.* to mdev31535_u1@localhost;

connect (con1,localhost,mdev31535_u1,,);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, but how we could verify that fast path was used and cases where not it was not used?
Maybe need again after select schema_name from information_schema.schemata; additional
explain format=json ...; so that it would show fast path in some field...

Check also if you do select schema_name from information_schema.schemata more than once does result come from query_cache or is same code executed again.

Comment thread sql/sql_acl.cc

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use strncmp instead

@janlindstrom janlindstrom self-assigned this Jul 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

2 participants