vitessio/vitess · error
process %v is still running
Error message
process %v is still running
What it means
cleanupLockfile detected that the PID recorded in the mysqld socket lock file is still alive, so it refuses to delete the lock file and returns 'process %v is still running'. This protects a running mysqld's lock from being stolen by a new instance.
Source
Thrown at go/vt/mysqlctl/mysqld.go:652
return os.Remove(lockPath)
}
proc, err := os.FindProcess(p)
if err != nil {
log.Error(fmt.Sprintf("%v: error finding process: %v", ts, err))
return err
}
err = proc.Signal(syscall.Signal(0))
if err == nil {
// If the process still exists, it's not safe to
// remove the lock file, so we have to keep it around.
cmdline, err := os.ReadFile(fmt.Sprintf("/proc/%d/cmdline", p))
if err == nil {
name := string(bytes.ReplaceAll(cmdline, []byte{0}, []byte(" ")))
log.Error(fmt.Sprintf("%v: not removing socket lock file: %v with pid %v for %q", ts, lockPath, p, name))
} else {
log.Error(fmt.Sprintf("%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) {
// Any errors except for the process being done
// is unexpected here.
log.Error(fmt.Sprintf("%v: error checking process %v: %v", ts, p, err))
return err
}
// All good, process is gone and we can safely clean up the lock file.
log.Info(fmt.Sprintf("%v: removing stale socket lock file: %v", ts, lockPath))
return os.Remove(lockPath)
}
// Wait returns nil when mysqld is up and accepting connections. It
// will use the dba credentials to try to connect. Use wait() with
// different credentials if needed.
func (mysqld *Mysqld) Wait(ctx context.Context, cnf *Mycnf) error {
params, err := mysqld.dbcfgs.DbaConnector().MysqlParams()View on GitHub (pinned to 01a25a7d17)
Solutions
- Check what process holds the PID: `ps -p <pid>` — if it's a live mysqld, stop it or use a different socket/port
- If the PID is reused by an unrelated process, remove the stale lock file manually after confirming mysqld is not running
- Clean up orphaned mysqld processes from failed previous starts
- Ensure prior vitess workflows terminate mysqld cleanly so locks are removed
Example fix
// before: start fails, lock file claims pid 1234 alive ps -p 1234 # old mysqld still running // after: stop it, then retry mysqladmin -S /path/mysql.sock shutdown # or if pid is reused and mysqld is gone: rm /path/mysql.sock.lock
Defensive patterns
Strategy: validation
Validate before calling
lockPid := readPidFromLockFile(socketPath + ".lock")
if lockPid > 0 {
if p, err := os.FindProcess(lockPid); err == nil && p.Signal(syscall.Signal(0)) == nil {
return fmt.Errorf("pid %d still alive; not safe to start mysqld", lockPid)
}
} Try / catch
if err := mysqld.Start(ctx, cnf); err != nil && strings.Contains(err.Error(), "is still running") {
// identify the pid from the error and inspect it before removing the lock
} Prevention
- Shut down mysqld cleanly so lock files are removed
- Watch for orphaned mysqld after failed workflows
- Be aware of PID reuse on long-lived hosts
- Use unique sockets/ports per tablet
When it happens
Trigger: Calling Mysqld.Start/Init (via startNoWait -> cleanupLockfile) when a lock file exists on the target socket path and the PID inside it belongs to a live process (Signal(0)/os.FindProcess check succeeds and err is not os.ErrProcessDone).
Common situations: A previous mysqld is genuinely still running on the same socket; orphaned mysqld after an aborted vtaction; PID reuse where a new unrelated process now owns the recorded PID; stale lock from an unclean shutdown whose PID happens to be recycled.
Related errors
- mysqld_start hook failed: %v
- postflight_mysqld_start hook failed: %v
- ReadFile cannot be called on read-write backup
- AddFile cannot be called on read-only backup
- EndBackup cannot be called on read-only backup
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/b7fe4e70ba8c7669.
Report an issue: GitHub.