### Apache Airflow version

2.2.1 (latest released)

### Operating System

PRETTY_NAME="Debian GNU/Linux 10 (buster)

### Versions of Apache Airflow Providers

apache-airflow-providers-ftp==2.0.1
apache-airflow-providers-http==2.0.1
apache-airflow-providers-imap==2.0.1
apache-airflow-providers-sqlite==2.0.1

### Deployment

Docker-Compose

### Deployment details

_No response_

### What happened

Backfilling via catchup=True leads to missing DagRuns. 

See reproduction steps for full details

### What you expected to happen

_No response_

### How to reproduce

Note, this is an issue which we have experienced in our production environment, with a much more complicated DAG. Below are the reproduction steps using breeze.

1. Setup ./breeze environment with the below config modifications
2. Create a simple DAG, with dummy tasks in it (see below example)
2. Set a `start_date` in the past
3. Set `catchup=True`
4. Unpause the DAG
5. Catch up starts and if you view the tree view, you have the false impression that everything has caught up correctly. 
6. However, access the calendar view, you can see the missing DagRuns. 

**Breeze Config**
```
export DB_RESET="true"
export START_AIRFLOW="true"
export INSTALL_AIRFLOW_VERSION="2.2.1"
export USE_AIRFLOW_VERSION="2.2.1"
```

**Dummy DAG**
```
from datetime import datetime
from airflow import DAG
from airflow.operators.dummy import DummyOperator

dag = DAG(
    dag_id="temp_test",
    schedule_interval="@daily",
    catchup=True,
    start_date=datetime(2021, 8, 1),
    max_active_tasks=10,
    max_active_runs=5,
    is_paused_upon_creation=True,
)

with dag:
    task1 = DummyOperator(task_id="task1")
    task2 = DummyOperator(task_id="task2")
    task3 = DummyOperator(task_id="task3")
    task4 = DummyOperator(task_id="task4")
    task5 = DummyOperator(task_id="task5")

    task1 >> task2 >> task3 >> task4 >> task5
```

**Results**
<img width="1430" alt="tree_view" src="https://user-images.githubusercontent.com/10559757/140715465-6bc3831c-d71c-4025-bcde-985010ab31f8.png">

<img width="1435" alt="calendar_view" src="https://user-images.githubusercontent.com/10559757/140715467-1a1a5c9a-3eb6-40ff-8720-ebe6db999028.png">


### Anything else

_No response_

### Are you willing to submit PR?

- [ ] Yes I am willing to submit a PR!

### Code of Conduct

- [X] I agree to follow this project's [Code of Conduct](https://github.com/apache/airflow/blob/main/CODE_OF_CONDUCT.md)

airflow/models/dag.py
:param executor: The executor instance to run the tasks
        :type executor: airflow.executor.base_executor.BaseExecutor
        :param donot_pickle: True to avoid pickling DAG object and send to workers
        :type donot_pickle: bool
        :param ignore_task_deps: True to skip upstream tasks
        :type ignore_task_deps: bool
        :param ignore_first_depends_on_past: True to ignore depends_on_past
            dependencies for the first set of tasks only
        :type ignore_first_depends_on_past: bool
        :param pool: Resource pool to use
        :type pool: str
        :param delay_on_limit_secs: Time in seconds to wait before next attempt to run
            dag run when max_active_runs limit has been reached
        :type delay_on_limit_secs: float
        :param verbose: Make logging output more verbose
        :type verbose: bool
        :param conf: user defined dictionary passed from CLI
        :type conf: dict
        :param rerun_failed_tasks:
        :type: bool
        :param run_backwards:
        :type: bool
        :param run_at_least_once: If true, always run the DAG at least once even
            if no logical run exists within the time range.
        :type: bool
        """
        from airflow.jobs.backfill_job import BackfillJob
        if not executor and local:
            from airflow.executors.local_executor import LocalExecutor
            executor = LocalExecutor()