提交 5ef6b86b 编写于 作者: L Larry Hamel 提交者: Melanie

Remove deprecated utility, gpdebug

-- including all text references
Signed-off-by: NMelanie Plageman <mplageman@pivotal.io>
上级 eb4a2bd1
bin/explain.pl
bin/gpcheckmirrorseg.pl
bin/gpdebug
bin/gpfaultinjector
bin/gptorment.pl
bin/lib/gpgetconfig.py
......
bin/gpcheckmirrorseg.pl
sbin/gprepairmirrorseg.py
bin/gpdebug
#!/usr/bin/env python
# Line too long - pylint: disable=C0301
# Invalid name - pylint: disable=C0103
"""
gpdebug
Copyright (c) EMC/Greenplum Inc 2011. All Rights Reserved.
"""
import os, signal, time
import psutil
from gppylib import gplog, pgconf
from gppylib.db import dbconn
from gppylib.gparray import get_segment_hosts, get_session_ids
from gppylib.mainUtils import YamlMain, Exit
from gppylib.commands import gp
from gppylib.commands.unix import check_pid
from gppylib.commands.base import run_remote_commands, Command
from gppylib.gp_era import read_era
from gppylib.util.ssh_utils import get_hosts
from gppylib.utils import TableLogger
class GpDebugMain(YamlMain):
"""
Main class for the gpdebug utility. The yaml document below specifies
* how command line options are parsed
* expected execution scenarios
* expected error conditions and messages
%YAML 1.1
---
#
# arguments
#
Usage: 'usage: %prog [options]'
Description: Investigate processes
Options:
Groups:
- Help Options
- Logging Options
- Connection Options
- Troubleshooting Options
- Orphan Options
Help Options:
-h,-?,--help,--usage:
help: Show help message and exit.
action: help
Logging Options:
-q: Quiet Mode - only show problems on stdout
-v: Verbose Mode - include verbose debugging information
Connection Options:
-d,--master_data_directory:
type: string
dest: masterDataDirectory
metavar: 'MASTERDATADIR'
help: |
Optional. The master host data directory.
If not specified, the value set for $MASTER_DATA_DIRECTORY will be used.
Troubleshooting Options:
--pid:
help: Capture Troubleshooting information for specified process.
action: store_const
dest: scenario
const: Capture Troubleshooting Information
Orphan Options:
-f:
help: Hosts file
type: string
dest: hostsfile
--orphans:
help: Search cluster for orphan processes
action: store_const
dest: scenario
const: Check Cluster For Orphans
--all:
help: Count system processes as orphans
action: store_true
--detailed:
help: Report orphan details
action: store_true
# gpdebug --orphans remotely executes gpdebug --orphans-host
# on each segment host with additional --era and --datadir parameters.
# note that --datadir may occur multiple times
--orphans-host:
help: hidden - Check host for orphan processes
action: store_const
dest: scenario
const: Check Host For Orphans
--host:
help: hidden - Current host
type: string
dest: host
--era:
help: hidden - Current master era (or None)
type: string
dest: era
--datadir:
help: hidden - segment data directory
type: string
action: append
dest: dirlist
--sessid:
help: hidden - session id
type: string
action: append
dest: sessionids
#
# scenarios
#
Default Scenario: Capture Troubleshooting Information
Scenarios:
Capture Troubleshooting Information:
- 1. On Current Host:
- 1.1. Validate PID
- 1.2. Troubleshoot Process
Check Cluster For Orphans:
- 1. On Current Host:
- 1.1. Identify Master
- 1.2. Identify Segments
- 1.3. Identify Sessions
- 1.4. Identify Current Era
- 1.5. Search for Orphans
- 1.6. Report Results
- 1.7. Generate Output File
Check Host For Orphans:
- 1. On Current Host:
- 1.1. Identify Orphans
- 1.2. Return Orphan Details
Errors:
nopid: 'no pid specified, consider --help'
badpid: 'invalid pid: %(pid)s'
get_segment_hosts: 'Unable to read hosts from master. Please investigate or consider -f hostfile option.'
"""
# GpDebugMain constructor
#
def __init__(self):
"Here we go..."
YamlMain.__init__(self)
# generic state set by YamlMain.run() we also set here mainly to make code clearer
#
self.scenario_name = None # what we call what we're doing, e.g. 'Examine Process'
self.plan = None # plan object built from the yaml above
self.logger = None # helpful logger object reference
self.errmsg = None # helpful errmsg function reference
# additional state we update during execution
self.pid = None # pid
# Orphans (master host)
self.master_datadir = None # master data directory
self.master_port = None # master port
self.host_list = None # list of hosts
self.era = None # master era
self.results = None # execution results
# Orphans (segment)
self.orphans = None
#
# Scenario: Capture Troubleshooting Information
#
def validate_pid(self):
""
# user has to give us an argument
if len(self.args) != 1:
raise Exit(1, 'nopid')
# the argument had better be a valid integer
pid = self.args[0]
try:
self.pid = int(pid)
except (ValueError), e:
raise Exit(1,'badpid')
def troubleshoot_process(self):
""
# use glider to capture the stack of the target process.
# we run it from a shell with an explicit ulimit to prevent
# this from taking too long (occasionally observed on osx).
#
pid = self.pid
shcmd = 'ulimit -t 4; $GPHOME/sbin/glider %(pid)s' % locals()
command = Command('Troubleshooting', shcmd)
self.logger.info(command)
command.run(validateAfter = False)
# log whatever output we get, stderr as error and stdout as info
#
for line in command.get_stderr_lines():
self.logger.info(line)
for line in command.get_stdout_lines():
self.logger.info(line)
#
# Scenario: Check Cluster For Orphans (master host)
#
def identify_master(self):
""
self.master_datadir = self.options.masterDataDirectory or gp.get_masterdatadir()
self.master_port = gp.get_masterport(self.master_datadir)
def identify_segments(self):
""
if self.options.hostsfile:
self.hosts_list = get_hosts(self.options.hostsfile)
else:
self.hosts_list = get_segment_hosts(self.master_port)
def identify_sessions(self):
""
if self.options.hostsfile:
self.session_ids = set()
else:
self.session_ids = get_session_ids(self.master_port)
for sess_id in self.session_ids:
self.logger.info('session id: %s' % sess_id)
def identify_current_era(self):
""
self.era = read_era(self.master_datadir, self.logger)
def search_for_orphans(self):
""
commands = {}
for host in self.hosts_list:
cmdlist = [
'$GPHOME/bin/gpdebug',
'-q',
'--orphans-host',
'--era', str(self.era),
'--host', str(host)
]
if self.options.all:
cmdlist.append('--all')
if self.options.detailed:
cmdlist.append('--detailed')
for s in self.session_ids:
cmdlist.append('--sessid')
cmdlist.append(str(s))
commands[host] = " ".join(cmdlist)
cmds = run_remote_commands('Search for Orphans', commands)
self.results = {}
for host, cmd in cmds.items():
self.results[host] = cmd.get_stdout_lines()
def report_results(self):
""
for host, lines in self.results.items():
if len(lines) < 1:
self.logger.info('no orphans observed on %s' % host)
continue
self.logger.info('found %d orphans on %s' % (len(lines), host))
# --detailed output
#
if self.options.detailed:
tabLog = None
for host, lines in self.results.items():
prev = None
for line in lines:
host2, era, sessid, pid, detail = line.split('|')
assert host == host2
if era != prev:
if tabLog:
self.logger.info("Era: %s" % prev)
tabLog.outputTable()
self.logger.info("--------------------------------------------")
tabLog = TableLogger()
tabLog.info(["Host","SessId","Pid","Detail"])
prev = era
tabLog.info([host, sessid, pid, detail])
if tabLog:
self.logger.info("Era: %s" % prev)
tabLog.outputTable()
self.logger.info("--------------------------------------------")
#
# Scenario: Check Host For Orphans (segment hosts, via search for orphans)
#
def identify_orphans(self):
""
self.logger.info("Era: %s" % self.options.era)
self.orphans = []
for p in psutil.process_iter():
try:
d = p.environ()
command = ' '.join(p.cmdline())
except psutil.Error:
continue
e = d.get('GPERA')
s = d.get('GPSESSID')
# look for processes from another era
if e is None:
continue
if e != self.options.era:
self.orphans.append((e, s, str(p.pid), command.strip()))
continue
# look for process in same era with a session id not in
# the list of session ids known to the master
if s is None:
continue
s = str(int(s)) # convert 0000000024 -> 24
# report all processes when --all is specified
# otherwise only show nonzero sessions not known at the master
#
if not self.options.all:
if s == '0' or s in (self.options.sessionids or []):
continue
self.orphans.append((e, s, str(p.pid), command.strip()))
def return_orphan_details(self):
""
for era, sessid, pid, command in self.orphans:
result = "|".join([ self.options.host, era, sessid, pid, command ])
print result
if __name__ == '__main__':
GpDebugMain().simple()
......@@ -275,7 +275,7 @@ class PgCtlStartArgs(CmdArgs):
"""
CmdArgs.__init__(self, [
"env", # variables examined by gpdebug/etc
"env",
"GPSESSID=0000000000", # <- overwritten with gp_session_id to help identify orphans
"GPERA=%s" % str(era), # <- master era used to help identify orphans
"$GPHOME/bin/pg_ctl",
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册