Chcete-li zjistit, který proces odesílá signál do mysqld, je nutné sledovat signály v jádře Linuxu. Dvě možnosti, jak to udělat, jsou:
- protokol auditu (auditd)
- klepnutí na systém
Každá z těchto metod bude diskutována v následujících částech.
Protokol auditu
Protokol auditu lze snadno nastavit, ale neposkytuje přesné řízení toho, které procesy a signály jsou monitorovány; vše je zahrnuto. Protokol může být docela hlučný, proto se doporučuje vypnout monitorování, jakmile je proces určen. Postup je následující:
1. Nakonfigurujte auditovaný pro monitorování signálů. To lze provést za běhu nebo prostřednictvím auditovaného konfiguračního souboru (/etc/audit/audit.rules ). Protože přidaný výstup protokolu je poměrně hlučný (zaznamenává všechny signály, dokonce i kill -0, tj. kontroluje, zda je proces aktivní) a pokud je změna provedena za účelem odladění jednoho problému, je obvykle vhodnější provést změnu za běhu. To provedete příkazem:
auditctl -a exit,always -F arch=b64 -S kill -k audit_kill
2. Počkejte, až bude mysqld zabit/vypnut signálem.
3. Znovu zastavte volání signálů auditovaného protokolování, nejjednodušší je restartovat (pokud jste přidali pravidlo do konfiguračního souboru, budete muset pravidlo nejprve odstranit):
# service auditd restart
Soubor protokolu (obvykle /var/log/audit.log ) by nyní měla mít událost podobnou:
type=SYSCALL msg=audit(1450214919.813:148): arch=c000003e syscall=62 success=yes exit=0 a0=f60 a1=9 a2=7f736e706980 a3=0 items=0 ppid=3649 pid=3997 auid=500 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts3 ses=1 comm="mykill" exe="/opt/bin/mykill" subj=user_u:system_r:unconfined_t:s0 key="audit_kill" type=OBJ_PID msg=audit(1450214919.813:148): opid=3936 oauid=500 ouid=102 oses=1 obj=user_u:system_r:mysqld_t:s0 ocomm="mysqld"
Důležité části jsou:
Obecné:
msg=audit(1450214919.813:148) :časové razítko události. Toto je v epoše (čas od 1. ledna 1970 o půlnoci UTC). Můžete např. použijte funkci FROM_UNIXTIME() v MySQL k převodu na normální datum:
mysql> SELECT FROM_UNIXTIME(1450214919); +---------------------------+ | FROM_UNIXTIME(1450214919) | +---------------------------+ | 2015-12-16 08:28:39 | +---------------------------+ 1 row in set (0.05 sec)
type=SYSCALL
Informace o spouštěči syscall.
syscall=62 :znamená, že jde o signál (zabití):
# ausyscall 62 kill
a1=9 :znamená, že signál je SIGKILL (pro signál SIGTERM je hodnota 15).
comm=”mykill” exe=”/opt/bin/mykill” :je proces, který vysílá signál – to je to, co vás zajímá.
key=”audit_kill” :je volba „-k audit_kill“ z příkazu auditctl. Pouze říká, že událost byla spuštěna pravidlem, které jsme přidali.
type=OBJ_PID
Informace o cíli syscall.
opid=3936 :je ID procesu (jako v tom, co vidíte nahoře nebo na výstupu ps) procesu přijímajícího signál.
ouid=102 :uživatelské ID uživatele, který provádí proces (jako v id z /etc/passwd).
ocomm=”mysqld” :název procesu.
Takže musíte hledat událost s typem=SYSCALL s a1=9 a key=”audit_kill”, kde má následující objekt ocomm=”mysqld”.
klepnutí na systém
systemtap vyžaduje skript určující, co by se mělo monitorovat a co by se mělo dělat s dostupnými informacemi. Díky tomu je použití složitější, ale také umožňuje mnohem větší flexibilitu. Příklad skriptu, který bude monitorovat odesílání SIGKILL a SIGTERM do procesu mysqld, je:
#! /usr/bin/env stap # # This systemtap script will monitor for SIGKILL and SIGTERM signals send to # a process named "mysqld". # probe signal.send { if ( (sig_name == "SIGKILL" || sig_name == "SIGTERM") && pid_name == "mysqld" ) { printf("%10d %-34s %-10s %5d %-7s %s\n", gettimeofday_s(), tz_ctime(gettimeofday_s()), pid_name, sig_pid, sig_name, execname()); } } probe begin { printf("systemtap script started at: %s\n\n", tz_ctime(gettimeofday_s())); printf("%50s%-18s\n", "", "Signaled Process"); printf("%-10s %-34s %-10s %5s %-7s %s\n", "Epoch", "Time of Signal", "Name", "PID", "Signal", "Signaling Process Name"); printf("---------------------------------------------------------------"); printf("---------------------------------------------------------------"); printf("\n"); } probe end { printf("\n"); }Poznámka :Výše uvedený skript je míněn jako příklad. Před použitím ve výrobě otestujte na testovacím systému.
Uložte skript do souboru (následující předpokládá, že název souboru je mysqld_kill_or_term.stp). Použití je:
# stap mysqld_kill_or_term.stp systemtap script started at: Fri Dec 18 13:35:44 2015 AEDT Signaled Process Epoch Time of Signal Name PID Signal Signaling Process Name ------------------------------------------------------------------------------------------------------------------------------ 1450406150 Fri Dec 18 13:35:50 2015 AEDT mysqld 21578 SIGKILL mykill 1450406161 Fri Dec 18 13:36:01 2015 AEDT mysqld 21942 SIGKILL mykill 1450406171 Fri Dec 18 13:36:11 2015 AEDT mysqld 22045 SIGTERM mykill ^C