You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by as...@apache.org on 2026/04/14 21:40:43 UTC
(airflow) branch main updated: Ensure that DB migrations run in a single connection. (#65231)
This is an automated email from the ASF dual-hosted git repository.
ash pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new e3fea3a5556 Ensure that DB migrations run in a single connection. (#65231)
e3fea3a5556 is described below
commit e3fea3a55564fb4b0daeafe43c521f0ee2001f7a
Author: Ash Berlin-Taylor <as...@apache.org>
AuthorDate: Tue Apr 14 22:40:34 2026 +0100
Ensure that DB migrations run in a single connection. (#65231)
This was discovered by running with a custom External DB manager that had some
gnarly queries that ended up being locked behind this transaction.
`_single_connection_pool` replaces `settings.engine` with a
SingletonThreadPool engine. But `work_session` was created before that — it
still holds an internal reference to the old engine object.
_single_connection_pool has no way to rebind work_session.
So when _get_current_revision(session=work_session) runs on line 1203 — inside
the _single_connection_pool() block — it calls session.connection() which goes
through the old engine, not the SingletonThreadPool. The old engine's pool was
disposed and recreated empty by engine.dispose(), so it creates a brand new
connection. That connection is completely outside _single_connection_pool's
control.
_single_connection_pool guarantees one connection on the new engine. It can't
prevent work_session from creating connections on the old one. The name is a
bit of a lie — it's really "single connection pool for new code that uses
settings.engine", not "single connection total."
---
airflow-core/src/airflow/utils/db.py | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/airflow-core/src/airflow/utils/db.py b/airflow-core/src/airflow/utils/db.py
index c16a797b1a2..9293f1c49ac 100644
--- a/airflow-core/src/airflow/utils/db.py
+++ b/airflow-core/src/airflow/utils/db.py
@@ -1204,6 +1204,13 @@ def _run_upgradedb(
with _configured_alembic_environment() as env:
source_heads = env.script.get_heads()
+ # End the read-only transaction from _get_current_revision before
+ # external DB manager migrations, which may run DDL that is blocked by
+ # open transactions (e.g. CREATE INDEX CONCURRENTLY). The advisory lock
+ # from create_global_lock() is unaffected: it is session-level and held
+ # on a separate connection.
+ work_session.rollback()
+
if current_revision == source_heads[0] and not _SKIP_EXTERNAL_DB_MANAGERS_UPGRADE.get():
external_db_manager = RunDBManager()
external_db_manager.upgradedb(work_session, use_migration_files=use_migration_files)