pingcap / tidb

TiDB is an open-source, cloud-native, distributed, MySQL-Compatible database for elastic scale and real-time analytics. Try AI-powered Chat2Query free at : https://www.pingcap.com/tidb-serverless/
https://pingcap.com
Apache License 2.0
36.58k stars 5.76k forks source link

'&' in User level lock name will displayed as \u0026 #34470

Open seiya-annie opened 2 years ago

seiya-annie commented 2 years ago

Bug Report

Please answer these questions before submitting your issue. Thanks!

1. Minimal reproduce step (Required)

  1. select getlock('!@#$%^&()+',3600); in session A
  2. select getlock('!@#$%^&()+',3600); in session B, session B will wait for the lock
  3. select * from information_schema.data_lock_waits;

2. What did you expect to see? (Required)

lock name in KEY_INFO should be : "indexvalues":["!@#$%^&()+"]}

3. What did you see instead (Required)

mysql>  select * from information_schema.data_lock_waits;
+------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------+--------------------+------------------------+------------------------------------------------------------------+-----------------+
| KEY                                                                          | KEY_INFO                                                                                                                                          | TRX_ID             | CURRENT_HOLDING_TRX_ID | SQL_DIGEST                                                       | SQL_DIGEST_TEXT |
+------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------+--------------------+------------------------+------------------------------------------------------------------+-----------------+
| 7480000000000000465F6980000000000000010121402324255E2628FF295F2B0000000000FA | {"db_id":3,"db_name":"mysql","table_id":70,"table_name":"advisory_locks","index_id":1,"index_name":"PRIMARY","index_values":["!@#$%^\u0026()_+"]} | 433082322883706884 |     433082321389223939 | 503fd5b0bd3ca476326b20cdb82e8088bb82376f9a3b81c2f1887bcf46bb3da6 | NULL            |
+------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------+--------------------+------------------------+------------------------------------------------------------------+-----------------+
1 row in set (0.01 sec)

4. What is your TiDB version? (Required)

| Release Version: v6.1.0-alpha Edition: Community Git Commit Hash: 2c19f0a116143fd8a5cefc9dcb5f3d9c6c894372 Git Branch: heads/refs/tags/v6.1.0-alpha UTC Build Time: 2022-05-05 14:58:11 GoVersion: go1.18 Race Enabled: false TiKV Min Version: v3.0.0-60965b006877ca7234adaced7890d7b029ed1306 Check Table Before Drop: false |

morgo commented 2 years ago

This is caused by the json.Marshall function in the lock view, not the get_lock function. Here is a quick patch to demonstrate:

diff --git a/executor/infoschema_reader.go b/executor/infoschema_reader.go
index 8131402ab..d9e39bbc7 100644
--- a/executor/infoschema_reader.go
+++ b/executor/infoschema_reader.go
@@ -2391,6 +2391,7 @@ func (r *dataLockWaitsTableRetriever) retrieve(ctx context.Context, sctx session
                                                } else {
                                                        decodedKeyStr = string(decodedKeyBytes)
                                                }
+                                               fmt.Printf("#### decodedKey: %#v, decodedKeyStr: %#v, \n", decodedKey, decodedKeyStr)
                                        } else {
                                                logutil.BgLogger().Warn("decode key failed", zap.Error(err))
                                        }

Outputs:

#### decodedKey: keydecoder.DecodedKey{DbID:3, DbName:"mysql", TableID:67, TableName:"advisory_locks", PartitionID:0, PartitionName:"", HandleType:"", IsPartitionHandle:false, HandleValue:"", IndexID:1, IndexName:"PRIMARY", IndexValues:[]string{"!@#$%^&()_+"}}, decodedKeyStr: "{\"db_id\":3,\"db_name\":\"mysql\",\"table_id\":67,\"table_name\":\"advisory_locks\",\"index_id\":1,\"index_name\":\"PRIMARY\",\"index_values\":[\"!@#$%^\\u0026()_+\"]}", 

You can see that in the non-json string, the encoding is with '&'. Because this is caused by a go library ("encoding/json"), it might be difficult to fix.