Использование PHP/PDO/MySQL: записи начали пропадать (буквально) без изменений кода.Php

Кемеровские программисты php общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Использование PHP/PDO/MySQL: записи начали пропадать (буквально) без изменений кода.

Сообщение Anonymous »

Я знаю, что тема сообщения не имеет смысла, как и моя ситуация. У меня есть простая таблица с именем «удалено», которая имеет три поля: автоинкремент rowid int не null, visitor_id int не null, tstamp timedate не null current_timestamp. Уже пару лет работает без сбоев. Когда посетитель удаляется, я добавляю связанный идентификатор строки из таблицы посетителей в удаленную таблицу. Когда я хочу проверить, был ли удален посетитель, я проверяю здесь: если visitor_id существует, значит, посетитель был удален. Как я уже сказал, это работает уже несколько лет.
Что-то "фанковое" произошло три дня назад - и нет, я пока не смог понять, что "фанково" означает. Но одним из симптомов является то, что записи, которые я добавляю или обновляю, больше не «берутся». Причина, по которой я начинаю с удаленной таблицы, заключается в том, что это место, где это происходит чаще всего, и его легче всего дублировать.
У меня открыто одно окно, в котором запущено веб-приложение, и еще одно окно открывается с запуском phpMyAdmin, а третье окно открывается с запуском приложения, которое отслеживает error_log, куда я сбрасываю выходные данные отладки.
  • В первом окне я Я запускаю приложение, в котором я помечаю посетителя для удаления, нажимаю «Отправить», а затем проверяю, исчез ли он. Это трехэтапный процесс: 1) перейдите к списку активных посетителей и выберите запись, 2) вы заходите в запись посетителя, где нажимаете "Удалить", затем нажмите "Отправить" и 3) возвращаетесь к списку активных посетителей, чтобы увидеть это. записи больше нет в списке.
  • Во втором окне я запускаю команду SQL для проверки таблиц. Ниже я включу команды SQL.
  • В третьем окне смотрю ошибки.
Вот код MySQL, который я запускаю во втором окне:

Код: Выделить всё

SELECT
COUNT(*) AS isGone,
R.tstamp_add AS WhenRemoved
FROM removed R
WHERE visitor_id = :id;

SELECT *
FROM removed R
ORDER BY R.rowid DESC
LIMIT 5;

SELECT V.rowid, V.visitor_name, V.tstamp_del
FROM visitors V
ORDER BY V.tstamp_del DESC
LIMIT 5;
После удаления тестового посетителя вот что я получаю от выполнения этих команд:
(Основные данные выделены жирным шрифтом):< /p>

Код: Выделить всё

isGone    WhenRemoved
1    **2024-07-16 23:24:04**
УДАЛЕНА ТАБЛИЦА

Код: Выделить всё

rowid  visitor_id  tstamp_add
**1471   213         2024-07-16 23:24:04**
1463   210         2024-07-16 18:06:46
1460   827         2024-07-16 17:33:34
1446   676         2024-07-16 03:24:05
1445   677         2024-07-16 03:23:50
ТАБЛИЦА ПОСЕТИТЕЛЕЙ

Код: Выделить всё

rowid  visitor_name  tstamp_del
**213    Daniel Berry  2024-07-16 23:24:04       **
212    Daniel Berry  2024-07-16 19:09:46
211    Daniel Berry  2024-07-16 18:36:58
210    Daniel Berry  2024-07-16 18:06:46
827    Josie Wales   2024-07-16 17:33:34
Вот строка из моего вывода error_log, связанная с этим:

Код: Выделить всё

[17-Jul-2024 03:24:04 UTC] 2024-07-17 03:24:04.905109
MSG: rval after archiving:
{"del":1,"remove":"**1471**","checking":"**2024-07-16 23:24:04**"}

[17-Jul-2024 03:24:04 UTC] 2024-07-17 03:24:04.901710
MSG: doing archive vid:[213]
Итак, на этом этапе, в середине процесса, команды MySQL phpMyAdmin показывают, что:

[*]Запись было помечено как удаленное. В первом сообщении журнала "del":1 показывает, что после процесса удаления была изменена одна строка в "удаленной" таблице, как указано в первом выводе SQL.
[*]"Удалено" " таблица имеет следующий ключ с правильными visitor_id и датой.
[*]В таблице "посетители" указана правильная дата в поле tstamp_del.

Я уверен, некоторые проницательные люди заметят, что поле auto_increment для новой записи (1471) на 8 больше, чем для следующей записи (1463), что на 3 больше, чем для следующей записи (1460). ), с еще одним большим пропуском перед следующим (1446).
Происходит следующее: после того, как я возвращаюсь к списку посетителей в приложении, tstamp_del в записи посетителя возвращается к NULL , а запись с идентификатором rowid 1471 просто исчезает из таблицы.
Об ошибках не сообщается, нет.
У меня есть 6 тестовых записей, которые я пробую чтобы разобраться: 827, 210, 211, 212, 213 и 214.
Чтобы попытаться выяснить, в чем заключается «проблема», я добавляю дополнительный код отладки. А когда у меня опечатка или еще какая подобная глупость и программа вылетает, то удаление "залипает". Вот почему вы можете видеть 827, 210 и 213. На самом деле вы видите только 213, потому что этот снимок находится в середине обработки — как только я обновлю страницу, он исчезнет.
Такое ощущение, что PDO выполняет откат, но у меня нулевой код транзакции. На самом деле, я потратил пару часов, пытаясь выяснить, как гарантировать, что PHP/PDO/MySQL запрещено выполнять транзакции, но безуспешно.
Просто для смеха и ухмылки. , вот метод, который добавляет элемент в удаленную таблицу:

Код: Выделить всё

    public function setRemoved($visitor_id)
{
$sql = 'INSERT INTO removed (visitor_id) VALUES (:v)';
$data = [ 'v' => $visitor_id ];

$sqlmsg = "Setting removed for prospect [$visitor_id]:" .
' for: ' . __METHOD__ . '::' . __LINE__ .
" // SQL: [$sql] // DATA:[" . $this->const->printr($data) . "]";
$this->log->log(logTRACE, __METHOD__, __LINE__, $sqlmsg);

try {
if ($stmt = $this->db->prepare($sql))
{
$stmt->execute($data);
return($this->db->lastInsertId());
}
else
{ throw new Exception('prepare == false', __LINE__); }
}
catch (PDOException $e)
{
$this->log->logsqlerr(__METHOD__, __LINE__,
$sqlmsg, $e);
return(false);
}
catch (Exception $e)
{
$this->log->logsqlerr(__METHOD__, __LINE__,
$sqlmsg, $e);
return(false);
}
}
Поскольку сообщение error_log содержит правильное значение LastInserId(), я знаю, что эта функция работала правильно.
Для полноты, вот что устанавливает запись посетителя:

Код: Выделить всё

    public function delVisitor($visitor_id = NULL)
{
if (empty($visitor_id)) { return(0); }

$sql = 'UPDATE visitors SET tstamp_del = :t WHERE rowid = :v';
$data = [
't' => $this->const->fixDateTime('now', 'Y-m-d H:i:s'),
'v' => $visitor_id
];

$sqlmsg = 'Deleting prospect record:' .
' for: ' . __METHOD__ . ' at: ' . __LINE__ .
" // SQL: [$sql] // DATA:[" . $this->const->printr($data) . "]";
$this->log->log(logTRACE, __METHOD__, __LINE__, $sqlmsg);
try {
if ($stmt = $this->db->prepare($sql))
{
$stmt->execute($data);
return(true);
}
else
{ throw new Exception('prepare == false', __LINE__); }
}
catch (PDOException $e)
{
$this->log->logsqlerr(__METHOD__, __LINE__,
$sqlmsg, $e);
return(false);
}
catch (Exception $e)
{
$this->log->logsqlerr(__METHOD__, __LINE__,
$sqlmsg, $e);
return(false);
}
}

Позвольте мне повторить: этот код не менялся более двух лет. Но начиная с этой временной метки или после нее (16 июля 2024 г., 03:24:05) эти записи начали исчезать. Чтобы прояснить этот момент: до rowid=1446 нет пробелов.
Я не против исследования; Я не против читать что-то — я действительно хочу понимать и учиться. Но я никогда не видел подобных вещей, за исключением транзакций, которые были отменены. Я старался НЕ использовать транзакции в этом приложении. Они слишком просто нужны.
Несколько подробностей: MariaDB 11.4.x, PHP 8.x.
Пожалуйста: есть ли у кого-нибудь еще видел такое? В чем была проблема?

Подробнее здесь: https://stackoverflow.com/questions/787 ... ut-changes
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Php»