【 TiDB 使用环境】生产环境 or 测试环境 or POC
poc
【 TiDB 版本】
4.0.14 和 5.4.1
【遇到的问题】
不同where条件加上括号后的sql 查询结果一样。
【复现路径】做过哪些操作出现的问题
package main
import (
"encoding/json"
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
"github.com/pkg/errors"
)
/*
CREATE TABLE `tidb_demo` (
`id` INT UNSIGNED AUTO_INCREMENT COMMENT '主键id',
`num` INT NOT NULL DEFAULT '0' COMMENT '数量',
`img` VARCHAR(256) NOT NULL DEFAULT '图片链接',
PRIMARY KEY (`id`),
UNIQUE INDEX de(`num`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT 'demo表';
INSERT INTO tidb_demo(`id`,`num`,`img`) VALUES(1,1,'http://demo.com/demo1.png'),(2,2,'http://demo.com/demo2.png');
*/
// TidbDemo demo表
type TidbDemo struct {
Id int64 `db:"id" json:"id"` // 主键id
Num int64 `db:"num" json:"num"` // 数量
Img string `db:"img" json:"img"` // 图片链接
}
type Config struct {
DbName string
Host string
Port string
User string
Password string
Charset string
MaxIdleCons int
MaxOpenCons int
}
func main() {
// 创建数据库链接
// TODO: 填充数据库链接信息
dbCfg := &Config{}
dbCfg.DbName = "test"
dbCfg.Host = "" //541
//dbCfg.Host = "" // 4014
dbCfg.Port = ""
dbCfg.User = ""
//dbCfg.User = "root"
dbCfg.Password = ""
//dbCfg.Password = ""
dbCfg.Charset = "utf8mb4"
db := newSqlInstance(dbCfg)
// 第一次执行sql
const querySql = "SELECT * FROM tidb_demo WHERE (id = ?)"
res1 := &TidbDemo{}
if err := db.Get(res1, querySql, 1); err != nil {
fmt.Println(errors.WithStack(err))
return
}
fmt.Println("1 time:", unsafeJsonToStr(res1))
// 第二次执行sql
res2 := &TidbDemo{}
if err := db.Get(res2, querySql, 2); err != nil {
fmt.Println(errors.WithStack(err))
return
}
fmt.Println("2 time:", unsafeJsonToStr(res2))
fmt.Println()
// 非主键字段
const querySql2 = "SELECT * FROM tidb_demo WHERE (num = ?)"
res3 := &TidbDemo{}
if err := db.Get(res3, querySql2, 1); err != nil {
fmt.Println(errors.WithStack(err))
return
}
fmt.Println("非主键字段 1 time", unsafeJsonToStr(res3))
// 第二次执行sql
res4 := &TidbDemo{}
if err := db.Get(res4, querySql2, 2); err != nil {
fmt.Println(errors.WithStack(err))
return
}
fmt.Println("非主键字段 2 time", unsafeJsonToStr(res4))
}
func newSqlInstance(conf *Config) *sqlx.DB {
charset := conf.Charset
if charset == "" {
charset = "utf8,utf8mb4"
}
dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s", conf.User, conf.Password, conf.Host, conf.Port, conf.DbName, conf.Charset)
fmt.Println("dsn", dsn)
db := sqlx.MustConnect("mysql", dsn)
if conf.MaxIdleCons != 0 {
db.SetMaxIdleConns(conf.MaxIdleCons)
}
if conf.MaxOpenCons != 0 {
db.SetMaxOpenConns(conf.MaxOpenCons)
}
return db.Unsafe()
}
func unsafeJsonToStr(data interface{}) string {
raw, _ := json.Marshal(data)
return string(raw)
}
【问题现象及影响】
- 通过proxysql 2.3.2 去连接tidb集群会出现这个问题
- 通过tidb直接连接则不会有这个问题
【附件】
请提供各个组件的 version 信息,如 cdc/tikv,可通过执行 cdc version/tikv-server --version 获取。
ProxySQL有query cache功能,建议排查一下
开启tidb GENERAL_LOG 看arguments也是对的
下面是query rule
+---------+--------+----------+--------------------+--------+-------------+------------+------------+--------+--------------+----------------------------------------------------------------------------------------------------------+----------------------+--------------+---------+-----------------+-----------------------+-----------+--------------------+---------------+-----------+---------+---------+-------+-------------------+----------------+------------------+------------------------------------------------------------+--------+-------------+-----------+---------------------+-----+-------+------------+---------+
| rule_id | active | username | schemaname | flagIN | client_addr | proxy_addr | proxy_port | digest | match_digest | match_pattern | negate_match_pattern | re_modifiers | flagOUT | replace_pattern | destination_hostgroup | cache_ttl | cache_empty_result | cache_timeout | reconnect | timeout | retries | delay | next_query_flagIN | mirror_flagOUT | mirror_hostgroup | error_msg | OK_msg | sticky_conn | multiplex | gtid_from_hostgroup | log | apply | attributes | comment |
+---------+--------+----------+--------------------+--------+-------------+------------+------------+--------+--------------+----------------------------------------------------------------------------------------------------------+----------------------+--------------+---------+-----------------+-----------------------+-----------+--------------------+---------------+-----------+---------+---------+-------+-------------------+----------------+------------------+------------------------------------------------------------+--------+-------------+-----------+---------------------+-----+-------+------------+---------+
| 1 | 1 | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*CREATE\s+USER | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to create user, please contact the db admin. | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 2 | 1 | NULL | mysql | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*INSERT\s+INTO\s+user | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to create user, please contact the db admin. | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 3 | 1 | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*INSERT\s+INTO\s+mysql\s*\.\s*user | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to create user, please contact the db admin. | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 4 | 1 | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*DROP\s+USER | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to drop user, please contact the db admin. | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 5 | 1 | NULL | mysql | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*DELETE\s+FROM\s+user | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to drop user, please contact the db admin. | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 6 | 1 | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*DELETE\s+FROM\s+mysql\s*\.\s*user | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to drop user, please contact the db admin. | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 7 | 1 | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*SET\s+PASSWORD | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to update user, please contact the db admin. | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 8 | 1 | NULL | mysql | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*UPDATE\s+user | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to update user, please contact the db admin. | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 9 | 1 | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*UPDATE\s+mysql\s*\.\s*user | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to update user, please contact the db admin. | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 12 | 1 | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL
| 13 | 1 | NULL | INFORMATION_SCHEMA | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*CREATE\s+TABLE | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to change system db, please contact the db admin | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 14 | 1 | NULL | METRICS_SCHEMA | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*CREATE\s+TABLE | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to change system db, please contact the db admin | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 15 | 1 | NULL | PERFORMANCE_SCHEMA | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*CREATE\s+TABLE | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to change system db, please contact the db admin | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 16 | 1 | NULL | mysql | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*CREATE\s+TABLE | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to change system db, please contact the db admin | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 17 | 1 | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*DROP\s+DATABASE\s+(INFORMATION_SCHEMA|METRICS_SCHEMA|PERFORMANCE_SCHEMA|mysql) | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to change system db, please contact the db admin | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 18 | 1 | NULL | INFORMATION_SCHEMA | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*DROP\s+TABLE | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to change system db, please contact the db admin | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 19 | 1 | NULL | METRICS_SCHEMA | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*DROP\s+TABLE | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to change system db, please contact the db admin | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 20 | 1 | NULL | PERFORMANCE_SCHEMA | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*DROP\s+TABLE | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to change system db, please contact the db admin | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 21 | 1 | NULL | mysql | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*DROP\s+TABLE | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to change system db, please contact the db admin | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 22 | 1 | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*INSERT\s+INTO\s+(INFORMATION_SCHEMA|METRICS_SCHEMA|PERFORMANCE_SCHEMA|mysql)\s*\. | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to change system db, please contact the db admin | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 23 | 1 | NULL | INFORMATION_SCHEMA | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*INSERT\s+INTO | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to change system db, please contact the db admin | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 24 | 1 | NULL | METRICS_SCHEMA | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*INSERT\s+INTO | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to change system db, please contact the db admin | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 25 | 1 | NULL | PERFORMANCE_SCHEMA | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*INSERT\s+INTO | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to change system db, please contact the db admin | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 26 | 1 | NULL | mysql | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*INSERT\s+INTO | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to change system db, please contact the db admin | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 27 | 1 | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*UPDATE\s+(INFORMATION_SCHEMA|METRICS_SCHEMA|PERFORMANCE_SCHEMA|mysql)\s*\. | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to change system db, please contact the db admin | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 28 | 1 | NULL | INFORMATION_SCHEMA | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*UPDATE | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to change system db, please contact the db admin | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 29 | 1 | NULL | METRICS_SCHEMA | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*UPDATE | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to change system db, please contact the db admin | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 30 | 1 | NULL | PERFORMANCE_SCHEMA | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*UPDATE | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to change system db, please contact the db admin | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 31 | 1 | NULL | mysql | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*UPDATE | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to change system db, please contact the db admin | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 32 | 1 | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*DELETE\s+FROM\s+(INFORMATION_SCHEMA|METRICS_SCHEMA|PERFORMANCE_SCHEMA|mysql)\s*\. | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to change system db, please contact the db admin | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 33 | 1 | NULL | INFORMATION_SCHEMA | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*DELETE\s+FROM | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to change system db, please contact the db admin | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 34 | 1 | NULL | METRICS_SCHEMA | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*DELETE\s+FROM | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to change system db, please contact the db admin | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 35 | 1 | NULL | PERFORMANCE_SCHEMA | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*DELETE\s+FROM | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to change system db, please contact the db admin | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
| 36 | 1 | NULL | mysql | 0 | NULL | NULL | NULL | NULL | NULL | ^\s*(\/\*(.*?)\*\/)?\s*DELETE\s+FROM | 0 | CASELESS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | not allow to change system db, please contact the db admin | NULL | NULL | NULL | NULL | NULL | 1 | | NULL |
+---------+--------+----------+--------------------+--------+-------------+------------+------------+--------+--------------+----------------------------------------------------------------------------------------------------------+----------------------+--------------+---------+-----------------+-----------------------+-----------+--------------------+---------------+-----------+---------+---------+-------+-------------------+----------------+------------------+------------------------------------------------------------+--------+-------------+-----------+---------------------+-----+-------+------------+---------+
这是tidb cfg.toml的配置吧。这个配置项没有写,看文档默认是false
使用proxysql 2.4.1没有问题。谢谢支持。
proxysql 官方叫我试下2.4.1,我试了下,没有问题。可能是吧
2.4.1也还是有问题的。之前测试没问题是因为我把括号注释了
tidb002.cap (14.3 KB)
看起来是tidb的bug
-
- proxysql发送req prepare statement
-
- tidb返回statement
-
- proxysql发送了arg,值为 1
-
- tidb返回结果
-
- proxysql发送了arg,值为2
-
- tidb返回了与arg 1相同的结果
在github上提个issue吧,论坛不跟踪bug进度。
有原因或者issue跟踪吗?
在5.0版本有修复或者修复计划吗?
目前5.0有解决方案可以暂时解决这个问题吗?