mirror of
https://github.com/Buriburizaem0n/nezha_domains.git
synced 2026-11-04 16:40:21 +00:00
fix(tsdb): survive low disk space
This commit is contained in:
1 parent
1155c17573
commit
06d387779d
6 files changed
+341
-14
No files matched your search
@@ -0,0 +1,124 @@
|
||||
package tsdb
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/storage"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type testReadOnlyChecker struct {
|
||||
value atomic.Bool
|
||||
}
|
||||
|
||||
func (c *testReadOnlyChecker) IsReadOnly() bool {
|
||||
return c.value.Load()
|
||||
}
|
||||
|
||||
func newDiskGuardTestDB(t *testing.T) *TSDB {
|
||||
t.Helper()
|
||||
db, err := Open(&Config{
|
||||
DataPath: filepath.Join(t.TempDir(), "tsdb"),
|
||||
RetentionDays: 1,
|
||||
MinFreeDiskSpaceGB: 1,
|
||||
DedupInterval: time.Second,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() { require.NoError(t, db.Close()) })
|
||||
return db
|
||||
}
|
||||
|
||||
func bufferedRows(w *bufferedWriter) int {
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
return len(w.buffer)
|
||||
}
|
||||
|
||||
func TestReadOnlyStorageDropsWritesAndKeepsQueriesAvailable(t *testing.T) {
|
||||
db := newDiskGuardTestDB(t)
|
||||
checker := &testReadOnlyChecker{}
|
||||
db.readOnly = checker
|
||||
originalAddRows := db.addRowsFn
|
||||
var addRowsCalls atomic.Int32
|
||||
db.addRowsFn = func(rows []storage.MetricRow, precisionBits uint8) {
|
||||
addRowsCalls.Add(1)
|
||||
originalAddRows(rows, precisionBits)
|
||||
}
|
||||
|
||||
firstTimestamp := time.Now().Add(-time.Minute)
|
||||
require.NoError(t, db.WriteServerMetrics(&ServerMetrics{
|
||||
ServerID: 1,
|
||||
Timestamp: firstTimestamp,
|
||||
CPU: 10,
|
||||
}))
|
||||
db.Flush()
|
||||
require.Equal(t, int32(1), addRowsCalls.Load())
|
||||
|
||||
before, err := db.QueryServerMetrics(1, MetricServerCPU, Period1Day)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, before)
|
||||
|
||||
checker.value.Store(true)
|
||||
require.NoError(t, db.WriteServerMetrics(&ServerMetrics{
|
||||
ServerID: 1,
|
||||
Timestamp: firstTimestamp.Add(2 * time.Second),
|
||||
CPU: 20,
|
||||
}))
|
||||
assert.True(t, db.WritesPaused())
|
||||
assert.Zero(t, bufferedRows(db.writer), "read-only writes must not accumulate in memory")
|
||||
assert.Equal(t, int32(1), addRowsCalls.Load(), "read-only samples must not reach VictoriaMetrics")
|
||||
|
||||
afterDrop, err := db.QueryServerMetrics(1, MetricServerCPU, Period1Day)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, before, afterDrop, "read-only mode must preserve existing query access")
|
||||
|
||||
checker.value.Store(false)
|
||||
require.NoError(t, db.WriteServerMetrics(&ServerMetrics{
|
||||
ServerID: 1,
|
||||
Timestamp: firstTimestamp.Add(4 * time.Second),
|
||||
CPU: 30,
|
||||
}))
|
||||
db.Flush()
|
||||
assert.False(t, db.WritesPaused())
|
||||
assert.Equal(t, int32(2), addRowsCalls.Load(), "writes must resume after storage leaves read-only mode")
|
||||
}
|
||||
|
||||
func TestDiskFullAddRowsPanicPausesWrites(t *testing.T) {
|
||||
db := newDiskGuardTestDB(t)
|
||||
db.addRowsFn = func([]storage.MetricRow, uint8) {
|
||||
panic("write data: no space left on device")
|
||||
}
|
||||
|
||||
require.NoError(t, db.WriteServerMetrics(&ServerMetrics{
|
||||
ServerID: 1,
|
||||
Timestamp: time.Now(),
|
||||
CPU: 10,
|
||||
}))
|
||||
assert.NotPanics(t, db.Flush)
|
||||
assert.True(t, db.WritesPaused())
|
||||
|
||||
require.NoError(t, db.WriteServerMetrics(&ServerMetrics{
|
||||
ServerID: 1,
|
||||
Timestamp: time.Now().Add(time.Second),
|
||||
CPU: 20,
|
||||
}))
|
||||
assert.Zero(t, bufferedRows(db.writer))
|
||||
}
|
||||
|
||||
func TestNonDiskStoragePanicIsNotHidden(t *testing.T) {
|
||||
db := newDiskGuardTestDB(t)
|
||||
db.addRowsFn = func([]storage.MetricRow, uint8) {
|
||||
panic("storage invariant failed")
|
||||
}
|
||||
|
||||
require.NoError(t, db.WriteServerMetrics(&ServerMetrics{
|
||||
ServerID: 1,
|
||||
Timestamp: time.Now(),
|
||||
CPU: 10,
|
||||
}))
|
||||
assert.PanicsWithValue(t, "storage invariant failed", db.Flush)
|
||||
}
|
||||
Reference in new issue
Block a user