In over 22 years of working with Linux systems, I have often seen people use excessive force to kill various computer programs, causing unnecessary suffering.
A typical example would be:
$ killall -9 mysqld
Please stop using this command. Both
killall and the parameter
-9 are harmful when dealing with programs that store data, like the MySQL or MariaDB database, and better alternatives exist.
Avoid killing in vain
9 means signal 9, which is SIGKILL. All standard Linux signals can easily be listed with:
$ kill -L 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
The Linux kernel sends most of these signals to the program itself, and we expect programs to have code to handle various signals. One exception is signal number 9 (SIGKILL). We use the SIGKILL signal to terminate the program immediately. The program cannot handle block or ignore it. Therefore, it is always fatal. If
kill is issued without parameters, it will default to signal 15 (SIGTERM) and the Linux kernel will request the running process to terminate itself and clean file pointers and other resources it was using. Thus, always prefer SIGTERM and only use SIGKILL as a last resort.
Violently killing programs that deal with data storage might cause writing into a file to abruptly stop halfway, leading to inconsistent data or even unusable corrupted files. For example, even if the program is not a database or similar, senseless immediate killing leads to everything dropping mid-flight, potentially causing unnecessary harm to other programs communicating over the same network. In some cases, albeit rare, poorly terminated programs may turn into zombie processes, showing up in the Linux process listing as
<defunct>. If that happens, the only way to clean them is to restart the entire operating system. So, please, do not kill without trying other means first.
Don’t be senseless
Let’s dive into the first part of the command in the opening paragraph, which is also wrong.
killall has been in Unix and all its descendants, such as Linux, since 1983. It does the job. However, we also have modern tools, which I prefer, like pkill from 1998.
pkill is superior because it has the parameter
-e to display what is killed (or terminated). Those who still use
killall but don’t want to be senseless also use variations of
ps ax | grep <processname> to see which processes are running before and after the killing.
Compare the clarity in these identical examples:
$ killall mysqld $ killall mysqld mysqld: no process found
killall command remains silent if it did something and only reports errors. In contrast,
pkill reports which process it terminated and is only silent if it didn’t do anything.
pkill -e mysqld mysqld_safe killed (pid 3911) mysqld killed (pid 4011) $ pkill -e mysqld (nothing)
The bonus of being sensible
A bonus for system administrators using
pkill is they could learn something valuable by observing the effects of their commands. For example, a database sysadmin could encounter the following:
$ pkill -9 -e mariadbd mariadbd killed (pid 5281) $ pkill -9 -e mariadbd mariadbd killed (pid 5383) $ pkill -9 -e mariadbd mariadbd killed (pid 5412) $ pkill -e mariadbd mariadbd killed (pid 5497) $ pkill -e mariadbd (nothing)
With MariaDB, if the main server abruptly dies (as with signal 9/SIGKILL), the wrapper
mysqld_safe (if used) will detect that and automatically restart the server because it assumes it died during a crash and knows getting it back up and running is desirable. However, when the proper signal 15/SIGTERM is used (default in
pkill when no signal is defined), the
mariadbd process intentionally shuts itself down. The wrapper respects that and understands that automatically restarting it would not make sense.
The procps package
pkill is part of the procps suite. You can find it by default on most Linux systems, but if you don’t have it, run
apt install procps or
yum install procps to get it. The suite also includes the command
pgrep, which replaces manual
ps ax | grep <processname> invocations, as mentioned above.
An example of
pgrep in action:
$ pgrep -af mysqld 5577 /bin/sh /usr/bin/mysqld_safe 5676 /usr/sbin/mariadbd --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib/mysql/plugin --user=mysql --skip-log-error --pid-file=/run/mysqld/mysqld.pid --socket=/run/mysqld/mysqld.sock 5677 logger -t mysqld -p daemon error
To see the complete list of options, run
pkill --help and
pgrep --help or
man pkill to read the man page. I recommend all system administrators make using
man <command> from the command line as a general habit to act more sensiblyin all command-line actions.
Most importantly, don’t use signal 9 (SIGKILL) on databases other than as the last resort. Please avoid any senseless killings!