Данные удаляются из таблицы - PullRequest
0 голосов
/ 21 февраля 2020

У меня действительно ужасная проблема, по какой-то причине данные стираются из столбца конкретной таблицы, и я понятия не имею, почему.

Таблица называется events. Внутри таблицы есть несколько столбцов: имя, дата и т. Д. c, но недавно я поместил поле в поле 'schedule', которое имеет тип TEXT.

На веб-странице вы можете редактировать событие на разных вкладках создайте расписание (поля, используя jQuery clone / et c), а затем, когда данные расписания будут сохранены в базе данных, данные HTML $ _POST преобразуются в массив JSON с использованием json_encode :

$db->prepared['schedule'] = json_encode(
    array(
        "scheduleday" => ($_POST['scheduleday'] ?? array()), 
        "scheduletime" => ($_POST['scheduletime'] ?? array()), 
        "scheduledescription" => ($_POST['scheduledescription'] ?? array()), 
        "schedulevenue" => ($_POST['schedulevenue'] ?? "")
    )
);

Полученный массив json может выглядеть следующим образом, например:

{"scheduleday":{"1":"2020-08-25","2":"2020-08-26"},"scheduletime":{"1":["19:30","20:00 - 20:50"],"2":["14:00 - 14:50","14:50 - 15:00","15:00 - 15:50","15:50 - 16:00","16:00 - 16:50"]},"scheduledescription":{"1":["Introduction","John Smith"],"2":["John Smith","Break","John Smith teaching","Break","John Smith teaching"]},"schedulevenue":"1 Acia Avenue"}

Сразу после того, как это INSERTED или UPDATEd в базу данных mysql, он затем отправляется к функции, которая использует fpdf для преобразования массива json в PDF, который можно загрузить.

Это хорошо работает, за исключением одной проблемы. Случайные (или то, что кажется случайным) расписания пропадают. Мы можем создать расписание на один день, а затем через неделю или несколько дней спустя, внезапно файл будет удален, а столбец в таблице удален. Никакие другие данные в таблице не удаляются, ничего кроме графика.

Вот что я пытался выяснить, что происходит:

SQL Триггер

Я установил триггер для таблицы событий, который сбрасывает данные в таблицу с именем event_trigger ПОСЛЕ запуска обновления. Вот код для триггера:

BEGIN
INSERT INTO `event_trigger` (oldID,name,old_schedule,new_schedule) VALUES
(OLD.id,
 OLD.name,
 OLD.schedule,
 NEW.schedule);
END

Это было полезно в том смысле, что я теперь знаю, если есть событие с пропущенным расписанием, потому что NEW.schedule будет пустым. Однако последние два раза расписание пропускало (фактически вчера и сегодня) время, оставшееся вне рабочих часов, 18:45 и 19:22, поэтому никто не должен обновлять события в те времена.

.txt Файловый журнал

Еще одна вещь, которую я сделал, - на странице, где обновляются события, я поместил текстовый журнал, который выдает подготовленные переменные, SQL оператор и пользователь и идентификатор пользователя в текстовый файл. К сожалению, это не работает, потому что, когда расписание пропадает, оно не регистрируется там. Все, что говорит мне, это то, что это происходит где-то еще.

Я не знаю, как сузить это дальше. В то время, когда событие удаляется, пользователь не предпринимает никаких действий. Самое близкое, что я получил, - это использовать TRIGGER. Но я настолько ограничен, что информации от триггера недостаточно; Я не могу получить IP, SQL оператор, идентификатор пользователя или что-то в этом роде. Только старые и новые переменные.

Может кто-нибудь помочь мне придумать способы расследования, я был бы очень благодарен. Это продолжается уже более месяца, и это бесит, потому что я просто не могу понять, почему это происходит.

Единственная дополнительная опция, которую я могу придумать, - это включить полные SQL журналы, но я Я не хочу этого делать, так как это сильно замедлит работу сервера.

1 Ответ

1 голос
/ 21 февраля 2020

Вы изучили логи вашего веб-сервера? Если это повреждение данных происходит через ваше веб-приложение, вы сможете увидеть точное время и исходный IP-адрес неудачного события. Вы также можете выяснить, на какой странице вашего веб-приложения возникла проблема.

Для более точного отслеживания событий на сервере базы данных добавьте в таблицу event_trigger следующие столбцы:

  • отметка времени (при срабатывании триггера)
  • пользователь (MySQL хост и пользователь, который выдал UPDATE, который запустил триггер)
  • запрос (текст запроса UPDATE)

Затем измените ваш триггер на:

BEGIN
  INSERT INTO event_trigger 
        (oldID,name,old_schedule,new_schedule, ts, user, query)
  VALUES
  (OLD.id,
   OLD.name,
   OLD.schedule,
   NEW.schedule,
   NOW(),
   CURRENT_USER(),
   (SELECT INFO FROM information_schema.process_list WHERE id=CONNECTION_ID())
);
END

Затем ваша таблица event_trigger покажет вам пользователя webapp@localhost или cybercreep@cracker.example.com, который выдал UPDATE, когда он был выпущен, и каков был точный запрос.

(С точный запрос, который вы можете искать в своей кодовой базе, чтобы попытаться отследить, какая функция выполняет amok.)

Как только вы узнаете, какой пользователь базы данных отправляет запрос, вы можете рассмотреть возможность приостановки доступа для этого конкретного пользователя в нерабочее время. и посмотреть, кто жалуется. Но имейте в виду, что пользователь базы данных, вероятно, является обобщенным c именем пользователя, используемым вашим веб-приложением, поэтому он может вам немного рассказать.

Вполне вероятно, что это законный пользователь веб-приложения, злоупотребляющий ошибка, ваша система.

Pro tip : поместите automati c столбцы меток времени во все таблицы своих приложений, чтобы вы могли отслеживать изменения. Добавьте

 ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

столбцы в свои таблицы, а MySQL позаботится об их обновлении.

Pro tip 2 (сложнее) добавьте таблицу журнала действий в свой базы данных, и заставьте ваше веб-приложение вставлять в него строку каждый раз, когда пользователь предпринимает какое-либо действие. Затем вы можете запускать запросы типа "кто что делал вчера с 19:00 до 19:30?" Служба поддержки людей любит это делать.

...