Files
openGauss-OM/script/gspylib/inspection/items/database/CheckGUCConsistent.py

242 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
from gspylib.common.DbClusterInfo import dbClusterInfo
from gspylib.inspection.common import SharedFuncs
from gspylib.common.ErrorCode import ErrorCode
from gspylib.inspection.common.CheckItem import BaseItem
from gspylib.inspection.common.CheckResult import ResultStatus
from base_utils.os.net_util import NetUtil
# 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 == NetUtil.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 where category != 'Customized Options';"
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
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