Паника во время массового копирования хранилища данных sql - PullRequest
0 голосов
/ 03 мая 2018

Я записываю данные в хранилище данных SQL Azure с помощью драйвера go-mssql .

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

Ошибка

panic: runtime error: slice bounds out of range

goroutine 56 [running]:
github.com/denisenkom/go-mssqldb.(*tdsBuffer).Write(0xc420614800, 0xc420547d40, 0x2, 0x8, 0x0, 0x0, 0x0)
        /Users/thihara/workspace/golang/src/favmed.unfuddle.com/src/github.com/denisenkom/go-mssqldb/buf.go:93 +0x194
encoding/binary.Write(0xd2f320, 0xc420614800, 0xd3b500, 0xda4e70, 0x8ea680, 0xa2cfb4, 0x8, 0x0)
        /usr/local/go/src/encoding/binary/binary.go:354 +0x188
github.com/denisenkom/go-mssqldb.(*Bulk).Done(0xc420506600, 0xc420691550, 0xda4e70, 0x10)
        /Users/thihara/workspace/golang/src/favmed.unfuddle.com/src/github.com/denisenkom/go-mssqldb/bulkcopy.go:219 +0xae
github.com/denisenkom/go-mssqldb.(*copyin).Exec(0xc4204a6bc0, 0xda4e70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
        /Users/thihara/workspace/golang/src/favmed.unfuddle.com/src/github.com/denisenkom/go-mssqldb/bulkcopy_sql.go:73 +0x1cb
database/sql.ctxDriverStmtExec(0xd38d60, 0xc42001a070, 0xd38fe0, 0xc4204a6bc0, 0xda4e70, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
        /usr/local/go/src/database/sql/ctxutil.go:78 +0x176
database/sql.resultFromStatement(0xd38d60, 0xc42001a070, 0xd36720, 0xc4205e95f0, 0xc42099c580, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
        /usr/local/go/src/database/sql/sql.go:2109 +0x184
database/sql.(*Stmt).ExecContext(0xc4202f87e0, 0xd38d60, 0xc42001a070, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
        /usr/local/go/src/database/sql/sql.go:2085 +0x223
database/sql.(*Stmt).Exec(0xc4202f87e0, 0x0, 0x0, 0x0, 0xd352e0, 0xc420421180, 0x0, 0x0)
        /usr/local/go/src/database/sql/sql.go:2097 +0x65

Кто-нибудь знает, что происходит?

Я подумал, что, возможно, это может быть связано с параллелизмом, но исключил его, запустив всего одну процедуру go (изначально это были процедуры 3 go).

По какой-то причине это происходит для некоторых пакетных вставок, а не для всех.

Это также не относится к размеру партии. У меня были партии из 1500 рядов, а партия из 1161 ряда провалилась из-за этой паники.

EDIT:

Я обошел эту проблему, вручную упаковав свои вставки в 1000 с.

Однако это не очень практичное решение, так как пропускная способность станет очень ограниченной.

код:

func (w Writer) Write(schema string, data []Datum) error {
    txn, err := w.connection.Begin()
    if err != nil {
        return err
    }

    fullTableName := fmt.Sprintf("[%s].[%s]", schema, TABLE_NAME)

    //Create a prepared statement, BulkOptions can be configured to handle the insert limits if necessary.
    stmt, err := txn.Prepare(mssql.CopyIn(fullTableName, mssql.BulkOptions{RowsPerBatch: 100000}, "unit_did", "chassis_did",
        "gateway_did", "location_code", "data_type", "value", "last_detected_timestamp", "sample_timestamp", "db_timestamp"))
    if err != nil {
        return err
    }
    defer stmt.Close()

    // Prepare the values to be inserted.
    for _, value := range data {
        _, err = stmt.Exec(value.UnitDID, value.ChassisDID, value.GatewayDID, value.LocationCode, value.DataType,
            value.Value, value.LastDetectedTimestamp, value.SampleTimestamp, value.DbTimestamp)

        // Fail the transaction if an error is encountered.
        if err != nil {
            txn.Rollback()
            return err
        }
    }

    // Execute the query against the database and fail the transaction if there's an error.
    _, err = stmt.Exec()
    if err != nil {
        txn.Rollback()
        return err
    }

    return txn.Commit()
}

Для этого была поднята проблема с github, когда тестовое шоу решало эту проблему.

https://github.com/denisenkom/go-mssqldb/issues/370

1 Ответ

0 голосов
/ 03 мая 2018

Паника дает полезную информацию:

panic: runtime error: slice bounds out of range

и

goroutine 56 [running]:
github.com/denisenkom/go-mssqldb.(*tdsBuffer).Write(0xc420614800, 0xc420547d40, 0x2, 0x8, 0x0, 0x0, 0x0)
/Users/thihara/workspace/golang/src/favmed.unfuddle.com/src/github.com/denisenkom/go-mssqldb/buf.go:93 +0x194

Итак, линия паники вполне может быть здесь:

https://github.com/denisenkom/go-mssqldb/blob/master/buf.go#L93

При циклическом перемещении по буферу может возникать ошибка «один за другим», приводящая к ошибке выхода за пределы допустимого диапазона.

Проект был недавно обновлен. Я бы просто подал вопрос по проекту.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...