From 150e99d403f01a89adcc21cbfa3408a8a9d768d3 Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Thu, 20 Oct 2022 16:17:09 +0300 Subject: [PATCH] lib/{mergeset,storage}: avoid `unaligned 64-bit atomic operation` panic on 32-bit platforms The panic has been introduced in 68f3a025897ed8fb6170f41bbd5d879016b075a8 While at it, add padding to shard structs in order to avoid false sharing on mordern CPUs This should improve scalability on systems with many CPU cores --- lib/mergeset/table.go | 17 ++++++++++++++--- lib/storage/partition.go | 16 +++++++++++++--- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/lib/mergeset/table.go b/lib/mergeset/table.go index 043260961a..28e632dd05 100644 --- a/lib/mergeset/table.go +++ b/lib/mergeset/table.go @@ -10,6 +10,7 @@ import ( "sync" "sync/atomic" "time" + "unsafe" "github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil" "github.com/VictoriaMetrics/VictoriaMetrics/lib/cgroup" @@ -158,10 +159,20 @@ func (riss *rawItemsShards) Len() int { return n } -type rawItemsShard struct { - mu sync.Mutex - ibs []*inmemoryBlock +type rawItemsShardNopad struct { + // Put lastFlushTime to the top in order to avoid unaligned memory access on 32-bit architectures lastFlushTime uint64 + + mu sync.Mutex + ibs []*inmemoryBlock +} + +type rawItemsShard struct { + rawItemsShardNopad + + // The padding prevents false sharing on widespread platforms with + // 128 mod (cache line size) = 0 . + _ [128 - unsafe.Sizeof(rawItemsShardNopad{})%128]byte } func (ris *rawItemsShard) Len() int { diff --git a/lib/storage/partition.go b/lib/storage/partition.go index 85568ee95b..9345abe892 100644 --- a/lib/storage/partition.go +++ b/lib/storage/partition.go @@ -445,10 +445,20 @@ func (rrss *rawRowsShards) Len() int { return n } -type rawRowsShard struct { - mu sync.Mutex - rows []rawRow +type rawRowsShardNopad struct { + // Put lastFlushTime to the top in order to avoid unaligned memory access on 32-bit architectures lastFlushTime uint64 + + mu sync.Mutex + rows []rawRow +} + +type rawRowsShard struct { + rawRowsShardNopad + + // The padding prevents false sharing on widespread platforms with + // 128 mod (cache line size) = 0 . + _ [128 - unsafe.Sizeof(rawRowsShardNopad{})%128]byte } func (rrs *rawRowsShard) Len() int {