Unable to parse key with tidb_decode_key?

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

Original topic: tidb_decode_key解析不了key?

| username: lindoubled

As shown above, it seems that this region is different from other regions. When using tidb_decode_key, an error occurs: 1105 invalid record/index key: 748000000000000B5A

| username: h5n1 | Original post link

What version, what is the table structure, and what is the result of show table xx regions?

| username: Billmay表妹 | Original post link

【TiDB Usage Environment】Production, Testing, Research
【TiDB Version】
【Encountered Issues】
【Reproduction Path】What operations were performed that led to the issue
【Issue Phenomenon and Impact】

Please describe your issue completely as required.

| username: lindoubled | Original post link

Version: 5.3.0

Table structure:

Create Table: CREATE TABLE `t1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin AUTO_INCREMENT=90001

show table t1 regions:

MySQL [test]> show table t1 regions\G;
*************************** 1. row ***************************
           REGION_ID: 555259
           START_KEY: t_2906_
             END_KEY: t_2908_
           LEADER_ID: 118969860
     LEADER_STORE_ID: 1
               PEERS: 118224069, 118969860, 259396236
          SCATTERING: 0
       WRITTEN_BYTES: 0
          READ_BYTES: 0
APPROXIMATE_SIZE(MB): 1
    APPROXIMATE_KEYS: 0
1 row in set (0.01 sec)

Data in the table:

MySQL [test]> select * from t1;
+----+------+
| id | name |
+----+------+
|  1 | 1    |
|  2 | 1    |
|  3 | 1    |
|  4 | 1    |
|  5 | 1    |
|  6 | 1    |
|  7 | 1    |
|  8 | 1    |
|  9 | 1    |
+----+------+

Question:

MySQL [test]> select * from information_schema.tikv_region_status where table_name='t1'\G;
*************************** 1. row ***************************
                REGION_ID: 555259
                START_KEY: 748000000000000BFF5A00000000000000F8
                  END_KEY: 748000000000000BFF5C00000000000000F8
                 TABLE_ID: 2906
                  DB_NAME: test
               TABLE_NAME: t1
                 IS_INDEX: 0
                 INDEX_ID: NULL
               INDEX_NAME: NULL
           EPOCH_CONF_VER: 3668
            EPOCH_VERSION: 1705
            WRITTEN_BYTES: 0
               READ_BYTES: 0
         APPROXIMATE_SIZE: 1
         APPROXIMATE_KEYS: 0
  REPLICATIONSTATUS_STATE: NULL
REPLICATIONSTATUS_STATEID: NULL
1 row in set (0.26 sec)

ERROR: No query specified

MySQL [test]> select tidb_decode_key('748000000000000BFF5A00000000000000F8');
+---------------------------------------------------------+
| tidb_decode_key('748000000000000BFF5A00000000000000F8') |
+---------------------------------------------------------+
| 748000000000000BFF5A00000000000000F8                    |
+---------------------------------------------------------+
| username: h5n1 | Original post link

select schema, table_name from information_schema.tables where TIDB_TABLE_ID in (2907, 2908, 2909). Check if these tables exist.
Currently, the TABLE_ID of table t1 is 2906, and the END_KEY of the region is t_2908_, which belongs to another table. It seems that table 2908 has been deleted.
TiDB has a cross-table merge parameter enable-cross-table-merge. If it’s a test environment, you can try setting this to false, then restart and check what the end key of t1 is.

| username: lindoubled | Original post link

2908 exists:

MySQL [information_schema]> select tidb_table_id,table_schema,table_name from information_schema.tables where TIDB_TABLE_ID in (2907,2908,2909);
+---------------+--------------+---------------+
| tidb_table_id | table_schema | table_name    |
+---------------+--------------+---------------+
|          2908 | passport_dev | log_user_type |
+---------------+--------------+---------------+

The default value of enable-cross-table-merge on PD is false:

» config show
{
  "replication": {
    "enable-placement-rules": "true",
    "enable-placement-rules-cache": "false",
    "isolation-level": "",
    "location-labels": "",
    "max-replicas": 3,
    "strictly-match-label": "false"
  },
  "schedule": {
    "enable-cross-table-merge": "false",
    "enable-joint-consensus": "true",
    "high-space-ratio": 0.7,
    "hot-region-cache-hits-threshold": 3,
    "hot-region-schedule-limit": 16,
    "hot-regions-reserved-days": 0,
    "hot-regions-write-interval": "10m0s",
    "leader-schedule-limit": 64,
    "leader-schedule-policy": "count",
    "low-space-ratio": 0.95,
    "max-merge-region-keys": 200000,
    "max-merge-region-size": 128,
    "max-pending-peer-count": 128,
    "max-snapshot-count": 3,
    "max-store-down-time": "30m0s",
    "merge-schedule-limit": 64,
    "patrol-region-interval": "10ms",
    "region-schedule-limit": 128,
    "region-score-formula-version": "",
    "replica-schedule-limit": 1024,
    "split-merge-interval": "1h0m0s",
    "tolerant-size-ratio": 0
  }
}
| username: h5n1 | Original post link

The structure of this table

| username: lindoubled | Original post link

Create Table: CREATE TABLE `log_user_type` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `app_id` varchar(255) NOT NULL DEFAULT '',
  `uid` varchar(255) NOT NULL DEFAULT '',
  `uuid` varchar(255) DEFAULT NULL,
  `old_username` varchar(255) DEFAULT NULL,
  `old_user_type` varchar(255) DEFAULT NULL,
  `old_device` varchar(255) DEFAULT NULL,
  `new_username` varchar(255) DEFAULT NULL,
  `new_user_type` varchar(255) DEFAULT NULL,
  `ip` varchar(255) DEFAULT NULL,
  `user_agent` json DEFAULT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */,
  KEY `idx_uid` (`uid`),
  KEY `idx_ip` (`ip`),
  KEY `idx_created_at` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin AUTO_INCREMENT=90001
| username: lindoubled | Original post link

The simplest way to reproduce:

  1. Create a table t11
 CREATE TABLE `t11` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin AUTO_INCREMENT=30001
  1. Insert a record:
insert into t11(name) values('1')
  1. Check the key range of t11:
MySQL [test]> select * from information_schema.tikv_region_status where table_name='t11'\G;
*************************** 1. row ***************************
                REGION_ID: 261077209
                START_KEY: 7480000000000020FF0E00000000000000F8
                  END_KEY: 7480000000000020FF1000000000000000F8
                 TABLE_ID: 8206
                  DB_NAME: test
               TABLE_NAME: t11
                 IS_INDEX: 0
                 INDEX_ID: NULL
               INDEX_NAME: NULL
           EPOCH_CONF_VER: 9410
            EPOCH_VERSION: 4764
            WRITTEN_BYTES: 0
               READ_BYTES: 0
         APPROXIMATE_SIZE: 1
         APPROXIMATE_KEYS: 1
  REPLICATIONSTATUS_STATE: NULL
REPLICATIONSTATUS_STATEID: NULL
  1. Unable to parse with tidb_decode_key
MySQL [test]> select tidb_decode_key('7480000000000020FF0E00000000000000F8');
+---------------------------------------------------------+
| tidb_decode_key('7480000000000020FF0E00000000000000F8') |
+---------------------------------------------------------+
| 7480000000000020FF0E00000000000000F8                    |
+---------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)

MySQL [test]> show warnings;
+---------+------+----------------------------------------------+
| Level   | Code | Message                                      |
+---------+------+----------------------------------------------+
| Warning | 1105 | invalid record/index key: 74800000000000200E |
+---------+------+----------------------------------------------+
1 row in set (0.00 sec)
| username: h5n1 | Original post link

It is probably a bug. I suggest testing it on the latest version 5.3.

| username: lindoubled | Original post link

I tested two clusters, and the results were the same. However, it seems that only small tables have this issue, i.e., when there is no data or very little data.

| username: h5n1 | Original post link

It is estimated that the absence of _rowid in the startkey/endkey leads to the inability to parse it. You can look at a start/end key with rowid; the records in tikv_region_status with rowid are much longer than those without.

| username: lindoubled | Original post link

That’s right, the keys that can be decoded are very long:

MySQL [information_schema]> select tidb_decode_key('748000000000001DFFB45F72CC00000002FF0A6CEA0000000000FA');
+---------------------------------------------------------------------------+
| tidb_decode_key('748000000000001DFFB45F72CC00000002FF0A6CEA0000000000FA') |
+---------------------------------------------------------------------------+
| {"_tidb_rowid":5476377146916760810,"table_id":"7604"}                     |
+---------------------------------------------------------------------------+
1 row in set (0.00 sec)

MySQL [information_schema]> select tidb_decode_key('7480000000000014FFC800000000000000F8');
+---------------------------------------------------------+
| tidb_decode_key('7480000000000014FFC800000000000000F8') |
+---------------------------------------------------------+
| 7480000000000014FFC800000000000000F8                    |
+---------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)
| username: lindoubled | Original post link

When inserting data normally, there will definitely be a rowid, right?

| username: h5n1 | Original post link

When inserting data normally, there is a rowid, but the region records the range of the region, i.e., start/end key. You can use curl http://tidbip:10080/mvcc/key/test/t11/2 to check the MVCC information of a specific row, which contains the KEY and can be parsed.

| username: lindoubled | Original post link

Indeed, it is possible. :smiley:

| username: system | Original post link

This topic will be automatically closed 60 days after the last reply. No new replies are allowed.