Статьи

Что остановило MySQL? Трассировка обратных сигналов, отправленных в MySQL

Первоначально Написал Роберт Барабас

Был ли у вас случай, когда вам нужно было найти процесс, который отправил бы HUP / KILL / TERM или другой сигнал в вашу базу данных? Позвольте мне перефразировать. Вам когда-нибудь приходилось находить, какой процесс испортил вашу ночь? ;)Если это так, вы можете читать дальше. Я собираюсь рассказать вам, как вы можете найти это.

Конечно, на небольших и / или тщательно управляемых системах отслеживание виновника, вероятно, не имеет большого значения. Скорее всего, вы можете идентифицировать ваш процесс, просто проверив, какие процессы имеют достаточные привилегии для отправки mysqld сигнала HUP / KILL / TERM. Однако часто мы видим случаи, когда это может не сработать или процесс удаления будет слишком утомительным для выполнения.

Недавно у нас был случай, когда процесс часто отправлял сообщения SIGHUP на mysqld, и клиент попросил нас посмотреть, сможем ли мы избавиться от его раздражения. Этот блог является прямым результатом обсуждения, которое я провел со своим коллегой Франсиско Борденаве , о возможных вариантах решения его проблемы. Я собираюсь рассказать о некоторых из них в этом блоге, но думаю, что большинство из вас сможет найти тот, который подойдет для вашего случая. Обратите внимание, что большинство инструментов трассировки увеличивают нагрузку на исследуемую систему. Инструменты, представленные ниже, разработаны так, чтобы быть легкими, поэтому воздействие должно быть в пределах приемлемого диапазона для большинства сред.

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ : При написании этого блога я обнаружил, что Дэвид Басби также обсуждал один из инструментов, которые я собираюсь осветить в своей статье. Для тех, кто читал статью, обратите внимание, что я собираюсь рассказать и о других инструментах, а также о некоторых дополнительных подробностях SystemTap в этом блоге. Для тех, у кого еще не было возможности прочитать блог Дэвида, вы можете прочитать его здесь .

Хорошо, давайте посмотрим, какие «низко висящие инструменты» нам доступны для решения нашей проблемы!

Linux

  • SystemTap : широко доступен в Linux, но обычно не включен по умолчанию. Вам нужно установить пакеты ядра debuginfo и devel и саму системную запись. Похож на DTrace.
  • Perf : хотя он и не совсем написан для общей трассировки, из-за его способности отследить системные вызовы, мы можем использовать его в своих интересах, если мы отслеживаем sys_enter_sigkill.
  • Аудит : общая платформа аудита системы. Учитывая его природу, мы можем использовать его для отслеживания многих вещей, включая мошеннические процессы, посылающие сигналы HUP нашему бедному mysqld!
  • Код! : Учитывая, что MySQL является открытым исходным кодом, вы можете настроить обработчик сигнала для получения дополнительной информации. Смотрите больше в sigaction (2) и флаге SA_SIGINFO . Я не уверен, стоит ли указывать это как более эффективное решение, но, тем не менее, это вариант. Я думаю, что можно также предварительно загрузить / внедрить его собственный обработчик сингла с помощью трюка LD_PRELOAD и пользовательской библиотеки, но это выходит за рамки того, что я собираюсь охватить. Тем не менее, для определенных сигналов (особенно SIGSEGV ) вам может не понадобиться писать свои собственные инструменты, поскольку ОС может уже поставляться с библиотеками / инструментами, которые могут вам помочь. См. Например, catchsegv Ульриха Дреппера или /usr/lib64/libSegFault.so .
  • Отладчики : в некоторых случаях они могут быть эффективны для использования, но на этот раз я не буду их освещать.

FreeBSD / Solaris

  • DTrace : очень достойная, стабильная платформа трассировки. По умолчанию включено в последние версии ядер для упомянутых платформ (FreeBSD 9.2+, FreeBSD 10+, Solaris 10+).

В этой статье я собираюсь сосредоточиться на Linux, так как это то, что люди в сообществе MySQL, кажется, волнуют большинство в настоящее время. Инструменты, которые я буду обсуждать, будут SystemTap, Perf и Audit. Если вы чувствуете, что хотели бы прочитать об остальном, дайте мне знать, и я расскажу об остальных вариантах в следующей статье.

SystemTap

Я собираюсь настроить SystemTap на недавней 64-битной системе CentOS 7. Я расскажу только о базовой установке, вы можете узнать больше о том, как установить SystemTap здесь .

Сильной стороной SystemTap, безусловно, является ее гибкость, потенциально лучший инструмент для решения нашей проблемы на платформе Linux. Это было в течение некоторого времени и, как правило, считается зрелым, но я бы рекомендовал протестировать ваши «тапскрипты» в dev / qa, прежде чем запускать их в производство.

Установка SystemTap

Выполните следующие шаги для установки SystemTap:

Включить репозиторий Debuginfo

[root@centos7]~# sed -i 's/enabled=0/enabled=1/' /etc/yum.repos.d/CentOS-Debuginfo.repo
[root@centos7]~# yum repolist
...
base-debuginfo/x86_64                         CentOS-7 - Debuginfo                                          1,688
...
Установка SystemTap

[root@centos7]~# yum install kernel-debuginfo kernel-debuginfo-common kernel-devel
[root@centos7]~# yum install systemtap systemtap-runtime 

Трассировка с помощью SystemTap

Создайте текстовый файл, как показано ниже:

Наш скрипт SystemTap

[root@centos7]~# cat find_sighupper.stp
#!/usr/bin/stap
# Prints information on process which sent HUP signal to mysqld
probe begin {
  printf("%-26s %-8s %-5s %-8s %-5sn", "TIME", "SOURCE", "SPID", "TARGET", "TPID");
}
probe nd_syscall.kill.return {
  sname = @entry(execname());
  spid = @entry(pid());
  sig = @entry(uint_arg(2));
  tpid = @entry(uint_arg(1));
  tname = pid2execname(tpid);
  time = ctime(gettimeofday_s());
  if (sig == 1 && tname == "mysqld")
    printf("%-26s %-8s %-5d %-8s %-5dn", time, sname, spid, tname, tpid);
}

Then run the tap script in a dedicated terminal:

Running our

[root@centos7]~# stap find_sighupper.stp
TIME                       SOURCE   SPID  TARGET   TPID 

Send your HUP signal to mysqld from another terminal:

Installing SystemTap

[root@centos7]~# kill -1 1984

The culprit should will show up on your first window like so:

Running our

[root@centos7]~# stap find_sighupper.stp
TIME                       SOURCE   SPID  TARGET   TPID
Thu Feb 26 21:20:44 2015   kill     6326  mysqld   1984
^C

Note that with this solution I was able to define fairly nice constraints relatively easily. With a single probe (well, quasi, as @entry refers back to the callee) I was able to get all this information and filter out HUP signals sent to mysqld. No other filtering is necessary!

Perf

Perf is another neat tool to have. As its name implies, it was originally developed for lightweight profiling, to use the performance counters subsystem in Linux. It became fairly popular and got extended many times over these past years. Since it happens to have probes we can leverage, we are going to use it!

Installing Perf

As you can see, installing Perf is relatively simple.

Install Perf

# yum install perf

Start perf in a separate terminal window. I’m only going to run it for a minute but I could run it in screen for a longer period of time.

Tracing with Perf

[root@centos7 ~]# perf record -a -e syscalls:sys_enter_kill sleep 60

In a separate terminal window send your test and obtain the results via “perf script”:

Testing and Observing Results

[root@centos7 ~]# echo $$
11380
[root@centos7 ~]# pidof mysqld
1984
[root@centos7 ~]# kill -1 1984
[root@centos7 ~]# perf script
# ========
# captured on: Thu Feb 26 14:25:02 2015
# hostname : centos7.local
# os release : 3.10.0-123.20.1.el7.x86_64
# perf version : 3.10.0-123.20.1.el7.x86_64.debug
# arch : x86_64
# nrcpus online : 2
# nrcpus avail : 2
# cpudesc : Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz
# cpuid : GenuineIntel,6,70,1
# total memory : 1885464 kB
# cmdline : /usr/bin/perf record -a -e syscalls:sys_enter_kill sleep 60
# event : name = syscalls:sys_enter_kill, type = 2, config = 0x9b, config1 = 0x0, config2 = 0x0, excl_usr = 0, exc
# HEADER_CPU_TOPOLOGY info available, use -I to display
# HEADER_NUMA_TOPOLOGY info available, use -I to display
# pmu mappings: software = 1, tracepoint = 2, breakpoint = 5
# ========
#
            bash 11380 [000]  6689.348219: syscalls:sys_enter_kill: pid: 0x000007c0, sig: 0x00000001

As you can see in above output process “bash” with pid of 11380 signalled pid 0x07c0 (decimal: 1984) a HUP signal (0x01). Thus, we found our culprit with this method as well.

Audit

You can read more about Audit in the Red Hat Security Guide.

Installing Audit

Depending on your OS installation, it may be already installed.

If case it is not, you can install it as follows:

Install Audit

[root@centos7 ~]# yum install audit

When you are done installing, start your trace and track 64 bit kill system calls that send HUP signals with signal ID of 1:

Tracing Audit

[root@centos7]~# auditctl -l
No rules
[root@centos7]~# auditctl -a exit,always -F arch=b64 -S kill -F a1=1
[root@centos7]~# auditctl -l
LIST_RULES: exit,always arch=3221225534 (0xc000003e) a1=1 (0x1) syscall=kill
[root@centos7]~# auditctl -s
AUDIT_STATUS: enabled=1 flag=1 pid=7010 rate_limit=0 backlog_limit=320 lost=0 backlog=0
[root@centos7]~# pidof mysqld
1984
[root@centos7]~# kill -1 1984
[root@centos7]~# tail -2 /var/log/audit/audit.log
type=SYSCALL msg=audit(1425007202.384:682): arch=c000003e syscall=62 success=yes exit=0 a0=7c0 a1=1 a2=a a3=7c0 items=0 ppid=11380 pid=3319 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=1 comm="zsh" exe="/usr/bin/zsh" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=OBJ_PID msg=audit(1425007202.384:682): opid=1984 oauid=-1 ouid=995 oses=-1 obj=system_u:system_r:mysqld_t:s0 ocomm="mysqld"

As you can see from above output, the results showed up nicely in the system audit.log. From the log it’s clear that I sent my SIGHUP to mysqld (pid 1984, “opid” field) from zsh (see the command name in the “comm” field) via the 64 bit kill syscall. Thus, mischief managed, once again!

Summary

In this blog I presented you three different tools to help you trace down sources of signals. The three tools each have their own strengths. SystemTap is abundant of features and really nicely scriptable. The additional features of auditd may make it appealing to deploy to your host. Perf is a great tool for CPU profiling and you might want to install it solely for that reason. On the other hand, your distribution might not have support compiled in its kernel or may make the setup harder for given tool. In my experience most modern distributions support the tools discussed here so the choice comes down to personal preference or convenience.

In case you were wondering, I often pick auditd because it is often already installed. SystemTap might be a bit more complicated to setup but I would likely invest some extra time into the setup if my case is more complex. I primary use perf for CPU tracing and tend to think of the other two tools before I think of perf for tracing signals.

Hope you enjoyed reading! Happy [h/t]racking!