kill process from a file or directly with top

i have edited a script to kill an exact mysql process is causing the high load on the server, my problem is, kill dont kill it!

script:

#!/bin/sh
top -n 1 -u mysql | grep mysqld | awk '{print $1}' > pid
proc='cat pid'
kill -9 $proc

or i try with

kill -9 `top -n 1 -u mysql | grep mysqld | awk '{print $1}'`

and none works.

the first one tell me.

toot@server [~]# sh kill.sh
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]

and the second one

toot@server [~]# kill -9 `top -n 1 -u mysql | grep mysqld | awk '{print $1}'`
-bash: kill: 17720: arguments must be process or job IDs

how to fix it, and what im doing wrong???

thank you.

What Operating System and version are you running?
I assume from the error message that /bin/sh is a link to bash on your system.

I don't think that "top" is suitable for this exercise because of the amount of irrelevant screen control characters etc. you will get. The formatted output from "top" is unsuitable for processing in unix Shell.
Really needs to use the "ps" command (not "top") combined with some base logic to decide if the process is rogue.

In general, never issue "kill -9" unless you are having trouble shutting a system down. Certainly never issue "kill -9" to a database process while the database is up.

Btw. The first script contains an error (wrong sort of quotes) but this does not mean that the script will work:

im using linux centos 5.5

for PS can use

ps -ef|grep -v grep |grep mysql| awk '{print $2}'

but give me 2 process.. the mysq1d and mysql

yes i know is bad to kill a process of a DB while database is running, but its the only way for now to make load get down.

i need to optimize database then.

The output of top is formatted.
When trying to reproduce your problem your

top -n 1 -u mysql | grep mysqld | awk '{print $1}'

command returns an empty strings. So that's why your kill asks for a PID.

try this one:

kill -9 $(top -bn1 -u mysql | grep mysqld | cut -c1-5)

The trick is in the b argument of top that removes the formatting.

But top continue to show the pid using the 5 first characters, so you can't use a simple

awk '{print $1}'

to get the pid. I suggest using the

cut -c1-5

instead

1 Like

Any reason to not use "ps -fu ....":

ps -fumysql|grep -v "grep" |grep "mysqld"| awk '{print $2}'

with my command i get this:

toot@server [~]# ps -ef|grep -v grep |grep mysql| awk '{print $2}'
16942
30862
toot@server [~]#

with your solution works smoothly...

i run that script on another i had, on crontab each 5 min checks if the load is bigguer than X then execute that script and email me server info, hostname and uptime,

thank you very much!!!

CTRL+X

---------- Post updated at 01:32 PM ---------- Previous update was at 01:30 PM ----------

that line dont show process id:

toot@server [~]# ps -ef|grep -v "grep" |grep " mysqld "| awk '{print $2}'
toot@server [~]# 

instead the first one i post

toot@server [~]# ps -ef|grep -v grep |grep mysql| awk '{print $2}'
18718  <- mysql database
30862  <-mysqld
toot@server [~]#

the code of Dahu solve my problem :cool:

cut and awk have the exactly the same problem when handling the formatted output of top command.

As Dahu stated : the trick is to use the b option of the top command, then, either cut or awk behaves as expected.

Save some pipe :

ps -ef | awk '/"[m]ysqld"/{print$2}'
kill -9 $(top -bn1 | awk '/"[m]ysqld"/{print$1}')

!!

thanks to all.

Last edit..... Reason: Use code tags, please...

sorry, im going to do it

Just beware that top, even with the b option, use a right formatted output for the pid ... that's why the awk command may fail of the pid is below 10000 (and I suggested the cut way, I'm no friend with awk :))!