Go-MySQL-Driver 中间件驱动程序连接器 - 文章教程

Go-MySQL-Driver 中间件驱动程序连接器

发布于 2021-08-11 字数 21080 浏览 1139 评论 0

Go-MySQL-Driver 中间件驱动程序连接器

特征

  • 轻量级和 快速
  • 本机 Go 实现。没有 C 绑定,只是纯粹的 Go
  • 通过 TCP/IPv4、TCP/IPv6、Unix 域套接字或 自定义协议的连接
  • 自动处理断开的连接
  • 自动连接池(通过 database/sql 包)
  • 支持大于 16MB 的查询
  • 全力sql.RawBytes支持。
  • LONG DATA准备好的语句中的智能处理
  • LOAD DATA LOCAL INFILE通过文件许可名单和io.Reader支持获得安全支持
  • 可选time.Time解析
  • 可选占位符插值

要求

  • 转到 1.13 或更高版本。我们的目标是支持 Go 的 3 个最新版本。
  • MySQL (4.1+)、MariaDB、Percona Server、Google CloudSQL 或 Sphinx (2.2.3+)

安装

使用 shell 中的 go 工具 将软件包简单地安装到您的 $GOPATH 中:

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

确保 Git 安装 在您的机器上和系统的 PATH

用法

Go MySQL Driver 是 Go database/sql/driver 接口的一个实现。您只需要导入驱动程序,然后就可以使用完整的 database/sql API。

使用 mysql as driverName 和有效的 DSN 作为dataSourceName

import (
	"database/sql"
	"time"

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

// ...

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

我们的 Wiki 中提供了示例

重要设置

db.SetConnMaxLifetime()在 MySQL 服务器、操作系统或其他中间件关闭连接之前,需要确保驱动程序安全地关闭连接。由于一些中间件会在 5 分钟后关闭空闲连接,我们建议超时时间短于 5 分钟。此设置也有助于负载平衡和更改系统变量。

db.SetMaxOpenConns()强烈建议限制应用程序使用的连接数。没有推荐的限制数量,因为它取决于应用程序和 MySQL 服务器。

db.SetMaxIdleConns()建议设置为相同db.SetMaxOpenConns()。当它小于 时SetMaxOpenConns(),连接可以比您预期的更频繁地打开和关闭。空闲连接可以由 关闭db.SetConnMaxLifetime()。如果你想更快地关闭空闲连接,你可以db.SetConnMaxIdleTime()从 Go 1.15 开始使用。

DSN(数据源名称)

数据源名称具有通用格式,例如PEAR DB使用它,但没有类型前缀(用方括号标记的可选部分):

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

最完整形式的 DSN:

username:password@protocol(address)/dbname?param=value

除 databasename 外,所有值都是可选的。所以最小的 DSN 是:

/dbname

如果您不想预先选择数据库,请将其dbname留空:

/

这与空的 DSN 字符串具有相同的效果:


或者,Config.FormatDSN可用于通过填充结构来创建 DSN 字符串。

密码

密码可以由任何字符组成。逃避是没有必要的。

协议

有关可用网络的详细信息,请参阅net.Dial。一般来说,您应该使用 Unix 域套接字(如果可用)和 TCP 否则以获得最佳性能。

地址

对于 TCP 和 UDP 网络,地址的形式为host[:port]. 如果port省略,将使用默认端口。如果host是文字 IPv6 地址,则必须将其括在方括号中。函数net.JoinHostPortnet.SplitHostPort以这种形式操作地址。

对于 Unix 域套接字,地址是 MySQL-Server-socket 的绝对路径,例如/var/run/mysqld/mysqld.sock/tmp/mysql.sock

参数

参数区分大小写!

请注意,任何true, TRUE,True1都被接受来代表真正的布尔值。不足为奇的是,假可以被指定为任何的:falseFALSEFalse0

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

allowAllFiles=true禁用文件许可名单LOAD DATA LOCAL INFILE并允许所有文件。 可能没有安全感!

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

allowCleartextPasswords=true如果帐户需要,允许使用明文客户端插件,例如使用PAM 身份验证插件定义的插件。在某些配置中,以明文形式发送密码可能是一个安全问题。为避免密码可能被截获时出现问题,客户端应使用保护密码的方法连接到 MySQL 服务器。可能性包括TLS/SSL、IPsec 或专用网络。

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

allowNativePasswords=false 不允许使用 MySQL 本机密码方法。

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

allowOldPasswords=true允许使用不安全的旧密码方法。这应该避免,但在某些情况下是必要的。另请参阅old_passwords 维基页面

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

设置用于客户端-服务器交互的字符集 ( "SET NAMES <value>")。如果设置了多个字符集(用逗号分隔),如果设置字符集失败,则使用以下字符集。例如,这可以支持utf8mb4在 MySQL 5.5.3 中引入)并回退到utf8旧服务器 ( charset=utf8mb4,utf8)。

charset不鼓励使用该参数,因为它会向服务器发出额外的查询。除非您需要回退行为,否则请collation改用。

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

在支持的平台上,从连接池中检索的连接在使用前会被检查活跃度。如果检查失败,则相应的连接被标记为错误,并使用另一个连接重试查询。 checkConnLiveness=false禁用此连接的活性检查。

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

设置用于连接时客户端-服务器交互的排序规则。与 相比charsetcollation不会发出额外的查询。如果指定的排序规则在目标服务器上不可用,则连接将失败。

可使用 检索服务器的有效字符集列表SHOW COLLATION

utf8mb4_general_ciMySQL 5.5 支持默认排序规则 ( )。utf8_general_ci对于较旧的 MySQL,您应该使用较旧的排序规则(例如)。

不能使用字符集“ucs2”、“utf16”、“utf16le”和“utf32”的排序规则(ref)。

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

clientFoundRows=true 导致 UPDATE 返回匹配行数而不是更改的行数。

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

columnsWithAlias为真时,调用sql.Rows.Columns()将返回表别名和用点分隔的列名。例如:

SELECT u.id FROM users as u

将返回u.id而不仅仅是idif columnsWithAlias=true

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

如果interpolateParams为 true,则?调用db.Query()db.Exec()中的占位符 ( )将插入到具有给定参数的单个查询字符串中。这减少了往返次数,因为驱动程序必须准备一个语句,使用给定的参数执行它并再次使用interpolateParams=false.

这不能与多字节编码 BIG5、CP932、GB2312、GBK 或 SJIS 一起使用。这些被拒绝,因为它们可能会引入 SQL 注入漏洞

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

设置 time.Time 值的位置(使用 时parseTime=true)。“本地”设置系统的位置。有关详细信息,请参阅time.LoadLocation

请注意,这会设置 time.Time 值的位置,但不会更改 MySQL 的time_zone 设置。为此,请参阅time_zone 系统变量,它也可以设置为 DSN 参数。

请记住,参数值必须是url.QueryEscape ‘ed。另外,您可以手动替换/%2F。例如US/Pacific将是loc=US%2FPacific.

maxAllowedPacket
Type:          decimal number
Default:       4194304

允许的最大数据包大小(以字节为单位)。默认值为 4 MiB,应进行调整以匹配服务器设置。maxAllowedPacket=0可用于在每个连接上自动max_allowed_packet从服务器获取变量。

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

允许在一个查询中使用多个语句。虽然这允许批量查询,但也大大增加了 SQL 注入的风险。只返回第一个查询的结果,所有其他结果都被静默丢弃。

multiStatements使用时,?参数必须仅在第一个语句中使用。

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

parseTime=true改变的输出类型DATEDATETIME值,以time.Time代替[]byte/string 日期或日期时间等0000-00-00 00:00:00被转换成零值time.Time

readTimeout
Type:           duration
Default:        0

I/O 读取超时。该值必须是带有单位后缀(“ms”“s”“m”“h”)的十进制数,例如“30s”“0.5m”“1m30s”

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

rejectReadOnly=true导致驱动程序拒绝只读连接。这是针对自动故障转移期间可能出现的竞争条件,其中 mysql 客户端在故障转移后连接到只读副本。

请注意,这应该是一种相当罕见的情况,因为自动故障转移通常在主服务器关闭时发生,并且竞争条件不应该发生,除非它在故障转移开始后立即恢复联机。另一方面,当发生这种情况时,MySQL 应用程序可能会卡在只读连接上,直到重新启动。然而,重现相当容易,例如,在 AWS Aurora 的 MySQL 兼容集群上使用手动故障转移。

如果您不依赖只读事务来拒绝不应该发生的写入,则在某些 MySQL 提供程序(例如 AWS Aurora)上设置此选项对于故障转移更安全。

请注意,可以为read-only服务器返回 ERROR 1290 ,此选项将导致对该错误进行重试。然而,相同的错误编号用于其他一些情况。read-only在启用此选项时,您应该确保您的应用程序永远不会导致 ERROR 1290,除了mode。

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

服务器公钥可以用 注册mysql.RegisterServerPubKey,然后可以由 DSN 中指定的名称使用。公钥用于传输加密数据,例如用于身份验证。如果服务器的公钥是已知的,则应手动设置它以避免每次需要时将公钥从服务器传输到客户端的昂贵且可能不安全的传输。

timeout
Type:           duration
Default:        OS default

建立连接超时,又名拨号超时。该值必须是带有单位后缀(“ms”“s”“m”“h”)的十进制数,例如“30s”“0.5m”“1m30s”

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

tls=true启用与服务器的 TLS / SSL 加密连接。使用skip-verify,如果你想使用自签名或无效证书(服务器端)或使用preferred只有当服务器发布到使用TLS。这类似于skip-verify,但另外允许回退到未加密的连接。既不skip-verify也不preferred添加任何可靠的安全性。使用 .tls 注册后,您可以使用自定义 TLS 配置mysql.RegisterTLSConfig

writeTimeout
Type:           duration
Default:        0

I/O 写入超时。该值必须是带有单位后缀(“ms”“s”“m”“h”)的十进制数,例如“30s”“0.5m”“1m30s”

系统变量

任何其他参数都被解释为系统变量:

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

规则:

  • 字符串变量的值必须用 引用'
  • 这些值也必须是 url.QueryEscape ‘ed!(这意味着字符串变量的值必须用 包裹 %27)。

例子:

例子

user@unix(/path/to/socket)/dbname
root:pw@unix(/tmp/mysql.sock)/myDatabase?loc=Local
user:password@tcp(localhost:5555)/dbname?tls=skip-verify&autocommit=true

通过设置系统变量将警告视为错误sql_mode

user:password@/dbname?sql_mode=TRADITIONAL

通过 IPv6 的 TCP:

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

远程主机上的 TCP,例如 Amazon RDS:

id:password@tcp(your-amazonaws-uri.com:3306)/dbname

App Engine 上的 Google Cloud SQL:

user:password@unix(/cloudsql/project-id:region-name:instance-name)/dbname

TCP 使用本地主机上的默认端口 (3306):

user:password@tcp/dbname?charset=utf8mb4,utf8&sys_var=esc%40ped

使用默认协议 (tcp) 和主机 (localhost:3306):

user:password@/dbname

未预选数据库:

user:password@/

连接池和超时

连接池由 Go 的 database/sql 包管理。有关如何配置池的大小和连接多久细节留在游泳池看到*DB.SetMaxOpenConns*DB.SetMaxIdleConns*DB.SetConnMaxLifetime将在 数据库/ SQL文档。读,写,和拨号为每个单独的连接超时被配置成与DSN参数readTimeoutwriteTimeout以及timeout分别。

ColumnType 支持

此驱动程序支持Go 1.8 中引入的ColumnType接口ColumnType.Length(),但目前不支持的 。所有未签名的数据库类型名称将返回UNSIGNED 带有INT, TINYINT, SMALLINT, BIGINT

context.Context 支持

Go 1.8 添加了database/sqlcontext.Context. 此驱动程序通过上下文支持查询超时和取消。有关更多详细信息,请参阅database/sql 包中的上下文支持

LOAD DATA LOCAL INFILE 支持

对于此功能,您需要直接访问包。因此,您必须更改导入路径(否_):

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

文件必须通过注册mysql.RegisterLocalFile(filepath)(推荐)明确允许,或者必须使用 DSN 参数停用许可名单检查allowAllFiles=true可能不安全!)。

要使用io.Reader处理程序函数,必须注册mysql.RegisterReaderHandler(name, handler)其返回 aio.Readerio.ReadCloser。然后,Reader 可与文件路径一起使用Reader::<name>。为不同的处理程序以及DeregisterReaderHandler当您不再需要它时选择不同的名称。

有关详细信息,请参阅 Go-MySQL-Drivergodoc

time.Time 支持

MySQLDATEDATETIME值的默认内部输出类型是[]byte允许您将值扫描到程序中的[]byte,stringsql.RawBytes变量中。

但是,许多人希望将 MySQLDATEDATETIME值扫描到time.Time变量中,这在 Go toDATEDATETIMEMySQL 中是逻辑等价的。您可以通过使用 DSN 参数将内部输出类型从 更改为[]byte来实现。您可以使用DSN 参数设置默认位置time.TimeparseTime=truetime.Timeloc

注意:从 Go 1.1 开始,这成为time.Time唯一可以扫描DATEDATETIME取值的变量类型。例如,这会中断sql.RawBytes支持

Unicode 支持

从 1.5 版开始,Go-MySQL-Driver utf8mb4_general_ci 默认自动使用排序规则。

可以使用collationDSN 参数设置其他排序规则/字符集。

驱动程序的 1.0 版建议将 &charset=utf8(别名为 SET NAMES utf8)添加到 DSN 以启用正确的 UTF-8 支持。这不再是必要的了。该collation参数应该优先于设置另一个排序规则/字符集而不是默认值。

有关 MySQL 的 Unicode 支持的更多详细信息,请参阅 http://dev.mysql.com/doc/refman/8.0/en/charset-unicode.html

项目地址:https://github.com/go-sql-driver/mysql

如果你对这篇文章有疑问,欢迎到本站 社区 发帖提问或使用手Q扫描下方二维码加群参与讨论,获取更多帮助。

扫码加入群聊

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

目前还没有任何评论,快来抢沙发吧!

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

2512 文章
30 评论
83586 人气
更多

推荐作者

魏剑帆

文章 0 评论 0

yanggwq

文章 0 评论 0

qq_c2gI5

文章 0 评论 0

qq_iQVWB

文章 0 评论 0