当发送给数据库的语句过大时,会报如下错误:
1
| panic: Error 1105: Parameter of prepared statement which is set through mysql_send_long_data() is longer than 'max_allowed_packet' bytes
|
从报错中可知,需要修改 max_allowed_packet 选项的值。
my.cnf
在 my.cnf 配置文件中修改该选项是最直接了当的,修改成合适的值后重启服务即可。
1
2
| [mysqld]
max_allowed_packet=16M
|
会话
当打开一个会话时,也可以使用下面的语句设置全局或当前的 max_allowed_packet 值。
1
2
| SET GLOBAL max_allowed_packet=1073741824;
SET max_allowed_packet=1073741824;
|
第 1 个在服务重启后失效,第 2 个在会话结束会失效。
go-sql-driver/mysql
更多情况下,还是希望在程序中控制该选项,所以要看下使用的数据库驱动是否支持该选项。很庆幸,go-sql-driver/mysql 是支持的,使用的版本如下:
1
| go-sql-driver/mysql@v1.6.0
|
在使用 gorm 中,返回一个 *gorm.DB 实例,我们都会使用下面的代码:
1
| db, err := gorm.Open(mysql.Open("username:password@tcp(host:port)/database?queryString"), &gorm.Config{})
|
下面说一下整行代码的执行顺序:
- mysql.Open 简单返回一个实现
gorm.Dialector 接口的实例(只是简单的赋值,并没有作解析); - gorm.Open 会调用
Dialector.Initialize 方法,并且会真正地打开数据库连接;
1
| db.ConnPool, err = sql.Open(dialector.DriverName, dialector.DSN)
|
- 在 sql.Open 中会调用;
1
| connector, err := driverCtx.OpenConnector(dataSourceName)
|
- 在 driverCtx.OpenConnector 中会调用
ParseDSN 方法; - ParseDSN 完成了对 DSN 的解析,包括
queryString 部分;
即:
1
2
3
4
| mysql.Open
\
\ gorm.Open -> Dialector.Initialize -> sql.Open -> driverCtx.OpenConnector
-> ParseDSN
|
go-sql-driver/mysql 支持的 query 参数包括如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| allowAllFiles
allowCleartextPasswords
allowNativePasswords
allowOldPasswords
checkConnLiveness
clientFoundRows
collation
columnsWithAlias
compress # 这个是没有实现的
interpolateParams
loc
multiStatements
parseTime
readTimeout
rejectReadOnly
serverPubKey
strict
timeout
tls
writeTimeout
maxAllowedPacket
|
参考
- max_allowed_packet in mySQLmax_allowed_packet in mySQL