Files
openGauss-OM/script/gspylib/inspection/items/database/CheckGUCConsistent.py
hangjin2020 a2679f0cf7 om仓迁移
2020-12-16 17:25:24 +08:00

243 lines
9.6 KiB
Python

# -*- coding:utf-8 -*-
# Copyright (c) 2020 Huawei Technologies Co.,Ltd.
#
# openGauss is licensed under Mulan PSL v2.
# You can use this software according to the terms
# and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#
# http://license.coscl.org.cn/MulanPSL2
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.
# ----------------------------------------------------------------------------
import os
import json
import configparser
import multiprocessing
from gspylib.common.DbClusterInfo import dbClusterInfo
from gspylib.inspection.common import SharedFuncs
from gspylib.common.Common import DefaultValue
from gspylib.common.ErrorCode import ErrorCode
from gspylib.inspection.common.CheckItem import BaseItem
from gspylib.inspection.common.CheckResult import ResultStatus
# master
MASTER_INSTANCE = 0
# standby
STANDBY_INSTANCE = 1
# dummy standby
DUMMY_STANDBY_INSTANCE = 2
# cn
INSTANCE_ROLE_COODINATOR = 3
# dn
INSTANCE_ROLE_DATANODE = 4
g_gucDist = {}
g_ignoreList = []
g_logicList = []
class CheckGUCConsistent(BaseItem):
def __init__(self):
super(CheckGUCConsistent, self).__init__(self.__class__.__name__)
def preCheck(self):
# check the threshold was set correctly
if (not self.threshold.__contains__('version')):
raise Exception(ErrorCode.GAUSS_530["GAUSS_53013"] % "version")
self.version = self.threshold['version']
def checkLogicCluster(self):
clusterInfo = dbClusterInfo()
staticConfigDir = os.path.join(self.cluster.appPath, "bin")
cmd = "find %s -name *.cluster_static_config" % staticConfigDir
output = SharedFuncs.runShellCmd(cmd)
if output:
for staticConfigFile in output.splitlines():
clusterInfo.initFromStaticConfig(self.user, staticConfigFile,
True)
lcName = os.path.splitext(os.path.basename(staticConfigFile))[
0]
for dbnode in clusterInfo.dbNodes:
if (dbnode.name == DefaultValue.GetHostIpOrName()):
return [lcName, dbnode]
return ["", None]
else:
return ["", None]
def getIgnoreParameters(self, configFile, ignoreSection, logicSection):
global g_ignoreList
global g_logicList
fp = configparser.RawConfigParser()
fp.read(configFile)
secs = fp.sections()
if (ignoreSection not in secs):
return
g_ignoreList = fp.options(ignoreSection)
if self.cluster.isSingleInstCluster():
g_ignoreList.append("synchronous_standby_names")
g_logicList = fp.options(logicSection)
def checkInstanceGucValue(self, Instance, needm, lcName="",
logicCluster=False):
"""
get CN/DN instance guc parameters
"""
global g_gucDist
LCInstanceGucDist = {}
lcInstance = {}
sqlcmd = "select name,setting from pg_settings;"
InstanceGucDist = {}
output = SharedFuncs.runSqlCmd(sqlcmd, self.user, "", Instance.port,
self.tmpPath, "postgres",
self.mpprcFile, needm)
gucValueList = output.split('\n')
for gucValue in gucValueList:
if (len(gucValue.split('|')) == 2):
(parameter, value) = gucValue.split('|')
if (
parameter == "transaction_read_only"
and Instance.instanceRole == INSTANCE_ROLE_DATANODE):
continue
if (parameter not in g_ignoreList):
if (not logicCluster):
InstanceGucDist[parameter] = value
else:
if (parameter not in g_logicList):
InstanceGucDist[parameter] = value
elif (lcName and parameter in g_logicList):
LCInstanceGucDist[parameter] = value
else:
continue
if (lcName):
instanceName = "%s_%s_%s" % (lcName, "DN", Instance.instanceId)
lcInstance[instanceName] = LCInstanceGucDist
return lcInstance
if Instance.instanceRole == INSTANCE_ROLE_DATANODE:
Role = "DN"
instanceName = "%s_%s" % (Role, Instance.instanceId)
g_gucDist[instanceName] = InstanceGucDist
def doCheck(self):
"""
"""
global g_gucDist
# get ignore list
dirName = os.path.dirname(os.path.realpath(__file__))
configFile = "%s/../../config/check_list_%s.conf" % (
dirName, self.version)
self.getIgnoreParameters(configFile, 'guc_ignore', 'guc_logic')
DNidList = []
result = []
logicCluster = False
nodeInfo = self.cluster.getDbNodeByName(self.host)
masterDnList = SharedFuncs.getMasterDnNum(self.user, self.mpprcFile)
for DnInstance in nodeInfo.datanodes:
if (DnInstance.instanceType != DUMMY_STANDBY_INSTANCE):
DNidList.append(DnInstance)
if len(DNidList) < 1:
raise Exception(ErrorCode.GAUSS_512["GAUSS_51249"])
# get information of logicCluster on current node
(lcName, dbnode) = self.checkLogicCluster()
if (dbnode):
logicCluster = True
for DnInstance in dbnode.datanodes:
if (DnInstance.instanceType != DUMMY_STANDBY_INSTANCE):
if (DnInstance.instanceId in masterDnList):
needm = False
else:
needm = True
result.append(
self.checkInstanceGucValue(DnInstance, needm, lcName,
logicCluster))
g_gucDist[lcName] = result
# test database Connection
for Instance in DNidList:
if not Instance:
continue
sqlcmd = "select pg_sleep(1);"
if Instance.instanceId in masterDnList:
needm = False
else:
needm = True
output = SharedFuncs.runSqlCmd(sqlcmd, self.user, "",
Instance.port, self.tmpPath,
'postgres', self.mpprcFile, needm)
self.checkInstanceGucValue(Instance, needm, "", logicCluster)
self.result.val = json.dumps(g_gucDist)
self.result.raw = str(g_gucDist)
self.result.rst = ResultStatus.OK
def postAnalysis(self, itemResult):
errors = []
ngs = []
dnGucDist = {}
lcdnGucDist = {}
for i in itemResult.getLocalItems():
if (i.rst == ResultStatus.ERROR):
errors.append("%s: %s" % (i.host, i.val))
if (i.rst == ResultStatus.NG):
ngs.append("%s: %s" % (i.host, i.val))
if (len(errors) > 0):
itemResult.rst = ResultStatus.ERROR
itemResult.analysis = "\n".join(errors)
return itemResult
if (len(ngs) > 0):
itemResult.rst = ResultStatus.NG
itemResult.analysis = "\n".join(ngs)
return itemResult
for v in itemResult.getLocalItems():
gucDist = json.loads(v.val)
for InstanceName in gucDist.keys():
if (InstanceName[:2] == 'DN'):
dnGucDist[InstanceName] = gucDist[InstanceName]
else:
if InstanceName in lcdnGucDist.keys():
lcdnGucDist[InstanceName].extend(gucDist[InstanceName])
else:
lcdnGucDist[InstanceName] = gucDist[InstanceName]
for parameter in dnGucDist[list(dnGucDist.keys())[0]].keys():
InstanceName = list(dnGucDist.keys())[0]
keyValue = dnGucDist[InstanceName][parameter]
relultStr = "\n%s:\n%s: %s\n" % (parameter, InstanceName, keyValue)
flag = True
for dnInstance in list(dnGucDist.keys())[1:]:
value = dnGucDist[dnInstance][parameter]
relultStr += "%s: %s\n" % (dnInstance, value)
if (value != keyValue):
flag = False
if (not flag):
itemResult.analysis += relultStr
for lcName in lcdnGucDist.keys():
lcInstanceResult = lcdnGucDist[lcName]
baseDn = lcInstanceResult[0]
baseParameter = baseDn[list(baseDn.keys())[0]]
for parameter in baseParameter.keys():
keyValue = baseParameter[parameter]
relultStr = "\n%s:\n%s: %s\n" % (
parameter, list(baseDn.keys())[0], keyValue)
flag = True
for otherDn in lcInstanceResult[1:]:
dnInstance = list(otherDn.keys())[0]
value = otherDn[dnInstance][parameter]
relultStr += "%s: %s\n" % (dnInstance, value)
if (value != keyValue):
flag = False
if (not flag):
itemResult.analysis += relultStr
if (itemResult.analysis):
itemResult.rst = ResultStatus.NG
else:
itemResult.rst = ResultStatus.OK
itemResult.analysis = "All DN instance guc value is consistent."
return itemResult