// Die Datei /Users/jinke/golang/src/cds_spider/common/dbpool/mysql.go
package dbpool
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
var DB *sql.DB
func init() {
db, err := sql.Open("mysql", "root:123456@tcp(192.168.1.20:3306)/?charset=utf8")
if err != nil {
panic("dbpool init >> " + err.Error())
}
DB = db
DB.SetMaxIdleConns(5)
}
// Die Datei /Users/jinke/golang/src/cds_spider/newCar/koubei/koubei.go
package koubei
import (
"cds_spider/common/dbpool"
)
type KouBei struct {
Auto_koubei_id int
Source string
Auto_brand_id, Auto_company_id, Auto_serial_id, Auto_type_id int
Username string
Price float64
Province_id, City_id int
Buy_date, Content, Spider_url, Created string
Level int
}
func (k *KouBei) Save() (insertID int64, err error) {
stmt, err := dbpool.DB.Prepare("INSERT mains.koubei SET source=?, auto_brand_id=?, auto_company_id=?, auto_serial_id=?, auto_type_id=?, username=?, price=?, province_id=?, city_id=?, buy_date=?, content=?, level=?, spider_url=?")
if err != nil {
return 0, err
}
defer stmt.Close()
res, err := stmt.Exec(k.Source, k.Auto_brand_id, k.Auto_company_id, k.Auto_serial_id, k.Auto_type_id, k.Username, k.Price, k.Province_id, k.City_id, k.Buy_date, k.Content, k.Level, k.Spider_url)
if err != nil {
return 0, err
}
return res.LastInsertId()
}
"stmt, err: = dbpool.DB.Prepare" ist Fehler ungültige Speicheradresse oder Nullzeiger-Dereferenzierung
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x41 pc=0x52fb5c]
goroutine 2208 [running]:
github.com/go-sql-driver/mysql.(*mysqlConn).writeCommandPacketUint32(0x0, 0x1048eca19, 0xc2046b8330, 0x2ba32ae35a88)
/Users/jinke/golang/src/github.com/go-sql-driver/mysql/packets.go:327 +0x1c
github.com/go-sql-driver/mysql.(*mysqlStmt).Close(0xc200e3ba50, 0x0, 0x0)
/Users/jinke/golang/src/github.com/go-sql-driver/mysql/statement.go:24 +0x46
database/sql.(*driverConn).finalClose(0xc2020d5cc0, 0xc20370d900, 0x2bbc7f0)
/usr/local/go/src/pkg/database/sql/sql.go:285 +0x87
database/sql.func·002(0xc2000ca200, 0xc2000aebd0)
/usr/local/go/src/pkg/database/sql/sql.go:372 +0x2c
database/sql.(*driverConn).Close(0xc2020d5cc0, 0x3, 0x4a173d)
/usr/local/go/src/pkg/database/sql/sql.go:278 +0x174
database/sql.(*DB).putConn(0xc2000ca1e0, 0xc2020d5cc0, 0x0, 0x0)
/usr/local/go/src/pkg/database/sql/sql.go:598 +0x2e2
database/sql.(*DB).prepare(0xc2000ca1e0, 0x742450, 0xd2, 0xc20035ba50, 0x85, ...)
/usr/local/go/src/pkg/database/sql/sql.go:640 +0x267
database/sql.(*DB).Prepare(0xc2000ca1e0, 0x742450, 0xd2, 0x4b2488, 0xc2000ae140, ...)
/usr/local/go/src/pkg/database/sql/sql.go:608 +0x5a
cds_spider/newCar/koubei.(*KouBei).Save(0xc2046ab790, 0x0, 0x0, 0x0)
/Users/jinke/golang/src/cds_spider/newCar/koubei/koubei.go:20 +0x6b
Wir benötigen folgende Informationen:
go version
in Ihrer Konsole aus)go version go1.1.2 darwin / amd64
Go-MySQL-Driver ist die neueste Version
Ich denke, die Panik sollte nicht mit v1.0.3 auftreten , einer Bugfix-Version, die wir gestern veröffentlicht haben ( go get
-fähig seit einigen Minuten).
Aber ich untersuche weiter, der Stacktrace sieht für mich wirklich seltsam aus. Die Panik wird durch eine nil
-Verbindung in stmt.Close
(Variable mc
) verursacht, bei der eine Verbindung mit dem obigen Code niemals nil
.
v1.0.3 kann zumindest die Nullzeiger-Panik verhindern, da zuerst mc == nil
überprüft wird.
Können Sie diesen Fehler reproduzieren?
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x41 pc=0x5304bc]
goroutine 25466 [running]:
github.com/go-sql-driver/mysql.(*mysqlConn).writeCommandPacketUint32(0x0, 0x305e92619, 0xc22b2fe650, 0x2b8b3c6167c0)
/Users/jinke/golang/src/github.com/go-sql-driver/mysql/packets.go:327 +0x1c
github.com/go-sql-driver/mysql.(*mysqlStmt).Close(0xc22b87a6f0, 0x0, 0x0)
/Users/jinke/golang/src/github.com/go-sql-driver/mysql/statement.go:24 +0x46
database/sql.(*driverConn).finalClose(0xc202a42780, 0xc2014fd1c0, 0x2210b5a80)
/usr/local/go/src/pkg/database/sql/sql.go:Jump {0 autohome 25 44 258 1977 hkyjh 12.68 394 397 2011-9-27 http://k.autohome.com.cn/spec/8288/hkyjh 2013-11-02 14:21:38 6}
285 +0x87
database/sql.func·002(0xc2000ca200, 0xc2000aebd0)
/usr/local/go/src/pkg/database/sql/sql.go:372 +0x2c
database/sql.(*driverConn).Close(0xc202a42780, 0x32, 0x9)
/usr/local/go/src/pkg/database/sql/sql.go:278 +0x174
database/sql.(*DB).putConn(0xc2000ca1e0, 0xc202a42780, 0x0, 0x0)
/usr/local/go/src/pkg/database/sql/sql.go:598 +0x2e2
database/sql.func·004()
/usr/local/go/src/pkg/database/sql/sql.go:664 +0x41
database/sql.(*DB).exec(0xc2000ca1e0, 0x738330, 0x40, 0x2b8b3c616cb8, 0x2, ...)
/usr/local/go/src/pkg/database/sql/sql.go:661 +0xb2
database/sql.(*DB).Exec(0xc2000ca1e0, 0x738330, 0x40, 0x2b8b3c616cb8, 0x2, ...)
/usr/local/go/src/pkg/database/sql/sql.go:650 +0x98
cds_spider/newCar/koubei.AddOk(0x6dee10, 0x8, 0x1, 0x0, 0x0, ...)
/Users/jinke/golang/src/cds_spider/newCar/koubei/log.go:49 +0x568
cds_spider/newCar/koubei.(*KouBei).Save(0xc20a0a74d0, 0x0, 0x0, 0x0)
/Users/jinke/golang/src/cds_spider/newCar/koubei/koubei.go:29 +0x3b7
main.func·006()
/Users/jinke/golang/src/cds_spider/newCar/koubei/main/autohome.go:241 +0x37
created by main.func·007
/Users/jinke/golang/src/cds_spider/newCar/koubei/log.go
func AddOk(source string, count int) error {
row := dbpool.DB.QueryRow("SELECT * FROM cheduoshao_spider_status.koubei WHERE source=? AND spider_date=?", source, gcode.Date())
var (
id, quantity int
sources, spider_date string
)
row.Scan(&id, &sources, &quantity, &spider_date)
if id == 0 {
stmt, err := dbpool.DB.Prepare("INSERT cheduoshao_spider_status.koubei SET source=?, quantity=?, spider_date=?")
if err != nil {
return err
}
defer stmt.Close()
_, err = stmt.Exec(source, 1, gcode.Date())
if err != nil {
return err
}
} else {
dbpool.DB.Exec("UPDATE main.koubei SET quantity=? WHERE id=?", quantity+1, id)
}
return nil
}
dbpool.DB.Exec ("UPDATE main.koubei SET Menge =? WHERE ID =?", Menge + 1, ID) IST FEHLER
Scheint eine solche Situation noch nicht gefunden zu haben, mein System ist OS X 10.9
Überprüfen Sie, ob row.Scan(&id, &sources, &quantity, &spider_date)
einen Fehler zurückgibt.
Haben Sie v1.0.3 ausprobiert? Wie gesagt, es sollte zumindest die Panik vermeiden.
Ich habe ein paar Mal mehr versucht, ich lösche einfach die alte Version, hol sie dir noch einmal
Ich wechselte zu:
err := row.Scan(&id, &sources, &quantity, &spider_date)
if err != nil {
return err
}
Ich glaube, ich konnte diesen Fehler reproduzieren. Dieser Fehler hängt erneut mit https://codereview.appspot.com/14920046 / Go-Problem 5718 (oder # 98, # 142) zusammen.
stmt.Exec
ignoriert Fehler des Treibers und stellt schlechte Verbindungen zum Pool wieder her.
v1.0.3 enthält # 143, wodurch zumindest die Panik vermieden wird. v1.1, das in wenigen Stunden veröffentlicht wird, wird # 151 enthalten, was dies ein bisschen mehr verbessert.
Ich würde vorschlagen, entweder Ihre Go-Version manuell mit https://codereview.appspot.com/14920046 zu patchen oder stmt.Exec
vermeiden, bis die nächste stabile Version mit diesem Fix veröffentlicht wird. Das wäre wahrscheinlich Go 1.3 im Juni 2014 ...
Und ein Hinweis zu Ihrem Code oben:
Wenn Sie ein stmt
nur einmal verwenden, gibt es keinen Grund, es manuell vorzubereiten. Verwenden Sie einfach db.Exec
, was übrigens nicht wie stmt.Exec
abgehört wird.
Hier ist, wie ich Ihren Code oben ändern würde:
func AddOk(source string, count int) error {
var (
id, quantity int
sources, spider_date string
)
if err := dbpool.DB.QueryRow("SELECT * FROM cheduoshao_spider_status.koubei WHERE source=? AND spider_date=?", source, gcode.Date()).Scan(&id, &sources, &quantity, &spider_date); err != nil {
return err
}
if id == 0 {
if _, err =: dbpool.DB.Exec("INSERT cheduoshao_spider_status.koubei SET source=?, quantity=?, spider_date=?", source, 1, gcode.Date()); err != nil {
return err
}
} else {
if _, err =: dbpool.DB.Exec("UPDATE main.koubei SET quantity=? WHERE id=?", quantity+1, id); err != nil {
return err
}
}
return nil
}
OK danke!
Ich habe auch dieses Problem, go-Version ist go1.7.4 linux/amd64
und go-sql-Treiber ist die neueste. Ich verbinde mich mit einer RDS-Instanz von AWS.
runtime error: invalid memory address or nil pointer dereference
/usr/local/go/src/runtime/panic.go:458 (0x42c653)
gopanic: reflectcall(nil, unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
/usr/local/go/src/runtime/panic.go:62 (0x42b1ad)
panicmem: panic(memoryError)
/usr/local/go/src/runtime/sigpanic_unix.go:24 (0x441054)
sigpanic: panicmem()
/usr/local/go/src/database/sql/sql.go:781 (0x557d0a)
(*DB).conn: db.mu.Lock()
/usr/local/go/src/database/sql/sql.go:1074 (0x559fbb)
(*DB).query: ci, err := db.conn(strategy)
/usr/local/go/src/database/sql/sql.go:1062 (0x559dc0)
(*DB).Query: rows, err = db.query(query, args, cachedOrNewConn)
/home/danilo/Go/src/github.com/DaniloMeritocracy/autocomplete/autocomplete.go:192 (0x402e27)
_getJSON: rows, err := db.Query(sqlString)
/home/danilo/Go/src/github.com/DaniloMeritocracy/autocomplete/autocomplete.go:130 (0x402b54)
school: res, err := _getJSON("SELECT * FROM university WHERE LOWER(name) LIKE '" + strings.Replace(term, "'", "\\'", -1) + "%' LIMIT 15")
/home/danilo/Go/src/github.com/DaniloMeritocracy/autocomplete/autocomplete.go:56 (0x403985)
main.func1: results = school(term)
/home/danilo/Go/src/gopkg.in/gin-gonic/gin.v1/context.go:97 (0x45d53a)
(*Context).Next: c.handlers[c.index](c)
/home/danilo/Go/src/gopkg.in/gin-gonic/gin.v1/recovery.go:45 (0x46d31a)
RecoveryWithWriter.func1: c.Next()
/home/danilo/Go/src/gopkg.in/gin-gonic/gin.v1/context.go:97 (0x45d53a)
(*Context).Next: c.handlers[c.index](c)
/home/danilo/Go/src/gopkg.in/gin-gonic/gin.v1/logger.go:72 (0x46c40f)
LoggerWithWriter.func1: c.Next()
/home/danilo/Go/src/gopkg.in/gin-gonic/gin.v1/context.go:97 (0x45d53a)
(*Context).Next: c.handlers[c.index](c)
/home/danilo/Go/src/gopkg.in/gin-gonic/gin.v1/gin.go:284 (0x4638ce)
(*Engine).handleHTTPRequest: context.Next()
/home/danilo/Go/src/gopkg.in/gin-gonic/gin.v1/gin.go:265 (0x4631b0)
(*Engine).ServeHTTP: engine.handleHTTPRequest(c)
/usr/local/go/src/net/http/server.go:2202 (0x4e1fdd)
serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
/usr/local/go/src/net/http/server.go:1579 (0x4de947)
(*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
/usr/local/go/src/runtime/asm_amd64.s:2086 (0x45c0f1)
goexit: BYTE $0x90 // NOP
Dies ist die Funktion _getJSON , die eine JSON-codierte Zeichenfolge der Ergebnisse zurückgibt:
func _getJSON(sqlString string) (string, error) {
rows, err := db.Query(sqlString)
if err != nil {
return "", err
}
defer rows.Close()
columns, err := rows.Columns()
if err != nil {
return "", err
}
count := len(columns)
tableData := make([]map[string]interface{}, 0)
values := make([]interface{}, count)
valuePtrs := make([]interface{}, count)
for rows.Next() {
for i := 0; i < count; i++ {
valuePtrs[i] = &values[i]
}
rows.Scan(valuePtrs...)
entry := make(map[string]interface{})
for i, col := range columns {
var v interface{}
val := values[i]
b, ok := val.([]byte)
if ok {
v = string(b)
} else {
v = val
}
entry[col] = v
}
tableData = append(tableData, entry)
}
jsonData, err := json.Marshal(tableData)
if err != nil {
return "", err
}
//fmt.Println(string(jsonData))
return string(jsonData), nil
}
@ DaniloPolani Deine
Warum sollte es gleich Null sein? Ich habe eine Datenbankvariable außerhalb der Funktionen var db *sql.DB
und in der Hauptfunktion habe ich die Verbindung mit geöffnet
db, err := sql.Open("mysql", "<USERNAME>:<PASSWORD>@tcp(<HOST>:3306)/<DB_NAME>")
if err != nil {
panic(err.Error())
}
defer db.Close()
Dann heißt es in _getJSON()
. Anmeldeinformationen sind in Ordnung. Vielleicht ist es ein AWS-Problem? Ich werde es mit localhost versuchen.
db, err := sql.Open("mysql", "<USERNAME>:<PASSWORD>@tcp(<HOST>:3306)/<DB_NAME>")
Dann ist db die lokale Variable der Hauptvariablen, nicht die globale Variable _getJSON()
using.
Ohne die Bereitstellung eines vollständig reproduzierbaren Codes kann niemand darauf hinweisen
wo Ihr Code Rennbedingung hat.
go build -race
ist dein Freund.
@methane , du db, err := [...]
ändern, wobei db, err = [...]
auch Fehler deklarierte. Mein schlimmer Ablenkungsfehler.
Bin gerade auf dasselbe Problem gestoßen. Überrascht, dass dies ein Problem war.
Lösung von @danilopolani funktioniert.
@danilopolani @methane ihr habt mir Zeit gespart
@danilopolani Du hast recht, vielen Dank für deine Hilfe, ich habe lange nach diesem Problem gesucht, danke
Wie verwende ich die @ danilopolani- Lösung?
Danke @methane @danilopolani Ich habe den gleichen Fehler gemacht, zum Glück habe ich diese Diskussion gefunden.
OMG, ich hätte mir nie vorstellen können, dass es bei der Lösung um das Scoping von Variablen geht.
Vielen Dank, Leute.
Hilfreichster Kommentar
@methane , du
db, err := [...]
ändern, wobeidb, err = [...]
auch Fehler deklarierte. Mein schlimmer Ablenkungsfehler.