Airflow异常:Web端已暂停的自定义DAG被调度器持续执行
刚上手Airflow遇到这种“不听指挥”的情况确实挺闹心😅,结合你的描述和常见的Airflow踩坑点,我整理了几个大概率的原因和对应的解决办法:
1. 代码里硬编码了强制启动的参数
先检查你的DAG定义代码,是不是在default_args或者DAG实例化时,手动加了is_paused_upon_creation=False?比如:
default_args = { # 其他参数... 'is_paused_upon_creation': False } dag = DAG( 'SWAT_Tutorial_01', default_args=default_args, # 也可能直接在这里设置 is_paused_upon_creation=False, schedule_interval='*/6 * * * *', start_date=datetime(2024, 1, 1) )
要是有这个设置,哪怕你在Web UI手动暂停,元数据库里的状态可能会被代码重载覆盖。解决方案就是删掉这个参数(默认是True,创建后自动暂停),或者改成True,然后重启调度器,再去UI里确认状态。
2. 调度器没同步到最新的DAG状态
Airflow调度器会定期拉取元数据库的DAG状态,但偶尔会因为缓存或进程没刷新导致不同步。试试这几个操作:
- 重启Airflow调度器:根据你的部署方式,比如用systemd的话就执行
sudo systemctl restart airflow-scheduler,直接用命令行启动的话就重启进程 - 在Web UI的该DAG页面,点击顶部的Refresh按钮强制刷新状态
- 清理DAG解析缓存:删除
$AIRFLOW_HOME/dags下的临时文件,或者执行airflow dags reserialize重新序列化DAG
3. start_date和catchup设置导致补跑任务
你设了每6小时调度一次,如果start_date是过去很久的时间,而且catchup=True(这是Airflow默认值),那么调度器会自动补跑从start_date到现在所有错过的周期。哪怕你暂停了DAG,暂停前已经触发的任务会继续执行,要是状态同步不及时,还可能继续生成新的补跑任务。
解决办法:
- 在DAG实例化时加上
catchup=False,禁止自动补跑:
dag = DAG( 'SWAT_Tutorial_01', # 其他参数... catchup=False, schedule_interval='*/6 * * * *' )
- 如果已经堆了一堆待执行的补跑任务,去UI里选中这些任务,点击Clear按钮删掉,再确认DAG的暂停状态。
4. 元数据库状态和UI显示不一致
极端情况下,元数据库(比如PostgreSQL/MySQL)的dag表里,这个DAG的is_paused字段可能和UI显示的不一样。可以直接查数据库验证:
SELECT dag_id, is_paused FROM dag WHERE dag_id = 'SWAT_Tutorial_01';
如果查询结果显示is_paused为false,但UI显示已暂停,那就是元数据不同步。手动更新一下:
UPDATE dag SET is_paused = true WHERE dag_id = 'SWAT_Tutorial_01';
然后重启调度器和Web服务器,让状态同步。
先从这几个方向排查,应该能解决问题。要是还不行,去看看调度器的日志,有没有关于这个DAG的解析错误或者状态读取失败的信息,能帮你进一步定位。
内容的提问来源于stack exchange,提问作者Dinesh Pohane




