All Products
Search
Document Center

ApsaraDB RDS:Use Go-MySQL-Driver to connect to an ApsaraDB RDS for MySQL instance

Last Updated:Mar 11, 2025

If your application uses the Go programming language and needs to frequently establish connections (such as short-lived connections) to an ApsaraDB RDS for MySQL instance, or the number of connections between your application and the RDS for MySQL instance exceeds the limit, you can use Go-MySQL-Driver to connect to the RDS instance. This helps reduce the frequency at which your application connects to the RDS instance and lower the main thread overhead of the RDS instance. This topic describes how to use Go-MySQL-Driver to connect to an RDS instance and how to perform operations on the databases of the connected RDS instance.

Note

Go-MySQL-Driver is a third-party database driver package provided by Go. You can use Go-MySQL-Driver to connect to MySQL and MariaDB databases.

Limits

Only RDS instances that run MySQL 5.7 or 8.0 can be connected by using Go-MySQL-Driver.

Preparations

  • Go 1.20 or later is installed. For more information, see Download and install.

  • The IP address of your client is added to the IP address whitelist of the RDS instance. For more information, see Configure an IP whitelist.

    Note

    If your application is deployed on an Elastic Compute Service (ECS) instance that resides in the same region and virtual private cloud (VPC) as the RDS instance, you do not need to configure an IP address whitelist.

Use Go-MySQL-Driver to connect to an RDS instance

1. Add a dependency

  1. Add the go-sql-driver dependency to the go.mod file of your Go project.

    require (
        github.com/go-sql-driver/mysql v1.8.1
    )
  2. Import required packages to the .go file.

    import (
        // Import the database/sql package that provides a general SQL interface.
        "database/sql"
        // Import the fmt package that provides formatted input and output.
        "fmt"
        // Import Go-MySQL-Driver to connect and manage databases in RDS for MySQL.
        "github.com/go-sql-driver/mysql"
        // Import the time package to handle time-related operations.
        "time"
    )

2. Initialize the connection pool

Use the main method of the .go file to initialize the connection pool and configure related parameters. Sample code:

// Establish a database connection.
cfg := mysql.NewConfig()
cfg.User = "****" // Replace the value with the username of the account used to log on to your RDS instance.
cfg.Passwd = "****" // Replace the value with the password of the account.
cfg.Net = "tcp" // The connection type is TCP by default. You do not need to modify the value.
cfg.Addr = "rm-2zefwjx1s8156******.mysql.rds.aliyuncs.com:3306" // Replace the value with the endpoint and port number of your RDS instance.
cfg.DBName = "****" // Replace the value with the name of the RDS instance.

conn, err := mysql.NewConnector(cfg)
if err != nil {
    panic(err.Error())
}

db := sql.OpenDB(conn)
defer func(db *sql.DB) {
    err := db.Close()
    if err != nil {
        fmt.Printf("Error closing database connection: %v\n", err)
    }
}(db)
// Configure the parameters related to the connection pool.
db.SetMaxOpenConns(20)   // Specify the maximum number of open connections in the connection pool. You can modify the value based on your business requirements.
db.SetMaxIdleConns(2)    // Specify the maximum number of idle connections in the connection pool. You can modify the value based on your business requirements.
db.SetConnMaxIdleTime(10 * time.Second)   // Specify the maximum period of time that a connection in the connection pool can stay idle. You can modify the value based on your business requirements.
db.SetConnMaxLifetime(80 * time.Second)   // Specify the maximum period of time that a connection can be reused. You can modify the value based on your business requirements.
Note

For more information about how to view the endpoint and port number of an RDS instance, see View and manage instance endpoints and ports.

Appendix:Key parameters of the connection pool

Important
  • We recommend that you configure the parameters in the Recommended configurations table to reduce database runtime risks. You can also configure the parameters in the Optional configurations table to improve database performance.

  • To minimize potential risks and uncertainties and ensure system stability and reliability, we recommend that you perform a complete feature and performance testing before you apply the new parameter values in your production environment.

Recommended configurations

Parameter

Description

Default value

Recommended value

Remarks

maxIdleTime

The maximum idle period of connections. Unit: minutes.

0

10~30

  • The default value 0 specifies that connections do not time out.

  • We recommend that you configure this parameter for your application based on actual requirements. You can use the SetConnMaxIdleTime method to configure the parameter.

maxLifetime

The maximum period of time that a connection can be reused. Unit: hours.

0

1~8

  • The default value 0 specifies that connections are always available for reuse and no limits are imposed.

  • This parameter is used to prevent long-lived connections and save resources. You can use the SetConnMaxLifetime method to configure the parameter.

maxOpen

The maximum number of connections in the connection pool.

0

100

  • The default value 0 specifies that no limits are imposed.

  • If the value of the MaxIdleConns parameter is greater than 0 and is greater than the new value of the MaxOpenConns parameter, the value of the MaxIdleConns parameter is decreased to meet the limit of the MaxOpenConns parameter.

  • We recommend that you configure this parameter for your application based on actual requirements. You can use the SetMaxOpenConns method to configure the parameter.

maxIdleCount

The maximum number of idle connections in the connection pool.

2

20

  • You can configure this parameter to reserve a specific number of connections to quickly respond to database request bursts.

  • If the value of the MaxOpenConns parameter is greater than 0 and less than the new value of the MaxIdleConns parameter, the new value of the MaxIdleConns is decreased to meet the limit of the MaxOpenConns parameter.

  • You can use the SetMaxIdleConns method to configure the parameter.

  • If you set the parameter to a value less than or equal to 0, idle connections are closed.

readTimeout

The timeout period for I/O reads. You can specify the value in milliseconds (ms), seconds (s), or minutes (m) based on your business requirements.

0

10000ms-60000ms

  • The default value 0 specifies that no timeout limits are imposed. We recommend that you retain the default value. You can modify the value based on your business requirements.

  • Set this parameter to a predefined unit constant that is provided by the time.Duration type defined in the time package of Go. Example: cfg.readTimeout = 30*time.Second. Do not set this parameter to a string, such as "30s".

writeTimeout

The timeout period for I/O writes. You can specify the value in milliseconds (ms), seconds (s), or minutes (m) based on your business requirements.

0

10000ms-60000ms

  • The default value 0 specifies that no timeout limits are imposed. We recommend that you retain the default value. You can modify the value based on your business requirements.

  • Set this parameter to a predefined unit constant that is provided by the time.Duration type defined in the time package of Go. Example: cfg.writeTimeout = 30*time.Second. Do not set this parameter to a string, such as "30s".

Optional configurations

Parameter

Description

Default value

Recommended value

Remarks

timeout

The timeout period for establishing a connection. You can specify the value in milliseconds (ms), seconds (s), or minutes (m) based on your business requirements.

The default value varies based on the default value of the operating system.

3000ms

  • Set this parameter to a predefined unit constant provided by the time.Duration type defined in the time package of Go. Example: cfg.timeout = 30*time.Second. Do not set this parameter to a string, such as "30s".

  • We recommend that you specify a timeout period in the range of 1s to 10s when you configure a connection pool. The timeout period varies based on the network quality and the distance between the application and the server.

Perform operations on a database

Create a table

In this example, a table named userinfo is created.

_, err = db.Exec("create table  if not exists userinfo( uid int auto_increment, username varchar(20) not null default '', departname varchar(20) not null default '', created varchar(10) not null default '', primary key(uid) );")
if err != nil {
    fmt.Println("create table error ", err)
    return
}

Write data to the table

In this example, data is written to the userinfo table.

Method 1: Directly write data to a table

stmt, err := db.Prepare("INSERT userinfo SET username=?,departname=?,created=?")
res, err := stmt.Exec("James", "Research", "2016-06-17")
id, err := res.LastInsertId()
if err != nil {
    panic(err)
}
fmt.Println(id)

Method 2: Write data to a table by performing a parameterized query

result, err := db.Exec("INSERT INTO userinfo (username, departname, created) VALUES (?, ?, ?)", "Linda", "Testing", "2016-06-21")
if err != nil {
    panic(err)
}
ids, err := result.LastInsertId()
fmt.Println(ids)

Update data

In this example, data in the userinfo table is updated.

stmtUpdate, err := db.Prepare("UPDATE userinfo SET username=?, departname=?, created=?  WHERE username=?")
if err != nil {
    fmt.Println("Prepare update statement error:", err)
    return
}
resUpdate, err := stmtUpdate.Exec("Robert", "Sales", "2024-09-23", "Linda")
if err != nil {
    fmt.Println(err)
}
rowCnt, _ := resUpdate.RowsAffected()
fmt.Println(rowCnt)

Query data

In this example, a data record from the userinfo table in which the value of the username field is Robert is queried.

Method 1: Directly query data

rows, err := db.Query("SELECT username,departname,created FROM userinfo WHERE username=?", "Robert")
if err != nil {
    panic(err)
}
for rows.Next() {
 var username, departname, created string
 if err := rows.Scan(&username, &departname, &created); err != nil {
     fmt.Println(err)
 }
 fmt.Println("username:", username, "departname:", departname, " created:", created)
}
defer func(rows *sql.Rows) {
 err := rows.Close()
 if err != nil {
     fmt.Println(err)
 }
}(rows)

Method 2: Query data by performing a parameterized query

stmtQuery, err := db.Prepare("SELECT username,departname,created FROM userinfo WHERE username=?")
if err != nil {
    fmt.Println("prepare error", err)
    return
}
rowData, err := stmtQuery.Query("Robert")
if err != nil {
    fmt.Println("query data error", err)
    return
}
for rowData.Next() {
 var username, departname, created string
 if err := rowData.Scan(&username, &departname, &created); err != nil {
     fmt.Println(err)
 }
 fmt.Println("username:", username, "departname:", departname, "created:", created)
}
defer func(rows *sql.Rows) {
 err := rows.Close()
 if err != nil {
     fmt.Println(err)
 }
}(rowData)

Delete data

In this example, a data record from the userinfo table in which the value of the username field is James is deleted.

delStmt, _ := db.Prepare("DELETE FROM userinfo WHERE username=?")
resultDel, err := delStmt.Exec("James")
if err != nil {
    panic(err)
}
rowAffect, _ := resultDel.RowsAffected()
fmt.Println("Data deletion completed.", rowAffect)

Example

package main

import (
    // Import the database/sql package that provides a general SQL interface.
    "database/sql"
    // Import the fmt package that provides formatted input and output.
    "fmt"
    // Import Go-MySQL-Driver to connect and manage databases in RDS for MySQL.
    "github.com/go-sql-driver/mysql"
    // Import the time package to handle time-related operations.
    "time"
)

func main() {
    // Establish a database connection.
    cfg := mysql.NewConfig()
    cfg.User = "****"                                                   /*Replace the value with the username of the account used to log on to your RDS instance.*/
    cfg.Passwd = "****"                                                 /*Replace the value with the password of the account.*/
    cfg.Net = "tcp"                                                     /*The connection type is TCP by default. You do not need to modify the value.*/
    cfg.Addr = "rm-2ze1vw17v542q6b****.mysql.pre.rds.aliyuncs.com:3306" /*Replace the value with the endpoint and port number of your RDS instance.*/
    cfg.DBName = "****"                                                 /*Replace the value with the name of the database.*/
    cfg.Timeout = 3 * time.Second                                       /*Specify the timeout period for establishing a connection to the database. You can specify the value in milliseconds (ms), seconds (s), or minutes (m) based on your business requirements.*/
    cfg.ReadTimeout = 60 * time.Second                                  /*The timeout period for I/O reads. You can specify the value in milliseconds (ms), seconds (s), or minutes (m) based on your business requirements.*/
    cfg.WriteTimeout = 60 * time.Second                                 /*The timeout period for I/O writes. You can specify the value in milliseconds (ms), seconds (s), or minutes (m) based on your business requirements.*/

    conn, err := mysql.NewConnector(cfg)
    if err != nil {
        panic(err.Error())
    }

    db := sql.OpenDB(conn)
    defer func(db *sql.DB) {
        err := db.Close()
        if err != nil {
            fmt.Printf("Error closing database connection: %v\n", err)
        }
    }(db)

    // Configure the parameters related to the connection pool.
    db.SetMaxOpenConns(100)                 /*Specify the maximum number of open connections in the connection pool.*/
    db.SetMaxIdleConns(20)                  /*Specify the maximum number of idle connections in the connection pool.*/
    db.SetConnMaxIdleTime(10 * time.Minute) /*Specify the maximum period of time that a connection in the connection pool can stay idle.*/
    db.SetConnMaxLifetime(8 * time.Hour) /*Specify the maximum period of time that a connection can be reused.*/

    // Create a table named userinfo.
    _, err = db.Exec("create table  if not exists userinfo( uid int auto_increment, username varchar(20) not null default '', departname varchar(20) not null default '', created varchar(10) not null default '', primary key(uid) );")
    if err != nil {
        fmt.Println("create table error ", err)
        return
    }

    // Directly write data to the table.
    stmt, err := db.Prepare("INSERT userinfo SET username=?,departname=?,created=?")
    res, err := stmt.Exec("James", "Research", "2016-06-17")
    id, err := res.LastInsertId()
    if err != nil {
        panic(err)
    }
    fmt.Println(id)

    // Write data to the table by performing a parameterized query.
    result, err := db.Exec("INSERT INTO userinfo (username, departname, created) VALUES (?, ?, ?)", "Linda", "Testing", "2016-06-21")
    if err != nil {
        panic(err)
    }
    ids, err := result.LastInsertId()
    fmt.Println(ids)

    // Update data in the table.
    stmtUpdate, err := db.Prepare("UPDATE userinfo SET username=?, departname=?, created=?  WHERE username=?")
    if err != nil {
        fmt.Println("Prepare update statement error:", err)
        return
    }
    resUpdate, err := stmtUpdate.Exec("Robert", "Sales", "2024-09-23", "Linda")
    if err != nil {
        fmt.Println(err)
    }
    rowCnt, _ := resUpdate.RowsAffected()
    fmt.Println(rowCnt)

    // Directly query data to the table.
    rows, err := db.Query("SELECT username,departname,created FROM userinfo WHERE username=?", "Robert")
    if err != nil {
        panic(err)
    }
    for rows.Next() {
        var username, departname, created string
        if err := rows.Scan(&username, &departname, &created); err != nil {
            fmt.Println(err)
        }
        fmt.Println("username:", username, "departname:", departname, "created:", created)
    }
    defer func(rows *sql.Rows) {
        err := rows.Close()
        if err != nil {
            fmt.Println(err)
        }
    }(rows)

    // Query data to the table by performing a parameterized query.
    stmtQuery, err := db.Prepare("SELECT username,departname,created FROM userinfo WHERE username=?")
    if err != nil {
        fmt.Println("prepare error", err)
        return
    }
    rowData, err := stmtQuery.Query("Robert")
    if err != nil {
        fmt.Println("query data error", err)
        return
    }
    for rowData.Next() {
        var username, departname, created string
        if err := rowData.Scan(&username, &departname, &created); err != nil {
            fmt.Println(err)
        }
        fmt.Println("username:", username, "departname:", departname, "created:", created)
    }
    defer func(rows *sql.Rows) {
        err := rows.Close()
        if err != nil {
            fmt.Println(err)
        }
    }(rowData)

    // Delete data from the table.
    delStmt, _ := db.Prepare("DELETE FROM userinfo WHERE username=?")
    resultDel, err := delStmt.Exec("James")
    if err != nil {
        panic(err)
    }
    rowAffect, _ := resultDel.RowsAffected()
    fmt.Println("Data deletion completed.", rowAffect)
}

References