ziutek / mymysql

MySQL Client API written entirely in Go
Other
736 stars 161 forks source link

queries to mysql 4.1.21 don't work #40

Closed tamird closed 11 years ago

tamird commented 12 years ago

Any statements that do not return data work fine - any SELECTs or SHOWs result in ErrBadConn. Everything works fine on MySQL 5.0+.

I'm using github.com/ziutek/mymysql/godrv with database/sql

ziutek commented 12 years ago

Please write some example code using mymysql.native engine and Conn.Debug=true.

tamird commented 12 years ago

How can I set Conn.Debug to true?

db := mysql.New("tcp", "", addresses[addressIndex], username, password, fmt.Sprintf("%s%03d", dbname, i+1))
db.Debug = true

Fails with

db.Debug undefined (type mysql.Conn has no field or method Debug)
tamird commented 12 years ago
db := mysql.New("tcp", "", hostname, username, password, dbname)
db.(*native.Conn).Debug = true
e := db.Connect()

rows, _, err := db.Query("select id from abtest_events2 limit 2")
if err != nil {
    panic(err) // panic happens here
}
for _, row := range rows {
    fmt.Println(row)
}

This prints:

2012/09/29 14:49:37 [ 0 ->] Init packet:
2012/09/29 14:49:37         ProtVer=10, ServVer="4.1.21-log" Status=0x2
2012/09/29 14:49:37 [ 1 <-] Authentication packet
2012/09/29 14:49:37 [ 2 ->] OK packet:
2012/09/29 14:49:37         AffectedRows=0 InsertId=0x0 Status=0x2 WarningCount=0 Message=""
2012/09/29 14:49:37 [ 0 <-] Command packet: Cmd=0x3
2012/09/29 14:49:37 [ 1 ->] Result set header packet:
2012/09/29 14:49:37         FieldCount=1
2012/09/29 14:49:37 [ 2 ->] Field packet:
2012/09/29 14:49:37         Name="id" Type=0x8
2012/09/29 14:49:37 [ 3 ->] EOF packet:
panic: unexpected EOF

to stdout.

ziutek commented 12 years ago

This error is io.UnexpectedEOF. It is returned by mymysql if socket returns EOF during read. Probably mysql server closes connection. Check your server logs (I have no 4.1 server to test this now).

Mercor commented 11 years ago

Any updates on this ? i got exactly the same problem with my 4.1.21 server.

ziutek commented 11 years ago

Dnia 20.02.2013 o 20:53 Mercor notifications@github.com Mercor
notifications@github.com napisał(a):

Any updates on this ? i got exactly the same problem with my 4.1.21
server.


Reply to this email directly or view it on GitHub: https://github.com/ziutek/mymysql/issues/40#issuecomment-13852650

Can you reproduce this error and check your server log?

Mercor commented 11 years ago

Here is sample code:

package main

import (
    "fmt"
    // _ "github.com/ziutek/mymysql/godrv"
    "github.com/ziutek/mymysql/mysql"
    "github.com/ziutek/mymysql/native"
)

func main() {
    db := mysql.New("tcp", "", "localhost:3306", "root", "", "go")
    db.(*native.Conn).Debug = true
    err := db.Connect()
    if err != nil {
        panic(err) // panic happens here
    }

    rows, _, err := db.Query("select * from config")
    if err != nil {
        panic(err) // panic happens here
    }
    for _, row := range rows {
        fmt.Println(row)
    }
}

Here the output: 2013/02/21 20:25:25 [ 0 ->] Init packet:? 2013/02/21 20:25:25 ProtVer=10, ServVer="4.1.21-community-nt" Status=0x2? 2013/02/21 20:25:25 [ 1 <-] Authentication packet? 2013/02/21 20:25:25 [ 2 ->] OK packet:? 2013/02/21 20:25:25 AffectedRows=0 InsertId=0x0 Status=0x2 WarningCount=0 Message=""? 2013/02/21 20:25:25 [ 0 <-] Command packet: Cmd=0x3? 2013/02/21 20:25:25 [ 1 ->] Result set header packet:? 2013/02/21 20:25:25 FieldCount=7? 2013/02/21 20:25:25 [ 2 ->] Field packet:? 2013/02/21 20:25:25 Name="Typ" Type=0xfe? 2013/02/21 20:25:25 [ 3 ->] Field packet:? 2013/02/21 20:25:25 Name="Standort" Type=0xfd? 2013/02/21 20:25:25 [ 4 ->] Field packet:? 2013/02/21 20:25:25 Name="ACDName" Type=0xfd? 2013/02/21 20:25:25 [ 5 ->] Field packet:? 2013/02/21 20:25:25 Name="DBIP" Type=0xfd? 2013/02/21 20:25:25 [ 6 ->] Field packet:? 2013/02/21 20:25:25 Name="DBPort" Type=0x3? 2013/02/21 20:25:25 [ 7 ->] Field packet:? 2013/02/21 20:25:25 Name="DBName" Type=0xfd? 2013/02/21 20:25:25 [ 8 ->] Field packet:? 2013/02/21 20:25:25 Name="Aktiv" Type=0x1? 2013/02/21 20:25:25 [ 9 ->] EOF packet:?panic: unexpected EOF?

The table looks like this:

    Typ Standort    ACDName DBIP    DBPort  DBName  Aktiv
    ACD Test1       Test1   127.0.0.1   3306    go      1
    ACD Test        Test    127.0.0.1   3306    go      1

So the EOF seems to come after the last Colum of the Table Header ?!?!

Hope this helps....

Jonas

Mercor commented 11 years ago

I forgot, there is nothing in the server log.

Mercor commented 11 years ago

MySQL Client Server Documentation:

EOF-Packet:

1 [fe] the EOF header if capabilities & CLIENT_PROTOCOL_41 { 2 warning count 2 status flags }

So it is 1 or 3 Fields depending on the Client Protocol ? It seems your code always expects 3 fields ?

ziutek commented 11 years ago

Yes. mymysql supports protocol version >=4.1 (i think that I mentioned about this in documentation).

The problem is that after EOF packet, mymysql expects ROW packest (or EOF packet if there is empty result set) but read from TCP socket returns io.EOF error, which probably means that server closed connection.

Mercor commented 11 years ago

I get it to work.

I changed the Funktion getEofPacket in file result.go in folder native:

func (my *Conn) getEofPacket(pr *pktReader) (warn_count int, status uint16) {
    if my.Debug {
        log.Printf("[%2d ->] EOF packet:", my.seq-1)
    }
    if pr.remain >= 2 {
        warn_count = int(readU16(pr))
    }
    if pr.remain >= 2 {
        status = readU16(pr)
    }
    pr.checkEof()

    if my.Debug {
        log.Printf(tab8s+"WarningCount=%d Status=0x%x", warn_count, status)
    }
    return
}

The two lines

    if pr.remain >= 2 {

are new. It seems that the EOF Packet sometimes don't consists of 3 Fields....

I think my changes do not introduce any errors so eventually you can take them in your code ?

Jonas

ziutek commented 11 years ago

Thanks!

It seems that io.EOF is from pktReader, not from tcp socket (I didn't notice this before) Now, I remembered that server sends such packet in case of old password.

Please use the last commit and publish there logs from your test app. I slightly changed debug code in getEofPacket to see this case, but I still haven't enough time to setup 4.1 server to check this myself.

Mercor commented 11 years ago

Works:

2013/02/25 19:27:52 [ 0 ->] Init packet:?
2013/02/25 19:27:52         ProtVer=10, ServVer="4.1.21-community-nt" Status=0x2?
2013/02/25 19:27:52 [ 1 <-] Authentication packet?
2013/02/25 19:27:52 [ 2 ->] OK packet:?
2013/02/25 19:27:52         AffectedRows=0 InsertId=0x0 Status=0x2 WarningCount=0 Message=""?
2013/02/25 19:27:52 [ 0 <-] Command packet: Cmd=0x3?
2013/02/25 19:27:52 [ 1 ->] Result set header packet:?
2013/02/25 19:27:52         FieldCount=7?
2013/02/25 19:27:52 [ 2 ->] Field packet:?
2013/02/25 19:27:52         Name="Typ" Type=0xfe?
2013/02/25 19:27:52 [ 3 ->] Field packet:?
2013/02/25 19:27:52         Name="Standort" Type=0xfd?
2013/02/25 19:27:52 [ 4 ->] Field packet:?
2013/02/25 19:27:52         Name="ACDName" Type=0xfd?
2013/02/25 19:27:52 [ 5 ->] Field packet:?
2013/02/25 19:27:52         Name="DBIP" Type=0xfd?
2013/02/25 19:27:52 [ 6 ->] Field packet:?
2013/02/25 19:27:52         Name="DBPort" Type=0x3?
2013/02/25 19:27:52 [ 7 ->] Field packet:?
2013/02/25 19:27:52         Name="DBName" Type=0xfd?
2013/02/25 19:27:52 [ 8 ->] Field packet:?
2013/02/25 19:27:52         Name="Aktiv" Type=0x1?
2013/02/25 19:27:52 [ 9 ->] EOF packet without body?
2013/02/25 19:27:52 [10 ->] Text row data packet?
2013/02/25 19:27:52 [11 ->] Text row data packet?
2013/02/25 19:27:52 [12 ->] EOF packet:?
2013/02/25 19:27:52         WarningCount=0 Status=0x22
``