|
|
@@ -550,6 +550,26 @@ func (im *IndexMetaPage) saveMeta(m *IndexMeta) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// rowStoreInsertKey 行存储索引的定位键:
|
|
|
+//
|
|
|
+// - 主键 B+ 树: 恒为 pkID(BE)。查询/删除/更新侧一律按 pkID 定位, 与镜像列
|
|
|
+// 的存储编码无关 —— 旧实现统一走 extractIndexKey (取镜像列字节), 镜像列是
|
|
|
+// Int64 等带 sort-key 编码的类型时, 树键与 pkID-BE 不一致: 按 pkID 查找
|
|
|
+// 退化成全叶扫描, 删除/更新按错键静默失效 (ErrNotFound 按索引逐个吞掉)。
|
|
|
+// Uint64 镜像因"存储字节==BE"而侥幸正确, 掩盖了这条错位。
|
|
|
+// - 时序索引: 键 = 时间分量 (extractIndexKey); 其顺序断言/分段路由都在同一
|
|
|
+// 编码内自洽 (sort-key 保序), 维持原样。
|
|
|
+//
|
|
|
+// 插入/删除/更新三侧必须用同一键源, 否则写进树里的键和去树里找的键对不上。
|
|
|
+func rowStoreInsertKey(meta *IndexMeta, pkID uint64, rowData []byte, fields []types.FieldInfo, versions []SchemaVersion) []byte {
|
|
|
+ if meta.IndexType == page.IndexTypePrimary {
|
|
|
+ key := make([]byte, 8)
|
|
|
+ binary.BigEndian.PutUint64(key, pkID)
|
|
|
+ return key
|
|
|
+ }
|
|
|
+ return extractIndexKey(rowData, meta, fields, versions)
|
|
|
+}
|
|
|
+
|
|
|
// extractIndexKey 从行数据中提取索引键 (版本感知)
|
|
|
// rowData 格式 (v9): [schemaVer 1B][列0 W0 B][列结束偏移表 2N][列1..N-1 内容][NULL 位图]
|
|
|
//
|
|
|
@@ -655,6 +675,9 @@ func (im *IndexMetaPage) InsertRow(fields []types.FieldInfo, pkID uint64, rowDat
|
|
|
for _, ri := range indexes {
|
|
|
m := ri.meta
|
|
|
indexKey := extractIndexKey(rowData, m, fields, versions)
|
|
|
+ if indexStoresRows(m) {
|
|
|
+ indexKey = rowStoreInsertKey(m, pkID, rowData, fields, versions)
|
|
|
+ }
|
|
|
if indexKey == nil {
|
|
|
continue
|
|
|
}
|
|
|
@@ -730,9 +753,15 @@ func (im *IndexMetaPage) InsertRows(fields []types.FieldInfo, pkIDs []uint64, ro
|
|
|
if bi, ok := ri.handler.(index.BatchInserter); ok {
|
|
|
rows := make([]index.BatchRow, len(rowDatas))
|
|
|
for i := range rowDatas {
|
|
|
+ var ik []byte
|
|
|
+ if indexStoresRows(m) {
|
|
|
+ ik = rowStoreInsertKey(m, pkIDs[i], rowDatas[i], fields, versions)
|
|
|
+ } else {
|
|
|
+ ik = extractIndexKey(rowDatas[i], m, fields, versions)
|
|
|
+ }
|
|
|
rows[i] = index.BatchRow{
|
|
|
PKID: pkIDs[i],
|
|
|
- IndexKey: extractIndexKey(rowDatas[i], m, fields, versions),
|
|
|
+ IndexKey: ik,
|
|
|
RowData: rowDatas[i],
|
|
|
}
|
|
|
}
|
|
|
@@ -740,6 +769,9 @@ func (im *IndexMetaPage) InsertRows(fields []types.FieldInfo, pkIDs []uint64, ro
|
|
|
} else {
|
|
|
for i := range rowDatas {
|
|
|
indexKey := extractIndexKey(rowDatas[i], m, fields, versions)
|
|
|
+ if indexStoresRows(m) {
|
|
|
+ indexKey = rowStoreInsertKey(m, pkIDs[i], rowDatas[i], fields, versions)
|
|
|
+ }
|
|
|
if indexKey == nil {
|
|
|
continue
|
|
|
}
|
|
|
@@ -986,6 +1018,9 @@ func (im *IndexMetaPage) DeleteByKey(idxName string, indexKey []byte, storeRow [
|
|
|
for _, ri := range im.resolveIndexes() {
|
|
|
m := ri.meta
|
|
|
key := extractIndexKey(rowData, m, fields, versions)
|
|
|
+ if indexStoresRows(m) {
|
|
|
+ key = rowStoreInsertKey(m, pkID, rowData, fields, versions)
|
|
|
+ }
|
|
|
if len(key) == 0 {
|
|
|
if m != meta {
|
|
|
continue // 取不到行数据, 无法推导该索引键, 跳过
|
|
|
@@ -1043,11 +1078,18 @@ func (im *IndexMetaPage) UpdateByKey(indexKey []byte, newRowData []byte, pkID ui
|
|
|
oldKey := indexKey
|
|
|
oldKeyFromRow := false
|
|
|
if oldRowData != nil {
|
|
|
- if k := extractIndexKey(oldRowData, m, fields, versions); len(k) > 0 {
|
|
|
+ if indexStoresRows(m) {
|
|
|
+ if k := rowStoreInsertKey(m, pkID, oldRowData, fields, versions); len(k) > 0 {
|
|
|
+ oldKey, oldKeyFromRow = k, true
|
|
|
+ }
|
|
|
+ } else if k := extractIndexKey(oldRowData, m, fields, versions); len(k) > 0 {
|
|
|
oldKey, oldKeyFromRow = k, true
|
|
|
}
|
|
|
}
|
|
|
newKey := extractIndexKey(newRowData, m, fields, versions)
|
|
|
+ if indexStoresRows(m) {
|
|
|
+ newKey = rowStoreInsertKey(m, pkID, newRowData, fields, versions)
|
|
|
+ }
|
|
|
|
|
|
entryPage := m.EntryPage
|
|
|
var err error
|