Потеря данных при записи в БД. Очередь? Блокировка таблицы?[~РЕШЕНО]

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
terrarium volition
Сообщения: 99
Зарегистрирован: 2021.07.15, 21:22

Потеря данных при записи в БД. Очередь? Блокировка таблицы?[~РЕШЕНО]

Сообщение terrarium volition »

Всем доброго дня!

Дело в том, что есть несколько пользователей, которые пишут данные в БД пачками.
Если писать строго по очереди, запуская запись следующего массива данных после завершения прошлой записи, то в БД пишутся все данные.
Если писать асинхронно, когда пакеты данных "встречаются" на входе в БД в момент записи, происходит потеря данных, каждый раз разных и в разных количествах.

Пытался решить вопрос через очереди, но они тут, почему-то, не помогают, делал их так:
Создаётся очередь под своим pid. Далее эту очередь наполняют запросы пользователей, которые асинхронно кликают на кнопку и пытаются записать данные в БД.
В логах видно, что очередь отрабатывается, запись в БД идёт, но это не помогает справиться с потерей данных.

Вопрос №1:
Если открывать несколько очередей, каждую со своим pid, поможет ли это исправить ситуацию?
Если да, то как в коде выполнить консольную команду

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

yii queue/listen
чтобы запускать работу новой очереди по готовности данных на запись от нового пользователя.
Как выполнять консольные команды из кода не совсем понятно. :?
Вопрос №2:
Как, если не через очереди, решать проблему множественного доступа на запись в БД средствами фреймворка? Не нашёл информацию по блокировке таблиц через activeRecord или Query или как-то ещё.

Спасибо.
Последний раз редактировалось terrarium volition 2023.06.24, 22:31, всего редактировалось 1 раз.
terrarium volition
Сообщения: 99
Зарегистрирован: 2021.07.15, 21:22

Re: Потеря данных при записи в БД. Очередь? Блокировка таблицы?

Сообщение terrarium volition »

Я обманулся и вас обманул.
Ошибка записи происходит даже при активности одного пользователя. Т.е. ошибка при записи пачки.
Видимо, тут, если была ошибка, нужно откатывать транзакцию и писать текущую порцию данный по одной строчке или, возможно, сначала пытаться уменьшить размер порции, разбивая её на подпорции.
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Потеря данных при записи в БД. Очередь? Блокировка таблицы?

Сообщение unknownby »

terrarium volition писал(а): 2023.06.20, 11:06 как в коде выполнить консольную команду

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

yii queue/listen
Выполнить консольную команду на хостингах можно при помощи планировщика задач, он же CRON.

Если у вас свой сервер, либо есть возможность установить supervisor, то при помощи его можно настроить работу с очередями.
И конечно же, лучше использовать не очереди в вашей БД для каких-то сложных задач, а подойдёт RabbitMQ.
Как вариант, посмотрите ещё Kafka, у вас там нужно же обновлять сразу много записей.

Возможно у вас на хостинге он есть (рэббит или кафка), при отсутствии используйте CRON
terrarium volition
Сообщения: 99
Зарегистрирован: 2021.07.15, 21:22

Re: Потеря данных при записи в БД. Очередь? Блокировка таблицы?

Сообщение terrarium volition »

Спасибо за развёрнутый ответ!
unknownby писал(а): 2023.06.20, 16:08 Выполнить консольную команду на хостингах можно при помощи планировщика задач, он же CRON.
Получается, при помощи php никак? Эх..жаль. Про CRON знаю, думал, что можно изнутри запуститься.
unknownby писал(а): 2023.06.20, 16:08 Если у вас свой сервер, либо есть возможность установить supervisor, то при помощи его можно настроить работу с очередями.
И конечно же, лучше использовать не очереди в вашей БД для каких-то сложных задач, а подойдёт RabbitMQ.
Как вариант, посмотрите ещё Kafka, у вас там нужно же обновлять сразу много записей.

Возможно у вас на хостинге он есть (рэббит или кафка), при отсутствии используйте CRON
Я использую Redis для управления очередями.
Посмотрю, что такое Kafka.
RabbitMQ, как пишут в доке на yii2-queue, не поддерживает проверку состояния очереди.
Аватара пользователя
samdark
Администратор
Сообщения: 9489
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Потеря данных при записи в БД. Очередь? Блокировка таблицы?

Сообщение samdark »

А какую вы получаете ошибку при потере данных? Что в логах PHP? Что в логах базы?
terrarium volition
Сообщения: 99
Зарегистрирован: 2021.07.15, 21:22

Re: Потеря данных при записи в БД. Очередь? Блокировка таблицы?

Сообщение terrarium volition »

samdark писал(а): 2023.06.21, 08:56 А какую вы получаете ошибку при потере данных? Что в логах PHP? Что в логах базы?
Ошибок, как будто, нет.
Пишу в БД и отлавливаю ошибку так:

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

use yii\db\Exception;
...
public function saverDBbatch($chunkedArray, $tabname, $attributes){
        $session = Yii::$app->session;
        $issaved = true;
        try {
            foreach($chunkedArray[0] as $key => $bArray){
                $transaction = Yii::$app->db->beginTransaction();
                $issave = Yii::$app->db->createCommand()->batchInsert($tabname, array_keys($attributes), $bArray)->execute();
                $transaction->commit();

                $issaved = $issaved && $issave;
            }
        } catch (Exception $e) {
            $transaction->rollBack();
            $issaved = false;

            if ($tabname == Tag::tableName()){
                $this->dberrorTag = $e->getMessage();
                $session->set('dberrorTag', $e->getMessage());
            }else{
                $this->dberrorLogger = $e->getMessage();
                $session->set('dberrorLogger', $e->getMessage());
            }
        } 

        return $issaved;
    }
В массиве сессии смотрю, что сохраняется при except, но там всегда пусто.
Я использую XAMPP, там есть логи mysql_error.log, но в нём ошибок нет, есть информационные сообщения, которые не множатся при запуске очередной записи, т.е. это точно не ошибки и не предупреждения по записи в БД. Если нужно, могу скинуть файл сюда.
По PHP ошибок тоже нет, всё отрабатывает, exception тоже отлавливается, но там тоже пусто.

Эксперименты показали, что ошибки записи возникают с момента, когда таблица БД становится заполнена на ~60к строк и более.
Возможно, какие-то настройки самой БД надо прописать, БД MySQL, но я пока не понимаю, какие.
terrarium volition
Сообщения: 99
Зарегистрирован: 2021.07.15, 21:22

Re: Потеря данных при записи в БД. Очередь? Блокировка таблицы?

Сообщение terrarium volition »

В общем, пересел на postgresql в части записи данных.
Все ~100к записей записались через очередь.

Не буду мучаться с MySQL, тем более, что в другом проекте именно postgresql используется. Зоопарк БД ликвидирую, повод есть.
Вопросов по yii2 здесь, получается, нет.

Но немного странно, что ошибок запись в БД не выдавала.
Вышеприведённый мною способ отлова ошибок рабочий, я проверял, намеренно вызывая ошибку. Она сохранялась и я её видел.

Всем спасибо.
Ответить