Skip to content

Commit 868456d

Browse files
authored
infoschema: refine info cache logic to reduce the impact of DDL on information schema cache (#48293)
1 parent 74df4d9 commit 868456d

File tree

2 files changed

+87
-6
lines changed

2 files changed

+87
-6
lines changed

infoschema/cache.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,16 @@ func (h *InfoCache) getSchemaByTimestampNoLock(ts uint64) (InfoSchema, bool) {
109109
// moreover, the most likely hit element in the array is the first one in steady mode
110110
// thus it may have better performance than binary search
111111
for i, is := range h.cache {
112-
if is.timestamp == 0 || (i > 0 && h.cache[i-1].infoschema.SchemaMetaVersion() != is.infoschema.SchemaMetaVersion()+1) {
113-
// the schema version doesn't have a timestamp or there is a gap in the schema cache
114-
// ignore all the schema cache equals or less than this version in search by timestamp
115-
break
112+
if is.timestamp == 0 || ts < uint64(is.timestamp) {
113+
continue
114+
}
115+
if i == 0 {
116+
return is.infoschema, true
116117
}
117-
if ts >= uint64(is.timestamp) {
118-
// found the largest version before the given ts
118+
if h.cache[i-1].infoschema.SchemaMetaVersion() == is.infoschema.SchemaMetaVersion()+1 && uint64(h.cache[i-1].timestamp) > ts {
119119
return is.infoschema, true
120120
}
121+
break
121122
}
122123

123124
logutil.BgLogger().Debug("SCHEMA CACHE no schema found")

infoschema/cache_test.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package infoschema_test
1616

1717
import (
18+
"fmt"
1819
"testing"
1920

2021
"github.com/pingcap/tidb/infoschema"
@@ -211,3 +212,82 @@ func TestReSize(t *testing.T) {
211212
require.Nil(t, ic.GetByVersion(3))
212213
require.Equal(t, is4, ic.GetByVersion(4))
213214
}
215+
216+
func TestCacheWithSchemaTsZero(t *testing.T) {
217+
ic := infoschema.NewCache(16)
218+
require.NotNil(t, ic)
219+
220+
for i := 1; i <= 8; i++ {
221+
ic.Insert(infoschema.MockInfoSchemaWithSchemaVer(nil, int64(i)), uint64(i))
222+
}
223+
224+
checkFn := func(start, end int64, exist bool) {
225+
require.True(t, start <= end)
226+
latestSchemaVersion := ic.GetLatest().SchemaMetaVersion()
227+
for ts := start; ts <= end; ts++ {
228+
is := ic.GetBySnapshotTS(uint64(ts))
229+
if exist {
230+
require.NotNil(t, is, fmt.Sprintf("ts %d", ts))
231+
if ts > latestSchemaVersion {
232+
require.Equal(t, latestSchemaVersion, is.SchemaMetaVersion(), fmt.Sprintf("ts %d", ts))
233+
} else {
234+
require.Equal(t, ts, is.SchemaMetaVersion(), fmt.Sprintf("ts %d", ts))
235+
}
236+
} else {
237+
require.Nil(t, is, fmt.Sprintf("ts %d", ts))
238+
}
239+
}
240+
}
241+
checkFn(1, 8, true)
242+
checkFn(8, 10, true)
243+
244+
// mock for meet error There is no Write MVCC info for the schema version
245+
ic.Insert(infoschema.MockInfoSchemaWithSchemaVer(nil, 9), 0)
246+
checkFn(1, 7, true)
247+
checkFn(8, 9, false)
248+
checkFn(9, 10, false)
249+
250+
for i := 10; i <= 16; i++ {
251+
ic.Insert(infoschema.MockInfoSchemaWithSchemaVer(nil, int64(i)), uint64(i))
252+
checkFn(1, 7, true)
253+
checkFn(8, 9, false)
254+
checkFn(10, 16, true)
255+
}
256+
require.Equal(t, 16, ic.Size())
257+
258+
// refill the cache
259+
ic.Insert(infoschema.MockInfoSchemaWithSchemaVer(nil, 9), 9)
260+
checkFn(1, 16, true)
261+
require.Equal(t, 16, ic.Size())
262+
263+
// Test more than capacity
264+
ic.Insert(infoschema.MockInfoSchemaWithSchemaVer(nil, 17), 17)
265+
checkFn(1, 1, false)
266+
checkFn(2, 17, true)
267+
checkFn(2, 20, true)
268+
require.Equal(t, 16, ic.Size())
269+
270+
// Test for there is a hole in the middle.
271+
ic = infoschema.NewCache(16)
272+
273+
// mock for restart with full load the latest version schema.
274+
ic.Insert(infoschema.MockInfoSchemaWithSchemaVer(nil, 100), 100)
275+
checkFn(1, 99, false)
276+
checkFn(100, 100, true)
277+
278+
for i := 1; i <= 16; i++ {
279+
ic.Insert(infoschema.MockInfoSchemaWithSchemaVer(nil, int64(i)), uint64(i))
280+
}
281+
checkFn(1, 1, false)
282+
checkFn(2, 15, true)
283+
checkFn(16, 16, false)
284+
checkFn(100, 100, true)
285+
require.Equal(t, 16, ic.Size())
286+
287+
for i := 85; i < 100; i++ {
288+
ic.Insert(infoschema.MockInfoSchemaWithSchemaVer(nil, int64(i)), uint64(i))
289+
}
290+
checkFn(1, 84, false)
291+
checkFn(85, 100, true)
292+
require.Equal(t, 16, ic.Size())
293+
}

0 commit comments

Comments
 (0)