数据库迁移
数据库迁移
相关源文件
本章引用的主要源码文件:
CONTRIBUTING.mdREADME.mdREADME.zh-CN.mdbackend/alembic.inibackend/alembic/README.mdbackend/alembic/env.pybackend/alembic/versions/351faebd379d_add_curator_fields.pybackend/alembic/versions/57b53544726e_add_document_set_tables.pybackend/alembic/versions/6a804aeb4830_duplicated_no_harm_user_file_migration.pybackend/alembic/versions/6d387b3196c2_basic_auth.pybackend/alembic/versions/800f48024ae9_add_id_to_connectorcredentialpair.pybackend/alembic/versions/9aadf32dfeb4_add_user_files.pybackend/alembic/versions/da4c21c69164_chosen_assistants_changed_to_jsonb.pybackend/alembic_tenants/README.mdbackend/alembic_tenants/env.pybackend/alembic_tenants/script.py.makobackend/alembic_tenants/versions/14a83a331951_create_usertenantmapping_table.pybackend/alembic_tenants/versions/3b45e0018bf1_add_new_available_tenant_table.pybackend/ee/onyx/background/celery/tasks/tenant_provisioning/tasks.pybackend/ee/onyx/server/tenants/schema_management.pybackend/onyx/connectors/README.mdbackend/onyx/db/tag.pybackend/onyx/server/features/build/db/sandbox.pybackend/tests/external_dependency_unit/db/test_tag_race_condition.pybackend/tests/integration/multitenant_tests/tenants/test_tenant_provisioning_rollback.pybackend/tests/integration/tests/indexing/file_connector/test_files/.onyx_metadata.jsonbackend/tests/unit/ee/onyx/server/tenants/test_schema_management.pybackend/tests/unit/onyx/background/celery/tasks/tenant_provisioning/__init__.pybackend/tests/unit/onyx/background/celery/tasks/tenant_provisioning/test_check_available_tenants.pydeployment/README.mddeployment/docker_compose/README.md
目的与范围
本文档介绍了 Onyx 中使用的数据库迁移系统,该系统用于管理 PostgreSQL 数据库的模式演进。内容涵盖 Alembic 迁移框架、迁移文件结构、如何创建和应用迁移,以及基于模式隔离和预置的多租户部署中的特殊注意事项。
有关数据库模式本身和 SQLAlchemy 模型的信息,请参见 8.1 数据库模型与模式。有关多租户架构的详细信息,请参见 9.2 多租户架构。
Alembic 迁移系统
Onyx 使用 Alembic(一种轻量级的 SQLAlchemy 数据库迁移工具)来管理随时间变化的模式变更。该迁移系统通过 alembic_version 表实现数据库模式变更的版本控制,并确保在不同安装环境中模式状态可重现。
配置与环境
迁移系统通过 backend/ 目录下的几个关键文件进行配置:
| 文件 | 用途 |
|---|---|
backend/alembic.ini | 主 Alembic 配置文件,包含命名环境如 [alembic] 和 [schema_private]。 |
backend/alembic/env.py | 主(公共)模式的迁移运行时环境。backend/alembic/env.py:1-47 |
backend/alembic_tenants/env.py | 租户特定共享管理模式的迁移运行时环境。backend/alembic_tenants/env.py:1-29 |
backend/alembic/versions/*.py | 包含 upgrade() 和 downgrade() 逻辑的单个迁移脚本。backend/alembic/versions/6d387b3196c2_basic_auth.py:1-20 |
Alembic 使用 alembic_version 表跟踪当前数据库版本,并根据修订 ID 按顺序应用迁移。
迁移存储结构
图示:Alembic 目录组织
来源: backend/alembic/env.py:47-49, backend/alembic_tenants/env.py:29-30, backend/alembic/versions/6d387b3196c2_basic_auth.py:1-16
迁移文件结构
每个迁移文件都遵循标准化的结构,包含修订元数据和用于修改数据库的功能逻辑。
修订元数据
每个迁移文件以标识该迁移并确定其在迁移链中位置的元数据开头。例如,在 Basic Auth 迁移中:
backend/alembic/versions/6d387b3196c2_basic_auth.py:15-18
down_revision 字段创建了一个模式变更的有向无环图(DAG),使 Alembic 能够确定应用迁移的正确顺序。
升级和降级函数
每个迁移实现了两个核心函数:
| 函数 | 用途 | 行为 |
|---|---|---|
upgrade() | 应用模式变更 | 使用 alembic.op 创建表、列或索引。 |
downgrade() | 回滚模式变更 | 撤销 upgrade() 操作以恢复之前的状态。 |
示例:用户表创建 在 6d387b3196c2_basic_auth.py 迁移中,upgrade() 函数使用 op.create_table 创建 user 表:
backend/alembic/versions/6d387b3196c2_basic_auth.py:21-37
对应的 downgrade() 函数会删除该表:
backend/alembic/versions/6d387b3196c2_basic_auth.py:92-93
多租户迁移管理
Onyx 支持多租户架构,通过 PostgreSQL 模式实现数据隔离。这需要一种专门的迁移策略,在 backend/alembic/env.py 中管理,并通过 run_alembic_migrations 以编程方式执行。
模式管理逻辑
当启用 MULTI_TENANT 时,迁移会针对特定的租户模式运行。系统使用严格的正则表达式校验来防止模式操作期间的 SQL 注入。
关键多租户函数:
run_alembic_migrations(schema_name):以编程方式对特定模式执行 Alembicupgrade head。backend/ee/onyx/server/tenants/schema_management.py:39-75validate_tenant_id(tenant_id):在将租户 ID 格式化为 SQL 之前,确保其符合 UUID 或 AWS 实例 ID 格式。backend/ee/onyx/server/tenants/schema_management.py:30-36filter_tenants_by_range():通过将租户列表拆分为范围来实现迁移并行化。backend/alembic/env.py:59-105get_schema_options():解析 CLI 参数(通过-x传递)以控制迁移行为(例如upgrade_all_tenants=true)。backend/alembic/env.py:108-180
租户预置与维护
在云/多租户部署中,后台任务 check_available_tenants 确保存在一个随时可用的租户池。
图示:租户预置与迁移流程
来源: backend/ee/onyx/background/celery/tasks/tenant_provisioning/tasks.py:39-114, backend/ee/onyx/background/celery/tasks/tenant_provisioning/tasks.py:127-165, backend/ee/onyx/server/tenants/schema_management.py:39-75
部署场景
迁移已集成到 Onyx 的生命周期中,以确保数据库始终与代码保持同步。
执行命令
| 场景 | 命令 | 上下文 |
|---|---|---|
| 标准生产环境 | alembic upgrade head | 在启动 FastAPI 应用之前,在 api_server 容器中执行。 |
| 多租户(全部) | alembic -x upgrade_all_tenants=true upgrade head | 按顺序升级每个租户模式。backend/alembic/README.md:32-35 |
| 特定模式 | alembic -x schemas=tenant_123,public upgrade head | 仅升级指定的模式。backend/alembic/README.md:37-44 |
| 租户范围 | alembic -x upgrade_all_tenants=true -x tenant_range_start=100 -x tenant_range_end=200 upgrade head | 用于并行化迁移。backend/alembic/README.md:46-56 |
迁移完整性与回滚
系统包含针对失败迁移的健壮错误处理:
- 编程式回滚: 如果
pre_provision_tenant在模式创建后失败,会调用drop_schema清理孤立的模式。backend/tests/integration/multitenant_tests/tenants/test_tenant_provisioning_rollback.py:38-46 - 幂等性:
run_alembic_migrations可以安全地重复执行;如果模式已经处于head状态,则快速执行无操作(no-op)。backend/ee/onyx/background/celery/tasks/tenant_provisioning/tasks.py:127-132
工作流总结
图示:代码实体空间到迁移空间
来源: backend/alembic/versions/6d387b3196c2_basic_auth.py:21-54, backend/ee/onyx/server/tenants/schema_management.py:39-75, backend/ee/onyx/background/celery/tasks/tenant_provisioning/tasks.py:127-165