tidb_decode_key解析不了key?

如上所示,貌似这种region与其它region不同,tidb_decode_key的时候报错:1105 invalid record/index key: 748000000000000B5A

什么版本,表结构什么样,show table xx regions结果

【 TiDB 使用环境】线上、测试、调研
【 TiDB 版本】
【遇到的问题】
【复现路径】做过哪些操作出现的问题
【问题现象及影响】

请按要求描述完整你的问题。

版本:5.3.0

表结构:

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)

表中的数据:

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    |
+----+------+

问题:

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                    |
+---------------------------------------------------------+

select schema,table_name from information_schema.tables where TIDB_TABLE_ID in (2907,2908,2909)。看下这几个表有吗。
目前t1表TABLE_ID: 2906,region的 END_KEY: t_2908_ 是一个其他的表,感觉2908这个表是被删除的。
tidb有个跨表合并参数 enable-cross-table-merge 要是测试环境可以试试将这个设置false 重启后然后看看t1的end key是多少?

2908有存在:

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 |
+---------------+--------------+---------------+

pd上面 enable-cross-table-merge 默认就是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
  }
}

这表的结构

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

最简单的复现方式:
1、创建一个表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

2、插入一条数据:

insert into t11(name) values('1')

3、查看t11的key范围:

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

4、用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)

估计bug,建议在5.3最新版上测试下

我测试了两套集群,结果都一样,不过貌似只有小表会有这个问题,即没有数据或者数据量很少的情况

image
估计是startkey/endkey中还没有_rowid导致无法解析出来,可以看一个带有rowid的start/end key ,tikv_region_status里的记录要比没有的长很多

没错,能解析出来的都是很长的key:

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)

正常插入数据的时候,肯定是会有rowid的?

正常插入数据是有rowid,但是region新里记录的是region的范围即start/end key,可以curl http://tidbip:10080/mvcc/key/test/t11/2 用这个查某行的mvcc信息,里面有KEY,可以解析

确实可以:smiley:

该主题在最后一个回复创建后60天后自动关闭。不再允许新的回复。