mirror of
https://github.com/open-webui/open-webui.git
synced 2026-07-25 13:22:59 -05:00
[PR #21944] feat: Implement Redis migration lock for coordinated database migrations #41986
Reference in New Issue
Block a user
📋 Pull Request Information
Original PR: https://github.com/open-webui/open-webui/pull/21944
Author: @jmleksan
Created: 2/27/2026
Status: 🔄 Open
Base:
dev← Head:feat/migration-redis-lock📝 Commits (1)
c03c37bfeat: coordinate DB migrations with Redis lock📊 Changes
4 files changed (+222 additions, -35 deletions)
View changed files
📝
backend/open_webui/config.py(+0 -22)📝
backend/open_webui/env.py(+29 -5)📝
backend/open_webui/internal/db.py(+189 -2)📝
backend/open_webui/migrations/env.py(+4 -6)📄 Description
Pull Request Checklist
Before submitting, make sure you've checked the following:
devbranch. PRs targetingmainwill be immediately closed.devto ensure no unrelated commits (e.g. frommain) are included. Push updates to the existing PR branch instead of closing and reopening.Description
The goal of this PR is to simplify database migrations for users with multiple pods/workers without needing manual intervention or increased overhead to handle race condition.
When multiple pods start with
ENABLE_DB_MIGRATIONS=True, each pod runs peewee and Alembic migrations. Migrations are idempotent, but running them concurrently can cause race conditions. This PR adds optional coordination via Redis: whenREDIS_URLis set and reachable, only one pod at a time holds a migration lock; others block until the lock is free, then run migrations sequentially. If Redis is not configured or unavailable, behavior is unchanged (every pod runs migrations, relying on idempotency).Changes:
MIGRATION_LOCK_TIMEOUT_SECS,MIGRATION_LOCK_RETRY_SLEEP_SECS,MIGRATION_LOCK_MAX_WAIT_SECSwith defaults (600, 5, 900). Used only when Redis is available for the lock._try_acquire_migration_lock()acquires a Redis lock (with retries and timeout) before peewee migrations;release_migration_lock_if_held()is called from config after Alembic. If Redis is unavailable, lock is skipped and all pods run migrations as before.run_migrations()callsrelease_migration_lock_if_held()in afinallyblock so the lock is always released after Alembic.No new dependencies; uses existing Redis client and
RedisLockfrom the codebase. Design uses smart defaults; the new env vars are optional tuning knobs for large or slow DBs.Changelog Entry
REDIS_URLis set and reachable, only one pod at a time runs DB migrations (peewee + Alembic); other pods wait for the lock then run migrations sequentially, avoiding concurrent migration races in multi-pod deployments. Optional env varsMIGRATION_LOCK_TIMEOUT_SECS,MIGRATION_LOCK_RETRY_SLEEP_SECS, andMIGRATION_LOCK_MAX_WAIT_SECS(defaults 600, 5, 900) allow tuning for large or slow databases. If Redis is not configured or unavailable, behavior is unchanged and all pods run migrations as before.Description
Added
MIGRATION_LOCK_TIMEOUT_SECS(default 600),MIGRATION_LOCK_RETRY_SLEEP_SECS(default 5),MIGRATION_LOCK_MAX_WAIT_SECS(default 900).internal/db.py: acquire before peewee migrations, release after Alembic inconfig.run_migrations().Changed
ENABLE_DB_MIGRATIONSis true: attempt to acquire Redis migration lock first (when Redis is available); then run peewee and Alembic as before; release lock inrun_migrations()finallyblock.Breaking Changes
Contributor License Agreement
By submitting this pull request, I confirm that I have read and fully agree to the Contributor License Agreement (CLA), and I am providing my contributions under its terms.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.