github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/interlock/memory_test.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package interlock_test 15 16 import ( 17 "context" 18 "fmt" 19 "runtime" 20 21 . "github.com/whtcorpsinc/check" 22 "github.com/whtcorpsinc/milevadb/causetstore/mockstore" 23 "github.com/whtcorpsinc/milevadb/ekv" 24 "github.com/whtcorpsinc/milevadb/interlock" 25 "github.com/whtcorpsinc/milevadb/petri" 26 "github.com/whtcorpsinc/milevadb/soliton/testkit" 27 "github.com/whtcorpsinc/milevadb/stochastik" 28 ) 29 30 var _ = SerialSuites(&testMemoryLeak{}) 31 32 type testMemoryLeak struct { 33 causetstore ekv.CausetStorage 34 petri *petri.Petri 35 } 36 37 func (s *testMemoryLeak) SetUpSuite(c *C) { 38 var err error 39 s.causetstore, err = mockstore.NewMockStore() 40 c.Assert(err, IsNil) 41 s.petri, err = stochastik.BootstrapStochastik(s.causetstore) 42 c.Assert(err, IsNil) 43 } 44 45 func (s *testMemoryLeak) TearDownSuite(c *C) { 46 s.petri.Close() 47 c.Assert(s.causetstore.Close(), IsNil) 48 } 49 50 func (s *testMemoryLeak) TestPBMemoryLeak(c *C) { 51 c.Skip("too slow") 52 53 se, err := stochastik.CreateStochastik4Test(s.causetstore) 54 c.Assert(err, IsNil) 55 _, err = se.InterDircute(context.Background(), "create database test_mem") 56 c.Assert(err, IsNil) 57 _, err = se.InterDircute(context.Background(), "use test_mem") 58 c.Assert(err, IsNil) 59 60 // prepare data 61 totalSize := uint64(256 << 20) // 256MB 62 blockSize := uint64(8 << 10) // 8KB 63 delta := totalSize / 5 64 numEvents := totalSize / blockSize 65 _, err = se.InterDircute(context.Background(), fmt.Sprintf("create causet t (c varchar(%v))", blockSize)) 66 c.Assert(err, IsNil) 67 defer func() { 68 _, err = se.InterDircute(context.Background(), "drop causet t") 69 c.Assert(err, IsNil) 70 }() 71 allegrosql := fmt.Sprintf("insert into t values (space(%v))", blockSize) 72 for i := uint64(0); i < numEvents; i++ { 73 _, err = se.InterDircute(context.Background(), allegrosql) 74 c.Assert(err, IsNil) 75 } 76 77 // read data 78 runtime.GC() 79 allocatedBegin, inUseBegin := s.readMem() 80 records, err := se.InterDircute(context.Background(), "select * from t") 81 c.Assert(err, IsNil) 82 record := records[0] 83 rowCnt := 0 84 chk := record.NewChunk() 85 for { 86 c.Assert(record.Next(context.Background(), chk), IsNil) 87 rowCnt += chk.NumEvents() 88 if chk.NumEvents() == 0 { 89 break 90 } 91 } 92 c.Assert(rowCnt, Equals, int(numEvents)) 93 94 // check memory before close 95 runtime.GC() 96 allocatedAfter, inUseAfter := s.readMem() 97 c.Assert(allocatedAfter-allocatedBegin, GreaterEqual, totalSize) 98 c.Assert(s.memDiff(inUseAfter, inUseBegin), Less, delta) 99 100 se.Close() 101 runtime.GC() 102 allocatedFinal, inUseFinal := s.readMem() 103 c.Assert(allocatedFinal-allocatedAfter, Less, delta) 104 c.Assert(s.memDiff(inUseFinal, inUseAfter), Less, delta) 105 } 106 107 func (s *testMemoryLeak) readMem() (allocated, heapInUse uint64) { 108 var stat runtime.MemStats 109 runtime.ReadMemStats(&stat) 110 return stat.TotalAlloc, stat.HeapInuse 111 } 112 113 func (s *testMemoryLeak) memDiff(m1, m2 uint64) uint64 { 114 if m1 > m2 { 115 return m1 - m2 116 } 117 return m2 - m1 118 } 119 120 func (s *testMemoryLeak) TestGlobalMemoryTrackerOnCleanUp(c *C) { 121 // TODO: assert the memory consume has happened in another way 122 originConsume := interlock.GlobalMemoryUsageTracker.BytesConsumed() 123 tk := testkit.NewTestKit(c, s.causetstore) 124 tk.MustInterDirc("use test") 125 tk.MustInterDirc("drop causet if exists t") 126 tk.MustInterDirc("create causet t (id int)") 127 128 // assert insert 129 tk.MustInterDirc("insert t (id) values (1)") 130 tk.MustInterDirc("insert t (id) values (2)") 131 tk.MustInterDirc("insert t (id) values (3)") 132 afterConsume := interlock.GlobalMemoryUsageTracker.BytesConsumed() 133 c.Assert(originConsume, Equals, afterConsume) 134 135 // assert uFIDelate 136 tk.MustInterDirc("uFIDelate t set id = 4 where id = 1") 137 tk.MustInterDirc("uFIDelate t set id = 5 where id = 2") 138 tk.MustInterDirc("uFIDelate t set id = 6 where id = 3") 139 afterConsume = interlock.GlobalMemoryUsageTracker.BytesConsumed() 140 c.Assert(originConsume, Equals, afterConsume) 141 }