Skip to content

MDEV-39548 Cleanup MDL_request boilerplate with ACQUIRE_LOCK macro#5075

Open
longjinvan wants to merge 1 commit into
MariaDB:mainfrom
longjinvan:MDEV-39548
Open

MDEV-39548 Cleanup MDL_request boilerplate with ACQUIRE_LOCK macro#5075
longjinvan wants to merge 1 commit into
MariaDB:mainfrom
longjinvan:MDEV-39548

Conversation

@longjinvan
Copy link
Copy Markdown
Contributor

Description

MDL (Metadata Lock) is MariaDB's locking subsystem that protects database objects (tables, schemas, stored procedures, etc.) from concurrent DDL — for example, preventing a table from being dropped while another thread is reading from it. MDL_request is the "lock request form" that callers must create, initialize, submit, and then extract the resulting MDL_ticket from.

Currently, every MDL lock acquisition requires repetitive boilerplate:

> MDL_request mdl_request;
> MDL_REQUEST_INIT(&mdl_request, namespace, db, object, lock_type, duration);
> if (mdl_context.acquire_lock(&mdl_request, lock_wait_timeout))
>   /* error */;
> ticket = mdl_request.ticket;

This patch introduces MDL_context::ACQUIRE_LOCK() — a set of overloaded methods (wrapped in a macro for FILE/LINE tracking) that combine the above steps into a single call returning MDL_ticket* directly:

> if (!(ticket = mdl_context.ACQUIRE_LOCK(namespace, db, object, lock_type, lock_wait_timeout)))
>   /* error */;
> 

This is a step toward making MDL_request a private implementation detail of the MDL subsystem, reducing its exposure to callers and preventing the class of bugs where stale or misused MDL_request objects cause issues (MDEV-39241, MDEV-39184).

Release Notes

N/A

How can this PR be tested?

  • All MTR tests pass, confirming no regressions introduced by this refactoring.

Basing the PR against the correct MariaDB version

  • This is a refactoring change, and the PR is based against the latest MariaDB development branch.

Copyright

All new code of the whole pull request, including one or several files that are either new files or modified ones, are contributed under the BSD-new license. I am contributing on behalf of my employer Amazon Web Services, Inc.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request streamlines the process of acquiring Metadata Locks (MDL) by adding new acquire_lock methods to the MDL_context class and introducing ACQUIRE_LOCK and ACQUIRE_LOCK_BY_KEY macros. These additions allow for more concise code by removing the need to manually declare and initialize MDL_request objects in many parts of the server, such as in backup operations, DDL logging, and table handling. The reviewer recommended adding an MDL_ prefix to the new macros to ensure consistency with existing naming patterns and to prevent potential namespace conflicts.

Comment thread sql/mdl.h Outdated
@gkodinov gkodinov added the External Contribution All PRs from entities outside of MariaDB Foundation, Corporation, Codership agreements. label May 14, 2026
@svoj svoj self-requested a review May 14, 2026 09:08
Copy link
Copy Markdown
Member

@gkodinov gkodinov left a comment

Choose a reason for hiding this comment

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

Thank you for your contribution! This is a preliminary review.

Nice cleanup. Some more changes and it will be perfect.

Comment thread sql/mdl.h Outdated
Comment thread sql/ddl_log.cc Outdated
@gkodinov gkodinov self-assigned this May 14, 2026
@longjinvan longjinvan force-pushed the MDEV-39548 branch 2 times, most recently from c2c8e8e to a0f3c13 Compare May 14, 2026 18:19
Copy link
Copy Markdown
Contributor

@svoj svoj left a comment

Choose a reason for hiding this comment

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

Looks very nice, a few comments inline.

Comment thread sql/mdl.h Outdated
Comment thread sql/ddl_log.cc
Comment thread sql/lock.cc Outdated
Comment thread sql/partition_info.cc
MDL_SHARED_NO_WRITE, thd->variables.lock_wait_timeout,
MDL_TRANSACTION)))
goto exit;
table->mdl_ticket= tl->mdl_request.ticket;
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.

Dunno, I'd avoid this change as we can't trivially verify that subsequently executed code doesn't rely on initialized tl->mdl_request. Or did you verify this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Reverted — keeping the original MDL_REQUEST_INIT + acquire_lock pattern here since subsequent code may rely on tl->mdl_request being initialized.

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.

I don't see this reverted. Please double check.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sorry about that — I forgot to copy the revert from my test workspace to the submission package. Fixed now.

Comment thread sql/sql_base.cc Outdated
Comment thread sql/sql_base.cc Outdated
Comment thread sql/sql_sequence.cc Outdated
@longjinvan longjinvan force-pushed the MDEV-39548 branch 2 times, most recently from 106f9e7 to 433b5cf Compare May 14, 2026 22:23
Copy link
Copy Markdown
Member

@gkodinov gkodinov left a comment

Choose a reason for hiding this comment

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

LGTM. Please keep working on it for the final review.

@gkodinov gkodinov assigned svoj and unassigned gkodinov May 15, 2026
Copy link
Copy Markdown
Contributor

@svoj svoj left a comment

Choose a reason for hiding this comment

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

There're a few more cases that can be updated:

  1. dict_acquire_mdl_share() - replace both acquire and try_acquire
  2. backup_lock() it is not right that sql_yacc.yy makes decision which lock type to use, change to MDL_ACQIRE_LOCK() please
  3. Item_func_get_lock::val_int() - pre-initialize ull_key instead of ull_request like in Item_func_release_lock::val_int()
  4. open_and_lock_for_insert_delayed() - protection_request can be replaced
  5. trx_purge_table_acquire()
  6. lock_table_names() - global_request can be moved

Comment thread sql/sql_table.cc Outdated
thd->variables.lock_wait_timeout))
if (!(mdl_ticket= thd->mdl_context.MDL_ACQUIRE_LOCK(
MDL_key::BACKUP, "", "", MDL_BACKUP_COMMIT,
MDL_TRANSACTION, thd->variables.lock_wait_timeout)))
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.

You don’t need to use mdl_ticket here. Checking the result of MDL_ACQUIRE_LOCK() is sufficient, as in the original code.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed. Now just checks the return value without assigning to mdl_ticket.

@longjinvan
Copy link
Copy Markdown
Contributor Author

longjinvan commented May 15, 2026

There're a few more cases that can be updated:

  1. dict_acquire_mdl_share() - replace both acquire and try_acquire
  2. backup_lock() it is not right that sql_yacc.yy makes decision which lock type to use, change to MDL_ACQIRE_LOCK() please
  3. Item_func_get_lock::val_int() - pre-initialize ull_key instead of ull_request like in Item_func_release_lock::val_int()
  4. open_and_lock_for_insert_delayed() - protection_request can be replaced
  5. trx_purge_table_acquire()
  6. lock_table_names() - global_request can be moved

Done. Updated in the latest revision:

  • dict_acquire_mdl_shared() — split trylock/blocking paths; trylock uses a new try_acquire_lock() overload, blocking uses MDL_ACQUIRE_LOCK().
  • backup_lock() — now uses MDL_ACQUIRE_LOCK() directly with MDL_SHARED_HIGH_PRIO, no longer relies on the lock type set in sql_yacc.yy.
  • Item_func_get_lock::val_int() — pre-initializes MDL_key ull_key (same pattern as Item_func_release_lock::val_int()), then uses MDL_ACQUIRE_LOCK_BY_KEY().
  • open_and_lock_for_insert_delayed() — protection_request replaced with MDL_ACQUIRE_LOCK(); delayed_get_table() now takes MDL_ticket* directly.
  • trx_purge_table_acquire() — uses the new try_acquire_lock() overload, MDL_request removed.
  • lock_table_names() — global_request removed; loop now uses try_acquire_lock() overload and MDL_ACQUIRE_LOCK() inline.

Add new acquire_lock() overloads on MDL_context that combine MDL_request
initialization and lock acquisition into a single call, returning
MDL_ticket* directly. Convert applicable call sites across the codebase
to use the new ACQUIRE_LOCK macro.

All new code of the whole pull request, including one or several files
that are either new files or modified ones, are contributed under the
BSD-new license. I am contributing on behalf of my employer Amazon Web
Services, Inc.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

External Contribution All PRs from entities outside of MariaDB Foundation, Corporation, Codership agreements.

Development

Successfully merging this pull request may close these issues.

3 participants