Skip to content

Conversation

@jamespud
Copy link

What type of PR is this?

  • fix

Check the PR title.

  • This PR title match the format: fix(mysql): ensure expected unix socket path for MySQL healthchecks
  • The description of this PR title is user-oriented and clear enough for others to understand.
  • Add documentation if the current PR requires user awareness at the usage level.

(Optional) Translate the PR title into Chinese.

修复(mysql):确保 MySQL 健康检查使用期望的 unix socket 路径

(Optional) More detailed description for this PR (en / zh)

en:
This PR fixes an issue where mysqladmin (and Docker healthchecks relying on the default socket path) fail to connect using the unix socket because MySQL creates its socket at /var/lib/mysql/mysql.sock while some checks expect /var/run/mysqld/mysqld.sock. Symptom observed when running inside the container:

docker exec -it coze-mysql /bin/bash
bash-5.1# mysqladmin ping -h localhost -u root -p
Enter password:
mysqladmin: connect to server at 'localhost' failed
error: 'Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)'
Check that mysqld is running and that the socket: '/var/run/mysqld/mysqld.sock' exists!

Root cause: mismatch between MySQL's socket location and the path expected by healthcheck tools. Fix applied: create a stable symlink from /var/run/mysqld/mysqld.sock to /var/lib/mysql/mysql.sock in the MySQL entrypoint wrapper before the first healthcheck, ensuring existing healthchecks continue to work without changing their invocation. This is a low-risk, backwards-compatible change.

zh:
该 PR 修复了一个问题:mysqladmin(以及依赖默认 socket 路径的 Docker 健康检查)无法通过 unix socket 连接,因为 MySQL 在容器中将 socket 创建在 /var/lib/mysql/mysql.sock,而某些检查期望的路径为 /var/run/mysqld/mysqld.sock。在容器内触发的故障示例如上。

根本原因:MySQL 的 socket 路径与健康检查工具期望的路径不一致。解决方法是在 MySQL 启动后的 entrypoint 脚本中(首次健康检查之前)创建从 /var/run/mysqld/mysqld.sock/var/lib/mysql/mysql.sock 的符号链接,保证现有健康检查和 mysqladmin 能够正常工作,风险低且向后兼容。

(Optional) Which issue(s) this PR fixes:

  • (none linked) — can be associated with an issue if desired.

Files changed

  • docker-compose.yml — add socket symlink creation in MySQL entrypoint wrapper prior to the first healthcheck loop.

Why this change

  • Restores compatibility with existing healthchecks that assume the socket at /var/run/mysqld/mysqld.sock.
  • Minimal, low-risk modification that avoids changing every healthcheck invocation to TCP.
  • Avoids surprising failures during local development and CI where images/entrypoints differ in socket locations.

Alternatives considered

  • Change healthcheck to use TCP (e.g., mysqladmin --protocol=TCP -h 127.0.0.1 ...) — more explicit but requires changing checks and may expose different networking semantics.
  • Modify the MySQL image or init scripts to set socket MySQL config to /var/run/mysqld/mysqld.sock — more invasive and could affect runtime config.

Testing / Verification

  • Manual runtime check:
    docker compose -f docker/docker-compose.yml --env-file docker/.env up -d --no-deps --force-recreate mysql
    docker exec -it coze-mysql /bin/bash -c "mysqladmin ping -h localhost -u root -p"
    
    Expected result: mysqladmin returns mysqld is alive (after entering the password).
  • Verify Docker health:
    docker inspect --format='{{json .State.Health}}' coze-mysql
    
    Expected: Status: "healthy" after initial start and migration steps complete.
  • Full stack:
    make web
    
    Should proceed past the previous failure point where the coze-mysql service was unhealthy.

Risks and Rollback

  • Risk: minimal — only creates a symlink; does not alter MySQL configuration or networking.
  • Rollback: revert the change to docker-compose.yml if unwanted.

Additional notes

  • If you prefer using TCP for healthchecks instead, I can instead update the healthcheck to mysqladmin --protocol=TCP -h 127.0.0.1 ... and increase start_period/retries.

@CLAassistant
Copy link

CLAassistant commented Jan 23, 2026

CLA assistant check
All committers have signed the CLA.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes MySQL startup/healthcheck failures caused by a Unix socket path mismatch by attempting to ensure /var/run/mysqld/mysqld.sock exists (via symlink) and adding a short wait for the socket before running readiness checks.

Changes:

  • Add logic to create /var/run/mysqld and (when detected) symlink /var/run/mysqld/mysqld.sock/var/lib/mysql/mysql.sock.
  • Add a brief pre-check loop to wait for the MySQL socket to appear before proceeding with existing mysqladmin ping readiness waiting.
  • Apply the same behavior to both normal and debug docker-compose configurations.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.

File Description
docker/docker-compose.yml Adds socket wait + symlink creation before MySQL readiness checks to keep socket-based healthchecks working.
docker/docker-compose-debug.yml Mirrors the socket wait + symlink creation logic for debug compose runs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +29 to +30

mkdir -p /var/run/mysqld 2>/dev/null || true
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There’s trailing whitespace on the blank line after MYSQL_PID=$$! (line 29) and an extra blank line later (line 43), which makes the YAML harder to review/maintain. Please remove the trailing spaces and collapse redundant blank lines.

Copilot uses AI. Check for mistakes.
Comment on lines +31 to +38
for i in $(seq 1 30); do
if [ -S /var/lib/mysql/mysql.sock ]; then
break
fi
sleep 1
done

if [ -S /var/lib/mysql/mysql.sock ] && [ ! -e /var/run/mysqld/mysqld.sock ]; then
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as in docker-compose.yml: the 30s wait loop can skip symlink creation if /var/lib/mysql/mysql.sock shows up after the loop, causing the later mysqladmin ping -h localhost ... wait (and healthcheck) to fail indefinitely because /var/run/mysqld/mysqld.sock never gets created. Prefer creating the symlink immediately (dangling is OK) and/or retrying symlink creation while waiting for MySQL, only skipping if /var/run/mysqld/mysqld.sock already exists as a real socket.

Suggested change
for i in $(seq 1 30); do
if [ -S /var/lib/mysql/mysql.sock ]; then
break
fi
sleep 1
done
if [ -S /var/lib/mysql/mysql.sock ] && [ ! -e /var/run/mysqld/mysqld.sock ]; then
# Ensure the socket symlink exists early; dangling is acceptable.
if [ ! -S /var/run/mysqld/mysqld.sock ]; then
ln -sf /var/lib/mysql/mysql.sock /var/run/mysqld/mysqld.sock 2>/dev/null || true
fi
for i in $(seq 1 30); do
# If the MySQL socket appears during the wait, re-ensure the symlink.
if [ -S /var/lib/mysql/mysql.sock ] && [ ! -S /var/run/mysqld/mysqld.sock ]; then
ln -sf /var/lib/mysql/mysql.sock /var/run/mysqld/mysqld.sock 2>/dev/null || true
echo 'Socket symlink ensured'
break
fi
if [ -S /var/lib/mysql/mysql.sock ]; then
break
fi
sleep 1
done
# Final safeguard to ensure the symlink exists once MySQL is up.
if [ -S /var/lib/mysql/mysql.sock ] && [ ! -S /var/run/mysqld/mysqld.sock ]; then

Copilot uses AI. Check for mistakes.
Comment on lines +39 to +40
ln -sf /var/lib/mysql/mysql.sock /var/run/mysqld/mysqld.sock 2>/dev/null || true
echo 'Socket symlink ensured'
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ln failures are ignored (2>/dev/null || true) but the script still prints Socket symlink ensured, which can report success even if the symlink wasn’t actually created. Consider letting ln fail loudly or gating the success message on ln’s exit code.

Suggested change
ln -sf /var/lib/mysql/mysql.sock /var/run/mysqld/mysqld.sock 2>/dev/null || true
echo 'Socket symlink ensured'
if ln -sf /var/lib/mysql/mysql.sock /var/run/mysqld/mysqld.sock 2>/dev/null; then
echo 'Socket symlink ensured'
else
echo 'Failed to ensure socket symlink' >&2
fi

Copilot uses AI. Check for mistakes.
Comment on lines +30 to +35
for i in $(seq 1 30); do
if [ -S /var/lib/mysql/mysql.sock ]; then
break
fi
sleep 1
done
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 30s wait loop can leave the symlink uncreated if /var/lib/mysql/mysql.sock appears after the loop finishes. In that case the subsequent mysqladmin ping -h localhost ... loop (and the container healthcheck) can keep failing indefinitely because /var/run/mysqld/mysqld.sock never gets created. Consider creating the /var/run/mysqld/mysqld.sock symlink up-front (a dangling symlink is fine) and/or retrying symlink creation while waiting for MySQL, only skipping if /var/run/mysqld/mysqld.sock already exists as a real socket.

Copilot uses AI. Check for mistakes.
Comment on lines +38 to +39
ln -sf /var/lib/mysql/mysql.sock /var/run/mysqld/mysqld.sock 2>/dev/null || true
echo 'Socket symlink ensured'
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ln errors are suppressed (2>/dev/null || true) but the script still prints Socket symlink ensured unconditionally, which can be misleading if the symlink creation fails. Consider either not swallowing the ln failure or checking ln’s exit status before emitting the success message.

Suggested change
ln -sf /var/lib/mysql/mysql.sock /var/run/mysqld/mysqld.sock 2>/dev/null || true
echo 'Socket symlink ensured'
ln -sf /var/lib/mysql/mysql.sock /var/run/mysqld/mysqld.sock 2>/dev/null
if [ $$? -eq 0 ]; then
echo 'Socket symlink ensured'
else
echo 'Failed to ensure socket symlink' >&2
fi

Copilot uses AI. Check for mistakes.
Comment on lines +30 to +32
mkdir -p /var/run/mysqld 2>/dev/null || true
for i in $(seq 1 30); do
if [ -S /var/lib/mysql/mysql.sock ]; then
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description’s “Files changed” list mentions only docker-compose.yml, but this PR also modifies docker-compose-debug.yml. Please update the description to reflect all changed files so reviewers/users aren’t surprised by debug compose behavior changes.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants