140 lines
6.6 KiB
Python
140 lines
6.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
|
|
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 domain_utils.sql_handler.sql_executor import SqlExecutor
|
|
|
|
|
|
class CheckTableSkew(BaseItem):
|
|
def __init__(self):
|
|
super(CheckTableSkew, self).__init__(self.__class__.__name__)
|
|
|
|
def doCheck(self):
|
|
security_mode_value = DefaultValue.getSecurityMode()
|
|
if (security_mode_value == "on"):
|
|
secMode = True
|
|
else:
|
|
secMode = False
|
|
if (self.cluster.isSingleInstCluster()):
|
|
if (secMode):
|
|
finalresult = ""
|
|
dbList = []
|
|
sqlList = []
|
|
sqlPath = os.path.realpath(
|
|
os.path.join(os.path.split(os.path.realpath(__file__))[0],
|
|
"../../lib/checkblacklist/"))
|
|
sqlFileName = os.path.join(sqlPath, "GetTableSkew.sql")
|
|
if (os.path.exists(sqlFileName)):
|
|
try:
|
|
with open(sqlFileName, "r") as fp:
|
|
lines = fp.read()
|
|
sqlList = lines.split("--sqlblock")
|
|
sqlList.pop()
|
|
except Exception as e:
|
|
raise Exception(ErrorCode.GAUSS_502["GAUSS_50204"]
|
|
% ("file:%s,Error:%s"
|
|
% (sqlFileName, str(e))))
|
|
else:
|
|
raise Exception(ErrorCode.GAUSS_502["GAUSS_50219"]
|
|
% ("sql file:%s" % sqlFileName))
|
|
sqldb = "select datname from pg_database;"
|
|
(status, result, error) = SqlExecutor.excuteSqlOnLocalhost(
|
|
self.port, sqldb)
|
|
if (status != 2):
|
|
raise Exception(ErrorCode.GAUSS_513["GAUSS_51300"]
|
|
% sqldb + (" Error:%s" % error))
|
|
recordsCount = len(result)
|
|
for i in range(0, recordsCount):
|
|
dbList.append(result[i][0])
|
|
dbList.remove("template0")
|
|
dbList.remove("template1")
|
|
for db in dbList:
|
|
schemaTable = []
|
|
for sql in sqlList:
|
|
sql = "set client_min_messages='error';\n" + sql
|
|
SqlExecutor.excuteSqlOnLocalhost(self.port, sql, db)
|
|
sql = "SELECT schemaname , tablename FROM " \
|
|
"PUBLIC.pgxc_analyzed_skewness WHERE " \
|
|
"skewness_tuple > 100000;"
|
|
(status, result,
|
|
error) = SqlExecutor.excuteSqlOnLocalhost(self.port,
|
|
sql, db)
|
|
if (status != 2):
|
|
raise Exception(ErrorCode.GAUSS_513["GAUSS_51300"]
|
|
% sql + (" Error:%s" % error))
|
|
else:
|
|
for i in iter(result):
|
|
schema = i[0]
|
|
table = i[1]
|
|
schemaTable.append("%s.%s" % (schema, table))
|
|
if (schemaTable):
|
|
finalresult += "%s:\n%s\n" % (
|
|
db, "\n".join(schemaTable))
|
|
if (finalresult):
|
|
self.result.rst = ResultStatus.WARNING
|
|
self.result.val = "The result is not ok:\n%s" % finalresult
|
|
else:
|
|
self.result.rst = ResultStatus.OK
|
|
self.result.val = "Data is well distributed"
|
|
else:
|
|
finalresult = ""
|
|
sqlPath = os.path.realpath(
|
|
os.path.join(os.path.split(os.path.realpath(__file__))[0],
|
|
"../../lib/checkblacklist/"))
|
|
sqlFileName = os.path.join(sqlPath, "GetTableSkew.sql")
|
|
sqldb = "select datname from pg_database;"
|
|
output = SharedFuncs.runSqlCmd(sqldb, self.user, "", self.port,
|
|
self.tmpPath, "postgres",
|
|
self.mpprcFile)
|
|
dbList = output.split("\n")
|
|
dbList.remove("template0")
|
|
dbList.remove("template1")
|
|
for db in dbList:
|
|
db = db.replace("$", "\\$")
|
|
cmd = "gsql -d %s -p %s -f %s" % (
|
|
db, self.port, sqlFileName)
|
|
tmpout = ""
|
|
output = SharedFuncs.runShellCmd(cmd, self.user,
|
|
self.mpprcFile)
|
|
if (output.find("(0 rows)") < 0):
|
|
tmpresult = output.splitlines()
|
|
idxS = 0
|
|
idxE = 0
|
|
for idx in range(len(tmpresult)):
|
|
if (not tmpresult[idx].find("---+---") < 0):
|
|
idxS = idx - 1
|
|
if (tmpresult[idx].find("row)") > 0 or tmpresult[
|
|
idx].find("rows)") > 0):
|
|
idxE = idx
|
|
for i in range(idxS, idxE):
|
|
tmpout += "%s\n" % tmpresult[i]
|
|
finalresult += "%s:\n%s\n" % (db, tmpout)
|
|
if (finalresult):
|
|
self.result.rst = ResultStatus.WARNING
|
|
self.result.val = "Data is not well distributed:\n%s" \
|
|
% finalresult
|
|
else:
|
|
self.result.rst = ResultStatus.OK
|
|
self.result.val = "Data is well distributed"
|
|
else:
|
|
self.result.rst = ResultStatus.NA
|
|
self.result.val = "First cn is not in this host"
|