144 lines
5.7 KiB
Python
144 lines
5.7 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 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
|