Skip to content

PT-2354: pt-mongodb-summary graceful ARBITER handling - #1144

Open
eslavyansky wants to merge 2 commits into
percona:3.xfrom
eslavyansky:PT-2354-pt-mongodb-summary-arbiter
Open

eslavyansky wants to merge 2 commits into
percona:3.xfrom
eslavyansky:PT-2354-pt-mongodb-summary-arbiter

Conversation

@eslavyansky

@eslavyansky eslavyansky commented Jun 26, 2026 •

Copy link
Copy Markdown
Contributor

PT-2354

Running pt-mongodb-summary directly against a replica-set arbiter crashed the report: hostInfo is denied on an arbiter, and main treated any hostInfo failure as fatal (os.Exit). Connecting to a data-bearing member also left the arbiter as a blank row in the Instances list.

  • The contributed code is licensed under GPL v2.0
  • Contributor Licence Agreement (CLA) is signed
  • util/update-modules has been ran
  • Documentation updated
  • Test suite update

Running pt-mongodb-summary directly against a replica-set arbiter crashed
the report: hostInfo is denied on an arbiter, and main treated any hostInfo
failure as fatal (os.Exit). Connecting to a data-bearing member also left the
arbiter as a blank row in the Instances list.

Detect arbiters via isMaster (arbiterOnly, with me-in-arbiters fallback) and:
- build a best-effort host summary from non-privileged fields instead of
  exiting, with a note explaining arbiter limitations;
- render the arbiter as ARBITER in the Instances list, with ReplSet filled;
- guard the mongos, runningOps and security report sections against nil so
  the formatter no longer panics when those collectors are unauthorized.
newArbiterHostInfo seeds ReplicasetName from isMaster's setName, but the
serverStatus block unconditionally overwrote it with ss.Repl.SetName,
which can be empty on an arbiter. Only override when non-empty so the
seeded value survives.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The updated HostInfo template’s whitespace-trimming can concatenate output lines when ProcCreateTime is zero (common for arbiters), producing incorrect report formatting.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Improves pt-mongodb-summary resiliency when connecting to MongoDB replica-set arbiters by avoiding fatal exits on commands that are unsupported/denied on arbiters, and by making the text output more tolerant of missing sections.

Changes:

  • Add arbiter detection and a non-fatal hostInfo fallback path, with a dedicated “Arbiter” output note.
  • Make output formatting skip optional sections (mongos/running ops/security) when the collected data is nil.
  • Expose GetMasterDoc and extend MasterDoc to support arbiter detection in shared MongoDB utilities.
File summaries
File Description
src/go/pt-mongodb-summary/templates/hostinfo.go Adds conditional “Started” line and an arbiter-specific note in the host report template.
src/go/pt-mongodb-summary/main.go Adds IsArbiter, arbiter hostInfo fallback, and guards template execution on nil sections.
src/go/mongolib/util/util.go Exports GetMasterDoc and annotates replica member state as ARBITER when appropriate.
src/go/mongolib/proto/master_doc.go Extends MasterDoc with arbiter-related fields and adds IsArbiter() helper.
Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 3
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines 28 to 32
Built On | {{.HostOsType}} {{.HostSystemCPUArch}}
{{- if not .ProcCreateTime.IsZero }}
Started | {{.ProcCreateTime}}
{{- end }}
{{- if .DBPath }}
Comment on lines 16 to +37
type MasterDoc struct {
SetName interface{} `bson:"setName"`
Hosts interface{} `bson:"hosts"`
Msg string `bson:"msg"`
SetName interface{} `bson:"setName"`
Hosts interface{} `bson:"hosts"`
Msg string `bson:"msg"`
ArbiterOnly bool `bson:"arbiterOnly"`
Me string `bson:"me"`
Arbiters []string `bson:"arbiters"`
}

func (md MasterDoc) IsArbiter() bool {
if md.ArbiterOnly {
return true
}
if md.Me == "" {
return false
}
for _, a := range md.Arbiters {
if a == md.Me {
return true
}
}
return false
Comment on lines +426 to +451
func newArbiterHostInfo(md proto.MasterDoc) *hostInfo {
setName, _ := md.SetName.(string)

return &hostInfo{
NodeType: "ARBITER",
Hostname: md.Me,
ReplicasetName: setName,
IsArbiter: true,
}
}

func getHostInfo(ctx context.Context, client *mongo.Client) (*hostInfo, error) {
var i *hostInfo

hi := proto.HostInfo{}
if err := client.Database("admin").RunCommand(ctx, primitive.M{"hostInfo": 1}).Decode(&hi); err != nil {
log.Debugf("run('hostInfo') error: %s", err)

return nil, errors.Wrap(err, "GetHostInfo.hostInfo")
}

nodeType, _ := getNodeType(ctx, client)
procCount, _ := countMongodProcesses()
md, mdErr := util.GetMasterDoc(ctx, client)
if mdErr != nil || !md.IsArbiter() {
return nil, errors.Wrap(err, "GetHostInfo.hostInfo")
}

i := &hostInfo{
Hostname: hi.System.Hostname,
HostOsType: hi.Os.Type,
HostSystemCPUArch: hi.System.CpuArch,
ProcProcessCount: procCount,
NodeType: nodeType,
CmdlineArgs: nil,
i = newArbiterHostInfo(md)
i.ProcProcessCount, _ = countMongodProcesses()
} else {

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants