From ea04398c413ab404eb88539877f103d89a53b572 Mon Sep 17 00:00:00 2001 From: Alkin Tezuysal Date: Sat, 31 Oct 2026 14:58:53 +0000 Subject: [PATCH] fix(docker): base plugin images on their exact build release The plugin images were built for 8.0.45 / 8.4.8 / 9.7.0 but based on the floating mysql:8.0 / 8.4 / 9.7 (now 8.0.46 / 8.4.13 / 9.7.4); a library built for one MySQL release can crash another (an 8.4.8 component crashed 8.4.11 in #244's dry run). - docker-publish.yml (plugin job): build for 8.0.46, 8.4.13, 9.7.4, base each image on mysql:, also tag it with the release; run on a dry_run dispatch too, building and testing without pushing. - Dockerfile.oraclelinux8/9: MYSQL_VERSION is required (no default). - build-docker-local.sh: same releases; reject versions other than 8.0/8.4/9.7. - benchmark-issue79.yml: base the image on 8.4.8, the release it builds. - docs/DOCKER_IMAGES.md, CHANGELOG. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/benchmark-issue79.yml | 2 +- .github/workflows/docker-publish.yml | 33 ++++++++++++++++--------- CHANGELOG.md | 1 + Dockerfile.oraclelinux8 | 4 ++- Dockerfile.oraclelinux9 | 4 ++- docs/DOCKER_IMAGES.md | 5 ++++ scripts/build-docker-local.sh | 19 ++++++++++---- 7 files changed, 49 insertions(+), 19 deletions(-) diff --git a/.github/workflows/benchmark-issue79.yml b/.github/workflows/benchmark-issue79.yml index ebf16267..022d430a 100644 --- a/.github/workflows/benchmark-issue79.yml +++ b/.github/workflows/benchmark-issue79.yml @@ -70,7 +70,7 @@ jobs: - name: Build Docker image run: | docker build \ - --build-arg MYSQL_VERSION=8.4 \ + --build-arg MYSQL_VERSION=8.4.8 \ --build-arg TARGETARCH=amd64 \ -t ghcr.io/${{ github.repository }}:mysql8.4-fix-issue79 \ -f Dockerfile.oraclelinux9 \ diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 6bd7d463..0cd94139 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -20,22 +20,30 @@ jobs: # Publish plugin images only from a dispatch that targets a VERSION tag # (refs/tags/v*). The version-tag guard stops a branch / non-version-tag # dispatch from overwriting the mutable public plugin tags - # (mysql8.0/8.4/9.7/latest). - if: github.event_name == 'workflow_dispatch' && startsWith(github.ref, 'refs/tags/v') + # (mysql8.0/8.4/9.7/latest). A dry_run dispatch builds and tests without pushing. + if: >- + (github.event_name == 'workflow_dispatch' && startsWith(github.ref, 'refs/tags/v')) || + (github.event_name == 'workflow_dispatch' && inputs.dry_run) runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: include: - - mysql-tag: 'mysql-8.0.45' + # A plugin works only on the exact release it was built against, so each image + # is based on mysql:, the release of mysql-tag, and also tagged + # with it (mysql). + - mysql-tag: 'mysql-8.0.46' + mysql-release: '8.0.46' mysql-version: '8.0' dockerfile: Dockerfile.oraclelinux8 compiler: 10 - - mysql-tag: 'mysql-8.4.8' + - mysql-tag: 'mysql-8.4.13' + mysql-release: '8.4.13' mysql-version: '8.4' dockerfile: Dockerfile.oraclelinux9 compiler: 10 - - mysql-tag: 'mysql-9.7.0' + - mysql-tag: 'mysql-9.7.4' + mysql-release: '9.7.4' mysql-version: '9.7' dockerfile: Dockerfile.oraclelinux9 compiler: 11 @@ -162,7 +170,7 @@ jobs: docker buildx build \ --platform "linux/${arch}" \ --file ${{ matrix.dockerfile }} \ - --build-arg MYSQL_VERSION=${{ matrix.mysql-version }} \ + --build-arg MYSQL_VERSION=${{ matrix.mysql-release }} \ -t "myvector-smoke:${{ matrix.mysql-version }}-${arch}" \ --load \ . @@ -191,10 +199,13 @@ jobs: context: . file: ${{ matrix.dockerfile }} platforms: linux/amd64,linux/arm64 - push: true - tags: ghcr.io/${{ github.repository }}:mysql${{ matrix.mysql-version }} + # Never push on a dry_run dispatch — build only, to prove the pipeline. + push: ${{ !inputs.dry_run }} + tags: | + ghcr.io/${{ github.repository }}:mysql${{ matrix.mysql-version }} + ghcr.io/${{ github.repository }}:mysql${{ matrix.mysql-release }} build-args: | - MYSQL_VERSION=${{ matrix.mysql-version }} + MYSQL_VERSION=${{ matrix.mysql-release }} - name: Tag and push latest if: matrix.mysql-version == '8.0' @@ -203,10 +214,10 @@ jobs: context: . file: ${{ matrix.dockerfile }} platforms: linux/amd64,linux/arm64 - push: true + push: ${{ !inputs.dry_run }} tags: ghcr.io/${{ github.repository }}:latest build-args: | - MYSQL_VERSION=${{ matrix.mysql-version }} + MYSQL_VERSION=${{ matrix.mysql-release }} # Component-based images (INSTALL COMPONENT), distinct from the legacy plugin # images built above. mysql8.4/mysql9.7 already ship as plugin images with diff --git a/CHANGELOG.md b/CHANGELOG.md index e404d565..9004787e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -125,6 +125,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 and rebuild the index. See [Declaring a Vector Column](docs/usage.md#declaring-a-vector-column). ### Fixed +- **Plugin images pinned to their build release.** The plugin images were built for 8.0.45, 8.4.8 and 9.7.0 but based on the floating `mysql:8.0`/`mysql:8.4`/`mysql:9.7` (now 8.0.46, 8.4.13, 9.7.4), and a library built for one MySQL release can crash another. `docker-publish.yml` now builds them for **8.0.46, 8.4.13 and 9.7.4**, bases each image on `mysql:` and also tags it with the release (`mysql8.0.46`, `mysql8.4.13`, `mysql9.7.4`). The plugin job also runs on a `dry_run` dispatch, building and testing without pushing. `Dockerfile.oraclelinux8`/`9` now require `MYSQL_VERSION`. `scripts/build-docker-local.sh` builds 8.0, 8.4 or 9.7 on the same releases and rejects other versions (it used to map 9.0 to 9.0.0). - **Component build scripts reconfigure the server tree after a failed configure.** A `.configure-ok` marker is written only after `cmake` succeeds; before, the scripts trusted `CMakeCache.txt`, which appears before configuration finishes, so a failed configure was skipped on the next run. - **Component build scripts no longer re-clone the MySQL source on every run.** Inside the build container, git refused the host-owned tree ("dubious ownership"), so the tag check always failed and the tree was deleted and cloned again, which also defeated the CI cache of the source tree. The scripts now mark the tree as a git safe directory. - **Component: `myvector_construct()` with a constant argument is built once, not per row** diff --git a/Dockerfile.oraclelinux8 b/Dockerfile.oraclelinux8 index 6e3e0473..1e05d7a1 100644 --- a/Dockerfile.oraclelinux8 +++ b/Dockerfile.oraclelinux8 @@ -1,4 +1,6 @@ -ARG MYSQL_VERSION=8.0 +# MYSQL_VERSION (required, no default) is the exact release the plugin was built against, +# for example 8.4.13: a plugin built for another release can crash the server. +ARG MYSQL_VERSION FROM mysql:${MYSQL_VERSION} ARG TARGETARCH diff --git a/Dockerfile.oraclelinux9 b/Dockerfile.oraclelinux9 index ad5d605e..a90227aa 100644 --- a/Dockerfile.oraclelinux9 +++ b/Dockerfile.oraclelinux9 @@ -1,4 +1,6 @@ -ARG MYSQL_VERSION=8.0 +# MYSQL_VERSION (required, no default) is the exact release the plugin was built against, +# for example 8.4.13: a plugin built for another release can crash the server. +ARG MYSQL_VERSION # Provide libstdc++ compatible with plugin (built with gcc-10). Use Ubuntu (lighter than Oracle Linux + gcc-toolset). FROM ubuntu:22.04 AS libstdcxx diff --git a/docs/DOCKER_IMAGES.md b/docs/DOCKER_IMAGES.md index 473495b4..4eaf125c 100644 --- a/docs/DOCKER_IMAGES.md +++ b/docs/DOCKER_IMAGES.md @@ -221,6 +221,11 @@ instructions in the main README: | `ghcr.io/askdba/myvector:mysql26.10` | 26.10.x (Innovation) | Component only (`INSTALL COMPONENT`) | | `ghcr.io/askdba/myvector:latest` | 8.0.x | Plugin (`INSTALL PLUGIN`) | +Each plugin image is based on the exact MySQL release its plugin was built against: a +plugin or component built for one release can crash another. The image is also +tagged with that release (`mysql8.0.46`, `mysql8.4.13`, `mysql9.7.4`); `mysql8.0`, +`mysql8.4`, `mysql9.7` and `latest` move to the new release when the build is updated. + Component images (`INSTALL COMPONENT`) contain `/usr/lib/mysql/plugin/myvector.so` + `myvector.json` and `/docker-entrypoint-initdb.d/myvector_install_component.sql`, rather than the plugin's `myvectorplugin.sql`. diff --git a/scripts/build-docker-local.sh b/scripts/build-docker-local.sh index 2224d1ea..643d9273 100755 --- a/scripts/build-docker-local.sh +++ b/scripts/build-docker-local.sh @@ -4,7 +4,7 @@ # On x86_64: builds amd64 plugin and image. # # Usage: ./scripts/build-docker-local.sh [mysql-version] -# Example: ./scripts/build-docker-local.sh 8.4 +# Example: ./scripts/build-docker-local.sh 8.4 (8.0, 8.4 or 9.7) set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" @@ -12,9 +12,18 @@ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" cd "$REPO_ROOT" MYSQL_VERSION="${1:-8.4}" -MYSQL_TAG="mysql-8.4.8" -[ "$MYSQL_VERSION" = "8.0" ] && MYSQL_TAG="mysql-8.0.45" -[ "$MYSQL_VERSION" = "9.0" ] && MYSQL_TAG="mysql-9.0.0" +case "$MYSQL_VERSION" in +8.0) MYSQL_TAG="mysql-8.0.46" ;; +8.4) MYSQL_TAG="mysql-8.4.13" ;; +9.7) MYSQL_TAG="mysql-9.7.4" ;; +*) + echo "unsupported MySQL version: $MYSQL_VERSION (use 8.0, 8.4 or 9.7)" >&2 + exit 1 + ;; +esac +# The image is based on the release the plugin is built against (a plugin built for +# another release can crash the server). +MYSQL_RELEASE="${MYSQL_TAG#mysql-}" # Build for native arch on Apple Silicon; amd64 on x86 # Set MYVECTOR_ARCH=amd64 to force amd64 (QEMU) on arm64 - slower but avoids compiler bugs @@ -91,7 +100,7 @@ cp sql/myvectorplugin.sql . echo "Building Docker image ($PLATFORM)..." docker build -f Dockerfile.oraclelinux9 \ --platform "$PLATFORM" \ - --build-arg MYSQL_VERSION="$MYSQL_VERSION" \ + --build-arg MYSQL_VERSION="$MYSQL_RELEASE" \ -t "myvector:mysql${MYSQL_VERSION}-local" . echo ""