Fix panic in ARM builds of Prometheus (#6110)

An extra sync.Pool was added during a refactor which caused some 64 bit,
atomically accessed variables to no longer be 64 bit aligned. By moving
all atomically accessed variables to the beginning of the struct they
are guaranteed to be 64 bit aligned.

Signed-off-by: Chris Marchbanks <csmarchbanks@gmail.com>
This commit is contained in:
Chris Marchbanks 2019-10-09 07:52:29 -06:00 committed by Krasi Georgiev
parent 6ea4252299
commit 6970f725c9
4 changed files with 21 additions and 13 deletions

View file

@ -21,12 +21,15 @@ import (
// ewmaRate tracks an exponentially weighted moving average of a per-second rate. // ewmaRate tracks an exponentially weighted moving average of a per-second rate.
type ewmaRate struct { type ewmaRate struct {
// Keep all 64bit atomically accessed variables at the top of this struct.
// See https://golang.org/pkg/sync/atomic/#pkg-note-BUG for more info.
newEvents int64 newEvents int64
alpha float64
interval time.Duration alpha float64
lastRate float64 interval time.Duration
init bool lastRate float64
mutex sync.Mutex init bool
mutex sync.Mutex
} }
// newEWMARate always allocates a new ewmaRate, as this guarantees the atomically // newEWMARate always allocates a new ewmaRate, as this guarantees the atomically

View file

@ -40,8 +40,11 @@ type pool struct {
} }
type entry struct { type entry struct {
s string // Keep all 64bit atomically accessed variables at the top of this struct.
// See https://golang.org/pkg/sync/atomic/#pkg-note-BUG for more info.
refs int64 refs int64
s string
} }
func newPool() *pool { func newPool() *pool {

View file

@ -216,7 +216,7 @@ func newDBMetrics(db *DB, r prometheus.Registerer) *dbMetrics {
db.mtx.RLock() db.mtx.RLock()
defer db.mtx.RUnlock() defer db.mtx.RUnlock()
if len(db.blocks) == 0 { if len(db.blocks) == 0 {
return float64(db.head.minTime) return float64(db.head.MinTime())
} }
return float64(db.blocks[0].meta.MinTime) return float64(db.blocks[0].meta.MinTime)
}) })

View file

@ -61,18 +61,20 @@ var (
// Head handles reads and writes of time series data within a time window. // Head handles reads and writes of time series data within a time window.
type Head struct { type Head struct {
chunkRange int64 // Keep all 64bit atomically accessed variables at the top of this struct.
// See https://golang.org/pkg/sync/atomic/#pkg-note-BUG for more info.
chunkRange int64
numSeries uint64
minTime, maxTime int64 // Current min and max of the samples included in the head.
minValidTime int64 // Mint allowed to be added to the head. It shouldn't be lower than the maxt of the last persisted block.
lastSeriesID uint64
metrics *headMetrics metrics *headMetrics
wal *wal.WAL wal *wal.WAL
logger log.Logger logger log.Logger
appendPool sync.Pool appendPool sync.Pool
seriesPool sync.Pool seriesPool sync.Pool
bytesPool sync.Pool bytesPool sync.Pool
numSeries uint64
minTime, maxTime int64 // Current min and max of the samples included in the head.
minValidTime int64 // Mint allowed to be added to the head. It shouldn't be lower than the maxt of the last persisted block.
lastSeriesID uint64
// All series addressable by their ID or hash. // All series addressable by their ID or hash.
series *stripeSeries series *stripeSeries