Skip to content

Commit

Permalink
mysqlctl: Improve handling of the lock file (#15404)
Browse files Browse the repository at this point in the history
Signed-off-by: Dirkjan Bussink <[email protected]>
  • Loading branch information
dbussink authored Mar 7, 2024
1 parent 9d895fb commit 6c73053
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 2 deletions.
12 changes: 11 additions & 1 deletion go/vt/mysqlctl/mysqld.go
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,10 @@ func cleanupLockfile(socket string, ts string) error {
log.Errorf("%v: error parsing pid from lock file: %v", ts, err)
return err
}
if os.Getpid() == p {
log.Infof("%v: lock file at %s is ours, removing it", ts, lockPath)
return os.Remove(lockPath)
}
proc, err := os.FindProcess(p)
if err != nil {
log.Errorf("%v: error finding process: %v", ts, err)
Expand All @@ -469,7 +473,13 @@ func cleanupLockfile(socket string, ts string) error {
if err == nil {
// If the process still exists, it's not safe to
// remove the lock file, so we have to keep it around.
log.Errorf("%v: not removing socket lock file: %v with pid %v", ts, lockPath, p)
cmdline, err := os.ReadFile(fmt.Sprintf("/proc/%d/cmdline", p))
if err == nil {
name := string(bytes.ReplaceAll(cmdline, []byte{0}, []byte(" ")))
log.Errorf("%v: not removing socket lock file: %v with pid %v for %q", ts, lockPath, p, name)
} else {
log.Errorf("%v: not removing socket lock file: %v with pid %v (failed to read process name: %v)", ts, lockPath, p, err)
}
return fmt.Errorf("process %v is still running", p)
}
if !errors.Is(err, os.ErrProcessDone) {
Expand Down
8 changes: 7 additions & 1 deletion go/vt/mysqlctl/mysqld_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,14 @@ func TestCleanupLockfile(t *testing.T) {
assert.NoError(t, cleanupLockfile("mysql.sock", ts))
assert.NoFileExists(t, "mysql.sock.lock")

// If the lockfile exists, and the process is found, we don't clean it up.
// If the lockfile exists, and the process is found, but it's for ourselves,
// we clean it up.
os.WriteFile("mysql.sock.lock", []byte(strconv.Itoa(os.Getpid())), 0o600)
assert.NoError(t, cleanupLockfile("mysql.sock", ts))
assert.NoFileExists(t, "mysql.sock.lock")

// If the lockfile exists, and the process is found, we don't clean it up.
os.WriteFile("mysql.sock.lock", []byte(strconv.Itoa(os.Getppid())), 0o600)
assert.Error(t, cleanupLockfile("mysql.sock", ts))
assert.FileExists(t, "mysql.sock.lock")
}

0 comments on commit 6c73053

Please sign in to comment.