Go MySQL Driver is a MySQL driver for Go's (golang) database/sql package

Overview

Go-MySQL-Driver

A MySQL-Driver for Go's database/sql package

Go-MySQL-Driver logo



Features

  • Lightweight and fast
  • Native Go implementation. No C-bindings, just pure Go
  • Connections over TCP/IPv4, TCP/IPv6, Unix domain sockets or custom protocols
  • Automatic handling of broken connections
  • Automatic Connection Pooling (by database/sql package)
  • Supports queries larger than 16MB
  • Full sql.RawBytes support.
  • Intelligent LONG DATA handling in prepared statements
  • Secure LOAD DATA LOCAL INFILE support with file allowlisting and io.Reader support
  • Optional time.Time parsing
  • Optional placeholder interpolation

Requirements

  • Go 1.10 or higher. We aim to support the 3 latest versions of Go.
  • MySQL (4.1+), MariaDB, Percona Server, Google CloudSQL or Sphinx (2.2.3+)

Installation

Simple install the package to your $GOPATH with the go tool from shell:

$ go get -u github.com/go-sql-driver/mysql

Make sure Git is installed on your machine and in your system's PATH.

Usage

Go MySQL Driver is an implementation of Go's database/sql/driver interface. You only need to import the driver and can use the full database/sql API then.

Use mysql as driverName and a valid DSN as dataSourceName:

import (
	"database/sql"
	"time"

	_ "github.com/go-sql-driver/mysql"
)

// ...

db, err := sql.Open("mysql", "user:[email protected]/dbname")
if err != nil {
	panic(err)
}
// See "Important settings" section.
db.SetConnMaxLifetime(time.Minute * 3)
db.SetMaxOpenConns(10)
db.SetMaxIdleConns(10)

Examples are available in our Wiki.

Important settings

db.SetConnMaxLifetime() is required to ensure connections are closed by the driver safely before connection is closed by MySQL server, OS, or other middlewares. Since some middlewares close idle connections by 5 minutes, we recommend timeout shorter than 5 minutes. This setting helps load balancing and changing system variables too.

db.SetMaxOpenConns() is highly recommended to limit the number of connection used by the application. There is no recommended limit number because it depends on application and MySQL server.

db.SetMaxIdleConns() is recommended to be set same to (or greater than) db.SetMaxOpenConns(). When it is smaller than SetMaxOpenConns(), connections can be opened and closed very frequently than you expect. Idle connections can be closed by the db.SetConnMaxLifetime(). If you want to close idle connections more rapidly, you can use db.SetConnMaxIdleTime() since Go 1.15.

DSN (Data Source Name)

The Data Source Name has a common format, like e.g. PEAR DB uses it, but without type-prefix (optional parts marked by squared brackets):

[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...&paramN=valueN]

A DSN in its fullest form:

username:[email protected](address)/dbname?param=value

Except for the databasename, all values are optional. So the minimal DSN is:

/dbname

If you do not want to preselect a database, leave dbname empty:

/

This has the same effect as an empty DSN string:


Alternatively, Config.FormatDSN can be used to create a DSN string by filling a struct.

Password

Passwords can consist of any character. Escaping is not necessary.

Protocol

See net.Dial for more information which networks are available. In general you should use an Unix domain socket if available and TCP otherwise for best performance.

Address

For TCP and UDP networks, addresses have the form host[:port]. If port is omitted, the default port will be used. If host is a literal IPv6 address, it must be enclosed in square brackets. The functions net.JoinHostPort and net.SplitHostPort manipulate addresses in this form.

For Unix domain sockets the address is the absolute path to the MySQL-Server-socket, e.g. /var/run/mysqld/mysqld.sock or /tmp/mysql.sock.

Parameters

Parameters are case-sensitive!

Notice that any of true, TRUE, True or 1 is accepted to stand for a true boolean value. Not surprisingly, false can be specified as any of: false, FALSE, False or 0.

allowAllFiles
Type:           bool
Valid Values:   true, false
Default:        false

allowAllFiles=true disables the file allowlist for LOAD DATA LOCAL INFILE and allows all files. Might be insecure!

allowCleartextPasswords
Type:           bool
Valid Values:   true, false
Default:        false

allowCleartextPasswords=true allows using the cleartext client side plugin if required by an account, such as one defined with the PAM authentication plugin. Sending passwords in clear text may be a security problem in some configurations. To avoid problems if there is any possibility that the password would be intercepted, clients should connect to MySQL Server using a method that protects the password. Possibilities include TLS / SSL, IPsec, or a private network.

allowNativePasswords
Type:           bool
Valid Values:   true, false
Default:        true

allowNativePasswords=false disallows the usage of MySQL native password method.

allowOldPasswords
Type:           bool
Valid Values:   true, false
Default:        false

allowOldPasswords=true allows the usage of the insecure old password method. This should be avoided, but is necessary in some cases. See also the old_passwords wiki page.

charset
Type:           string
Valid Values:   <name>
Default:        none

Sets the charset used for client-server interaction ("SET NAMES <value>"). If multiple charsets are set (separated by a comma), the following charset is used if setting the charset failes. This enables for example support for utf8mb4 (introduced in MySQL 5.5.3) with fallback to utf8 for older servers (charset=utf8mb4,utf8).

Usage of the charset parameter is discouraged because it issues additional queries to the server. Unless you need the fallback behavior, please use collation instead.

checkConnLiveness
Type:           bool
Valid Values:   true, false
Default:        true

On supported platforms connections retrieved from the connection pool are checked for liveness before using them. If the check fails, the respective connection is marked as bad and the query retried with another connection. checkConnLiveness=false disables this liveness check of connections.

collation
Type:           string
Valid Values:   <name>
Default:        utf8mb4_general_ci

Sets the collation used for client-server interaction on connection. In contrast to charset, collation does not issue additional queries. If the specified collation is unavailable on the target server, the connection will fail.

A list of valid charsets for a server is retrievable with SHOW COLLATION.

The default collation (utf8mb4_general_ci) is supported from MySQL 5.5. You should use an older collation (e.g. utf8_general_ci) for older MySQL.

Collations for charset "ucs2", "utf16", "utf16le", and "utf32" can not be used (ref).

clientFoundRows
Type:           bool
Valid Values:   true, false
Default:        false

clientFoundRows=true causes an UPDATE to return the number of matching rows instead of the number of rows changed.

columnsWithAlias
Type:           bool
Valid Values:   true, false
Default:        false

When columnsWithAlias is true, calls to sql.Rows.Columns() will return the table alias and the column name separated by a dot. For example:

SELECT u.id FROM users as u

will return u.id instead of just id if columnsWithAlias=true.

interpolateParams
Type:           bool
Valid Values:   true, false
Default:        false

If interpolateParams is true, placeholders (?) in calls to db.Query() and db.Exec() are interpolated into a single query string with given parameters. This reduces the number of roundtrips, since the driver has to prepare a statement, execute it with given parameters and close the statement again with interpolateParams=false.

This can not be used together with the multibyte encodings BIG5, CP932, GB2312, GBK or SJIS. These are rejected as they may introduce a SQL injection vulnerability!

loc
Type:           string
Valid Values:   <escaped name>
Default:        UTC

Sets the location for time.Time values (when using parseTime=true). "Local" sets the system's location. See time.LoadLocation for details.

Note that this sets the location for time.Time values but does not change MySQL's time_zone setting. For that see the time_zone system variable, which can also be set as a DSN parameter.

Please keep in mind, that param values must be url.QueryEscape'ed. Alternatively you can manually replace the / with %2F. For example US/Pacific would be loc=US%2FPacific.

maxAllowedPacket
Type:          decimal number
Default:       4194304

Max packet size allowed in bytes. The default value is 4 MiB and should be adjusted to match the server settings. maxAllowedPacket=0 can be used to automatically fetch the max_allowed_packet variable from server on every connection.

multiStatements
Type:           bool
Valid Values:   true, false
Default:        false

Allow multiple statements in one query. While this allows batch queries, it also greatly increases the risk of SQL injections. Only the result of the first query is returned, all other results are silently discarded.

When multiStatements is used, ? parameters must only be used in the first statement.

parseTime
Type:           bool
Valid Values:   true, false
Default:        false

parseTime=true changes the output type of DATE and DATETIME values to time.Time instead of []byte / string The date or datetime like 0000-00-00 00:00:00 is converted into zero value of time.Time.

readTimeout
Type:           duration
Default:        0

I/O read timeout. The value must be a decimal number with a unit suffix ("ms", "s", "m", "h"), such as "30s", "0.5m" or "1m30s".

rejectReadOnly
Type:           bool
Valid Values:   true, false
Default:        false

rejectReadOnly=true causes the driver to reject read-only connections. This is for a possible race condition during an automatic failover, where the mysql client gets connected to a read-only replica after the failover.

Note that this should be a fairly rare case, as an automatic failover normally happens when the primary is down, and the race condition shouldn't happen unless it comes back up online as soon as the failover is kicked off. On the other hand, when this happens, a MySQL application can get stuck on a read-only connection until restarted. It is however fairly easy to reproduce, for example, using a manual failover on AWS Aurora's MySQL-compatible cluster.

If you are not relying on read-only transactions to reject writes that aren't supposed to happen, setting this on some MySQL providers (such as AWS Aurora) is safer for failovers.

Note that ERROR 1290 can be returned for a read-only server and this option will cause a retry for that error. However the same error number is used for some other cases. You should ensure your application will never cause an ERROR 1290 except for read-only mode when enabling this option.

serverPubKey
Type:           string
Valid Values:   <name>
Default:        none

Server public keys can be registered with mysql.RegisterServerPubKey, which can then be used by the assigned name in the DSN. Public keys are used to transmit encrypted data, e.g. for authentication. If the server's public key is known, it should be set manually to avoid expensive and potentially insecure transmissions of the public key from the server to the client each time it is required.

timeout
Type:           duration
Default:        OS default

Timeout for establishing connections, aka dial timeout. The value must be a decimal number with a unit suffix ("ms", "s", "m", "h"), such as "30s", "0.5m" or "1m30s".

tls
Type:           bool / string
Valid Values:   true, false, skip-verify, preferred, <name>
Default:        false

tls=true enables TLS / SSL encrypted connection to the server. Use skip-verify if you want to use a self-signed or invalid certificate (server side) or use preferred to use TLS only when advertised by the server. This is similar to skip-verify, but additionally allows a fallback to a connection which is not encrypted. Neither skip-verify nor preferred add any reliable security. You can use a custom TLS config after registering it with mysql.RegisterTLSConfig.

writeTimeout
Type:           duration
Default:        0

I/O write timeout. The value must be a decimal number with a unit suffix ("ms", "s", "m", "h"), such as "30s", "0.5m" or "1m30s".

System Variables

Any other parameters are interpreted as system variables:

  • <boolean_var>=<value>: SET <boolean_var>=<value>
  • <enum_var>=<value>: SET <enum_var>=<value>
  • <string_var>=%27<value>%27: SET <string_var>='<value>'

Rules:

  • The values for string variables must be quoted with '.
  • The values must also be url.QueryEscape'ed! (which implies values of string variables must be wrapped with %27).

Examples:

Examples

[email protected](/path/to/socket)/dbname
root:[email protected](/tmp/mysql.sock)/myDatabase?loc=Local
user:[email protected](localhost:5555)/dbname?tls=skip-verify&autocommit=true

Treat warnings as errors by setting the system variable sql_mode:

user:[email protected]/dbname?sql_mode=TRADITIONAL

TCP via IPv6:

user:[email protected]([de:ad:be:ef::ca:fe]:80)/dbname?timeout=90s&collation=utf8mb4_unicode_ci

TCP on a remote host, e.g. Amazon RDS:

id:[email protected](your-amazonaws-uri.com:3306)/dbname

Google Cloud SQL on App Engine:

user:[email protected](/cloudsql/project-id:region-name:instance-name)/dbname

TCP using default port (3306) on localhost:

user:[email protected]/dbname?charset=utf8mb4,utf8&sys_var=esc%40ped

Use the default protocol (tcp) and host (localhost:3306):

user:[email protected]/dbname

No Database preselected:

user:[email protected]/

Connection pool and timeouts

The connection pool is managed by Go's database/sql package. For details on how to configure the size of the pool and how long connections stay in the pool see *DB.SetMaxOpenConns, *DB.SetMaxIdleConns, and *DB.SetConnMaxLifetime in the database/sql documentation. The read, write, and dial timeouts for each individual connection are configured with the DSN parameters readTimeout, writeTimeout, and timeout, respectively.

ColumnType Support

This driver supports the ColumnType interface introduced in Go 1.8, with the exception of ColumnType.Length(), which is currently not supported.

context.Context Support

Go 1.8 added database/sql support for context.Context. This driver supports query timeouts and cancellation via contexts. See context support in the database/sql package for more details.

LOAD DATA LOCAL INFILE support

For this feature you need direct access to the package. Therefore you must change the import path (no _):

import "github.com/go-sql-driver/mysql"

Files must be explicitly allowed by registering them with mysql.RegisterLocalFile(filepath) (recommended) or the allowlist check must be deactivated by using the DSN parameter allowAllFiles=true (Might be insecure!).

To use a io.Reader a handler function must be registered with mysql.RegisterReaderHandler(name, handler) which returns a io.Reader or io.ReadCloser. The Reader is available with the filepath Reader::<name> then. Choose different names for different handlers and DeregisterReaderHandler when you don't need it anymore.

See the godoc of Go-MySQL-Driver for details.

time.Time support

The default internal output type of MySQL DATE and DATETIME values is []byte which allows you to scan the value into a []byte, string or sql.RawBytes variable in your program.

However, many want to scan MySQL DATE and DATETIME values into time.Time variables, which is the logical equivalent in Go to DATE and DATETIME in MySQL. You can do that by changing the internal output type from []byte to time.Time with the DSN parameter parseTime=true. You can set the default time.Time location with the loc DSN parameter.

Caution: As of Go 1.1, this makes time.Time the only variable type you can scan DATE and DATETIME values into. This breaks for example sql.RawBytes support.

Unicode support

Since version 1.5 Go-MySQL-Driver automatically uses the collation utf8mb4_general_ci by default.

Other collations / charsets can be set using the collation DSN parameter.

Version 1.0 of the driver recommended adding &charset=utf8 (alias for SET NAMES utf8) to the DSN to enable proper UTF-8 support. This is not necessary anymore. The collation parameter should be preferred to set another collation / charset than the default.

See http://dev.mysql.com/doc/refman/8.0/en/charset-unicode.html for more details on MySQL's Unicode support.

Testing / Development

To run the driver tests you may need to adjust the configuration. See the Testing Wiki-Page for details.

Go-MySQL-Driver is not feature-complete yet. Your help is very appreciated. If you want to contribute, you can work on an open issue or review a pull request.

See the Contribution Guidelines for details.


License

Go-MySQL-Driver is licensed under the Mozilla Public License Version 2.0

Mozilla summarizes the license scope as follows:

MPL: The copyleft applies to any files containing MPLed code.

That means:

  • You can use the unchanged source code both in private and commercially.
  • When distributing, you must publish the source code of any changed files licensed under the MPL 2.0 under a) the MPL 2.0 itself or b) a compatible license (e.g. GPL 3.0 or Apache License 2.0).
  • You needn't publish the source code of your library as long as the files licensed under the MPL 2.0 are unchanged.

Please read the MPL 2.0 FAQ if you have further questions regarding the license.

You can read the full terms here: LICENSE.

Go Gopher and MySQL Dolphin

Issues
  • packets.go: read tcp [ip-address]: connection timed out

    packets.go: read tcp [ip-address]: connection timed out

    UPDATE: My resolution was to remove all "Idle" connections from the pool. See this comment:

    https://github.com/go-sql-driver/mysql/issues/257#issuecomment-53886663

    I am currently experiencing a stalling or broken web app after a period of idle between 15 to 48 minutes. The most critical issue is described below:

    • Visit a URL, any url on the site, and load the page completely (as in, the page actually loads and the logs show a complete page has loaded).
    • Close browser, and wait.

    A typical request is logged like this:

    2014/07/13 15:29:54 INFO template rendering: index
    2014/07/13 15:29:54 METRIC, URL: /, HANDLER TIME: 7.2339ms, CTX TIME: 5.0894ms, TOTAL TIME: 12.3258ms
    

    After a long period of time (ranging from 15m to 48m), the system all of a sudden logs these lines below with no interaction - the web app has been idle this entire time:

    [MySQL] 2014/07/13 16:00:09 packets.go:32: read tcp remote-mysql-server-address:3306: connection timed out
    [MySQL] 2014/07/13 16:00:09 packets.go:118: write tcp remote-mysql-server-address:3306: broken pipe
    2014/07/13 16:00:10 INFO template rendering: index
    2014/07/13 16:00:10 METRIC, URL: /, HANDLER TIME: 8.8574ms, CTX TIME: 31m19.2606723s, TOTAL TIME: 31m19.2695329s
    

    Notice the "TOTAL TIME" is 31 minutes and 19 seconds? Also, notice the MySql driver error that is logged at the same time?

    There was no activity / no web request made. The web app was simply idle.

    The most critical issue is what comes next after these log messages: _the very next web request is stalls completely, never returning a response_:

    [email protected]:~$ wget http://localhost
    --2014-07-13 17:11:18--  http://localhost/
    Resolving localhost (localhost)... 127.0.0.1
    Connecting to localhost (localhost)|127.0.0.1|:80... connected.
    HTTP request sent, awaiting response... Read error (Connection timed out) in headers.
    Retrying.
    
    --2014-07-13 17:26:19--  (try: 2)  http://localhost/
    Connecting to localhost (localhost)|127.0.0.1|:80... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: unspecified [text/html]
    Saving to: `index.html.4'
    
        [ <=>                                                                                  ] 6,310       --.-K/s   in 0.001s
    
    2014-07-13 17:26:20 (9.61 MB/s) - `index.html.4' saved [6310]
    

    And it sits idle, no response, for 15 minutes until wget times out.

    Now, if I make a 2nd or 3rd request immediately after this one is stalled and anytime while it is stalled, the go web app responds and returns a full page for other requests. No issues. And then, the cycle starts over from the last request I make and let it site idle.

    After this 15m, you can guess exactly what is logged next:

    [MySQL] 2014/07/13 17:26:57 packets.go:32: read tcp remote-mysql-server-address:3306: connection timed out
    [MySQL] 2014/07/13 17:26:57 packets.go:118: write tcp remote-mysql-server-address:3306: broken pipe
    2014/07/13 17:26:57 INFO template rendering: index
    2014/07/13 17:26:57 METRIC, URL: /, HANDLER TIME: 6.8938ms, CTX TIME: 15m39.1718434s, TOTAL TIME: 15m39.1787398s
    

    Another 15m wait time.

    I eliminated Windows Azure, the Cluster VIP and Firewall/Linux VM running the go web app as an issue because I ran wget http://localhost locally on the same box, and I get this "stalled" request that never completes and never sends back anything.

    There are a number of factors in my web app so I will try to outline them accordingly.

    Using:

    • Go 1.3
    • go-sql-driver/mysql ## Version 1.2 (2014-06-03)
    • Ubuntu 12.04 LTS, ~June 2014 Updates
    • Windows Azure

    Do note that the Linux box running MySql is a different Linux box running the cluster of GoLang apps - and they are in separate dedicated Cloud Services. The MySql vm is a single VM, no cluserting.

    Here is some related code:

    // global handler for our DB
    var db *sql.DB
    
    // CLI parameter
    var dbdsn string
    
    func init() {
    
        flag.StringVar(&dbdsn, "dbdsn", "root:[email protected](localhost:3306)/prod?timeout=5s&tls=false&autocommit=true", "Specifies the MySql DSN connection.")
        flag.Parse()
    
        var err error
        db, err = sql.Open("mysql", dbdsn)
        if err != nil {
            log.Printf("ERROR in sql.Open(): %v", err)
        }
    
        //db.SetMaxIdleConns(5)
    
        // verify the DSN is setup properly1
        err = db.Ping()
        if err != nil {
            panic("PANIC when pinging db: " + err.Error()) // proper error handling instead of panic in your app
        }
    }
    
    // **********
    // * omitted is the Gorilla MUX router and http handler registrations
    // **********
    
    func ArticleHandler(w http.ResponseWriter, r *http.Request, c *Context) (err error) {
    
        m := NewArticle(c)
        id := c.Vars["id"]
    
        var pid int
        var title, body, excerpt, date, slug, fi, fv, region, region_slug string
        err = db.QueryRow(
            "SELECT p.ID, p.post_title, p.post_content, p.post_excerpt, p.post_date, p.post_name, "+
                "(SELECT fpim.meta_value FROM wp_postmeta fpim WHERE fpim.meta_key = '_wp_attached_file' AND fpim.post_id = (SELECT fpim2.meta_value FROM wp_postmeta fpim2 WHERE fpim2.post_id = p.ID AND fpim2.meta_key = '_thumbnail_id' LIMIT 1) LIMIT 1) AS featured_image, "+
                "(SELECT fpim3.meta_value FROM wp_postmeta fpim3 WHERE fpim3.meta_key = 'fv_video' AND fpim3.post_id = p.ID LIMIT 1) AS featured_video, "+
                "t.name as region, t.slug as region_slug "+
                "FROM wp_posts p "+
                "JOIN wp_term_relationships tr ON tr.object_id=p.ID "+
                "JOIN wp_term_taxonomy tt ON tt.term_taxonomy_id=tr.term_taxonomy_id "+
                "JOIN wp_terms t ON t.term_id=tt.term_id "+
                "WHERE p.post_name=? AND p.post_type='post' AND p.post_status='publish' AND p.post_date <= UTC_TIMESTAMP()"+
                "AND tr.object_id=p.ID AND tt.parent = (SELECT t3.term_id FROM wp_terms t3 WHERE t3.name=? LIMIT 1) LIMIT 1",
            id, RegionsParentCategory).
            Scan(&pid, &title, &body, &excerpt, &date, &slug, &fi, &fv, &region, &region_slug)
    
        if err != nil {
            if err == sql.ErrNoRows {
    
                // snipped code for redirects
    
                // article was not found
                return handleNotFound(w, r, c)
    
            } else {
                log.Printf("ERROR in .Scan(): %v", err)
            }
        } else {
            m.Region = Region{
                Name: region,
                Slug: region_slug,
            }
            m.Id = pid
            m.Title = title
            m.Body = template.HTML(body) // render the raw html
            m.Excerpt = excerpt
            m.Datetime = date
            m.Slug = slug
            m.FeaturedImageUrl = fi
            m.FeaturedVideoUrl = fv
        }
    
        web.RenderTemplate(w, "article", m)
        return
    }
    

    5 more DB queries, per request

    In addition to this query, my "Context" you see being passed into the handler runs 4 to 6 additional SQL queries. Therefore, each "article" handler that loads runs about 5 to 7 SQL queries, minimal, using the exact same pattern and *db global variable you see above.

    Timeouts / errors are always on the same DB query

    Here's one of the "context" queries as a comparison:

    rows2, err := db.Query(
        "SELECT p.post_title, p.post_name "+
            "FROM wp_posts p "+
            "WHERE p.post_type='page' AND p.post_status='publish' AND p.post_date <= UTC_TIMESTAMP() "+
            "AND p.post_parent = (SELECT p2.ID FROM wp_posts p2 WHERE p2.post_name=? LIMIT 1) "+
            "ORDER BY p.menu_order",
        FooterPagesParentNameSlug)
    if err != nil {
        log.Printf("ERROR in AllPages .Query() : %v", err)
    } else {
        defer rows2.Close()
        c.AllFooterPages = make([]FooterPage, 0)
        for rows2.Next() {
            var name, slug string
            err := rows2.Scan(&name, &slug)
            if err != nil {
                log.Printf("ERROR in AllPages row.Scan() : %v", err)
            } else {
                p := FooterPage{
                    Page: Page{
                        Title: name,
                        Slug:  slug,
                    },
                }
                c.AllFooterPages = append(c.AllFooterPages, p)
            }
        }
    }
    

    Nothing special there.

    I do call defer rows2.Close() only if there was no error. Perhaps that is part of the issue? This particular SQL query seems to log errors under load tests as no response or mysql driver timing out.

    Questions

    Why am I getting request timeouts logged in excess of 15 to 30 minutes, from an idle site? That seems like a bug with the mysql driver I am using, possibly holding a connection open. But, the last http request was successful and returned a complete page + template.

    I even have the Timeout set in the connection string, which is 5 seconds. Even if it is a problem with the mysql server, why the 15 minute timeout/request logged? Where did that request come from?

    It still could be a MySql driver issue, blocking the request from completing - maybe being blocked by the MySql dedicated VM and an issue there. If that is the case, then how come nothing is logged? What is this random timeout of 15m to 49m minutes? It is usually only 15m or 31m, but sometimes 48m is logged.

    It is very interesting on the "15m" multiples there in the timeouts (@15m, 31m and 48m), allotting for some padding there in seconds.

    Thanks in advance.

    bug database/sql issue 
    opened by eduncan911 58
  • Implement Context Interface

    Implement Context Interface

    See https://github.com/golang/go/issues/15123

    Go1.8 enhancement 
    opened by julienschmidt 57
  • Still can't authenticate with allowOldPasswords=1

    Still can't authenticate with allowOldPasswords=1

    We're running Go 1.1.1, MySQL 5.0.22 on a separate server (but the database is legacy and MySQL itself has been upgraded a few times, I'm sure it was 4.x at some point.) and "old_passwords" is set to ON. (verified with SHOW VARIABLES.)

    I'm converting a batch of Perl and Ruby scripts to Go, and the Perl and Ruby scripts can connect to this legacy database with no problem. I'm trying to determine if I'm doing something wrong (relatively new to Go) or not.

    In packets.go readResultOK(), the first time through it returns errOldPassword (data=[254]) as expected. Second time through it hits the default branch of the case statement, ultimately returning a "Error 1045: Access denied for user" back to the calling script.

    I'm going to see if I can get the DBA to set "old_passwords" to OFF, but am still curious if I'm missing something. Thanks!

    bug wontfix 
    opened by dsparling 43
  • Best practice

    Best practice

    With this driver, is it best practice to every HTTP request open the database using Open("mysql","...") and close it using Close() at the end of every requst cycle

    OR

    just open it once and never close it irrespective of the request cycle?

    opened by pjebs 40
  • EOF error in packets.go readPacket() not propagating

    EOF error in packets.go readPacket() not propagating

    I'm running a query that is returning around 250k rows from a MySQL 5.1 server. Occasionally I will get incomplete result sets without an error being returned to my invocation of the API methods. The following is printed:

    [MySQL] 2013/07/10 11:18:38 packets.go:67: EOF
    

    The relevant snippet of code:

    errLog.Print(err.Error())
    return nil, driver.ErrBadConn
    

    Replacing "Print" with "Panic" shows the following stack trace:

    [MySQL] 2013/07/10 11:23:33 packets.go:67: EOF panic: EOF

    goroutine 1 [running]: log.(_Logger).Panic(0xc2000aa1e0, 0x7fd696a4f460, 0x1, 0x1) /usr/local/go/src/pkg/log/log.go:193 +0xa7 github.com/go-sql-driver/mysql.(_mysqlConn).readPacket(0xc2000c3770, 0xc200100000, 0x66, 0x1000, 0xc2000ae000, ...) ROOT/src/github.com/go-sql-driver/mysql/packets.go:67 +0x683 github.com/go-sql-driver/mysql.(_mysqlRows).readBinaryRow(0xc2000fe540, 0xc2000f6680, 0x4, 0x4, 0x0, ...) ROOT/src/github.com/go-sql-driver/mysql/packets.go:861 +0x4e github.com/go-sql-driver/mysql.(_mysqlRows).Next(0xc2000fe540, 0xc2000f6680, 0x4, 0x4, 0x0, ...) ROOT/src/github.com/go-sql-driver/mysql/rows.go:68 +0x120 database/sql.(*Rows).Next(0xc2000c24e0, 0x676020) /usr/local/go/src/pkg/database/sql/sql.go:1310 +0xc1 main.writeBooks(0xc2000c2120, 0xc2000aa5f0) ROOT/src/example.com/sitemap/sitemapgenerator.go:152 +0x167 main.main() ROOT/src/example.com/sitemap/sitemapgenerator.go:280 +0x87e

    goroutine 2 [syscall]: exit status 2

    It looks like readBinaryRow is not actually returning the non-nil error, and instead returning early with a nil error:

    func (rows *mysqlRows) readBinaryRow(dest []driver.Value) (err error) { data, err := rows.mc.readPacket() if err != nil { return }

    This bug is particularly insidious because it is happening in a call to .Next(), which means that callers will be operating on partial result sets without knowing it.

    System:

    • Ubuntu 13.04 64-bit
    • go 1.1
    • MySQL 5.1.63-0ubuntu0.10.04.1-log

    This happens with both an SSH port forward and when on a proper network connection (rackspace cloud).

    bug waiting for reply 
    opened by insasho 38
  • packets.go:66: unexpected EOF followed by packets.go:412: busy buffer followed by driver: bad connection followed by connection.go:319: invalid connection

    packets.go:66: unexpected EOF followed by packets.go:412: busy buffer followed by driver: bad connection followed by connection.go:319: invalid connection

    Issue description

    MySQL SELECT queries fail unexpectedly at random times in a long running CLI script.

    Example code

    I can't really provide a sample code, but I can tell you that I only do simple SELECTqueries in my CLI program. I don't do any transactions, nor any UPDATEs. All the MySQL operations in my program are read-only (just a lot of SELECTs only). My program is doing just ONE query at a time, it runs on a single core virtual machine ($5 DigitalOcean Droplet) with only one go routine running at a time. I do not run out of RAM, I checked that, the swap file is only barely used on this virtual machine.

    Error log

    [mysql] 2017/05/02 16:48:51 packets.go:66: unexpected EOF
    [mysql] 2017/05/02 16:48:52 packets.go:412: busy buffer
    driver: bad connection
    [mysql] 2017/05/02 16:48:52 connection.go:319: invalid connection
    

    Configuration

    Driver version (or git SHA): git log shows: commit 147bd02c2c516cf9a8878cb75898ee8a9eea0228 Author: astaxie [email protected] Date: Sat Apr 29 00:02:31 2017 +0800

    But the exact same issue is happening with a version from December, 2016. With that version the log is:

    [mysql] 2017/05/01 09:55:47 packets.go:66: unexpected EOF
    [mysql] 2017/05/01 09:55:47 packets.go:412: busy buffer
    driver: bad connection
    [mysql] 2017/05/01 09:55:48 connection.go:312: invalid connection
    

    So this problem is not new. I first noticed this issue this year. Sometime last fall I was using the exact same program on the exact same database, compiled by the then latest stable version of Go (probably Go 1.7), and at that time I never ran into this issue. So this must be something new, it must be related to some change(s) that occurred right around or before Go 1.8 got released.

    Go version: go version go1.8.1 linux/amd64

    Server version: mysql-5.5.55

    Server OS: CentOS release 6.9 (but I compiled the program under Debian 8.7 (jessie), transferred the binary file over to the CentOS 6.9 droplet and ran it under CentOS 6.9 -- thanks to static builds this should not be a problem. I do the same with a bunch of other Go programs and this is the only one which fails)

    I noticed today that someone else also ran into this error pattern ( "packets.go:66: unexpected EOF followwed by packets.go:412: busy buffer followed by driver: bad connection" ) recently, please see his Edit#2 on this StackOverflow page: http://stackoverflow.com/questions/43696607/mysql-to-json-inconsistent-extraction

    This is a showstopper bug for me. I might need to switch back to Go 1.7.x and recompile my program and see if that fixes this issue or not. Or do you have a better idea on how to debug this?

    BTW, my program is doing millions of SELECT queries and only a few of them fail. On every run different queries fail, it seems to me totally random.

    opened by tssajo 37
  • Google Cloud SQL on App Engine - Connection String Outdated?

    Google Cloud SQL on App Engine - Connection String Outdated?

    Issue description

    In the readme for this driver, the connection string for connecting to Google Cloud SQL on App Engine is given as:

    [email protected](project-id:instance-name)/dbname

    While Google's cloudsql package documentation also affirms this for your driver, there are posts on Stack Overflow such as this one which claim that one needs to use projectid:regionname:instancename rather than projectid:instancename.

    What is the correct connection string? Neither of these is currently working.

    Example code

    A more detailed post can be found here: http://stackoverflow.com/questions/39668672/trouble-connecting-to-google-cloud-sql-server-from-deployed-app

    Error log

    My server is returning a 500 response whenever I make a call to an endpoint that uses the Cloud SQL database. The database connection works fine when I am connecting to the server from a locally served version of my app.

    I have tried a variety of connection strings, and here are some errors that were logged in the Google Cloud Console:

    5447 [Warning] 'user' entry '[email protected]' ignored in --skip-name-resolve mode.
    
    5447 [Warning] entry 'root'@'localhost' in mysql.user is ignored because it duplicates entry in mysql.system_user
    
    14409 [Note] Aborted connection 14409 to db: 'User' user: 'root' host: 'xxx.xxx.xxx.xxx' (Got an error reading communication packets)
    

    (No password was specified in the connection string because the documentation does not specify the need for a password.This postmentions that the connection password must be null when the app attempts to connect to the server using [email protected].)

    6170 [Note] Access denied for user 'root'@'cloudsqlproxy~xx.xxx.xxx.xx' (using password: NO) 
    

    I also tried connecting with a user other than the root user (username: newuser):

    5447 [Warning] 'user' entry '[email protected]' ignored in --skip-name-resolve mode.
    

    Configuration

    Driver version (or git SHA): https://github.com/go-sql-driver/mysql/tree/3654d25ec346ee8ce71a68431025458d52a38ac0

    Go version: go version go1.6.2 linux/amd64

    Server version: The Google Cloud SQL instance is running MySQL 5.7

    Server OS: From the Compute Engine tab, it looks like the server hosting the most recent version of my app is running Debian 7.11 (Wheezy)

    documentation 
    opened by lennrt 35
  • Multi Result support

    Multi Result support

    I am getting the following error when calling on my stored procedure

    Error 1312: PROCEDURE mydb.GetAllNotes can't return a result set in the given context
    

    I am calling on my stored procedure with this code

    db.Query("CALL MyStoredProcedure()")
    
    database/sql issue enhancement 
    opened by emilsjolander 33
  • packets.go:417: busy buffer, packets.go:436: busy buffer

    packets.go:417: busy buffer, packets.go:436: busy buffer

    Issue description

    Tell us what should happen and what happens instead

    in console output: Scenarion 1: `[mysql] 2019/07/10 14:54:46 packets.go:417: busy buffer

    [mysql] 2019/07/10 14:54:46 packets.go:417: busy buffer

    [mysql] 2019/07/10 14:54:47 packets.go:436: busy buffer

    [mysql] 2019/07/10 14:54:47 packets.go:417: busy buffer

    commands out of sync. You can't run this command now

    [mysql] 2019/07/10 14:54:47 packets.go:436: busy buffer

    [mysql] 2019/07/10 14:54:47 packets.go:417: busy buffer

    commands out of sync. You can't run this command now

    [mysql] 2019/07/10 14:54:47 packets.go:436: busy buffer

    [mysql] 2019/07/10 14:54:47 packets.go:417: busy buffer

    commands out of sync. You can't run this command now

    [mysql] 2019/07/10 14:54:47 packets.go:436: busy buffer

    [mysql] 2019/07/10 14:54:47 packets.go:417: busy buffer

    [mysql] 2019/07/10 14:54:48 packets.go:436: busy buffer

    [mysql] 2019/07/10 14:54:48 packets.go:417: busy buffer sql: expected 4 arguments, got 2 sql: expected 4 arguments, got 2 sql: expected 4 arguments, got 2 **Scenario 2:**[mysql] 2019/07/10 14:58:53 packets.go:417: busy buffer

    [mysql] 2019/07/10 14:59:11 packets.go:417: busy buffer

    [mysql] 2019/07/10 14:59:43 packets.go:417: busy buffer`

    Example code

    Scenario 1: I got a http message to API, create another goroutine (and close a first one to let free http connection) and do something with message, try to get data from MySQL.. all fine if I mak a tests with <100 messages and all bad if I got more then 100 messages per second. Output in the top...

    Scenario 2 ok just like a test I create new logic with separate DB connection for each incoming message, works better but expensive by connections resources... and one buffer error. Output in top

    Results:

    Some part of messages was processed, some (with errors in output, no)... if we get first error in console any other Querys not work, if we try to use ping method before send - hi return nil... All errors handled by mysql golang driver and just printed with log. but not returned to upper level (????!!!) So like a result impossible to detect error and establish new connection. And yes all fine if you have <100 requests and <100 DB querys.

    P.S. I have found issue (dated by 2015) about same problems in multi routines mode, but this absolutely not explained why we cant handle error on app level and why we still get :417 error in each 1 goroutine=1 DB connector mode. Any Ideas how to solve this?

    If possible, please enter some example code here to reproduce the issue.
    

    Error log

    If you have an error log, please paste it here.
    

    Configuration

    Driver version (or git SHA): last

    Go version: run go version in your console 1.12.6

    Server version: E.g. MySQL 5.6, MariaDB 10.0.20

    Server OS: E.g. Debian 8.1 (Jessie), Windows 10 Windows 10

    waiting for reply 
    opened by oranze 32
  • fix driver.ErrBadConn behavior, stop repeated queries

    fix driver.ErrBadConn behavior, stop repeated queries

    The docs for database/sql/driver note that driver.ErrBadConn should only be returned when a connection is in a bad state. We overused it, which has lead to re-executed queries in some cases.

    With this change, all instances of driver.ErrBadConn are replaced with ErrInvalidConn unless they are in an exported function and appear before the network is hit. I also replaced it as a return value in Close, where retrying makes no sense whatsoever (EDIT database/sql does not retry in that case anyway).

    I'm on the fence, maybe we should drop it altogether - usage is optional anyway.

    Inspired by / fixes #295 Probably also fixes at least parts of #185 and maybe even #257 and #281...

    This could impact legacy client code - but only if it ignores errors and has no internal retry logic.

    bug thinking 
    opened by arnehormann 30
  • Does the driver support `useServerPrepStmts`?

    Does the driver support `useServerPrepStmts`?

    Issue description

    Does the driver support useServerPrepStmts?

    opened by valord577 0
  • add `//go:build` lines

    add `//go:build` lines

    Description

    I added //go:build lines with go1.17rc1 fmt. From Go 1.17, the go command understands the new syntax //go:build. See https://golang.org/design/draft-gobuild

    Checklist

    • [x] Code compiles correctly
    • [x] Created tests which fail without the change (if possible)
    • [x] All tests passing
    • [x] Extended the README / documentation, if necessary
    • [x] Added myself / the copyright holder to the AUTHORS file
    opened by shogo82148 0
  • Use standard library to compare bytes in `parseDateTime`

    Use standard library to compare bytes in `parseDateTime`

    Description

    • ~Use a pre-allocated time.Time in function parseDateTime.~
    • Use standard library to compare bytes, no need for a variable base.
    • Add more comments.

    Checklist

    • [x] Code compiles correctly
    • [x] Created tests which fail without the change (if possible)
    • [x] All tests passing
    • [x] Extended the README / documentation, if necessary
    • [x] Added myself / the copyright holder to the AUTHORS file
    opened by zihengCat 5
  • Add gssapi plugin auth

    Add gssapi plugin auth

    Description

    Added support for GSSAPI protocol, that now we can connect to mysql via Kerberos user from Linux server without password. Oppened issue - https://github.com/go-sql-driver/mysql/issues/1232

    Checklist

    • [ + ] Code compiles correctly
    • [ - ] Created tests which fail without the change (if possible)
    • [ + ] All tests passing
    • [ - ] Extended the README / documentation, if necessary
    • [ + ] Added myself / the copyright holder to the AUTHORS file
    opened by PolliO 0
  • Add support of GSSAPI protocol connection

    Add support of GSSAPI protocol connection

    Issue description

    go-mysql-driver does not support connection by GSSAPI, which is used by Kerberos.

    Example code

    so, for now while I'm trying to connect to mysql via Kerberos user I failed with default case of auth() method in auth.go :

     default:
                    errLog.Print("unknown auth plugin:", plugin)
                    return nil, ErrUnknownPlugin
            }
    

    for plugin - auth_gssapi_client

    Configuration

    Driver version (or git SHA):

    Go version: run go version in your console : go1.15.8

    Server version: E.g. MySQL 5.6, MariaDB 10.0.20

    Server OS: E.g. Debian 8.1 (Jessie), Windows 10

    opened by PolliO 0
  • Commit() function can not distinguish whether the transaction has been sent

    Commit() function can not distinguish whether the transaction has been sent

    Issue description

    when I call func (tx *mysqlTx) Commit() (err error) ,if connection has problem it return an ErrInvalidConn

    commit

    but if current connection is fine it call exec

    exec

    and in exec it call readResultSetHeaderPacket after the transaction sent to db successfully, and readResultSetHeaderPacket call readPacket() and it also may lead to ErrInvalidConn

    readpackets

    thus I can't distinguish whether the transaction has been sent, it lead to one transaction sent twice and data not correct. Is it possible to add a new error to distinguish this two cases?

    Example code

    If possible, please enter some example code here to reproduce the issue.
    

    err = tx.Commit(ctx) if err != nil { xlog.Errorf(ctx, "%s commit transaction failed, table:%v err:%v", fun, table, err) ...

    Error log

    ***err:invalid connection 
    

    Configuration

    Driver version (or git SHA):

    *Go version: go1.12 linux/amd64

    *Server version: tidb

    *Server OS: redhat7.2

    opened by syuanyuan708 4
  • year 0 in time.Time is valid but always throws an error

    year 0 in time.Time is valid but always throws an error

    Issue description

    after upgrade from v1.5.0 to v.1.6.0, a time.Time representing an actual time without a date cannot be inserted into a column of type TIME any longer, as it has year 0 set. funnily, this value was previously even retrieved from the DB. year 0 is also in general not an invalid time.Time value for real dates.

    from https://golang.org/pkg/time/#Parse :

    Elements omitted from the value are assumed to be zero or, when zero is impossible, one, so parsing "3:04pm" returns the time corresponding to Jan 1, year 0, 15:04:00 UTC (note that because the year is 0, this time is before the zero Time). Years must be in the range 0000..9999.

    the following recently added line throws an error when the year is 0: https://github.com/go-sql-driver/mysql/blob/417641ad42910e50863a0caf4740ce319262f2f9/utils.go#L285

    as far as i can see, appendDateTime(), the function which contains this line, is called twice, and both times when the given time.Time does not have its zero value as determined by IsZero(). however, the zero value for a time.Time is in year 1, see https://golang.org/pkg/time/#Time.IsZero :

    IsZero reports whether t represents the zero time instant, January 1, year 1, 00:00:00 UTC.

    what is the reason the range was picked to be [1, 9999] here?

    if you can confirm this is actually an issue, i'm willing to try and fix it :slightly_smiling_face:

    Example code

    package main
    
    import (
    	"database/sql"
    	"fmt"
    	"time"
    
    	_ "github.com/go-sql-driver/mysql"
    )
    
    func main() {
    	db, err := sql.Open("mysql", "user:[email protected]:3306/db")
    	if err != nil {
    		panic(err)
    	}
    
    	if _, err := db.Exec("CREATE TEMPORARY TABLE IF NOT EXISTS `time_test` (`id` int not null, `some_time` time not null);"); err != nil {
    		panic(err)
    	}
    
    	if _, err := db.Exec("insert into `time_test` values(1, '08:30:30');"); err != nil {
    		panic(err)
    	}
    
    	var someTime string
    	row := db.QueryRow("select some_time from `time_test` where id = 1;")
    	if err := row.Scan(&someTime); err != nil {
    		panic(err)
    	}
    
    	fmt.Printf("this worked: %v\n", someTime)
    
    	mysqlTimeFormat := "15:04:05"
    	parsedTime, err := time.Parse(mysqlTimeFormat, someTime)
    	if err != nil {
    		panic(err)
    	}
    
    	// this works in 1.5.0, panics in 1.6.0
    	if _, err := db.Exec("update `time_test` set some_time = ? where id = 1;", parsedTime); err != nil {
    		panic(err)
    	}
    
    	fmt.Println("success!")
    }
    
    

    Error log

    the error i receive is the error from the line i specified above: panic: year is not in the range [1, 9999]: 0

    Configuration

    Driver version (or git SHA): v1.6.0

    Go version: 1.16.2

    Server version: MySQL 8.0.20

    Server OS: official mysql docker container, iirc its based on debian but should be irrelevant.

    opened by gkdr 14
  • add support for ed25519 authentication

    add support for ed25519 authentication

    Description

    This adds support for connecting to servers that require ed25519 authentication.

    Checklist

    • [x] Code compiles correctly
    • [x] Created tests which fail without the change (if possible)
    • [x] All tests passing
    • [ ] Extended the README / documentation, if necessary
      • I don't think this is necessary, since it does not appear that the supported authentication methods are listed anywhere
    • [x] Added myself / the copyright holder to the AUTHORS file

    Reference implementations:

    The ed25519 implementation was taken from here because it was portable C (and therefore easy to make work with cgo) and because it was very close to the code the reference C implementation was derived from.

    The biggest issue with this is that it introduces a dependency on cgo. I spent a fair amount of time trying to get this going with the ed25519 implementation from the standard library (crypto/ed25519), but I lack the cryptography knowledge to figure out what is happening here on a high level so I can use the corresponding high-level functions from crypto/ed25519.

    If cgo is a deal breaker (and there is not someone else on the team with the knowledge/time to implement this in pure go), would it be worth exploring an API to allow additional authentication methods as "plugins"? I could then implement this as a plugin and only users who needed ed25519 would have to worry about cgo.

    opened by 9072997 2
  • add support for time.Duration

    add support for time.Duration

    Today I learned two fun facts:

    1. in MySQL, although now() is a datetime, now() + 0 is an integer formed from all of the decimal digits in the date. e.g. 2021-05-27 17:00:26 vs 20210527170026. (I'm not sure why one would ever want that.)
    2. in Go's database/sql API for prepared statements, "?" applied to a duration value treats the duration (thanks to reflection on the underlying type) as an integer number of nanoseconds, not an interval. I don't know why one would ever want that either, since nanoseconds are not really useful in SQL.

    The combination of these two facts means that the behavior of query("now() + ?", 1*time.Hour) isn't remotely close to what one might expect:

    mysql> select now(), now() + interval 1 hour, now() + 60*60*1e9;
    +---------------------+-------------------------+-------------------+
    | now()               | now() + interval 1 hour | now() + 60*60*1e9 |
    +---------------------+-------------------------+-------------------+
    | 2021-05-27 17:13:53 | 2021-05-27 18:13:53     |    23810527171353 |
    +---------------------+-------------------------+-------------------+
    1 row in set (0.00 sec)
    

    Perhaps go-sql-driver could support time.Duration by mapping it to interval 1 hour, thereby avoiding this pitfall. Alternatively, simply rejecting it with a clear error ("you cannot possibly have wanted this behavior") would be an improvement.

    (See also https://github.com/golang/go/issues/46427: I reported this initially against database/sql, and it was closed as a driver-specific issue.)

    opened by adonovan 9
  • Automatically reprepare statements on error 1615

    Automatically reprepare statements on error 1615

    Description

    This pull request proposes a workaround for a bug in both MySQL and MariaDB. This bug spuriously invalidates prepared statements, forcing the client to reprepare them. The implemented workaround just do that: it automatically reprepares statements when error 1615 is raised. The workaround is optional and controlled by a new DSN parameter named autoReprepare.

    Due to the lack of a comprehensive connection mock, I've been unable to implement proper tests for the new code. Discussion on that issue would be welcome.

    Checklist

    • [x] Code compiles correctly
    • [ ] Created tests which fail without the change (if possible)
    • [x] All tests passing
    • [x] Extended the README / documentation, if necessary
    • [x] Added myself / the copyright holder to the AUTHORS file
    opened by Jogo27 4
Releases(v1.6.0)
  • v1.6.0(Mar 31, 2021)

    Major Release

    • Migrate the CI service from travis-ci to GitHub Actions (#1176, #1183, #1190)
    • NullTime is deprecated (#960, #1144)
    • Reduce allocations when building SET command (#1111)
    • Performance improvement for time formatting (#1118)
    • Performance improvement for time parsing (#1098, #1113)

    See CHANGELOG.md for full details

    Source code(tar.gz)
    Source code(zip)
  • v1.5.0(Jan 7, 2020)

    Major Release

    • Added Go Module support
    • Dropped support for Go 1.9 and lower
    • Implemented Connector interface
    • Improved buffering
    • Added connection liveness check
    • Improved marking of bad connnections
    • Updated collations and made utf8mb4 default
    • Made mysql.NullTime compatible with sql.NullTime
    • Removed support for CloudSQL via appengine/cloudsql

    See CHANGELOG.md for full details

    Source code(tar.gz)
    Source code(zip)
  • v1.4.1(Nov 14, 2018)

  • v1.4.0(Jun 3, 2018)

    Major Release

    • Multi-Results support
    • context.Context support
    • ColumnType support
    • caching_sha2_password (MySQL 8 default) and sha256_password authentication support
    • Transaction isolation level support
    • Read-Only transactions support
    • Many, many bugfixes

    See CHANGELOG.md for full details

    Source code(tar.gz)
    Source code(zip)
  • v1.3.0(Dec 1, 2016)

    Major Release

    • Microsecond resolution on date and time fields
    • Placeholder interpolation
    • Support for cleartext and native authentication plugins
    • Config struct and ParseDSN / FormatDSN funtctions exported
    • Read / Write timeouts
    • Support for JSON field type
    • Support for multi-statements and multi-results
    • Many, many bugfixes

    See CHANGELOG.md for full details

    Source code(tar.gz)
    Source code(zip)
  • v1.2.0(Jun 3, 2014)

  • beta4(Nov 3, 2013)

  • v1.0.3(Nov 1, 2013)

    Minor Bugfix release

    • Make Close idempotent
    • Fix sign byte for positive TIME fields
    • No panic on closed connection reuse
    • Avoid false nil values for empty strings
    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(Nov 2, 2013)

    Major release

    • Lowered Memory Footprint
    • Improved Stability
    • Slightly improved Performance

    New Features:

    • old_passwords: Old password auth mechanism
    • clientFoundRows: Number of matching rows instead of the number of rows changed
    • TLS/SSL: TLS/SSL encrypted connections

    See CHANGELOG.md for full details

    Source code(tar.gz)
    Source code(zip)
  • v1.0.2(Oct 24, 2013)

  • v1.0.1(Jul 2, 2013)

  • v1.0.0(Jul 2, 2013)

Microsoft SQL server driver written in go language

A pure Go MSSQL driver for Go's database/sql package Install Requires Go 1.8 or above. Install with go get github.com/denisenkom/go-mssqldb . Connecti

null 1.4k Jul 22, 2021
A pure go library to handle MySQL network protocol and replication.

A pure go library to handle MySQL network protocol and replication.

null 3.1k Jul 24, 2021
PostgreSQL driver and toolkit for Go

pgx - PostgreSQL Driver and Toolkit pgx is a pure Go driver and toolkit for PostgreSQL. pgx aims to be low-level, fast, and performant, while also ena

Jack Christensen 4.3k Jul 25, 2021
sqlite3 driver for go using database/sql

go-sqlite3 Latest stable version is v1.14 or later not v2. NOTE: The increase to v2 was an accident. There were no major changes or features. Descript

mattn 5k Jul 23, 2021
GO DRiver for ORacle DB

Go DRiver for ORacle godror is a package which is a database/sql/driver.Driver for connecting to Oracle DB, using Anthony Tuininga's excellent OCI wra

null 270 Jul 23, 2021
The Go driver for MongoDB

MongoDB Go Driver The MongoDB supported driver for Go. Requirements Installation Usage Bugs / Feature Reporting Testing / Development Continuous Integ

mongodb 5.9k Jul 23, 2021
Go Sql Server database driver.

gofreetds Go FreeTDS wrapper. Native Sql Server database driver. Features: can be used as database/sql driver handles calling stored procedures handle

minus5 104 Jun 17, 2021
Pure Go Postgres driver for database/sql

pq - A pure Go postgres driver for Go's database/sql package Install go get github.com/lib/pq Features SSL Handles bad connections for database/sql S

null 6.7k Jul 26, 2021
Mirror of Apache Calcite - Avatica Go SQL Driver

Apache Avatica/Phoenix SQL Driver Apache Calcite's Avatica Go is a Go database/sql driver for the Avatica server. Avatica is a sub-project of Apache C

The Apache Software Foundation 74 Jun 24, 2021
SAP (formerly sybase) ASE/RS/IQ driver written in pure go

tds import "github.com/thda/tds" Package tds is a pure Go Sybase ASE/IQ/RS driver for the database/sql package. Status This is a beta release. This dr

Thomas 47 May 30, 2021
Go language driver for RethinkDB

RethinkDB-go - RethinkDB Driver for Go Go driver for RethinkDB Current version: v6.2.1 (RethinkDB v2.4) Please note that this version of the driver on

RethinkDB 1.6k Jul 15, 2021
RethinkDB-go - RethinkDB Driver for Go

Go language driver for RethinkDB

RethinkDB 1.6k Jul 15, 2021
Golang driver for ClickHouse

ClickHouse Golang SQL database driver for Yandex ClickHouse Key features Uses native ClickHouse tcp client-server protocol Compatibility with database

ClickHouse 1.4k Jul 23, 2021
Qmgo - The Go driver for MongoDB. It‘s based on official mongo-go-driver but easier to use like Mgo.

Qmgo English | 简体中文 Qmgo is a Go driver for MongoDB . It is based on MongoDB official driver, but easier to use like mgo (such as the chain call). Qmg

Qiniu Cloud 528 Jul 23, 2021