В методе insert_batch() Codeigniter с тысячами вставок отсутствуют записи.

Я использую insert_batch() для массовой вставки 10000+ строк в таблицу базы данных. Я делаю некоторые тесты и заметил, что иногда все 10 000+ строк вставляются правильно, но в некоторых случаях я пропускаю 100+ строк в общем количестве моей таблицы.

Данные полей в имеющихся у меня записях в порядке, поскольку я использую одни и те же данные для каждого из своих тестов, и в большинстве случаев у меня нет проблем. Например, я пытался 20 раз вставить одни и те же данные в свою базу данных, и в 19 раз все строки будут вставлены правильно, но в этот раз я пропущу 100 или, может быть, больше строк.

Функция для insert_batch() следующая:

protected function save_sms_to_database() {
    //insert_Batch
    $datestring = "%Y-%m-%d %h:%m:%s";
    $time = time();
    $datetime = mdate($datestring, $time);

    $this->date_sent = $datetime;

    foreach ($this->destinations as $k => $v) {
        $sms_data[$k] = array(
            'campaign_id' => $this->campaign_id,
            'sender_id' => $this->from,
            'destination' => $v,
            'token' => md5(time() . 'smstoken' . rand(1, 99999999999)),
            'message' => $this->body,
            'unicode' => $this->unicode,
            'long' => $this->longsms,
            'credit_cost' => $this->eachMsgCreditCost,
            'date_sent' => $this->date_sent,
            'deleted' => 0,
            'status' => 1,
            'scheduled' => $this->scheduled,
        );
    }

    $this->ci->db->insert_batch('outgoingSMS', $sms_data);
    if ($this->ci->db->affected_rows() > 0) {
        // outgoingSMS data were successfully inserted      
        return TRUE;
    } else {
        log_message('error', $this->campaign_id.' :: Could not insert sms into database');
        log_message('error', $this->ci->db->_error_message());
        return FALSE; // sms was not inserted correctly
    }
}

Как мне отладить insert_batch() для такого случая?

Я внес некоторые изменения в DB_active_rec.php, чтобы вести журнал во время вставки_пакета, и до сих пор я не могу успешно воспроизвести проблему, чтобы увидеть, что происходит не так. Но так как проблема появлялась 2-3 раза в начале и я не делал серьезных изменений в своей логике, чтобы исправить это, я не могу оставить это так, так как не доверяю функции codeigniter insert_batch() для производства.

Я также добавляю функцию insert_batch() codeigniter:

    public function insert_batch($table = '', $set = NULL)
{
        $countz = 0;
    if ( ! is_null($set))
    {
        $this->set_insert_batch($set);
    }

    if (count($this->ar_set) == 0)
    {
        if ($this->db_debug)
        {
            //No valid data array.  Folds in cases where keys and values did not match up
            return $this->display_error('db_must_use_set');
        }
        return FALSE;
    }

    if ($table == '')
    {
        if ( ! isset($this->ar_from[0]))
        {
            if ($this->db_debug)
            {
                return $this->display_error('db_must_set_table');
            }
            return FALSE;
        }

        $table = $this->ar_from[0];
    }

    // Batch this baby
    for ($i = 0, $total = count($this->ar_set); $i < $total; $i = $i + 100)
    {

        $sql = $this->_insert_batch($this->_protect_identifiers($table, TRUE, NULL, FALSE), $this->ar_keys, array_slice($this->ar_set, $i, 100));

        //echo $sql;

        $this->query($sql);
                    $countz = $countz + $this->affected_rows();
    }

    $this->_reset_write();
            log_message('info', "Total inserts from batch:".$countz);

    return TRUE;
}

Последнее log_message() с общим количеством вставок из партии также показывает проблему, поскольку, когда у меня меньше вставок, чем ожидалось, я также получаю неожидаемое количество вставок.

Мне нужно придумать что-то еще для вставки тысяч строк в мою базу данных с кодовым загрузчиком или без него.

у кого-нибудь есть какие-либо подсказки для такого рода проблемы? Может быть, это как-то связано с жестким диском или памятью системы во время нехватки производительности? Это старый компьютер с 1 ГБ оперативной памяти.

РЕДАКТИРОВАТЬ: В соответствии с запросом я помещаю здесь пример оператора INSERT с 9 строками, который создается функцией codeigniter insert_batch()

INSERT INTO `outgoingSMS` (`campaign_id`, `credit_cost`, `date_sent`, `deleted`, `destination`, `long`, `message`, `scheduled`, `sender_id`, `status`, `token`, `unicode`) VALUES ('279',1,'2013-08-02 02:08:34',0,'14141415151515',0,'fd',0,'sotos',1,'4d270f6cc2fb32fb47f81e8e15412a36',0), ('279',1,'2013-08-02 02:08:34',0,'30697000000140',0,'fd',0,'sotos',1,'9d5a0572f5bb2807e33571c3cbf8bd09',0), ('279',1,'2013-08-02 02:08:34',0,'30697000000142',0,'fd',0,'sotos',1,'ab99174d88f7d19850fde010a1518854',0), ('279',1,'2013-08-02 02:08:34',0,'30697000000147',0,'fd',0,'sotos',1,'95c48b96397b21ddbe17ad8ed026221e',0), ('279',1,'2013-08-02 02:08:34',0,'306972233469',0,'fd',0,'sotos',1,'6c55bc3181be50d8a99f0ddba1e783bf',0), ('279',1,'2013-08-02 02:08:34',0,'306972233470',0,'fd',0,'sotos',1,'d9cae1cbe7eaecb9c0726dce5f872e1c',0), ('279',1,'2013-08-02 02:08:34',0,'306972233474',0,'fd',0,'sotos',1,'579c34fa7778ac2e329afe894339a43d',0), ('279',1,'2013-08-02 02:08:34',0,'306972233475',0,'fd',0,'sotos',1,'77d68c23422bb11558cf6fa9718b73d2',0), ('279',1,'2013-08-02 02:08:34',0,'30697444333',0,'fd',0,'sotos',1,'a7fd63b8b053b04bc9f83dcd4cf1df55',0)

Это была законченная вставка.


person sotoz    schedule 02.08.2013    source источник
comment
В этом случае я бы предложил вставлять записи в цикл вместо одного запроса (insert_batch). И таким образом вы также можете отлаживать свои запросы.   -  person Nil'z    schedule 02.08.2013
comment
Можете ли вы показать нам SQL-запросы, которые выполняются? Может быть, некоторые неправильно сформированы? Рассматривали ли вы возможность использования массового оператора INSERT?   -  person Halcyon    schedule 02.08.2013
comment
@NiloySaha Я не могу использовать цикл для такого большого количества вставок, так как это снизит производительность моей системы. Особенно в производстве это будет губительно. Когда я использовал цикл при разработке для вставок, у меня не было проблем, насколько я помню, но я не могу использовать эту логику для такого большого количества вставок.   -  person sotoz    schedule 02.08.2013
comment
@FritsvanCampen, оператор массовой вставки - это то, что codeigniter использует для insert_batch, и, насколько я понимаю, он ограничивает количество каждого оператора до 100 строк на оператор вставки. Я отредактирую сообщение с одним оператором вставки с 9 строками.   -  person sotoz    schedule 02.08.2013
comment
Можно ли использовать транзакции? ellislab.com/codeigniter/user-guide/database/transactions.html   -  person cartalot    schedule 03.08.2013
comment
транзакции будут ответом, если я не найду, что не так с insert_batch() в первую очередь.   -  person sotoz    schedule 05.08.2013


Ответы (2)


insert_batch() пытается избежать именно вашей проблемы - пытается вставить данные больше, чем MySQL настроен для обработки за раз. Я не уверен, что вариант MySQL для этого был max_allowed_packet или что-то еще, но проблема в том, что он устанавливает ограничение в байтах, а не в количестве строк.

Если вы будете редактировать DB_active_rec.php, mysql_driver.php или что-то подходящее... попробуйте изменить этот счетчик 100 в цикле for(). 50 должно быть более безопасным выбором.

Помимо этого, FYI - affected_rows() не вернет правильное значение, если вы вставляете более 100 строк через insert_batch(), поэтому использовать его для проверки успеха/ошибки ненадежно. Это связано с тем, что insert_batch() вставляет ваши данные по 100 записей за раз, а affected_rows() возвращает данные только для последнего запроса.

person Narf    schedule 05.08.2013
comment
спасибо за ваш ответ, за affected_rows(), если вы видите изменения, которые я внес в DB_active_rec.php, мне удалось точно подсчитать, сколько вставок было сделано с помощью insert_batch, и общее количество, которое я получаю, всегда правильное (поскольку я также могу проверить это с помощью select count(*) ). Я попытаюсь изменить количество циклов, как вы сказали, и проведу там несколько тестов. Если все пойдет хорошо, я приму ваш ответ :) - person sotoz; 05.08.2013
comment
Поделитесь, пожалуйста, как вы решили эту проблему? - person NaN; 27.09.2016

Решение этой проблемы, вам нужно зайти в каталог /system/database/ и открыть файл DB_query_builder.php и обновить

public function insert_batch($table, $set = NULL, $escape = NULL, $batch_size = 1000)

Вы можете установить размер вашего требования.

person Anand agrawal    schedule 14.02.2018