DecodeKey decodes `key` (either a Record key or an Index key) into `DecodedKey`, which is used to fill KEY_INFO field in `DEADLOCKS` and `DATA_LOCK_WAITS`
(key []byte, is infoschema.InfoSchema)
| 72 | |
| 73 | // DecodeKey decodes `key` (either a Record key or an Index key) into `DecodedKey`, which is used to fill KEY_INFO field in `DEADLOCKS` and `DATA_LOCK_WAITS` |
| 74 | func DecodeKey(key []byte, is infoschema.InfoSchema) (DecodedKey, error) { |
| 75 | var result DecodedKey |
| 76 | if !tablecodec.IsRecordKey(key) && !tablecodec.IsIndexKey(key) { |
| 77 | return result, errors.Errorf("Unknown key type for key %v", key) |
| 78 | } |
| 79 | tableOrPartitionID, indexID, isRecordKey, err := tablecodec.DecodeKeyHead(key) |
| 80 | if err != nil { |
| 81 | return result, err |
| 82 | } |
| 83 | result.TableID = tableOrPartitionID |
| 84 | |
| 85 | table, tableFound := is.TableByID(context.Background(), tableOrPartitionID) |
| 86 | |
| 87 | // The schema may have changed since when the key is get. |
| 88 | // Then we just omit the table name and show the table ID only. |
| 89 | // Otherwise, we can show the table name and table ID. |
| 90 | if tableFound { |
| 91 | result.TableName = table.Meta().Name.O |
| 92 | |
| 93 | schema, ok := infoschema.SchemaByTable(is, table.Meta()) |
| 94 | if !ok { |
| 95 | logutil.BgLogger().Warn("no schema associated with table found in infoschema", zap.Int64("tableOrPartitionID", tableOrPartitionID)) |
| 96 | return result, nil |
| 97 | } |
| 98 | result.DbID = schema.ID |
| 99 | result.DbName = schema.Name.O |
| 100 | } else { |
| 101 | // If the table of this ID is not found, try to find it as a partition. |
| 102 | var schema *model.DBInfo |
| 103 | var partition *model.PartitionDefinition |
| 104 | table, schema, partition = is.FindTableByPartitionID(tableOrPartitionID) |
| 105 | if table != nil { |
| 106 | tableFound = true |
| 107 | result.TableID = table.Meta().ID |
| 108 | result.TableName = table.Meta().Name.O |
| 109 | } |
| 110 | if schema != nil { |
| 111 | result.DbID = schema.ID |
| 112 | result.DbName = schema.Name.O |
| 113 | } |
| 114 | if partition != nil { |
| 115 | result.PartitionID = partition.ID |
| 116 | result.PartitionName = partition.Name.O |
| 117 | } |
| 118 | if !tableFound { |
| 119 | logutil.BgLogger().Warn("no table found in infoschema", zap.Int64("tableOrPartitionID", tableOrPartitionID)) |
| 120 | } |
| 121 | } |
| 122 | if isRecordKey { |
| 123 | _, handle, err := tablecodec.DecodeRecordKey(key) |
| 124 | if err != nil { |
| 125 | logutil.BgLogger().Warn("decode record key failed", zap.Int64("tableOrPartitionID", tableOrPartitionID), zap.Error(err)) |
| 126 | return result, errors.Errorf("cannot decode record key of table %d", tableOrPartitionID) |
| 127 | } |
| 128 | result.HandleType = handleType(handle) |
| 129 | // The PartitionHandle is used by the Global Index feature for partition tables, which is currently an |
| 130 | // unfinished feature. So we don't care about it much for now. |
| 131 | _, result.IsPartitionHandle = handle.(kv.PartitionHandle) |