Skip to content

Commit d1c9d2d

Browse files
authored
Build a MySQL debug image (#4441)
INCIDENT_LOST_EVENTS binlog event (8.0+) can only reliably be triggered by a debug command that's only available in a debug build. There don't seem to be any community images we can use for this, so making one to have an easy way to repro.
1 parent b5c24ef commit d1c9d2d

3 files changed

Lines changed: 182 additions & 0 deletions

File tree

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
name: MySQL Debug Docker Image
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
mysql_version:
7+
description: MySQL version tag to build.
8+
required: true
9+
default: "8.0.46"
10+
push:
11+
branches: [main]
12+
paths:
13+
- ".github/workflows/mysql-debug-docker.yml"
14+
- "flow/e2e/test_data/mysql-debug/docker-bake.hcl"
15+
- "flow/e2e/test_data/mysql-debug/Dockerfile"
16+
pull_request:
17+
branches: [main]
18+
paths:
19+
- ".github/workflows/mysql-debug-docker.yml"
20+
- "flow/e2e/test_data/mysql-debug/docker-bake.hcl"
21+
- "flow/e2e/test_data/mysql-debug/Dockerfile"
22+
23+
env:
24+
MYSQL_DEBUG_VERSION: ${{ github.event.inputs.mysql_version || '8.0.46' }}
25+
26+
jobs:
27+
docker-build-external:
28+
if: |
29+
github.event_name == 'pull_request' &&
30+
github.event.pull_request.head.repo.full_name != github.repository
31+
runs-on: ubuntu-latest
32+
permissions:
33+
contents: read
34+
steps:
35+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
36+
with:
37+
persist-credentials: false
38+
39+
- name: Build MySQL debug image
40+
run: |
41+
docker build \
42+
--build-arg MYSQL_VERSION="${MYSQL_DEBUG_VERSION}" \
43+
--tag peerdb-mysql-debug:e2e \
44+
flow/e2e/test_data/mysql-debug
45+
46+
docker-build:
47+
if: |
48+
github.event_name == 'push' ||
49+
github.event_name == 'workflow_dispatch' ||
50+
(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository)
51+
runs-on: ubuntu-latest
52+
permissions:
53+
contents: read
54+
packages: write
55+
steps:
56+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
57+
with:
58+
persist-credentials: false
59+
60+
- uses: depot/setup-action@15c09a5f77a0840ad4bce955686522a257853461 # v1
61+
62+
- name: Login to GitHub Container Registry
63+
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4
64+
with:
65+
registry: ghcr.io
66+
username: ${{ github.actor }}
67+
password: ${{ secrets.GITHUB_TOKEN }}
68+
69+
- name: Set Short Commit Hash
70+
id: vars
71+
run: echo "sha_short=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
72+
73+
- name: Build MySQL debug image
74+
uses: depot/bake-action@1d58c2668346981089b088b7ef36755b206b20e9 # v1
75+
with:
76+
token: ${{ secrets.DEPOT_TOKEN }}
77+
files: ./flow/e2e/test_data/mysql-debug/docker-bake.hcl
78+
push: ${{ github.event_name != 'pull_request' }}
79+
env:
80+
MYSQL_VERSION: ${{ env.MYSQL_DEBUG_VERSION }}
81+
SHA_SHORT: ${{ steps.vars.outputs.sha_short }}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# MySQL debug build for e2e binlog INCIDENT_EVENT testing.
2+
#
3+
# The official mysql image ships only the minimal server, which is not compiled WITH_DEBUG and
4+
# therefore lacks the DBUG facility needed to inject a LOST_EVENTS incident at runtime
5+
# (SET GLOBAL debug='+d,binlog_inject_incident'). We swap the minimal server for the full server
6+
# plus mysqld-debug, then route only the final foreground server to mysqld-debug. The stock
7+
# entrypoint's config checks, datadir initialization, and temporary init server keep using the
8+
# release binary because the debug binary can trip InnoDB assertions on that path.
9+
ARG MYSQL_VERSION=8.0.46
10+
FROM mysql:${MYSQL_VERSION}
11+
ARG MYSQL_VERSION
12+
13+
LABEL org.opencontainers.image.source="https://github.com/PeerDB-io/peerdb" \
14+
org.opencontainers.image.title="PeerDB MySQL Debug" \
15+
org.opencontainers.image.description="MySQL ${MYSQL_VERSION} debug image for PeerDB e2e tests"
16+
17+
# Keep the debug/full-server RPMs exactly matched to the server-minimal RPM in the base image.
18+
# This lets MYSQL_VERSION move without independently hard-coding package versions here.
19+
#
20+
# Installing mysql-community-server rewrites /etc/my.cnf with RPM defaults, so preserve the
21+
# official Docker image config first. It keeps server logs on stderr and includes conf.d.
22+
RUN set -eux; \
23+
mysql_rpm_version="$(rpm -q --qf '%{VERSION}-%{RELEASE}.%{ARCH}' mysql-community-server-minimal)"; \
24+
cp /etc/my.cnf /tmp/docker-my.cnf; \
25+
printf '%s\n' \
26+
'[mysql80-community]' \
27+
'name=MySQL 8.0 Community Server' \
28+
'baseurl=https://repo.mysql.com/yum/mysql-8.0-community/el/9/$basearch/' \
29+
'enabled=1' \
30+
'gpgcheck=1' \
31+
'gpgkey=https://repo.mysql.com/RPM-GPG-KEY-mysql-2023' \
32+
> /etc/yum.repos.d/mysql-community-debug.repo \
33+
&& microdnf -y remove mysql-community-server-minimal \
34+
&& microdnf -y --setopt=install_weak_deps=0 install \
35+
"mysql-community-client-${mysql_rpm_version}" \
36+
"mysql-community-client-plugins-${mysql_rpm_version}" \
37+
"mysql-community-common-${mysql_rpm_version}" \
38+
"mysql-community-icu-data-files-${mysql_rpm_version}" \
39+
"mysql-community-libs-${mysql_rpm_version}" \
40+
"mysql-community-server-${mysql_rpm_version}" \
41+
"mysql-community-server-debug-${mysql_rpm_version}" \
42+
&& microdnf clean all \
43+
&& rm -f /etc/yum.repos.d/mysql-community-debug.repo
44+
45+
# Restore the official Docker config, but keep the RPM socket path. The official image normally
46+
# uses /var/run/mysqld/mysqld.sock and creates a compatibility symlink in /var/lib/mysql; mysqld-debug
47+
# asserts while scanning that dangling symlink during final startup.
48+
RUN set -eux; \
49+
cp /tmp/docker-my.cnf /etc/my.cnf; \
50+
sed -i 's!socket=/var/run/mysqld/mysqld.sock!socket=/var/lib/mysql/mysql.sock!g' /etc/my.cnf; \
51+
rm -f /tmp/docker-my.cnf
52+
53+
# Route entrypoint checks, datadir init, and the temporary init server to the release binary.
54+
# Only the final foreground server should use mysqld-debug; running debug for init/temp startup
55+
# trips InnoDB debug assertions before the test can run.
56+
RUN set -eux; \
57+
mv /usr/sbin/mysqld /usr/sbin/mysqld-release; \
58+
printf '%s\n' \
59+
'#!/bin/bash' \
60+
'for arg in "$@"; do' \
61+
' case "$arg" in' \
62+
' --initialize|--initialize-insecure|--daemonize|--verbose|--help|--validate-config)' \
63+
' exec /usr/sbin/mysqld-release "$@"' \
64+
' ;;' \
65+
' esac' \
66+
'done' \
67+
'exec /usr/sbin/mysqld-debug "$@"' \
68+
> /usr/sbin/mysqld; \
69+
chmod +x /usr/sbin/mysqld
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
variable MYSQL_VERSION {
2+
default = "8.0.46"
3+
}
4+
5+
variable REGISTRY {
6+
default = "ghcr.io/peerdb-io"
7+
}
8+
9+
variable SHA_SHORT {
10+
default = "dev"
11+
}
12+
13+
group "default" {
14+
targets = ["mysql-debug"]
15+
}
16+
17+
target "mysql-debug" {
18+
context = "flow/e2e/test_data/mysql-debug"
19+
dockerfile = "Dockerfile"
20+
platforms = [
21+
"linux/amd64",
22+
"linux/arm64",
23+
]
24+
args = {
25+
MYSQL_VERSION = "${MYSQL_VERSION}"
26+
}
27+
tags = [
28+
"${REGISTRY}/mysql-debug:${MYSQL_VERSION}",
29+
"${REGISTRY}/mysql-debug:${MYSQL_VERSION}-${SHA_SHORT}",
30+
"${REGISTRY}/mysql-debug:latest",
31+
]
32+
}

0 commit comments

Comments
 (0)