fix(inputs.mongodb): SIGSEGV when restarting MongoDB node (#12604)

This commit is contained in:
Dmitry Khamitov 2023-02-03 09:12:16 +00:00 committed by GitHub
parent d137d97ed0
commit e466cab0c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 418 additions and 5 deletions

View File

@ -1222,16 +1222,18 @@ func NewStatLine(oldMongo, newMongo MongoStatus, key string, all bool, sampleSec
oldStat.ExtraInfo.PageFaults != nil && newStat.ExtraInfo.PageFaults != nil {
returnVal.Faults, returnVal.FaultsCnt = diff(*(newStat.ExtraInfo.PageFaults), *(oldStat.ExtraInfo.PageFaults), sampleSecs)
}
if !returnVal.IsMongos && oldStat.Locks != nil {
globalCheck, hasGlobal := oldStat.Locks["Global"]
if hasGlobal && globalCheck.AcquireCount != nil {
if !returnVal.IsMongos && oldStat.Locks != nil && newStat.Locks != nil {
globalCheckOld, hasGlobalOld := oldStat.Locks["Global"]
globalCheckNew, hasGlobalNew := newStat.Locks["Global"]
if hasGlobalOld && globalCheckOld.AcquireCount != nil && hasGlobalNew && globalCheckNew.AcquireCount != nil {
// This appears to be a 3.0+ server so the data in these fields do *not* refer to
// actual namespaces and thus we can't compute lock %.
returnVal.HighestLocked = nil
// Check if it's a 3.0+ MMAP server so we can still compute collection locks
collectionCheck, hasCollection := oldStat.Locks["Collection"]
if hasCollection && collectionCheck.AcquireWaitCount != nil {
collectionCheckOld, hasCollectionOld := oldStat.Locks["Collection"]
collectionCheckNew, hasCollectionNew := newStat.Locks["Collection"]
if hasCollectionOld && collectionCheckOld.AcquireWaitCount != nil && hasCollectionNew && collectionCheckNew.AcquireWaitCount != nil {
readWaitCountDiff := newStat.Locks["Collection"].AcquireWaitCount.Read - oldStat.Locks["Collection"].AcquireWaitCount.Read
readTotalCountDiff := newStat.Locks["Collection"].AcquireCount.Read - oldStat.Locks["Collection"].AcquireCount.Read
writeWaitCountDiff := newStat.Locks["Collection"].AcquireWaitCount.Write - oldStat.Locks["Collection"].AcquireWaitCount.Write

View File

@ -198,3 +198,414 @@ func TestLatencyStatsDiff(t *testing.T) {
require.Equal(t, sl.ReadOpsCnt, int64(4189049884))
require.Equal(t, sl.WriteOpsCnt, int64(1691021287))
}
func TestLocksStatsNilWhenLocksMissingInOldStat(t *testing.T) {
sl := NewStatLine(
MongoStatus{
ServerStatus: &ServerStatus{
Connections: &ConnectionStats{},
Mem: &MemStats{
Supported: false,
},
},
},
MongoStatus{
ServerStatus: &ServerStatus{
Connections: &ConnectionStats{},
Mem: &MemStats{
Supported: false,
},
Locks: map[string]LockStats{
"Global": {
AcquireCount: &ReadWriteLockTimes{},
},
},
},
},
"foo",
true,
60,
)
require.Nil(t, sl.CollectionLocks)
}
func TestLocksStatsNilWhenGlobalLockStatsMissingInOldStat(t *testing.T) {
sl := NewStatLine(
MongoStatus{
ServerStatus: &ServerStatus{
Connections: &ConnectionStats{},
Mem: &MemStats{
Supported: false,
},
Locks: map[string]LockStats{},
},
},
MongoStatus{
ServerStatus: &ServerStatus{
Connections: &ConnectionStats{},
Mem: &MemStats{
Supported: false,
},
Locks: map[string]LockStats{
"Global": {
AcquireCount: &ReadWriteLockTimes{},
},
},
},
},
"foo",
true,
60,
)
require.Nil(t, sl.CollectionLocks)
}
func TestLocksStatsNilWhenGlobalLockStatsEmptyInOldStat(t *testing.T) {
sl := NewStatLine(
MongoStatus{
ServerStatus: &ServerStatus{
Connections: &ConnectionStats{},
Mem: &MemStats{
Supported: false,
},
Locks: map[string]LockStats{
"Global": {},
},
},
},
MongoStatus{
ServerStatus: &ServerStatus{
Connections: &ConnectionStats{},
Mem: &MemStats{
Supported: false,
},
Locks: map[string]LockStats{
"Global": {
AcquireCount: &ReadWriteLockTimes{},
},
},
},
},
"foo",
true,
60,
)
require.Nil(t, sl.CollectionLocks)
}
func TestLocksStatsNilWhenCollectionLockStatsMissingInOldStat(t *testing.T) {
sl := NewStatLine(
MongoStatus{
ServerStatus: &ServerStatus{
Connections: &ConnectionStats{},
Mem: &MemStats{
Supported: false,
},
Locks: map[string]LockStats{
"Global": {
AcquireCount: &ReadWriteLockTimes{},
},
},
},
},
MongoStatus{
ServerStatus: &ServerStatus{
Connections: &ConnectionStats{},
Mem: &MemStats{
Supported: false,
},
Locks: map[string]LockStats{
"Global": {
AcquireCount: &ReadWriteLockTimes{},
},
},
},
},
"foo",
true,
60,
)
require.Nil(t, sl.CollectionLocks)
}
func TestLocksStatsNilWhenCollectionLockStatsEmptyInOldStat(t *testing.T) {
sl := NewStatLine(
MongoStatus{
ServerStatus: &ServerStatus{
Connections: &ConnectionStats{},
Mem: &MemStats{
Supported: false,
},
Locks: map[string]LockStats{
"Global": {
AcquireCount: &ReadWriteLockTimes{},
},
"Collection": {},
},
},
},
MongoStatus{
ServerStatus: &ServerStatus{
Connections: &ConnectionStats{},
Mem: &MemStats{
Supported: false,
},
Locks: map[string]LockStats{
"Global": {
AcquireCount: &ReadWriteLockTimes{},
},
},
},
},
"foo",
true,
60,
)
require.Nil(t, sl.CollectionLocks)
}
func TestLocksStatsNilWhenLocksMissingInNewStat(t *testing.T) {
sl := NewStatLine(
MongoStatus{
ServerStatus: &ServerStatus{
Connections: &ConnectionStats{},
Mem: &MemStats{
Supported: false,
},
Locks: map[string]LockStats{
"Global": {
AcquireCount: &ReadWriteLockTimes{},
},
},
},
},
MongoStatus{
ServerStatus: &ServerStatus{
Connections: &ConnectionStats{},
Mem: &MemStats{
Supported: false,
},
},
},
"foo",
true,
60,
)
require.Nil(t, sl.CollectionLocks)
}
func TestLocksStatsNilWhenGlobalLockStatsMissingInNewStat(t *testing.T) {
sl := NewStatLine(
MongoStatus{
ServerStatus: &ServerStatus{
Connections: &ConnectionStats{},
Mem: &MemStats{
Supported: false,
},
Locks: map[string]LockStats{
"Global": {
AcquireCount: &ReadWriteLockTimes{},
},
},
},
},
MongoStatus{
ServerStatus: &ServerStatus{
Connections: &ConnectionStats{},
Mem: &MemStats{
Supported: false,
},
Locks: map[string]LockStats{},
},
},
"foo",
true,
60,
)
require.Nil(t, sl.CollectionLocks)
}
func TestLocksStatsNilWhenGlobalLockStatsEmptyInNewStat(t *testing.T) {
sl := NewStatLine(
MongoStatus{
ServerStatus: &ServerStatus{
Connections: &ConnectionStats{},
Mem: &MemStats{
Supported: false,
},
Locks: map[string]LockStats{
"Global": {
AcquireCount: &ReadWriteLockTimes{},
},
},
},
},
MongoStatus{
ServerStatus: &ServerStatus{
Connections: &ConnectionStats{},
Mem: &MemStats{
Supported: false,
},
Locks: map[string]LockStats{
"Global": {},
},
},
},
"foo",
true,
60,
)
require.Nil(t, sl.CollectionLocks)
}
func TestLocksStatsNilWhenCollectionLockStatsMissingInNewStat(t *testing.T) {
sl := NewStatLine(
MongoStatus{
ServerStatus: &ServerStatus{
Connections: &ConnectionStats{},
Mem: &MemStats{
Supported: false,
},
Locks: map[string]LockStats{
"Global": {
AcquireCount: &ReadWriteLockTimes{},
},
},
},
},
MongoStatus{
ServerStatus: &ServerStatus{
Connections: &ConnectionStats{},
Mem: &MemStats{
Supported: false,
},
Locks: map[string]LockStats{
"Global": {
AcquireCount: &ReadWriteLockTimes{},
},
},
},
},
"foo",
true,
60,
)
require.Nil(t, sl.CollectionLocks)
}
func TestLocksStatsNilWhenCollectionLockStatsEmptyInNewStat(t *testing.T) {
sl := NewStatLine(
MongoStatus{
ServerStatus: &ServerStatus{
Connections: &ConnectionStats{},
Mem: &MemStats{
Supported: false,
},
Locks: map[string]LockStats{
"Global": {
AcquireCount: &ReadWriteLockTimes{},
},
},
},
},
MongoStatus{
ServerStatus: &ServerStatus{
Connections: &ConnectionStats{},
Mem: &MemStats{
Supported: false,
},
Locks: map[string]LockStats{
"Global": {
AcquireCount: &ReadWriteLockTimes{},
},
"Collection": {},
},
},
},
"foo",
true,
60,
)
require.Nil(t, sl.CollectionLocks)
}
func TestLocksStatsPopulated(t *testing.T) {
sl := NewStatLine(
MongoStatus{
ServerStatus: &ServerStatus{
Connections: &ConnectionStats{},
Mem: &MemStats{
Supported: false,
},
Locks: map[string]LockStats{
"Global": {
AcquireCount: &ReadWriteLockTimes{},
},
"Collection": {
AcquireWaitCount: &ReadWriteLockTimes{
Read: 1,
Write: 2,
},
AcquireCount: &ReadWriteLockTimes{
Read: 5,
Write: 10,
},
TimeAcquiringMicros: ReadWriteLockTimes{
Read: 100,
Write: 200,
},
},
},
},
},
MongoStatus{
ServerStatus: &ServerStatus{
Connections: &ConnectionStats{},
Mem: &MemStats{
Supported: false,
},
Locks: map[string]LockStats{
"Global": {
AcquireCount: &ReadWriteLockTimes{},
},
"Collection": {
AcquireWaitCount: &ReadWriteLockTimes{
Read: 2,
Write: 4,
},
AcquireCount: &ReadWriteLockTimes{
Read: 10,
Write: 30,
},
TimeAcquiringMicros: ReadWriteLockTimes{
Read: 250,
Write: 310,
},
},
},
},
},
"foo",
true,
60,
)
expected := &CollectionLockStatus{
ReadAcquireWaitsPercentage: 20,
WriteAcquireWaitsPercentage: 10,
ReadAcquireTimeMicros: 150,
WriteAcquireTimeMicros: 55,
}
require.Equal(t, expected, sl.CollectionLocks)
}