TiDB Query Issues

Note:
This topic has been translated from a Chinese forum by GPT and might contain errors.

Original topic: tidb 查询问题

| username: zhangyan0328

【TiDB Usage Environment】Production environment or Test environment or POC
POC
【TiDB Version】
4.0.14 and 5.4.1
【Problem Encountered】
The SQL query results are the same after adding parentheses to different WHERE conditions.
【Reproduction Path】What operations were performed to encounter the problem

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 'Primary key id',
   `num` INT NOT NULL DEFAULT '0' COMMENT 'Quantity',
   `img` VARCHAR(256) NOT NULL DEFAULT 'Image link',
   PRIMARY KEY (`id`),
   UNIQUE INDEX de(`num`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT 'demo table';

INSERT INTO tidb_demo(`id`,`num`,`img`) VALUES(1,1,'http://demo.com/demo1.png'),(2,2,'http://demo.com/demo2.png');
*/

// TidbDemo demo table
type TidbDemo struct {
	Id  int64  `db:"id" json:"id"`   // Primary key id
	Num int64  `db:"num" json:"num"` // Quantity
	Img string `db:"img" json:"img"` // Image link
}

type Config struct {
	DbName      string
	Host        string
	Port        string
	User        string
	Password    string
	Charset     string
	MaxIdleCons int
	MaxOpenCons int
}

func main() {
	// Create database connection
	// TODO: Fill in database connection information
	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)

	// First SQL execution
	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))
	// Second SQL execution
	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()

	// Non-primary key field
	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("Non-primary key field 1 time", unsafeJsonToStr(res3))
	// Second SQL execution
	res4 := &TidbDemo{}
	if err := db.Get(res4, querySql2, 2); err != nil {
		fmt.Println(errors.WithStack(err))
		return
	}
	fmt.Println("Non-primary key field 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)
}

【Problem Phenomenon and Impact】

Please provide the version information of each component, such as cdc/tikv, which can be obtained by executing cdc version/tikv-server --version.

| username: ddhe9527 | Original post link

ProxySQL has a query cache feature, it is recommended to check it.

| username: zhangyan0328 | Original post link

  1. I tested it again, and there is no problem with proxysql backend connected to MySQL.
  2. In the case of proxysql backend connected to TiDB, if the parentheses in the SQL code SELECT * FROM tidb_demo WHERE (id = ?) are removed, i.e., SELECT * FROM tidb_demo WHERE id = ?, there is no problem. However, with the parentheses, it doesn’t work correctly.
| username: ShawnYan | Original post link

What is the query rule in prxsql?

| username: zhangyan0328 | Original post link

Enabling TiDB GENERAL_LOG to view arguments is also correct.

| username: zhangyan0328 | Original post link

Hello, how is this issue going?

| username: yilong | Original post link

  1. Has the plan cache been enabled for the TiDB cluster? If so, you can try disabling it first.
| username: zhangyan0328 | Original post link

This is the configuration for tidb cfg.toml, right? This configuration item is not written, and according to the documentation, the default is false.

| username: yilong | Original post link

  1. There is no problem with directly connecting to the tidb-server. It seems like it might be an issue with proxysql. You can consider raising an issue for proxysql as well.
  2. Alternatively, you can use Tcpdump port xxx -w xxx.cap to capture packets. Try capturing packets on the tidb-server port and compare the differences between direct connection and connection through proxysql.
| username: zhangyan0328 | Original post link

There are no issues using proxysql 2.4.1. Thank you for your support.

| username: ShawnYan | Original post link

Is it a bug in proxysql since it’s a newly released version?

| username: zhangyan0328 | Original post link

The official ProxySQL team asked me to try version 2.4.1. I tried it, and there were no issues. Maybe that’s it.

| username: ShawnYan | Original post link

I see it, renecannao responded quite quickly.

| username: zhangyan0328 | Original post link

:grin:

| username: zhangyan0328 | Original post link

Version 2.4.1 still has issues. The reason there were no problems during previous tests is that I commented out the parentheses.

| username: zhangyan0328 | Original post link

It looks like a TiDB bug.

    1. proxysql sends req prepare statement
    1. tidb returns statement
    1. proxysql sends arg with value 1
    1. tidb returns result
    1. proxysql sends arg with value 2
    1. tidb returns the same result as arg 1
| username: ShawnYan | Original post link

You should open an issue on GitHub; the forum does not track bug progress.

| username: zhangyan0328 | Original post link

Submitted Tidb as the backend of proxysql. The query result is incorrect · Issue #35946 · pingcap/tidb · GitHub

| username: Min_Chen | Original post link

I tried version 6.1.0 and it has been fixed. You can use the latest version.

| username: zhangyan0328 | Original post link

Is there a reason or an issue being tracked?
Has it been fixed or is there a plan to fix it in version 5.0?
Is there a temporary solution to address this issue in version 5.0?