github.com/ledgerwatch/erigon-lib@v1.0.0/common/dbg/experiments.go (about) 1 /* 2 Copyright 2021 Erigon contributors 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package dbg 18 19 import ( 20 "os" 21 "runtime" 22 "strconv" 23 "sync" 24 "time" 25 26 "github.com/ledgerwatch/log/v3" 27 ) 28 29 var doMemstat = true 30 31 func init() { 32 _, ok := os.LookupEnv("NO_MEMSTAT") 33 if ok { 34 doMemstat = false 35 } 36 } 37 38 func DoMemStat() bool { return doMemstat } 39 func ReadMemStats(m *runtime.MemStats) { 40 if doMemstat { 41 runtime.ReadMemStats(m) 42 } 43 } 44 45 var ( 46 writeMap bool 47 writeMapOnce sync.Once 48 ) 49 50 func WriteMap() bool { 51 writeMapOnce.Do(func() { 52 v, _ := os.LookupEnv("WRITE_MAP") 53 if v == "true" { 54 writeMap = true 55 log.Info("[Experiment]", "WRITE_MAP", writeMap) 56 } 57 }) 58 return writeMap 59 } 60 61 var ( 62 dirtySace uint64 63 dirtySaceOnce sync.Once 64 ) 65 66 func DirtySpace() uint64 { 67 dirtySaceOnce.Do(func() { 68 v, _ := os.LookupEnv("MDBX_DIRTY_SPACE_MB") 69 if v != "" { 70 i, err := strconv.Atoi(v) 71 if err != nil { 72 panic(err) 73 } 74 dirtySace = uint64(i * 1024 * 1024) 75 log.Info("[Experiment]", "MDBX_DIRTY_SPACE_MB", dirtySace) 76 } 77 }) 78 return dirtySace 79 } 80 81 var ( 82 noSync bool 83 noSyncOnce sync.Once 84 ) 85 86 func NoSync() bool { 87 noSyncOnce.Do(func() { 88 v, _ := os.LookupEnv("NO_SYNC") 89 if v == "true" { 90 noSync = true 91 log.Info("[Experiment]", "NO_SYNC", noSync) 92 } 93 }) 94 return noSync 95 } 96 97 var ( 98 mergeTr int 99 mergeTrOnce sync.Once 100 ) 101 102 func MergeTr() int { 103 mergeTrOnce.Do(func() { 104 v, _ := os.LookupEnv("MERGE_THRESHOLD") 105 if v != "" { 106 i, err := strconv.Atoi(v) 107 if err != nil { 108 panic(err) 109 } 110 if i < 0 || i > 4 { 111 panic(i) 112 } 113 mergeTr = i 114 log.Info("[Experiment]", "MERGE_THRESHOLD", mergeTr) 115 } 116 }) 117 return mergeTr 118 } 119 120 var ( 121 mdbxReadahead bool 122 mdbxReadaheadOnce sync.Once 123 ) 124 125 func MdbxReadAhead() bool { 126 mdbxReadaheadOnce.Do(func() { 127 v, _ := os.LookupEnv("MDBX_READAHEAD") 128 if v == "true" { 129 mdbxReadahead = true 130 log.Info("[Experiment]", "MDBX_READAHEAD", mdbxReadahead) 131 } 132 }) 133 return mdbxReadahead 134 } 135 136 var ( 137 discardHistory bool 138 discardHistoryOnce sync.Once 139 ) 140 141 func DiscardHistory() bool { 142 discardHistoryOnce.Do(func() { 143 v, _ := os.LookupEnv("DISCARD_HISTORY") 144 if v == "true" { 145 discardHistory = true 146 log.Info("[Experiment]", "DISCARD_HISTORY", discardHistory) 147 } 148 }) 149 return discardHistory 150 } 151 152 var ( 153 bigRoTx uint 154 getBigRoTx sync.Once 155 ) 156 157 // DEBUG_BIG_RO_TX_KB - print logs with info about large read-only transactions 158 // DEBUG_BIG_RW_TX_KB - print logs with info about large read-write transactions 159 // DEBUG_SLOW_COMMIT_MS - print logs with commit timing details if commit is slower than this threshold 160 func BigRoTxKb() uint { 161 getBigRoTx.Do(func() { 162 v, _ := os.LookupEnv("DEBUG_BIG_RO_TX_KB") 163 if v != "" { 164 i, err := strconv.Atoi(v) 165 if err != nil { 166 panic(err) 167 } 168 bigRoTx = uint(i) 169 log.Info("[Experiment]", "DEBUG_BIG_RO_TX_KB", bigRoTx) 170 } 171 }) 172 return bigRoTx 173 } 174 175 var ( 176 bigRwTx uint 177 getBigRwTx sync.Once 178 ) 179 180 func BigRwTxKb() uint { 181 getBigRwTx.Do(func() { 182 v, _ := os.LookupEnv("DEBUG_BIG_RW_TX_KB") 183 if v != "" { 184 i, err := strconv.Atoi(v) 185 if err != nil { 186 panic(err) 187 } 188 bigRwTx = uint(i) 189 log.Info("[Experiment]", "DEBUG_BIG_RW_TX_KB", bigRwTx) 190 } 191 }) 192 return bigRwTx 193 } 194 195 var ( 196 slowCommit time.Duration 197 slowCommitOnce sync.Once 198 ) 199 200 func SlowCommit() time.Duration { 201 slowCommitOnce.Do(func() { 202 v, _ := os.LookupEnv("SLOW_COMMIT") 203 if v != "" { 204 var err error 205 slowCommit, err = time.ParseDuration(v) 206 if err != nil { 207 panic(err) 208 } 209 log.Info("[Experiment]", "SLOW_COMMIT", slowCommit.String()) 210 } 211 }) 212 return slowCommit 213 } 214 215 var ( 216 slowTx time.Duration 217 slowTxOnce sync.Once 218 ) 219 220 func SlowTx() time.Duration { 221 slowTxOnce.Do(func() { 222 v, _ := os.LookupEnv("SLOW_TX") 223 if v != "" { 224 var err error 225 slowTx, err = time.ParseDuration(v) 226 if err != nil { 227 panic(err) 228 } 229 log.Info("[Experiment]", "SLOW_TX", slowTx.String()) 230 } 231 }) 232 return slowTx 233 } 234 235 var ( 236 stopBeforeStage string 237 stopBeforeStageFlag sync.Once 238 stopAfterStage string 239 stopAfterStageFlag sync.Once 240 ) 241 242 func StopBeforeStage() string { 243 f := func() { 244 v, _ := os.LookupEnv("STOP_BEFORE_STAGE") // see names in eth/stagedsync/stages/stages.go 245 if v != "" { 246 stopBeforeStage = v 247 log.Info("[Experiment]", "STOP_BEFORE_STAGE", stopBeforeStage) 248 } 249 } 250 stopBeforeStageFlag.Do(f) 251 return stopBeforeStage 252 } 253 254 // TODO(allada) We should possibly consider removing `STOP_BEFORE_STAGE`, as `STOP_AFTER_STAGE` can 255 // perform all same the functionality, but due to reverse compatibility reasons we are going to 256 // leave it. 257 func StopAfterStage() string { 258 f := func() { 259 v, _ := os.LookupEnv("STOP_AFTER_STAGE") // see names in eth/stagedsync/stages/stages.go 260 if v != "" { 261 stopAfterStage = v 262 log.Info("[Experiment]", "STOP_AFTER_STAGE", stopAfterStage) 263 } 264 } 265 stopAfterStageFlag.Do(f) 266 return stopAfterStage 267 } 268 269 var ( 270 stopAfterReconst bool 271 stopAfterReconstOnce sync.Once 272 ) 273 274 func StopAfterReconst() bool { 275 stopAfterReconstOnce.Do(func() { 276 v, _ := os.LookupEnv("STOP_AFTER_RECONSTITUTE") 277 if v == "true" { 278 stopAfterReconst = true 279 log.Info("[Experiment]", "STOP_AFTER_RECONSTITUTE", writeMap) 280 } 281 }) 282 return stopAfterReconst 283 }