iharshlalakiya opened a new pull request, #73251:
URL: https://github.com/apache/airflow/pull/73251
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
closes: #73248
On PostgreSQL, migration 0049 converts `xcom.value` from `bytea` to `jsonb`.
A single `jsonb` document holds at most 268435455 bytes of array elements or
object pairs, while `bytea` allowed up to 1 GB, so a value written by Airflow 2
can be impossible to convert. The conversion is a single atomic `ALTER TABLE
xcom ALTER COLUMN value TYPE JSONB USING CAST(...)`, so one such row aborts the
entire migration with `ProgramLimitExceeded`, leaves alembic at `9fc3fc5de720`,
and
every retry fails at the same step. The only way forward today is to find
and delete the rows by hand.
This moves those values into the `_xcom_archive` table the migration already
creates for the pickled values it also cannot convert, so no new table is
introduced and the upgrade completes. The `dag_id`/`task_id`/`run_id`/`key` of
everything archived is printed, so the affected XComs can still be retrieved
afterwards. The two kinds of archived row are distinguishable by their
first byte (`0x80` for pickled).
### Why the rows are chosen by attempting the conversion, not by size
Size is unreliable in both directions, so the migration defines a `pg_temp`
function that tries the exact cast the `ALTER` will perform and archives only
the rows that genuinely fail:
- The limit applies to a document's **elements**, not to the value as a
whole, so a long top-level string can be far larger than 268435455 bytes and
still convert. Filtering on size would archive data unnecessarily.
- The parse expands the value enormously, so a value far **under** the limit
can still fail. Measured on PostgreSQL 16, the densest possible input
(`[1,1,1,...]`, two bytes per element) converts fine at 30.5 MB of text and
fails from roughly 34.3 MB with `invalid memory alloc request size 1073741824`
— it exhausts the 1 GB allocation limit long before the element cap is reached.
Filtering at 268435455 would miss these entirely and the migration would still
abort.
An `octet_length` screen in front of the probe keeps it off rows that cannot
be affected. It is set at 8 MB, about 4x below the smallest measured failure,
and is deliberately not derived from the element cap, which is not what a value
of this shape hits first.
Scoped to PostgreSQL — MySQL and SQLite use generic `JSON` and have no
equivalent per-value cap.
### Testing
Verified against PostgreSQL 16:
- Reproduced the reported failure: a 283 MB value fails the unpatched cast
with
`ProgramLimitExceeded: total size of jsonb array elements exceeds the
maximum of 268435455 bytes`,
and with this change it is archived and the cast completes.
- The added test asserts that an unconvertible row is archived, that a
**valid** row above the
screen is kept (so the probe decides, not the size), and that the cast
then succeeds.
- The existing sanitization regression suite still passes — no change to
NaN/Infinity or NUL
handling.
### Note on the issue's suggested detection query
The issue proposes `octet_length(value) > 268435455` as a pre-upgrade check.
That is a useful
guide but, per the above, is neither necessary nor sufficient. The upgrade
docs updated here say
so and point at the list the migration itself prints.
* Read the **[Pull Request
Guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#pull-request-guidelines)**
for more information. Note: commit author/co-author name and email in commits
become permanently public when merged.
* For fundamental code changes, an Airflow Improvement Proposal
([AIP](https://cwiki.apache.org/confluence/display/AIRFLOW/Airflow+Improvement+Proposals))
is needed.
* When adding dependency, check compliance with the [ASF 3rd Party License
Policy](https://www.apache.org/legal/resolved.html#category-x).
* For significant user-facing changes create newsfragment:
`{pr_number}.significant.rst`, in
[airflow-core/newsfragments](https://github.com/apache/airflow/tree/main/airflow-core/newsfragments).
You can add this file in a follow-up commit after the PR is created so you
know the PR number.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]