# -*- 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 grp import pwd from multiprocessing.dummy import Pool as ThreadPool from gspylib.inspection.common import SharedFuncs from gspylib.inspection.common.CheckItem import BaseItem from gspylib.inspection.common.CheckResult import ResultStatus from gspylib.common.Common import DefaultValue from gspylib.common.ErrorCode import ErrorCode from gspylib.inspection.common.Exception import CheckNAException from base_utils.os.file_util import FileUtil # cn INSTANCE_ROLE_COODINATOR = 3 # dn INSTANCE_ROLE_DATANODE = 4 MASTER_INSTANCE = 0 class CheckSysTable(BaseItem): def __init__(self): super(CheckSysTable, self).__init__(self.__class__.__name__) self.database = None def preCheck(self): # check the threshold was set correctly if (not self.threshold.__contains__('database')): raise Exception(ErrorCode.GAUSS_530["GAUSS_53013"] % "threshold database") self.database = self.threshold['database'] def checkSingleSysTable(self, Instance): tablelist = ["pg_attribute", "pg_class", "pg_constraint", "pg_partition", "pgxc_class", "pg_index", "pg_stats"] resultMap = {} try: for i in tablelist: sqlFile = "%s/sqlFile_%s_%s.sql" % ( self.tmpPath, i, Instance.instanceId) resFile = "%s/resFile_%s_%s.out" % ( self.tmpPath, i, Instance.instanceId) FileUtil.createFile(sqlFile, True, DefaultValue.SQL_FILE_MODE) FileUtil.createFile(resFile, True, DefaultValue.SQL_FILE_MODE) FileUtil.changeOwner(self.user, sqlFile) FileUtil.changeOwner(self.user, resFile) sql = "select * from pg_table_size('%s');" % i sql += "select count(*) from %s;" % i sql += "select * from pg_column_size('%s');" % i FileUtil.writeFile(sqlFile, [sql]) cmd = "gsql -d %s -p %s -f %s --output %s -t -A -X" % ( self.database, Instance.port, sqlFile, resFile) if (self.mpprcFile != "" and self.mpprcFile is not None): cmd = "source '%s' && %s" % (self.mpprcFile, cmd) SharedFuncs.runShellCmd(cmd, self.user) restule = FileUtil.readFile(resFile) FileUtil.removeFile(sqlFile) FileUtil.removeFile(resFile) size = restule[0].strip() line = restule[1].strip() width = restule[2].strip() Role = "" if (Instance.instanceRole == INSTANCE_ROLE_COODINATOR): Role = "CN" elif (Instance.instanceRole == INSTANCE_ROLE_DATANODE): Role = "DN" instanceName = "%s_%s" % (Role, Instance.instanceId) resultMap[i] = [instanceName, size, line, width] return resultMap except Exception as e: if os.path.exists(sqlFile): FileUtil.removeFile(sqlFile) if os.path.exists(resFile): FileUtil.removeFile(resFile) raise Exception(str(e)) def checkSysTable(self): primaryDNidList = [] nodeInfo = self.cluster.getDbNodeByName(self.host) CN = nodeInfo.coordinators masterDnList = SharedFuncs.getMasterDnNum(self.user, self.mpprcFile) for DnInstance in nodeInfo.datanodes: if (DnInstance.instanceId in masterDnList): primaryDNidList.append(DnInstance) if (len(CN) < 1 and len(primaryDNidList) < 1): raise CheckNAException( "There is no primary database node instance in the " "current node.") # test database Connection for Instance in (CN + primaryDNidList): if not Instance: continue sqlcmd = "select pg_sleep(1);" SharedFuncs.runSqlCmd(sqlcmd, self.user, "", Instance.port, self.tmpPath, self.database, self.mpprcFile) outputList = [] pool = ThreadPool(DefaultValue.getCpuSet()) results = pool.map(self.checkSingleSysTable, CN + primaryDNidList) pool.close() pool.join() for result in results: if (result): outputList.append(result) outputList.sort() return outputList def doCheck(self): resultStr = "" resultStr += "Instance table size row " \ "width row*width\n" outputList = self.checkSysTable() for resultMap in outputList: for table in resultMap.keys(): resultStr += "%s %s %s %s %s %s\n" % ( resultMap[table][0], table.ljust(15), resultMap[table][1].ljust(15), resultMap[table][2].ljust(8), resultMap[table][3].ljust(5), int(resultMap[table][2]) * int(resultMap[table][3])) self.result.val = resultStr self.result.raw = resultStr self.result.rst = ResultStatus.OK