2017-02-05 38 views
0

我在使用golang中的postgresql使用rows.next()對行進行交互時遇到錯誤。這隻發生在幾臺機器上,而且時間相當不可預測,這使得調試變得困難。Golang,postgresql rows.next()panic

panic: runtime error: index out of range [recovered] 
     panic: runtime error: index out of range 

goroutine 28078 [running]: 
panic(0xa63ae0, 0xc420014090) 
     /usr/local/go/src/runtime/panic.go:500 +0x1a1 
github.com/lib/pq.(*conn).errRecover(0xc420780500, 0xc420d2ef28) 
     /share/dpkg-build/pacman-build/src/github.com/lib/pq/error.go:482 +0x57e 
panic(0xa63ae0, 0xc420014090) 
     /usr/local/go/src/runtime/panic.go:458 +0x243 
github.com/lib/pq.binaryDecode(0xc420780728, 0xc4207806f0, 0x0, 0x30, 0xc400000017, 0xa24300, 0xc421fcb4b0) 
     /share/dpkg-build/pacman-build/src/github.com/lib/pq/encode.go:76 +0x385 
github.com/lib/pq.decode(0xc420780728, 0xc4207806f0, 0x0, 0x30, 0x17, 0x1, 0xa24300, 0xc421fcb4b0) 
     /share/dpkg-build/pacman-build/src/github.com/lib/pq/encode.go:61 +0x6c 
github.com/lib/pq.(*rows).Next(0xc42281e310, 0xc420b82000, 0x2f, 0x2f, 0x0, 0x0) 
     /share/dpkg-build/pacman-build/src/github.com/lib/pq/conn.go:1369 +0x420 
database/sql.(*Rows).Next(0xc42005b560, 0xc4204eb590) 
     /usr/local/go/src/database/sql/sql.go:1758 +0x6c 
github.com/xxxxx/yyyyy/src/product/elasticsearch.getPart1(0xc4204eb590, 0xa24300, 0xc420a04190, 0x0, 0x0) <-- rows.next() here 
     /share/dpkg-build/pacman-build/src/github.com/xxxxxx/yyyyyy/src/product/elasticsearch/collector.go:71 +0xff 
github.com/xxxxx/yyyyy/src/product/elasticsearch.Get(0xa24300, 0xc420a04190, 0xc420a04190, 0xa24300, 0xc420a04190, 0xc420980a00) 
     /share/dpkg-build/pacman-build/src/github.com/xxxxxx/yyyyyy/src/product/elasticsearch/collector.go:29 +0x118 

從上面的調用堆棧來的恐慌來自binaryDecode函數,我想解釋爲什麼它只發生在某些機器上。有可能是一些不好的網絡包或消息被破壞,所以驅動程序無法解碼消息,然後失敗。

但是我不知道該去哪裏,有人有想法嗎?

由於

+1

你有測試此代碼與競爭檢測器?這是您應該對看似隨機或不可預知的錯誤首先做的事情。 – JimB

+0

還沒有, 對我來說是一個很好的起點[Data Race Detector](https://golang.org/doc/articles/race_detector.html)? 還是你有另一個建議 –

+0

我正在使用準備好的語句,如果它的競爭條件,它可能來自那裏。 –

回答

0

。司機一個4字節的切片編碼爲一個整數,但試圖索引的單個字節時恐慌。

數據意外可能是零,還是小於4字節的數據類型?

在驅動程序github.com/lib/pq/encode.go

case oid.T_int4: 
    return int64(int32(binary.BigEndian.Uint32(s))) 

在編碼/二進制Uint32(與指數這一行的恐慌出界):

return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24