Apache Airflow 数据库后端搭建与配置完全指南:SQLite / PostgreSQL / MySQL 实战
Apache Airflow 依赖关系型元数据库来存储 DAG、任务实例、调度状态等核心元数据,所有调度与执行逻辑都围绕它运转。本文以 Airflow 官方 HowTo 文档(airflow-core/docs/howto/set-up-database.rst)为骨架,结合当前仓库源码,完整讲解数据库后端的选择、连接串(Database URI)配置、SQLite / PostgreSQL / MySQL 三种后端的搭建步骤、驱动与连接池调优、数据库初始化,以及生产环境下的监控与维护方案。读完本文,你将能独立为 Airflow 部署一个可用的元数据库,并理解底层配置项的真实作用。
选择数据库后端
Airflow 通过 SQLAlchemy 与元数据库交互(参见 airflow-core/src/airflow/settings.py 中引擎与 Session 的构建逻辑)。如果你想真正"试驾"Airflow,官方建议将数据库后端设置为 PostgreSQL 或 MySQL;默认情况下 Airflow 使用 SQLite,它仅用于开发目的。
当前仓库支持的数据库引擎版本如下,请先核对你的数据库版本——过旧的版本可能无法支持全部 SQL 语句:
| 数据库 | 支持版本 |
|---|---|
| PostgreSQL | 14、15、16、17、18 |
| MySQL | 8.0、8.4、Innovation 版本 |
| SQLite | 3.15.0+ |
如果你计划运行多个 Scheduler(调度器高可用),还需要满足额外要求:多个 Scheduler 共同写入元数据库,因此后端必须选用支持并发写入的 PostgreSQL 或 MySQL,且连接配置需符合 Scheduler HA 的数据库要求,可参考仓库中关于 Scheduler 高可用的文档说明。
警告:不支持 MariaDB。尽管 MariaDB 与 MySQL 高度相似,Airflow 官方明确不将 MariaDB 作为后端支持。两者之间已知存在差异(例如索引处理方式),Airflow 的迁移脚本和应用程序执行均未在 MariaDB 上做过测试。曾有用户尝试用 MariaDB 跑 Airflow 并引发大量运维问题,官方强烈不鼓励这种做法,且由于使用者极少,社区也不会为 MariaDB 后端提供支持。
数据库 URI 与连接配置
Airflow 使用 SQLAlchemy 连接数据库,因此需要配置 Database URL。你可以在 [database] 配置段的 sql_alchemy_conn 选项中设置它,常见的做法是通过环境变量 AIRFLOW__DATABASE__SQL_ALCHEMY_CONN 注入:
export AIRFLOW__DATABASE__SQL_ALCHEMY_CONN="postgresql+psycopg://airflow_user:airflow_pass@localhost/airflow_db"
关于 Airflow 配置系统的更多说明,参见 set-config 文档;配置参数的具体定义可查看 config.yml 中
database段。
想查看当前生效的连接串,可以用 airflow config get-value 命令(该命令实现位于 config_command.py):
$ airflow config get-value database sql_alchemy_conn
sqlite:////tmp/airflow/airflow.db
SQLAlchemy 连接串的完整格式由其 URL 规范定义,基本形态为 dialect+driver://user:password@host:port/dbname。下文各数据库章节会给出具体示例。
搭建 SQLite 数据库
SQLite 不需要独立的数据库服务器(数据保存在本地文件中),因此适合开发场景快速跑通 Airflow。但它的限制很多,绝不能用于生产环境。
版本要求与排查
运行 Airflow 2.0+ 需要系统级 SQLite 版本 3.15.0 以上。一些老旧系统的默认 SQLite 版本过低,需要手动升级。注意:这里说的不是 Python 的 sqlite3 库版本,而是系统级 SQLite 应用程序。
有时即使你升级了 SQLite,本机 Python 也报告了高版本,但 Airflow 实际使用的 Python 解释器仍可能通过 LD_LIBRARY_PATH 加载到旧版本。可以用下面的方式确认解释器实际使用的版本:
$ python
Python 3.8.10 (default, Mar 15 2022, 12:22:08)
>>> import sqlite3
>>> sqlite3.sqlite_version
'3.27.2'
需要留意的是,为 Airflow 部署设置环境变量可能会改变 SQLite 库的查找顺序,所以最好保证系统中只保留一个"足够高"版本的 SQLite。
SQLite 连接串示例(四个斜杠表示绝对路径):
sqlite:////home/airflow/airflow.db
在 AmazonLinux AMI 或容器镜像中升级 SQLite
AmazonLinux 的源仓库只能把 SQLite 升级到 3.7,无法满足 Airflow 3.15+ 的要求。可按照以下步骤构建带最新 SQLite3 的基础镜像(或 AMI)。
前置条件:需要 wget、tar、gzip、gcc、make、expect:
yum -y install wget tar gzip gcc make expect
从 sqlite.org 下载源码,本地编译安装(编译参数建议原样保留,其中包含了 FTS、JSON1、RTREE 等扩展):
wget https://www.sqlite.org/src/tarball/sqlite.tar.gz
tar xzf sqlite.tar.gz
cd sqlite/
export CFLAGS="-DSQLITE_ENABLE_FTS3 \
-DSQLITE_ENABLE_FTS3_PARENTHESIS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS5 \
-DSQLITE_ENABLE_JSON1 \
-DSQLITE_ENABLE_LOAD_EXTENSION \
-DSQLITE_ENABLE_RTREE \
-DSQLITE_ENABLE_STAT4 \
-DSQLITE_ENABLE_UPDATE_DELETE_LIMIT \
-DSQLITE_SOUNDEX \
-DSQLITE_TEMP_STORE=3 \
-DSQLITE_USE_URI \
-O2 \
-fPIC"
export PREFIX="/usr/local"
LIBS="-lm" ./configure --disable-tcl --enable-shared --enable-tempstore=always --prefix="$PREFIX"
make
make install
安装完成后,把 /usr/local/lib 加入库搜索路径:
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
搭建 PostgreSQL 数据库
PostgreSQL 是 Airflow 生产环境最推荐的后端之一,先创建 Airflow 使用的数据库与用户:
CREATE DATABASE airflow_db;
CREATE USER airflow_user WITH PASSWORD 'airflow_pass';
GRANT ALL PRIVILEGES ON DATABASE airflow_db TO airflow_user;
-- PostgreSQL 15 需要额外授权:
-- 注意:先连接到 airflow_db 数据库再执行下面的 GRANT
-- 在 psql 中可用 \c airflow_db 切换
GRANT ALL ON SCHEMA public TO airflow_user;
数据库必须使用 UTF-8 字符集。
你可能还需要在 Postgres 的 pg_hba.conf 中加入 airflow 用户的访问控制记录,并 reload 数据库配置使其生效(详见 PostgreSQL 官方关于 pg_hba.conf 的文档)。
警告:在 SQLAlchemy 1.4+ 中,
sql_alchemy_conn必须使用postgresql://作为连接串 scheme。旧版本中可用的postgres://在 SQLAlchemy 1.4+ 会直接报错:sqlalchemy.exc.NoSuchModuleError: Can't load plugin: sqlalchemy.dialects:postgres。
官方建议在连接串中显式指定驱动,例如 psycopg:
postgresql+<driver>://<user>:<password>@<host>/<db>
同步引擎与同步驱动
psycopg(psycopg3)是元数据库的默认同步驱动。当 sql_alchemy_conn 省略驱动(裸 postgresql:// scheme)或仍使用旧的 postgres:// / postgres+psycopg2:// scheme 时,Airflow 会将其自动重写为:
postgresql+psycopg://<user>:<password>@<host>/<db>
如果你需要旧版 psycopg2 驱动,可安装 apache-airflow-providers-postgres[psycopg2] extra,并显式设置连接串:
[database]
sql_alchemy_conn = postgresql+psycopg2://<user>:<password>@<host>/<db>
显式给出的 postgresql+psycopg2:// URL 不会被重写。但要注意:如果配置了该 URL 而环境中没有安装 psycopg2,Airflow 会在连接时直接报错,而不会静默回退到其他驱动。这一逻辑与 settings.py 中对 postgresql+psycopg2 前缀的检测(use_psycopg2_tuning)相呼应——Airflow 对驱动类型非常敏感。
异步引擎与异步驱动
除同步引擎外,Airflow 还为元数据库维护了一个异步 SQLAlchemy 引擎(例如供异步 API 端点使用)。当 [database] sql_alchemy_conn_async 未设置时,其 URL 会从 sql_alchemy_conn 自动推导而来,默认使用 psycopg3 作为异步驱动:
postgresql+psycopg_async://<user>:<password>@<host>/<db>
这一推导逻辑在 settings.py 的 _get_async_conn_uri_from_sync 中实现:映射表将 sqlite 映射为 aiosqlite、postgresql 映射为 psycopg_async(未安装 psycopg 时回退为 asyncpg)、mysql 映射为 aiomysql,其余 scheme 原样返回。
psycopg3 之所以成为默认,是因为它在事务模式 PgBouncer(官方推荐所有生产 Postgres 安装都使用 PgBouncer,见下文)后面无需额外配置即可安全运行:psycopg3 会在默认阈值(5 次执行)之后才延迟语句准备(deferred statement preparation),并且可以用 prepare_threshold=None 完全禁用。
如果 psycopg3 未安装(例如较旧的 apache-airflow-providers-postgres 发行版只带 asyncpg 而不带 psycopg),Airflow 会自动改为推导出 asyncpg URL。
如果你需要 asyncpg 的更高吞吐量,可安装 apache-airflow-providers-postgres[asyncpg] extra 并显式设置异步 URL:
[database]
sql_alchemy_conn_async = postgresql+asyncpg://<user>:<password>@<host>/<db>
注意:asyncpg 使用命名服务端预编译语句(named server-side prepared statements),在事务模式 PgBouncer 下会失效。如果你在事务模式 PgBouncer 后面使用 asyncpg,必须通过 sql_alchemy_connect_args_async 指向 airflow_local_settings.py 中定义的字典来禁用其预编译语句缓存:
# airflow_local_settings.py
connect_args_async = {
"statement_cache_size": 0,
"prepared_statement_cache_size": 0,
}
[database]
sql_alchemy_connect_args_async = airflow_local_settings.connect_args_async
另外,由于 SQLAlchemy 无法在数据库 URI 中直接指定 schema,你需要确保 public schema 在 Postgres 用户的 search_path 中:
- 如果为 Airflow 新建了 Postgres 账号,其默认
search_path为"$user", public,无需修改; - 如果复用了带自定义
search_path的现有账号,可通过命令修改:
ALTER USER airflow_user SET search_path = public;
生产环境强烈建议使用 PgBouncer
Airflow(尤其在高性能场景下)会向元数据库打开大量连接。Postgres 中每个连接都会创建一个进程,连接过多会让 Postgres 资源消耗激增。因此官方建议所有 Postgres 生产部署都使用 PgBouncer 作为数据库代理:它既能聚合来自多个组件的连接池,也能在远端数据库网络不稳定时显著增强连接韧性。仓库中的 Helm Chart 提供了预配置的 PgBouncer 部署方案,只需翻转一个布尔开关即可启用,即使你不用官方 Helm Chart,也可以参考其实现思路。
托管 Postgres 的 keepalive 配置
对于 Azure Postgres、CloudSQL、Amazon RDS 等托管服务,这类服务通常会在空闲约 300 秒后关闭空闲连接,导致报错 psycopg2.operationalerror: SSL SYSCALL error: EOF detected。解决办法是在连接参数中设置 keepalives_idle,使其小于服务端的空闲关闭时间。keepalive 设置可通过 [database] 段的 sql_alchemy_connect_args 配置参数修改,该参数是一个完整导入路径,指向 airflow_local_settings.py 中存放配置参数的字典:
keepalive_kwargs = {
"keepalives": 1,
"keepalives_idle": 30,
"keepalives_interval": 5,
"keepalives_count": 5,
}
然后配置导入路径:
sql_alchemy_connect_args = airflow_local_settings.keepalive_kwargs
关于本地设置(local settings)的配置方式,可参考 Airflow 文档中 Configuring local settings 一节(对应 set-config 相关文档)。
搭建 MySQL 数据库
同样先创建数据库和用户:
CREATE DATABASE airflow_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'airflow_user' IDENTIFIED BY 'airflow_pass';
GRANT ALL PRIVILEGES ON airflow_db.* TO 'airflow_user';
数据库必须使用 UTF-8 字符集。需要注意:较新版本 MySQL 中的
utf8实际是utf8mb4,会导致 Airflow 的索引过大。因此自 Airflow 2.2 起,所有 MySQL 数据库的sql_engine_collation_for_ids会被自动设置为utf8mb3_bin(除非你显式覆盖)。这可能导致 Airflow 数据库中 id 字段出现混合排序规则,但由于 Airflow 所有相关 ID 仅使用 ASCII 字符,不会产生负面影响。该默认值的详细说明见 config.yml。
Airflow 依赖 MySQL 更严格的 ANSI SQL 设置以获得合理的默认行为。请确保在 my.cnf 的 [mysqld] 段下指定 explicit_defaults_for_timestamp=1,也可以给 mysqld 可执行文件传 --explicit-defaults-for-timestamp 开关启动。
官方推荐使用 mysqlclient 驱动,并在 SQLAlchemy 连接串中显式指定:
mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>
重要:Apache Airflow 的持续集成(CI)流程只验证过
mysqlclient驱动与 MySQL 后端的集成。想使用其他驱动,请参阅 SQLAlchemy 的 MySQL Dialect 文档了解下载与连接配置。
另外要特别关注 MySQL 的编码。虽然 utf8mb4 越来越流行(且在 MySQL 8.0 中成为默认字符集),但在 Airflow 2+ 中使用 utf8mb4 需要额外设置:如果使用 utf8mb4 作为字符集,应同时设置 sql_engine_collation_for_ids=utf8mb3_bin。
严格模式下
0000-00-00不是合法日期。某些 Airflow 表使用0000-00-00 00:00:00作为时间戳字段默认值,因此你可能遇到"Invalid default value for 'end_date'"之类的错误。解决办法是禁用 MySQL 服务器的NO_ZERO_DATE模式(参见 MySQL 官方 SQL Mode 文档中的 NO_ZERO_DATE 说明)。
MsSQL:自 Airflow 2.9.0 起不再支持
经 Airflow PMC 成员与 Committer 的讨论和投票决议,MsSQL 不再作为 Airflow 的受支持数据库后端。自 Airflow 2.9.0 起,MsSQL 后端支持已被移除。这不影响现有的 providers(operators 和 hooks)——DAG 依然可以访问和处理 MsSQL 中的数据;但继续将 MsSQL 用作 Airflow 核心元数据库可能报错,导致 Airflow 核心功能不可用。
对于运行在 Airflow 2.7.x 或 2.8.x、希望从 SQL Server 迁移走的用户,官方提供了迁移脚本(airflow-mssql-migration 仓库)。注意该脚本不提供任何支持与担保。
其他相关配置选项
[database] 段还有更多用于控制 SQLAlchemy 行为的配置项,完整清单可在 config.yml 中查看。下面列出与数据库连接直接相关的核心参数:
| 配置项 | 默认值 | 说明 |
|---|---|---|
sql_alchemy_conn |
sqlite:///{AIRFLOW_HOME}/airflow.db |
元数据库的 SQLAlchemy 连接串,敏感项 |
sql_alchemy_conn_async |
由 sql_alchemy_conn 自动推导 |
异步连接使用的连接串;推导逻辑不一定适配所有驱动,可直接显式设置 |
sql_alchemy_schema |
空 | 元数据库使用的 schema(适用于支持多 schema 的数据库) |
sql_alchemy_engine_args |
空 | 以 JSON 编码传给 SQLAlchemy create_engine 的额外引擎关键字参数 |
sql_alchemy_connect_args |
空字典 | 连接参数(connect args)的导入路径;3.1.0 起仅作用于同步引擎 |
sql_alchemy_connect_args_async |
空字典 | 异步连接参数的导入路径,仅作用于异步引擎 |
sql_alchemy_pool_enabled |
True |
是否启用 SQLAlchemy 连接池 |
sql_alchemy_pool_size |
5 |
连接池最大连接数,0 表示不限 |
sql_alchemy_max_overflow |
10 |
池溢出上限,连接总数上限为 pool_size + max_overflow;-1 表示无溢出限制 |
sql_alchemy_pool_recycle |
1800 |
连接在池中空闲多少秒后被失效回收(不适用于 SQLite) |
sql_alchemy_pool_pre_ping |
True |
每次从池取出连接前执行探测(如 SELECT 1),应对连接失效 |
sql_engine_encoding |
utf-8 |
数据库编码 |
sql_engine_collation_for_ids |
同数据库默认 | dag_id、task_id、key、external_executor_id 等列的排序规则 |
sql_alchemy_session_maker |
空 | 自定义 sessionmaker 工厂的导入路径;官方强烈不鼓励使用,配置不当可能导致数据损坏 |
check_migrations |
True |
Airflow 启动时是否运行 alembic 迁移检查 |
max_db_retries |
3 |
数据库操作失败时的重试次数 |
migration_batch_size |
10000 |
迁移时每批处理的行数,大表场景可避免锁与查询超时 |
指定元数据库 schema 的示例
例如,你希望 Airflow 把表安装到 PostgreSQL 数据库的 airflow schema 中,可以设置如下环境变量(注意连接串末尾的 search_path 参数):
export AIRFLOW__DATABASE__SQL_ALCHEMY_CONN="postgresql+psycopg://postgres@localhost:5432/my_database?options=-csearch_path%3Dairflow"
export AIRFLOW__DATABASE__SQL_ALCHEMY_SCHEMA="airflow"
SQL_ALCHEMY_SCHEMA 告诉 Airflow 建表目标 schema,而连接串中的 search_path 则确保会话默认使用该 schema。
初始化数据库
配置好数据库并让 Airflow 连上之后,需要创建数据库 schema。执行迁移命令(实现位于 db_command.py):
airflow db migrate
该命令基于 Alembic 迁移脚本(Airflow 的迁移版本历史位于 airflow-core/src/airflow/migrations)将元数据库结构升级到当前 Airflow 版本所需的状态,同时也会处理已安装 providers 的扩展表迁移(可通过 external_db_managers 配置额外的 DB 管理器)。
Airflow 中的数据库监控与维护
Airflow 重度依赖关系型元数据库来完成任务调度与执行,数据库的监控和正确配置对 Airflow 的性能至关重要。
核心关注点
- 性能影响:过长或过多的查询会显著影响 Airflow 功能,可能源于工作流特殊性、缺少优化或代码缺陷。
- 数据库统计信息:数据库引擎因数据统计信息过期而做出错误的优化决策,会导致性能下降。
职责划分
数据库监控与维护的职责取决于你使用的是自管数据库 + 自管 Airflow,还是托管服务:
- 完全自管环境:部署管理员负责数据库的搭建、配置与维护,包括性能监控、备份管理、周期性清理,以及确保数据库与 Airflow 协同处于最佳状态。
- 托管数据库服务:备份、打补丁、基础监控等由服务商负责;部署管理员仍需监督 Airflow 配置、针对自身工作流优化性能设置、执行周期性清理并持续监控数据库。
- 托管 Airflow 服务:服务商负责 Airflow 及其数据库的配置与维护;部署管理员需要与服务配置协作,确保工作流规模和需求与托管服务的规格、配置相匹配。
监控内容
定期监控应包含:
- CPU、I/O 与内存使用情况;
- 查询频率与数量;
- 慢查询、长查询的识别与记录;
- 低效查询执行计划的检测;
- 磁盘交换与内存使用、缓存交换频率的分析。
工具与策略
- Airflow 本身不提供直接的数据库监控工具;
- 使用服务端监控与日志获取指标;
- 基于设定阈值启用长查询追踪;
- 定期执行维护类任务(如
ANALYZESQL 命令)保持统计信息新鲜。
数据库清理工具
airflow db clean命令:用于帮助管理和清理数据库(如按保留期清理过期元数据);airflow.utils.db_cleanup中的 Python 方法:提供更细粒度、可定制的数据库清理与维护手段,满足特定需求。
建议
- 主动监控:在不显著影响性能的前提下,于生产环境落地监控与日志;
- 数据库专属指南:查阅所选数据库的官方文档获取监控配置指引;
- 托管数据库服务:确认服务商是否提供自动维护任务。
SQLAlchemy 日志(客户端侧)
如需进行详细的查询分析,可以启用 SQLAlchemy 客户端日志(在引擎配置中设置 echo=True)。注意:
- 该方法侵入性较强,会影响 Airflow 客户端侧性能;
- 在繁忙的 Airflow 环境中会产生大量日志;
- 适合 staging 等非生产环境。
可以通过 sql_alchemy_engine_args 配置参数将 echo 参数设为 True,例如:
[database]
sql_alchemy_engine_args = {"echo": true}
谨慎:启用大量日志会影响 Airflow 性能与系统资源。生产环境应优先使用服务端监控而非客户端日志,以最小化性能干扰。
下一步:选择合适的执行器
默认情况下 Airflow 使用 LocalExecutor。配置好元数据库后,你应该考虑为更好的性能配置不同的执行器——元数据库与执行器共同决定了 Airflow 的调度吞吐与并发能力,在生产环境中通常会切换到 CeleryExecutor、KubernetesExecutor 等分布式执行器以匹配 PostgreSQL/MySQL 后端的能力。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0631
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
video-shotcraftAI宣传片skill,使用 Remotion 制作电影级产品视频:提供106 张镜头配方卡和可复用的视频魔板。适用于 Claude Code 与 Codex以及所有其他智能体Markdown00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python09
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00