sobota, 21 sierpnia 2010

Zabijanie procesów MySQL wybranego użytkownika

Kilka razy zdarzyło mi się, że klient miał jakiś błąd w skrypcie, który powodował otwieranie mnóstwa procesów w bazie danych MySQL, które nie chciały się zakończyć.

Wyjściem z sytuacji może być restart MySQL'a ale nie zawsze możemy sobie na takie rozwiązanie pozwolić (właściciele, blogów, portali, wortali, sklepów internetowych mogą nas zlinczować).

Pozostaje nam wyłapać procesy określonego użytkownika i je zabić.
Poniżej umieszczam ciąg poleceń, które nam to umożliwią (wiem, że można to zrobić o wiele prościej ale akurat tych poleceń nie mam pod ręką). Wersja hardcore:
mysqladmin processlist -p > dupa.txt && cat dupa.txt | grep root > dupa2.txt && cat dupa2.txt | tr '|' ' ' > dupa3.txt && cat dupa3.txt | awk '{print $1}' > dupa4.txt && for adresss in $(cat dupa4.txt); do mysqladmin kill $adresss -p ; done

Jeżeli chcecie powyższe polecenie stosować na serwerach produkcyjnych to można je znacznie skrócić.
Mysqladmin processlist wyświetla listę wszystkich procesów MySQL'a, przełącznik -p zaznacza, że ma pytać o hasło (w pracy z konta roota mogę zalogować się bez podania hasła - jak ktoś się włamie na root'a to i tak może wszystko), robię zrzut listy procesów do pliku dupa.txt i wyświetlam plik dupa.txt, znajduję wszystkie procesy uruchomione przez użytkownika root (można zmienić na dowolnego) i robię zrzut do pliku dupa2.txt. Wyświetlam zawartość dupa2.txt i za pomocą polecenia tr (od transform) przekształcam wszystkie znaki "|" na "nic" robię zrzut do pliku dupa3.txt. Ponownie wyświetlam zawartość pliku i wynik przekierowuje do programu awk aby wyświetlić tylko pierwszą kolumnę, w której są zawarte numery ID procesów użytkownika root i zrzucam do pliku dupa4.txt. Dla każdego adresu z pliku dupa4.txt wykonuje polecenie mysqladmin kill numer_id_procesu i oczywiście ma spytać o hasło.
Pozostaje tylko wpisać hasło tyle razy, ile mam procesów do ubicia.

I w ten oto niesprytny sposób, ubiliśmy wszystkie procesy MySQL użytkownika root.

Procesy przed wykonaniem polecenia:
+-----+------+-----------+----+---------+------+-------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+-----+------+-----------+----+---------+------+-------+------------------+
| 236 | root | localhost | | Sleep | 500 | | |
| 237 | root | localhost | | Sleep | 428 | | |
| 247 | root | localhost | | Query | 0 | | show processlist |
+-----+------+-----------+----+---------+------+-------+------------------+

Procesy po wykonaniu polecenia:
+-----+------+-----------+----+---------+------+-------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+-----+------+-----------+----+---------+------+-------+------------------+
| 254 | root | localhost | | Query | 0 | | show processlist |
+-----+------+-----------+----+---------+------+-------+------------------+


Wiem, że można znacznie łatwiej, za pomocą xargs, ale jest późno, komary atakują i oczy tracą ostrość.

W planach mam opisanie w niekoniecznie najbliższej przyszłości: bind ciąg dalszy, postfix czyszczenie kolejki, no i może psychole FTP atakują - czyli jak wyczerpać ilość dostępnych sesji FTP i siać zamęt i zgorszenie.

Brak komentarzy:

Prześlij komentarz