Bug 43651

Summary: Не очищается / удаляется lock файл /var/lib/mysql/mysql.sock.lock
Product: Sisyphus Reporter: Горев Андрей <nekapitan2009>
Component: MySQL-serverAssignee: Николай Костригин <nickel>
Status: REOPENED --- QA Contact: qa-sisyphus
Severity: major    
Priority: P5 CC: alimektor, doroshenkogv, iluha.companets, lav, mike, nickel, rider, shaba
Version: unstable   
Hardware: x86_64   
OS: Linux   
Attachments:
Description Flags
патч none

Description Горев Андрей 2022-08-30 07:27:00 MSK
Проблема в том,что он почему-то не всегда удаляется при остановке сервера. В большом количестве случаев этого не происходит. Вероятность где-то от 10 до 20%%. В файлах запуска/остановки сервера чистки нет для этого файла. Перезапуск путём systemctl/service не помогает так как не удаляется файл. Благо что я бывший системный программист UNIX - ошибку нашёл быстро, но подумал о других только сегодня.
   Исправьте!
Comment 1 Николай Костригин 2022-08-30 10:56:28 MSK
(Ответ для Горев Андрей на комментарий #0)
> Проблема в том,что он почему-то не всегда удаляется при остановке сервера. В
> большом количестве случаев этого не происходит. Вероятность где-то от 10 до
> 20%%. В файлах запуска/остановки сервера чистки нет для этого файла.
> Перезапуск путём systemctl/service не помогает так как не удаляется файл.

В Sisyphus и p10 проявляется?
Каким образом нужно останавливать сервер, чтобы воспроизвести проблему?

> Благо что я бывший системный программист UNIX - ошибку нашёл быстро, но
> подумал о других только сегодня.

Если исправили, можете предложить патч.
Comment 2 Дорошенко Глеб 2022-12-11 16:12:36 MSK
(Ответ для Горев Андрей на комментарий #0)

> Проблема в том,что он почему-то не всегда удаляется при остановке сервера. В
> большом количестве случаев этого не происходит. Вероятность где-то от 10 до
> 20%%. В файлах запуска/остановки сервера чистки нет для этого файла.
> Перезапуск путём systemctl/service не помогает так как не удаляется файл.
> Благо что я бывший системный программист UNIX - ошибку нашёл быстро, но
> подумал о других только сегодня.
>    Исправьте!

Т.к. ответа не последовало в течении 4 месяцев, перевожу в Worksforme.
Comment 3 iluha 2025-02-20 07:29:45 MSK
баг стабильно повторялся на платформе p10, и сейчас на p11

> он почему-то не всегда удаляется при остановке сервера

поправка - он _всегда_ не удаляется при остановке сервиса, такого быть не должно (сравнивал поведение с debian), но это полбеды - файл может "залипнуть" при отключении питания, например

> Вероятность где-то от 10 до 20%

это вероятность совпадения PID, который записан в lock-файле с уже существующим в системе (любого процесса)

с вероятностью 100% повторить баг можно так:
1) остановить сервис (lock-файл остаётся)
2) изменить lock-файл, записав в него PID любого существующего процесса в системе
3) запустить сервис - будет ошибка

для решения проблемы предлагаю "костыль" (другого способа не вижу), благо у сервисного файла `/lib/systemd/system/mysqld.service` уже есть
```
ExecStartPre=/etc/chroot.d/mysql.all
```
где в свою очередь вызывается `mysql.lib`, который и предлагаю добавить строками

```
# socket lock file issue #43651
if [ -f ./mysql.sock.lock ] && [ "$(pidof mysqld)" != "$(cat ./mysql.sock.lock)" ]; then
  rm ./mysql.sock.lock
fi
```
Comment 4 iluha 2025-02-20 08:59:16 MSK
я пробовал запускать без `chroot` - результат тот же
пробовал искусственно повторить ситуацию на debian (в т.ч. на Астре) - не получилось, ошибки не происходит
Comment 5 iluha 2025-02-20 09:02:08 MSK
кстати, вероятность ошибки повышается при рестарте системы, в случае сервис не перезапускался после предыдущего рестарта - в таком случае PID'ы будут небольшие, в одном "кучном" диапазоне
Comment 6 iluha 2025-02-20 09:03:33 MSK
я пробовал запускать без `chroot` - результат тот же

пробовал искусственно повторить ситуацию на debian (в т.ч. на Астре) - не получилось, ошибки не происходит

кстати, вероятность ошибки повышается при рестарте системы, если сервис не перезапускался после предыдущего рестарта - в таком случае PID'ы будут небольшие, в одном "кучном" диапазоне
Comment 7 iluha 2025-02-20 15:41:06 MSK
поотлаживал - всё работает "как задумано", вот только не понимаю, почему в debian сымитировать эту ошибку не получается, лезть ещё там в отладку уже лень )

`MySQL/sql/conn_handler/socket_connection.cc:775`
```
    if (read_pid != cur_pid && read_pid != parent_pid) {
      if (kill(read_pid, 0) == 0) {
        LogErr(ERROR_LEVEL, ER_CONN_UNIX_PID_CLAIMED_SOCKET_FILE,
               static_cast<int>(read_pid));
        return true;
      }
    }
```
Comment 8 iluha 2025-02-20 16:02:12 MSK
> не понимаю, почему в debian сымитировать эту ошибку не получается

подозреваю, что разница в том, что там pid- и lock-файлы создаются в /var/run, а не в /var/lib
Comment 9 Evgeny Shesteperov 2025-02-20 16:10:38 MSK
Шаги для воспроизведения ошибки:

1. Установить MySQL:

    # apt-get install -y MySQL-server && \
    systemctl enable --now mysqld.service && \
    systemctl status mysqld.service --no-pager -l && \
    systemctl disable --now mysqld && \
    reboot

2. Создать скрипт:

    # cat > run.sh <<'EOF'
    #!/bin/bash -xe

    spawn_pids() {
        NUM_PROCESSES=$1
        current_pid=""
        mysql_pid="$(cat /var/lib/mysql/mysql.sock.lock)"
        for ((i=1; i<=NUM_PROCESSES; i++)); do
            sleep 600 &
            current_pid=$!
            if [[ "$mysql_pid" == "$current_pid" ]]; then
                echo "MySQL ($mysql_pid) created. OK!"
                sleep 10
                return 0
            fi 
        done
    }

    systemctl status mysqld.service --no-pager -l && (echo "Looks like MySQL is running!.. stop it.") ||:
    spawn_pids 10000
    systemctl start mysqld.service && \
    sleep 5
    systemctl status mysqld.service --no-pager -l
    EOF

    # chmod +x run.sh

3. Перезагрузить машину:

    # reboot

4. Запустить скрипт:

    ./run.sh

Ожидаемый результат: Успешное выполнение скрипта

Фактический результат: ошибка MYSQL:

    [ERROR] [MY-010259] [Server] Another process with pid 7419 is using unix socket file.
    [ERROR] [MY-010268] [Server] Unable to setup unix socket lock file.

Воспроизводится в P11.
Comment 10 iluha 2025-02-20 16:52:42 MSK
> pid- и lock-файлы создаются в /var/run

попробовал запустить в Альте MySQL без chroot, используя /run:

[mysqld]
socket   = /var/run/mysqld/mysql.sock
pid-file = /var/run/mysqld/mysqld.pid

это решило проблему автоматического удаления lock-файла при нормальном завершении сервиса

к тому же, учитывая самоочищение /run при перезагрузке - это решает и проблему с блокированием сервиса практически на 100%
(вероятность получить уже имеющийся в системе PID при рестарте сервиса - ооочень мала)
Comment 11 iluha 2025-02-22 08:45:11 MSK
Created attachment 17809 [details]
патч

так более правильно:
```
# socket lock file issue (ALT#43651)
if [ -f ./mysql.sock.lock ]; then
  lock_pid=$(cat ./mysql.sock.lock)
  if [ "mysqld" != "$(cat /proc/$lock_pid/comm)" ]; then
    rm ./mysql.sock.lock
  fi
fi
```
Comment 12 Vitaly Lipatov 2025-03-05 21:29:03 MSK
(Ответ для Evgeny Shesteperov на комментарий #9)
> Шаги для воспроизведения ошибки:
> 
...
А что делает функция spawn_pids ?