Merge branch 'master' of gitee.com:opengauss/openGauss-OM
This commit is contained in:
commit
29ab05e272
@ -8,7 +8,9 @@ Common functions include database installtion, startup, stop, upgrade, backup, s
|
||||
|
||||
- See the compilation description of the [opengauss third-party-software](https://gitee.com/opengauss/openGauss-server/blob/master/README.en.md#compiling-third-party-software)。
|
||||
The final compilation and build result is stored in the binarylibs directory at the same level as openGauss-third_party.
|
||||
The binarylibs directory will be the value of '-3rd' for build.sh
|
||||
The binarylibs directory will be the value of '-3rd' for build.sh
|
||||
You can obtain the binarylibs we have compiled. [openGauss-third_party_binarylibs-om.tar.gz](https://opengauss.obs.cn-south-1.myhuaweicloud.com/latest/binarylibs/openGauss-third_party_binarylibs-om.tar.gz)
|
||||
|
||||
- ./build.sh -3rd ${BINARYLIBS_PATH}
|
||||
The generated installation package is stored in the ./package directory:
|
||||
openGauss-1.1.0-CentOS-64bit-om.sha256
|
||||
@ -20,7 +22,7 @@ The OM tool strongly depends on opengaussServer. Please see the [opengauss Insta
|
||||
|
||||
## Quick Start
|
||||
|
||||
See the [Quick Start](https://opengauss.org/en/docs/1.0.1/docs/Quickstart/Quickstart.html).
|
||||
See the [Quick Start](https://opengauss.org/en/docs/1.1.0/docs/Quickstart/Quickstart.html).
|
||||
|
||||
## Docs
|
||||
|
||||
@ -44,7 +46,7 @@ Welcome contributions. See our [Contributor](https://opengauss.org/en/contributi
|
||||
|
||||
## Release Notes
|
||||
|
||||
For the release notes, see our [RELEASE](https://opengauss.org/en/docs/1.0.1/docs/Releasenotes/Releasenotes.html).
|
||||
For the release notes, see our [RELEASE](https://opengauss.org/en/docs/1.1.0/docs/Releasenotes/Releasenotes.html).
|
||||
|
||||
## License
|
||||
|
||||
|
@ -7,7 +7,8 @@
|
||||
#### 编译出包
|
||||
|
||||
- 参考opengauss的[三方库说明](https://gitee.com/opengauss/openGauss-server#%E7%BC%96%E8%AF%91%E7%AC%AC%E4%B8%89%E6%96%B9%E8%BD%AF%E4%BB%B6),准备好编译完的三方库,
|
||||
目录名记为 ${BINARYLIBS_PATH} 。
|
||||
目录名记为 ${BINARYLIBS_PATH} 。
|
||||
提供编译好的三方库二进制可以直接下载使用: [openGauss-third_party_binarylibs-om.tar.gz](https://opengauss.obs.cn-south-1.myhuaweicloud.com/latest/binarylibs/openGauss-third_party_binarylibs-om.tar.gz)
|
||||
- ./build.sh -3rd ${BINARYLIBS_PATH}
|
||||
命令执行成功后,生成的包在package目录下:
|
||||
openGauss-1.1.0-CentOS-64bit-om.sha256
|
||||
@ -20,7 +21,7 @@ OM工具强依赖opengaussServer,安装教程参考[opengauss安装指南](htt
|
||||
|
||||
## 快速入门
|
||||
|
||||
参考[快速入门](https://opengauss.org/zh/docs/1.0.1/docs/Quickstart/Quickstart.html)。
|
||||
参考[快速入门](https://opengauss.org/zh/docs/1.1.0/docs/Quickstart/Quickstart.html)。
|
||||
|
||||
## 文档
|
||||
|
||||
@ -44,7 +45,7 @@ OM工具强依赖opengaussServer,安装教程参考[opengauss安装指南](htt
|
||||
|
||||
## 发行说明
|
||||
|
||||
请参见[发行说明](https://opengauss.org/zh/docs/1.0.1/docs/Releasenotes/Releasenotes.html)。
|
||||
请参见[发行说明](https://opengauss.org/zh/docs/1.1.0/docs/Releasenotes/Releasenotes.html)。
|
||||
|
||||
## 许可证
|
||||
|
||||
|
@ -29,6 +29,16 @@ import time
|
||||
import pwd
|
||||
import grp
|
||||
import pickle
|
||||
package_path = os.path.dirname(os.path.realpath(__file__))
|
||||
ld_path = package_path + "/gspylib/clib"
|
||||
if 'LD_LIBRARY_PATH' not in os.environ:
|
||||
os.environ['LD_LIBRARY_PATH'] = ld_path
|
||||
os.execve(os.path.realpath(__file__), sys.argv, os.environ)
|
||||
if not os.environ.get('LD_LIBRARY_PATH').startswith(ld_path):
|
||||
os.environ['LD_LIBRARY_PATH'] = \
|
||||
ld_path + ":" + os.environ['LD_LIBRARY_PATH']
|
||||
os.execve(os.path.realpath(__file__), sys.argv, os.environ)
|
||||
|
||||
import xml.etree.cElementTree as ETree
|
||||
from itertools import combinations
|
||||
from datetime import datetime, timedelta
|
||||
|
@ -26,7 +26,16 @@ import subprocess
|
||||
import sys
|
||||
import pwd
|
||||
import grp
|
||||
|
||||
package_path = os.path.dirname(os.path.realpath(__file__))
|
||||
ld_path = package_path + "/gspylib/clib"
|
||||
if 'LD_LIBRARY_PATH' not in os.environ:
|
||||
os.environ['LD_LIBRARY_PATH'] = ld_path
|
||||
os.execve(os.path.realpath(__file__), sys.argv, os.environ)
|
||||
if not os.environ.get('LD_LIBRARY_PATH').startswith(ld_path):
|
||||
os.environ['LD_LIBRARY_PATH'] = \
|
||||
ld_path + ":" + os.environ['LD_LIBRARY_PATH']
|
||||
os.execve(os.path.realpath(__file__), sys.argv, os.environ)
|
||||
|
||||
sys.path.append(sys.path[0])
|
||||
from gspylib.common.DbClusterInfo import dbClusterInfo
|
||||
from gspylib.common.DbClusterStatus import DbClusterStatus
|
||||
@ -321,9 +330,9 @@ if __name__ == "__main__":
|
||||
dropNode.initLogs()
|
||||
dropNode.check_repeat_process()
|
||||
dropNode.checkParameters()
|
||||
dropNode.check_cluster_status()
|
||||
dropNode.flagForOnlyPrimaryLeft()
|
||||
dropNode.checkConnection(list(dropNode.backIpNameMap.keys()),
|
||||
dropNode.envFile)
|
||||
dropNode.check_cluster_status()
|
||||
dropNode.flagForOnlyPrimaryLeft()
|
||||
dropNodeImpl = DropnodeImpl(dropNode)
|
||||
dropNodeImpl.run()
|
||||
|
@ -21,7 +21,15 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
package_path = os.path.dirname(os.path.realpath(__file__))
|
||||
ld_path = package_path + "/gspylib/clib"
|
||||
if 'LD_LIBRARY_PATH' not in os.environ:
|
||||
os.environ['LD_LIBRARY_PATH'] = ld_path
|
||||
os.execve(os.path.realpath(__file__), sys.argv, os.environ)
|
||||
if not os.environ.get('LD_LIBRARY_PATH').startswith(ld_path):
|
||||
os.environ['LD_LIBRARY_PATH'] = \
|
||||
ld_path + ":" + os.environ['LD_LIBRARY_PATH']
|
||||
os.execve(os.path.realpath(__file__), sys.argv, os.environ)
|
||||
|
||||
sys.path.append(sys.path[0])
|
||||
from gspylib.common.DbClusterInfo import dbClusterInfo, \
|
||||
@ -134,6 +142,7 @@ General options:
|
||||
GaussLog.exitWithError(ErrorCode.GAUSS_357["GAUSS_35701"] % "-h")
|
||||
|
||||
clusterInfo = ExpansipnClusterInfo()
|
||||
self.clusterInfo = clusterInfo
|
||||
hostNameIpDict = clusterInfo.initFromXml(self.xmlFile)
|
||||
clusterDict = clusterInfo.getClusterDirectorys()
|
||||
backIpList = clusterInfo.getClusterBackIps()
|
||||
|
@ -21,6 +21,15 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
package_path = os.path.dirname(os.path.realpath(__file__))
|
||||
ld_path = package_path + "/gspylib/clib"
|
||||
if 'LD_LIBRARY_PATH' not in os.environ:
|
||||
os.environ['LD_LIBRARY_PATH'] = ld_path
|
||||
os.execve(os.path.realpath(__file__), sys.argv, os.environ)
|
||||
if not os.environ.get('LD_LIBRARY_PATH').startswith(ld_path):
|
||||
os.environ['LD_LIBRARY_PATH'] = \
|
||||
ld_path + ":" + os.environ['LD_LIBRARY_PATH']
|
||||
os.execve(os.path.realpath(__file__), sys.argv, os.environ)
|
||||
|
||||
sys.path.append(sys.path[0])
|
||||
from gspylib.common.GaussLog import GaussLog
|
||||
|
@ -38,6 +38,7 @@ from gspylib.common.VersionInfo import VersionInfo
|
||||
# action type
|
||||
ACTION_START = "start"
|
||||
ACTION_STOP = "stop"
|
||||
ACTION_RESTART = "restart"
|
||||
ACTION_STATUS = "status"
|
||||
ACTION_REBUID = "generateconf"
|
||||
ACTION_CERT = "cert"
|
||||
@ -124,6 +125,8 @@ Usage:
|
||||
[--security-mode=MODE] [-l LOGFILE]
|
||||
gs_om -t stop [-h HOSTNAME] [-D dataDir] [--time-out=SECS] [-m MODE]
|
||||
[-l LOGFILE]
|
||||
gs_om -t restart [-h HOSTNAME] [-D dataDir] [--time-out=SECS]
|
||||
[--security-mode=MODE] [-l LOGFILE] [-m MODE]
|
||||
gs_om -t status [-h HOSTNAME] [-o OUTPUT] [--detail] [--all] [-l LOGFILE]
|
||||
gs_om -t generateconf -X XMLFILE [--distribute] [-l LOGFILE]
|
||||
gs_om -t cert [--cert-file=CERTFILE | --rollback] [-L] [-l LOGFILE]
|
||||
@ -478,6 +481,8 @@ Install options:
|
||||
self.checkStartParameter()
|
||||
elif (self.g_opts.action == ACTION_STOP):
|
||||
self.checkStopParameter()
|
||||
elif (self.g_opts.action == ACTION_RESTART):
|
||||
pass
|
||||
elif (self.g_opts.action == ACTION_STATUS):
|
||||
self.checkOutFileParameter()
|
||||
elif (self.g_opts.action == ACTION_REBUID):
|
||||
@ -714,6 +719,7 @@ def main():
|
||||
|
||||
if (manager.g_opts.action not in [ACTION_START,
|
||||
ACTION_STOP,
|
||||
ACTION_RESTART,
|
||||
ACTION_STATUS,
|
||||
ACTION_REBUID,
|
||||
ACTION_CERT,
|
||||
@ -733,6 +739,8 @@ def main():
|
||||
impl.doStart()
|
||||
elif (manager.g_opts.action == ACTION_STOP):
|
||||
impl.doStop()
|
||||
elif (manager.g_opts.action == ACTION_RESTART):
|
||||
impl.doStop(), impl.doStart()
|
||||
elif (manager.g_opts.action == ACTION_STATUS):
|
||||
impl.doStatus()
|
||||
elif (manager.g_opts.action == ACTION_REBUID):
|
||||
|
@ -31,7 +31,7 @@ ld_path = package_path + "/gspylib/clib"
|
||||
if 'LD_LIBRARY_PATH' not in os.environ:
|
||||
os.environ['LD_LIBRARY_PATH'] = ld_path
|
||||
os.execve(os.path.realpath(__file__), sys.argv, os.environ)
|
||||
if ld_path not in os.environ.get('LD_LIBRARY_PATH'):
|
||||
if not os.environ.get('LD_LIBRARY_PATH').startswith(ld_path):
|
||||
os.environ['LD_LIBRARY_PATH'] = \
|
||||
ld_path + ":" + os.environ['LD_LIBRARY_PATH']
|
||||
os.execve(os.path.realpath(__file__), sys.argv, os.environ)
|
||||
|
@ -318,9 +318,9 @@ General options:
|
||||
ld_path = package_path + "/gspylib/clib"
|
||||
rerun = True
|
||||
|
||||
if not 'LD_LIBRARY_PATH' in os.environ:
|
||||
if 'LD_LIBRARY_PATH' not in os.environ:
|
||||
os.environ['LD_LIBRARY_PATH'] = ld_path
|
||||
elif not ld_path in os.environ.get('LD_LIBRARY_PATH'):
|
||||
elif not os.environ.get('LD_LIBRARY_PATH').startswith(ld_path):
|
||||
os.environ['LD_LIBRARY_PATH'] = \
|
||||
ld_path + ":" + os.environ['LD_LIBRARY_PATH']
|
||||
else:
|
||||
|
@ -20,6 +20,15 @@
|
||||
#############################################################################
|
||||
import os
|
||||
import sys
|
||||
package_path = os.path.dirname(os.path.realpath(__file__))
|
||||
ld_path = package_path + "/gspylib/clib"
|
||||
if 'LD_LIBRARY_PATH' not in os.environ:
|
||||
os.environ['LD_LIBRARY_PATH'] = ld_path
|
||||
os.execve(os.path.realpath(__file__), sys.argv, os.environ)
|
||||
if not os.environ.get('LD_LIBRARY_PATH').startswith(ld_path):
|
||||
os.environ['LD_LIBRARY_PATH'] = \
|
||||
ld_path + ":" + os.environ['LD_LIBRARY_PATH']
|
||||
os.execve(os.path.realpath(__file__), sys.argv, os.environ)
|
||||
|
||||
from gspylib.common.GaussLog import GaussLog
|
||||
from gspylib.common.Common import DefaultValue
|
||||
|
@ -33,6 +33,16 @@ import grp
|
||||
import socket
|
||||
import getpass
|
||||
import shutil
|
||||
package_path = os.path.dirname(os.path.realpath(__file__))
|
||||
ld_path = package_path + "/gspylib/clib"
|
||||
if 'LD_LIBRARY_PATH' not in os.environ:
|
||||
os.environ['LD_LIBRARY_PATH'] = ld_path
|
||||
os.execve(os.path.realpath(__file__), sys.argv, os.environ)
|
||||
if not os.environ.get('LD_LIBRARY_PATH').startswith(ld_path):
|
||||
os.environ['LD_LIBRARY_PATH'] = \
|
||||
ld_path + ":" + os.environ['LD_LIBRARY_PATH']
|
||||
os.execve(os.path.realpath(__file__), sys.argv, os.environ)
|
||||
|
||||
from gspylib.common.GaussLog import GaussLog
|
||||
from gspylib.common.ErrorCode import ErrorCode
|
||||
from gspylib.threads.parallelTool import parallelTool
|
||||
@ -155,9 +165,11 @@ Usage:
|
||||
|
||||
General options:
|
||||
-f Host file containing the IP address of nodes.
|
||||
-h Host ip list. Separate multiple nodes with commas(,).
|
||||
-l Path of log file.
|
||||
--skip-hostname-set Whether to skip hostname setting.
|
||||
(The default value is set.)
|
||||
-W Password of nodes.
|
||||
-?, --help Show help information for this utility,
|
||||
and exit the command line mode.
|
||||
-V, --version Show version information.
|
||||
@ -178,10 +190,14 @@ General options:
|
||||
|
||||
if ("hostfile" in paraDict.keys()):
|
||||
self.hostFile = paraDict.get("hostfile")
|
||||
if ("nodename" in paraDict.keys()):
|
||||
self.hostList = paraDict.get("nodename")
|
||||
if ("logFile" in paraDict.keys()):
|
||||
self.logFile = paraDict.get("logFile")
|
||||
if ("skipHostnameSet" in paraDict.keys()):
|
||||
self.skipHostnameSet = paraDict.get("skipHostnameSet")
|
||||
if ("passwords" in paraDict.keys()):
|
||||
self.passwd = paraDict.get("passwords")
|
||||
|
||||
def checkParameter(self):
|
||||
"""
|
||||
@ -190,23 +206,24 @@ General options:
|
||||
output: NA
|
||||
"""
|
||||
# check required parameters
|
||||
if (self.hostFile == ""):
|
||||
self.usage()
|
||||
GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"]
|
||||
% 'f' + ".")
|
||||
if (not os.path.exists(self.hostFile)):
|
||||
GaussLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50201"]
|
||||
% self.hostFile)
|
||||
if (not os.path.isabs(self.hostFile)):
|
||||
GaussLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50213"]
|
||||
% self.hostFile)
|
||||
if len(self.hostList) == 0:
|
||||
if (self.hostFile == ""):
|
||||
self.usage()
|
||||
GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50001"]
|
||||
% 'f' + ".")
|
||||
if (not os.path.exists(self.hostFile)):
|
||||
GaussLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50201"]
|
||||
% self.hostFile)
|
||||
if (not os.path.isabs(self.hostFile)):
|
||||
GaussLog.exitWithError(ErrorCode.GAUSS_502["GAUSS_50213"]
|
||||
% self.hostFile)
|
||||
|
||||
# read host file to hostList
|
||||
self.readHostFile()
|
||||
# read host file to hostList
|
||||
self.readHostFile()
|
||||
|
||||
if (self.hostList == []):
|
||||
GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50004"]
|
||||
% 'f' + " It cannot be empty.")
|
||||
if (self.hostList == []):
|
||||
GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50004"]
|
||||
% 'f' + " It cannot be empty.")
|
||||
|
||||
# check logfile
|
||||
if (self.logFile != ""):
|
||||
|
@ -43,6 +43,7 @@ import os
|
||||
import sys
|
||||
import pwd
|
||||
import grp
|
||||
import copy
|
||||
import socket
|
||||
|
||||
from gspylib.common.Common import DefaultValue
|
||||
@ -213,6 +214,39 @@ General options:
|
||||
self.initClusterInfoFromStaticFile(self.user)
|
||||
self.logger.debug("Successfully init global infos")
|
||||
|
||||
def distributeFileToSpecialNode(self, file, destDir, hostList):
|
||||
"""
|
||||
distribute file to special node
|
||||
:param file:
|
||||
:param destDir:
|
||||
:param hostList:
|
||||
:return:
|
||||
"""
|
||||
if not hostList:
|
||||
hostList = copy.deepcopy(self.clusterNodes)
|
||||
else:
|
||||
hostList = copy.deepcopy(hostList)
|
||||
if DefaultValue.GetHostIpOrName() in hostList:
|
||||
hostList.remove(DefaultValue.GetHostIpOrName())
|
||||
|
||||
self.logger.debug("Start copy file:{0} to hosts:{1}.".format(
|
||||
file, hostList))
|
||||
if not os.path.exists(file):
|
||||
raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % file)
|
||||
self.logger.debug("Distribute the file %s" % file)
|
||||
retry = True
|
||||
count = 0
|
||||
while retry:
|
||||
try:
|
||||
if count > 4:
|
||||
retry = False
|
||||
self.sshTool.scpFiles(file, destDir, hostList)
|
||||
retry = False
|
||||
except Exception as e:
|
||||
count += 1
|
||||
self.logger.debug("Retry distributing xml command, "
|
||||
"the {0} time.".format(count))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
"""
|
||||
|
@ -109,6 +109,7 @@ from gspylib.common.VersionInfo import VersionInfo
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher, \
|
||||
algorithms, modes
|
||||
import impl.upgrade.UpgradeConst as Const
|
||||
|
||||
noPassIPs = []
|
||||
g_lock = thread.allocate_lock()
|
||||
@ -3674,6 +3675,11 @@ class DefaultValue():
|
||||
|
||||
tarLists = "--exclude=script/*.log --exclude=*.log script " \
|
||||
"version.cfg lib"
|
||||
upgrade_sql_file_path = os.path.join(packageDir,
|
||||
Const.UPGRADE_SQL_FILE)
|
||||
if os.path.exists(upgrade_sql_file_path):
|
||||
tarLists += " %s %s" % (Const.UPGRADE_SQL_SHA,
|
||||
Const.UPGRADE_SQL_FILE)
|
||||
if "HOST_IP" in os.environ.keys():
|
||||
tarLists += " cluster_default_agent.xml"
|
||||
try:
|
||||
@ -4163,6 +4169,37 @@ class DefaultValue():
|
||||
else:
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def getPrimaryNode(userProfile):
|
||||
"""
|
||||
:param
|
||||
:return: PrimaryNode
|
||||
"""
|
||||
try:
|
||||
primaryFlag = "Primary"
|
||||
count = 0
|
||||
while count < 60:
|
||||
count = 0
|
||||
cmd = "source {0} && gs_om -t status --detail".format(
|
||||
userProfile)
|
||||
(status, output) = subprocess.getstatusoutput(cmd)
|
||||
if status == 0:
|
||||
break
|
||||
time.sleep(10)
|
||||
count += 1
|
||||
if status != 0:
|
||||
raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] %
|
||||
"Command:%s. Error:\n%s" % (cmd, output))
|
||||
targetString = output.split("Datanode")[1]
|
||||
dnPrimary = [x for x in re.split(r"[|\n]", targetString)
|
||||
if primaryFlag in x]
|
||||
primaryList = []
|
||||
for dn in dnPrimary:
|
||||
primaryList.append(list(filter(None, dn.split(" ")))[1])
|
||||
return primaryList, output
|
||||
except Exception as e:
|
||||
raise Exception(str(e))
|
||||
|
||||
|
||||
class ClusterCommand():
|
||||
'''
|
||||
|
@ -804,31 +804,6 @@ class peerInstanceInfo():
|
||||
ret += ",peer2Role=%d" % self.peer2Role
|
||||
return ret
|
||||
|
||||
|
||||
class dnSyncInfo():
|
||||
def __init__(self):
|
||||
self.senderSentLocation = "0/0"
|
||||
self.senderWriteLocation = "0/0"
|
||||
self.senderFlushLocation = "0/0"
|
||||
self.senderReplayLocation = "0/0"
|
||||
self.receiverReceivedLocation = "0/0"
|
||||
self.receiverWriteLocation = "0/0"
|
||||
self.receiverFlushLocation = "0/0"
|
||||
self.receiverReplayLocation = "0/0"
|
||||
self.syncState = "Unknown"
|
||||
self.peerRole = "Unknown"
|
||||
self.secondSenderSentLocation = ""
|
||||
self.secondSenderWriteLocation = ""
|
||||
self.secondSenderFlushLocation = ""
|
||||
self.secondSenderReplayLocation = ""
|
||||
self.secondReceiverReceivedLocation = ""
|
||||
self.secondReceiverWriteLocation = ""
|
||||
self.secondReceiverFlushLocation = ""
|
||||
self.secondReceiverReplayLocation = ""
|
||||
self.secondSyncState = ""
|
||||
self.secondPeerRole = ""
|
||||
|
||||
|
||||
class instanceInfo():
|
||||
"""
|
||||
Instance information
|
||||
@ -1410,9 +1385,9 @@ class dbClusterInfo():
|
||||
"""
|
||||
try:
|
||||
with open(staticConfigFile, "rb") as fp:
|
||||
info = fp.read(32)
|
||||
info = fp.read(28)
|
||||
(crc, lenth, version, currenttime, nodeNum,
|
||||
localNodeId) = struct.unpack("=qIIqiI", info)
|
||||
localNodeId) = struct.unpack("=IIIqiI", info)
|
||||
except Exception as e:
|
||||
raise Exception(
|
||||
ErrorCode.GAUSS_512["GAUSS_51236"] + " Error: \n%s." % str(e))
|
||||
@ -1446,7 +1421,6 @@ class dbClusterInfo():
|
||||
(clusterState, syncInfo) = self.__getDnSenderStatus(sshtool,
|
||||
localHostName,
|
||||
nodeId)
|
||||
dnTotalNum = self.__getDnInstanceNum()
|
||||
outText = \
|
||||
"--------------------------------------------------------------" \
|
||||
"---------\n\n"
|
||||
@ -1457,13 +1431,11 @@ class dbClusterInfo():
|
||||
"----------------------------------\n\n"
|
||||
for dbNode in self.dbNodes:
|
||||
if dbNode.id == nodeId or nodeId == 0:
|
||||
outText = outText + (
|
||||
"node : %u\n" % dbNode.id)
|
||||
outText = outText + (
|
||||
"node_name : %s\n\n" % dbNode.name)
|
||||
for dnInst in dbNode.datanodes:
|
||||
outText = outText + (
|
||||
"node : %u\n" % dbNode.id)
|
||||
outText = outText + (
|
||||
"node_name : %s\n" % dbNode.name)
|
||||
outText = outText + (
|
||||
"instance_id : %u\n" %
|
||||
dnInst.instanceId)
|
||||
@ -1474,128 +1446,65 @@ class dbClusterInfo():
|
||||
dnInst.datadir)
|
||||
outText = outText + "type : " \
|
||||
"Datanode\n"
|
||||
if dnTotalNum == 1 and dnInst.localRole in \
|
||||
DN_ROLE_MAP.keys():
|
||||
outText = outText + "instance_state : " \
|
||||
"Primary\n"
|
||||
else:
|
||||
outText = outText + (
|
||||
"instance_state : %s\n" %
|
||||
dnInst.localRole)
|
||||
outText = outText + (
|
||||
"static_connections : %s\n" %
|
||||
dnInst.staticConnections)
|
||||
outText = outText + (
|
||||
"HA_state : %s\n" %
|
||||
"instance_state : %s\n" %
|
||||
dnInst.state)
|
||||
if dnInst.state == "Normal":
|
||||
outText = outText + "reason : " \
|
||||
"Normal\n"
|
||||
else:
|
||||
outText = outText + "reason : " \
|
||||
"Unknown\n"
|
||||
if dnInst.localRole == "Primary":
|
||||
if syncInfo.peerRole == "":
|
||||
syncInfo.peerRole = "Unknown"
|
||||
outText = outText + (
|
||||
"standby_state : %s\n" %
|
||||
syncInfo.peerRole)
|
||||
"static_connections : %s\n\n" %
|
||||
dnInst.staticConnections)
|
||||
outText = outText + (
|
||||
"sender_sent_location : %s\n" %
|
||||
syncInfo.senderSentLocation)
|
||||
outText = outText + (
|
||||
"sender_write_location : %s\n" %
|
||||
syncInfo.senderWriteLocation)
|
||||
outText = outText + (
|
||||
"sender_flush_location : %s\n" %
|
||||
syncInfo.senderFlushLocation)
|
||||
outText = outText + (
|
||||
"sender_replay_location : %s\n" %
|
||||
syncInfo.senderReplayLocation)
|
||||
outText = outText + (
|
||||
"receiver_received_location: %s\n" %
|
||||
syncInfo.receiverReceivedLocation)
|
||||
outText = outText + (
|
||||
"receiver_write_location : %s\n" %
|
||||
syncInfo.receiverWriteLocation)
|
||||
outText = outText + (
|
||||
"receiver_flush_location : %s\n" %
|
||||
syncInfo.receiverFlushLocation)
|
||||
outText = outText + (
|
||||
"receiver_replay_location : %s\n" %
|
||||
syncInfo.receiverReplayLocation)
|
||||
if syncInfo.syncState == "":
|
||||
syncInfo.syncState = "Unknown"
|
||||
outText = outText + (
|
||||
"sync_state : %s\n" %
|
||||
syncInfo.syncState)
|
||||
if syncInfo.secondPeerRole == "":
|
||||
outText = outText + "\n------------------------" \
|
||||
"---------------" \
|
||||
"HA_state : %s\n" %
|
||||
clusterState)
|
||||
outText = outText + (
|
||||
"instance_role : %s\n" %
|
||||
dnInst.localRole)
|
||||
if dnInst.localRole == "Primary":
|
||||
outText = outText + "------------------------" \
|
||||
"---------------" \
|
||||
"--------------------------------\n\n"
|
||||
continue
|
||||
for i_loop in syncInfo:
|
||||
if i_loop[11] == '':
|
||||
i_loop[11] = 'Unknown'
|
||||
if i_loop[0] == dnInst.listenIps[0]:
|
||||
outText = outText + (
|
||||
"HA_state : %s\n" %
|
||||
i_loop[1])
|
||||
outText = outText + (
|
||||
"sender_sent_location : %s\n" %
|
||||
i_loop[2])
|
||||
outText = outText + (
|
||||
"sender_write_location : %s\n" %
|
||||
i_loop[3])
|
||||
outText = outText + (
|
||||
"sender_flush_location : %s\n" %
|
||||
i_loop[4])
|
||||
outText = outText + (
|
||||
"sender_replay_location : %s\n" %
|
||||
i_loop[5])
|
||||
outText = outText + (
|
||||
"receiver_received_location: %s\n" %
|
||||
i_loop[6])
|
||||
outText = outText + (
|
||||
"receiver_write_location : %s\n" %
|
||||
i_loop[7])
|
||||
outText = outText + (
|
||||
"receiver_flush_location : %s\n" %
|
||||
i_loop[8])
|
||||
outText = outText + (
|
||||
"receiver_replay_location : %s\n" %
|
||||
i_loop[9])
|
||||
outText = outText + (
|
||||
"sync_percent : %s\n" %
|
||||
i_loop[10])
|
||||
outText = outText + (
|
||||
"sync_state : %s\n\n" %
|
||||
i_loop[11])
|
||||
outText = outText + "------------------------" \
|
||||
"---------------" \
|
||||
"--------------------------------\n\n"
|
||||
continue
|
||||
if syncInfo.secondSyncState == "":
|
||||
syncInfo.secondSyncState = "Unknown"
|
||||
outText = outText + (
|
||||
"secondary_state : %s\n" %
|
||||
syncInfo.secondPeerRole)
|
||||
outText = outText + (
|
||||
"sender_sent_location : %s\n" %
|
||||
syncInfo.secondSenderSentLocation)
|
||||
outText = outText + (
|
||||
"sender_write_location : %s\n" %
|
||||
syncInfo.secondSenderWriteLocation)
|
||||
outText = outText + (
|
||||
"sender_flush_location : %s\n" %
|
||||
syncInfo.secondSenderFlushLocation)
|
||||
outText = outText + (
|
||||
"sender_replay_location : %s\n" %
|
||||
syncInfo.secondSenderReplayLocation)
|
||||
outText = outText + (
|
||||
"receiver_received_location: %s\n" %
|
||||
syncInfo.secondReceiverReceivedLocation)
|
||||
outText = outText + (
|
||||
"receiver_write_location : %s\n" %
|
||||
syncInfo.secondReceiverWriteLocation)
|
||||
outText = outText + (
|
||||
"receiver_flush_location : %s\n" %
|
||||
syncInfo.secondReceiverFlushLocation)
|
||||
outText = outText + (
|
||||
"receiver_replay_location : %s\n" %
|
||||
syncInfo.secondReceiverReplayLocation)
|
||||
outText = outText + (
|
||||
"sync_state : %s\n" %
|
||||
syncInfo.secondSyncState)
|
||||
else:
|
||||
outText = outText + (
|
||||
"sender_sent_location : %s\n" %
|
||||
syncInfo.senderSentLocation)
|
||||
outText = outText + (
|
||||
"sender_write_location : %s\n" %
|
||||
syncInfo.senderWriteLocation)
|
||||
outText = outText + (
|
||||
"sender_flush_location : %s\n" %
|
||||
syncInfo.senderFlushLocation)
|
||||
outText = outText + (
|
||||
"sender_replay_location : %s\n" %
|
||||
syncInfo.senderReplayLocation)
|
||||
outText = outText + (
|
||||
"receiver_received_location: %s\n" %
|
||||
syncInfo.receiverReceivedLocation)
|
||||
outText = outText + (
|
||||
"receiver_write_location : %s\n" %
|
||||
syncInfo.receiverWriteLocation)
|
||||
outText = outText + (
|
||||
"receiver_flush_location : %s\n" %
|
||||
syncInfo.receiverFlushLocation)
|
||||
outText = outText + (
|
||||
"receiver_replay_location : %s\n" %
|
||||
syncInfo.receiverReplayLocation)
|
||||
outText = outText + (
|
||||
"sync_state : Async\n")
|
||||
outText = outText + \
|
||||
"\n---------------------------------------" \
|
||||
"--------------------------------\n\n"
|
||||
break
|
||||
if nodeId != 0:
|
||||
break
|
||||
else:
|
||||
@ -1802,8 +1711,8 @@ class dbClusterInfo():
|
||||
outText = \
|
||||
"-------------------------------------------------" \
|
||||
"----------------------\n\n" \
|
||||
"cluster_state : %s\nredistributing : No\n\n" % \
|
||||
clusterState
|
||||
"cluster_name : %s\ncluster_state : %s\nredistributing : No\n\n" % \
|
||||
(self.name, clusterState)
|
||||
outText = outText + \
|
||||
"-------------------------------------------" \
|
||||
"----------------------------\n"
|
||||
@ -1895,23 +1804,14 @@ class dbClusterInfo():
|
||||
return dnInsNum
|
||||
|
||||
def __getDnSenderStatus(self, sshtool, localHostName, nodeId):
|
||||
secondSql = "select sender_sent_location,sender_write_location," \
|
||||
"sender_flush_location," \
|
||||
"sender_replay_location,receiver_received_location," \
|
||||
"receiver_write_location," \
|
||||
"receiver_flush_location,receiver_replay_location," \
|
||||
"sync_state,peer_role " \
|
||||
" from pg_stat_get_wal_senders() where " \
|
||||
"peer_role='Standby';"
|
||||
thirdSql = "select sender_sent_location,sender_write_location," \
|
||||
"sender_flush_location," \
|
||||
"sender_replay_location,receiver_received_location," \
|
||||
"receiver_write_location," \
|
||||
"receiver_flush_location,receiver_replay_location," \
|
||||
"sync_state,peer_role " \
|
||||
" from pg_stat_get_wal_senders() where " \
|
||||
"peer_role='Secondary';"
|
||||
syncInfo = dnSyncInfo()
|
||||
sql_get = "select a.client_addr, b.state, b.sender_sent_location," \
|
||||
"b.sender_write_location, b.sender_flush_location," \
|
||||
"b.sender_replay_location, b.receiver_received_location," \
|
||||
"b.receiver_write_location, b.receiver_flush_location," \
|
||||
"b.receiver_replay_location, b.sync_percent, b.sync_state " \
|
||||
"from pg_stat_replication a inner join " \
|
||||
"pg_stat_get_wal_senders() b on a.pid = b.pid;"
|
||||
syncInfo = []
|
||||
clusterState = "Normal"
|
||||
primaryDbState = "Normal"
|
||||
primaryDbNum = 0
|
||||
@ -1919,7 +1819,6 @@ class dbClusterInfo():
|
||||
for dbNode in self.dbNodes:
|
||||
for dnInst in dbNode.datanodes:
|
||||
dnNodeCount += 1
|
||||
minValidLine = 2
|
||||
self.__getDnState(dnInst, dbNode, localHostName, sshtool)
|
||||
if dnInst.localRole == "Primary":
|
||||
primaryDbState = dnInst.state
|
||||
@ -1927,83 +1826,28 @@ class dbClusterInfo():
|
||||
output = ""
|
||||
if dbNode.name != localHostName:
|
||||
cmd = "[need_replace_quotes] gsql -m -d postgres -p " \
|
||||
"%s -c \"%s\"" % \
|
||||
(dnInst.port, secondSql)
|
||||
"%s -A -t -c \"%s\"" % \
|
||||
(dnInst.port, sql_get)
|
||||
(statusMap, output) = sshtool.getSshStatusOutput(cmd, [
|
||||
dbNode.name])
|
||||
if statusMap[dbNode.name] != 'Success' or output.find(
|
||||
"failed to connect") >= 0:
|
||||
continue
|
||||
else:
|
||||
output = '\n'.join(output.split('\n')[1:])
|
||||
output = output.split('\n')[1:-1]
|
||||
else:
|
||||
cmd = "gsql -m -d postgres -p %s -c \"%s\"" % (
|
||||
dnInst.port, secondSql)
|
||||
cmd = "gsql -m -d postgres -p %s -A -t -c \"%s\"" % (
|
||||
dnInst.port, sql_get)
|
||||
(status, output) = subprocess.getstatusoutput(cmd)
|
||||
if status != 0 or output.find(
|
||||
"failed to connect") >= 0:
|
||||
continue
|
||||
lineSplitRes = output.split("\n")
|
||||
if len(lineSplitRes) <= minValidLine:
|
||||
continue
|
||||
columnRes = lineSplitRes[minValidLine].split("|")
|
||||
if len(columnRes) != 10:
|
||||
continue
|
||||
syncInfo.senderSentLocation = columnRes[0].strip()
|
||||
syncInfo.senderWriteLocation = columnRes[1].strip()
|
||||
syncInfo.senderFlushLocation = columnRes[2].strip()
|
||||
syncInfo.senderReplayLocation = columnRes[3].strip()
|
||||
syncInfo.receiverReceivedLocation = columnRes[4].strip()
|
||||
syncInfo.receiverWriteLocation = columnRes[5].strip()
|
||||
syncInfo.receiverFlushLocation = columnRes[6].strip()
|
||||
syncInfo.receiverReplayLocation = columnRes[7].strip()
|
||||
syncInfo.syncState = columnRes[8].strip()
|
||||
syncInfo.peerRole = columnRes[9].strip()
|
||||
if nodeId == dbNode.id:
|
||||
output = ""
|
||||
if dbNode.name != localHostName:
|
||||
cmd = "[need_replace_quotes] gsql -m -d " \
|
||||
"postgres -p %s -c \"%s\"" % (
|
||||
dnInst.port, thirdSql)
|
||||
(statusMap, output) = sshtool.getSshStatusOutput(
|
||||
cmd, [dbNode.name])
|
||||
if statusMap[
|
||||
dbNode.name] != 'Success' or output.find(
|
||||
"failed to connect") >= 0:
|
||||
continue
|
||||
else:
|
||||
cmd = "gsql -m -d postgres -p %s -c \"%s\"" % (
|
||||
dnInst.port, thirdSql)
|
||||
(status, output) = subprocess.getstatusoutput(cmd)
|
||||
if status != 0 or output.find(
|
||||
"failed to connect") >= 0:
|
||||
continue
|
||||
|
||||
lineSplitRes = output.split("\n")
|
||||
if len(lineSplitRes) <= minValidLine:
|
||||
continue
|
||||
columnRes = lineSplitRes[minValidLine].split("|")
|
||||
if len(columnRes) != 10:
|
||||
# maybe no sql query result
|
||||
continue
|
||||
syncInfo.secondSenderSentLocation = columnRes[
|
||||
0].strip()
|
||||
syncInfo.secondSenderFlushLocation = columnRes[
|
||||
1].strip()
|
||||
syncInfo.secondSenderReplayLocation = columnRes[
|
||||
2].strip()
|
||||
syncInfo.secondReceiverReceivedLocation = columnRes[
|
||||
3].strip()
|
||||
syncInfo.secondReceiverWriteLocation = columnRes[
|
||||
4].strip()
|
||||
syncInfo.secondReceiverFlushLocation = columnRes[
|
||||
5].strip()
|
||||
syncInfo.receiver_replay_location = columnRes[
|
||||
6].strip()
|
||||
syncInfo.secondReceiverReplayLocation = columnRes[
|
||||
7].strip()
|
||||
syncInfo.secondSyncState = columnRes[8].strip()
|
||||
syncInfo.secondPeerRole = columnRes[9].strip()
|
||||
output = output.split('\n')
|
||||
if not len(output):
|
||||
continue
|
||||
for col_loop in output:
|
||||
syncInfo.append(col_loop.split('|'))
|
||||
else:
|
||||
if dnInst.localRole != "Standby" and \
|
||||
dnInst.localRole != "Secondary" and \
|
||||
@ -2218,12 +2062,22 @@ class dbClusterInfo():
|
||||
# find the path from right to left
|
||||
self.logPath = logPathWithUser[
|
||||
0:(logPathWithUser.rfind(splitMark))]
|
||||
staticConfigFilePath = os.path.split(staticConfigFile)[0]
|
||||
versionFile = os.path.join(
|
||||
staticConfigFilePath, "upgrade_version")
|
||||
version, number, commitid = VersionInfo.get_version_info(
|
||||
versionFile)
|
||||
try:
|
||||
# read static_config_file
|
||||
fp = open(staticConfigFile, "rb")
|
||||
info = fp.read(32)
|
||||
(crc, lenth, version, currenttime, nodeNum,
|
||||
localNodeId) = struct.unpack("=qIIqiI", info)
|
||||
if float(number) <= 92.200:
|
||||
info = fp.read(32)
|
||||
(crc, lenth, version, currenttime, nodeNum,
|
||||
localNodeId) = struct.unpack("=qIIqiI", info)
|
||||
else:
|
||||
info = fp.read(28)
|
||||
(crc, lenth, version, currenttime, nodeNum,
|
||||
localNodeId) = struct.unpack("=IIIqiI", info)
|
||||
self.version = version
|
||||
self.installTime = currenttime
|
||||
self.localNodeId = localNodeId
|
||||
@ -2266,7 +2120,7 @@ class dbClusterInfo():
|
||||
for i in range(nodeNum):
|
||||
offset = (fp.tell() // PAGE_SIZE + 1) * PAGE_SIZE
|
||||
fp.seek(offset)
|
||||
dbNode = self.__unPackNodeInfo(fp, isLCCluster)
|
||||
dbNode = self.__unPackNodeInfo(fp, number, isLCCluster)
|
||||
self.dbNodes.append(dbNode)
|
||||
fp.close()
|
||||
except Exception as e:
|
||||
@ -2278,14 +2132,18 @@ class dbClusterInfo():
|
||||
fp.close()
|
||||
raise Exception(str(e))
|
||||
|
||||
def __unPackNodeInfo(self, fp, isLCCluster=False):
|
||||
def __unPackNodeInfo(self, fp, number, isLCCluster=False):
|
||||
"""
|
||||
function : unpack a node config info
|
||||
input : file
|
||||
output : Object
|
||||
"""
|
||||
info = fp.read(76)
|
||||
(crc, nodeId, nodeName) = struct.unpack("=qI64s", info)
|
||||
if float(number) <= 92.200:
|
||||
info = fp.read(76)
|
||||
(crc, nodeId, nodeName) = struct.unpack("=qI64s", info)
|
||||
else:
|
||||
info = fp.read(72)
|
||||
(crc, nodeId, nodeName) = struct.unpack("=II64s", info)
|
||||
nodeName = nodeName.decode().strip('\x00')
|
||||
dbNode = dbNodeInfo(nodeId, nodeName)
|
||||
info = fp.read(68)
|
||||
@ -2570,11 +2428,21 @@ class dbClusterInfo():
|
||||
"""
|
||||
fp = None
|
||||
try:
|
||||
staticConfigFilePath = os.path.split(staticConfigFile)[0]
|
||||
versionFile = os.path.join(
|
||||
staticConfigFilePath, "upgrade_version")
|
||||
version, number, commitid = VersionInfo.get_version_info(
|
||||
versionFile)
|
||||
# read cluster info from static config file
|
||||
fp = open(staticConfigFile, "rb")
|
||||
info = fp.read(32)
|
||||
(crc, lenth, version, currenttime, nodeNum,
|
||||
localNodeId) = struct.unpack("=qIIqiI", info)
|
||||
if float(number) <= 92.200:
|
||||
info = fp.read(32)
|
||||
(crc, lenth, version, currenttime, nodeNum,
|
||||
localNodeId) = struct.unpack("=qIIqiI", info)
|
||||
else:
|
||||
info = fp.read(28)
|
||||
(crc, lenth, version, currenttime, nodeNum,
|
||||
localNodeId) = struct.unpack("=IIIqiI", info)
|
||||
if (version <= 100):
|
||||
raise Exception(ErrorCode.GAUSS_516["GAUSS_51637"]
|
||||
% ("cluster static config version[%s]"
|
||||
@ -2608,7 +2476,7 @@ class dbClusterInfo():
|
||||
for i in range(nodeNum):
|
||||
offset = (fp.tell() // PAGE_SIZE + 1) * PAGE_SIZE
|
||||
fp.seek(offset)
|
||||
dbNode = self.__unPackNodeInfo(fp)
|
||||
dbNode = self.__unPackNodeInfo(fp, number)
|
||||
self.dbNodes.append(dbNode)
|
||||
fp.close()
|
||||
except Exception as e:
|
||||
@ -4371,9 +4239,8 @@ class dbClusterInfo():
|
||||
raise Exception(ErrorCode.GAUSS_532["GAUSS_53200"])
|
||||
|
||||
if peerNum > 8:
|
||||
raise Exception(ErrorCode.GAUSS_512["GAUSS_51230"] % \
|
||||
("database node standbys", "be less than 5")
|
||||
+ " Please set it.")
|
||||
raise Exception(ErrorCode.GAUSS_512["GAUSS_51230"] % (
|
||||
"database node standbys", "be less than 9") + " Please set it.")
|
||||
|
||||
|
||||
|
||||
@ -4566,13 +4433,21 @@ class dbClusterInfo():
|
||||
else:
|
||||
return instances
|
||||
|
||||
def saveToStaticConfig(self, filePath, localNodeId, dbNodes=None):
|
||||
def saveToStaticConfig(self, filePath, localNodeId, dbNodes=None,
|
||||
upgrade=False):
|
||||
"""
|
||||
function : Save cluster info into to static config
|
||||
input : String,int
|
||||
output : NA
|
||||
"""
|
||||
fp = None
|
||||
number = None
|
||||
if upgrade:
|
||||
staticConfigFilePath = os.path.split(filePath)[0]
|
||||
versionFile = os.path.join(
|
||||
staticConfigFilePath, "upgrade_version")
|
||||
version, number, commitid = VersionInfo.get_version_info(
|
||||
versionFile)
|
||||
try:
|
||||
if (dbNodes is None):
|
||||
dbNodes = self.dbNodes
|
||||
@ -4590,14 +4465,20 @@ class dbClusterInfo():
|
||||
info += struct.pack("I", localNodeId)
|
||||
|
||||
crc = binascii.crc32(info)
|
||||
info = struct.pack("q", crc) + info
|
||||
if upgrade:
|
||||
if float(number) <= 92.200:
|
||||
info = struct.pack("q", crc) + info
|
||||
else:
|
||||
info = struct.pack("I", crc) + info
|
||||
else:
|
||||
info = struct.pack("I", crc) + info
|
||||
fp.write(info)
|
||||
|
||||
for dbNode in dbNodes:
|
||||
offset = (fp.tell() // PAGE_SIZE + 1) * PAGE_SIZE
|
||||
fp.seek(offset)
|
||||
|
||||
info = self.__packNodeInfo(dbNode)
|
||||
info = self.__packNodeInfo(dbNode, number, upgrade=upgrade)
|
||||
fp.write(info)
|
||||
endBytes = PAGE_SIZE - fp.tell() % PAGE_SIZE
|
||||
if (endBytes != PAGE_SIZE):
|
||||
@ -4613,7 +4494,7 @@ class dbClusterInfo():
|
||||
"static configuration file"
|
||||
+ " Error: \n%s" % str(e))
|
||||
|
||||
def __packNodeInfo(self, dbNode):
|
||||
def __packNodeInfo(self, dbNode, number, upgrade=False):
|
||||
"""
|
||||
function : Pack the info of node
|
||||
input : []
|
||||
@ -4649,7 +4530,13 @@ class dbClusterInfo():
|
||||
info += struct.pack("I", 0)
|
||||
crc = binascii.crc32(info)
|
||||
|
||||
return struct.pack("q", crc) + info
|
||||
if upgrade:
|
||||
if float(number) <= 92.200:
|
||||
return struct.pack("q", crc) + info
|
||||
else:
|
||||
return struct.pack("I", crc) + info
|
||||
else:
|
||||
return struct.pack("I", crc) + info
|
||||
|
||||
def __packNodeInfoForLC(self, dbNode):
|
||||
"""
|
||||
@ -4672,7 +4559,7 @@ class dbClusterInfo():
|
||||
info += struct.pack("I", 0)
|
||||
crc = binascii.crc32(info)
|
||||
|
||||
return struct.pack("q", crc) + info
|
||||
return struct.pack("I", crc) + info
|
||||
|
||||
def __packEtcdInfo(self, dbNode):
|
||||
"""
|
||||
@ -6092,7 +5979,7 @@ class dbClusterInfo():
|
||||
# node count
|
||||
info += struct.pack("I", len(self.dbNodes))
|
||||
crc = binascii.crc32(info)
|
||||
info = struct.pack("q", crc) + info
|
||||
info = struct.pack("I", crc) + info
|
||||
fp.write(info)
|
||||
primaryDnNum = 0
|
||||
for dbNode in self.dbNodes:
|
||||
@ -6195,7 +6082,7 @@ class dbClusterInfo():
|
||||
info += struct.pack("I", 0)
|
||||
info += struct.pack("I", 0)
|
||||
crc = binascii.crc32(info)
|
||||
return (primaryNum, struct.pack("q", crc) + info)
|
||||
return (primaryNum, struct.pack("I", crc) + info)
|
||||
|
||||
def __getClusterSwitchTime(self, dynamicConfigFile):
|
||||
"""
|
||||
@ -6207,9 +6094,9 @@ class dbClusterInfo():
|
||||
fp = None
|
||||
try:
|
||||
fp = open(dynamicConfigFile, "rb")
|
||||
info = fp.read(28)
|
||||
info = fp.read(24)
|
||||
(crc, lenth, version, switchTime, nodeNum) = \
|
||||
struct.unpack("=qIIqi", info)
|
||||
struct.unpack("=IIIqi", info)
|
||||
fp.close()
|
||||
except Exception as e:
|
||||
if fp:
|
||||
@ -6344,15 +6231,25 @@ class dbClusterInfo():
|
||||
logPathWithUser[0:(logPathWithUser.rfind(splitMark))]
|
||||
dynamicConfigFile = self.__getDynamicConfig(user)
|
||||
# read dynamic_config_file
|
||||
dynamicConfigFilePath = os.path.split(dynamicConfigFile)[0]
|
||||
versionFile = os.path.join(
|
||||
dynamicConfigFilePath, "upgrade_version")
|
||||
version, number, commitid = VersionInfo.get_version_info(
|
||||
versionFile)
|
||||
fp = open(dynamicConfigFile, "rb")
|
||||
info = fp.read(28)
|
||||
(crc, lenth, version, currenttime, nodeNum) = \
|
||||
struct.unpack("=qIIqi", info)
|
||||
if float(number) <= 92.200:
|
||||
info = fp.read(28)
|
||||
(crc, lenth, version, currenttime, nodeNum) = \
|
||||
struct.unpack("=qIIqi", info)
|
||||
else:
|
||||
info = fp.read(24)
|
||||
(crc, lenth, version, currenttime, nodeNum) = \
|
||||
struct.unpack("=IIIqi", info)
|
||||
totalMaterDnNum = 0
|
||||
for i in range(nodeNum):
|
||||
offset = (fp.tell() // PAGE_SIZE + 1) * PAGE_SIZE
|
||||
fp.seek(offset)
|
||||
(dbNode, materDnNum) = self.__unpackDynamicNodeInfo(fp)
|
||||
(dbNode, materDnNum) = self.__unpackDynamicNodeInfo(fp, number)
|
||||
totalMaterDnNum += materDnNum
|
||||
self.dbNodes.append(dbNode)
|
||||
if totalMaterDnNum != 1:
|
||||
@ -6365,9 +6262,13 @@ class dbClusterInfo():
|
||||
raise Exception(ErrorCode.GAUSS_502["GAUSS_50204"] %
|
||||
dynamicConfigFile + " Error:\n" + str(e))
|
||||
|
||||
def __unpackDynamicNodeInfo(self, fp):
|
||||
info = fp.read(76)
|
||||
(crc, nodeId, nodeName) = struct.unpack("=qI64s", info)
|
||||
def __unpackDynamicNodeInfo(self, fp, number):
|
||||
if float(number) <= 92.200:
|
||||
info = fp.read(76)
|
||||
(crc, nodeId, nodeName) = struct.unpack("=qI64s", info)
|
||||
else:
|
||||
info = fp.read(72)
|
||||
(crc, nodeId, nodeName) = struct.unpack("=II64s", info)
|
||||
nodeName = nodeName.decode().strip('\x00')
|
||||
dbNode = dbNodeInfo(nodeId, nodeName)
|
||||
info = fp.read(4)
|
||||
|
@ -1126,9 +1126,9 @@ class ErrorCode():
|
||||
"missing in the command.",
|
||||
"GAUSS_35802": "[GAUSS-35802] The IP list of target node: %s"
|
||||
"is not in the current cluster. Please check!",
|
||||
"GAUSS_35803": "[GAUSS-35803] The IP of primary node %s is in the "
|
||||
"GAUSS_35803": "[GAUSS-35803] The IP of local host %s is in the "
|
||||
"target node list. \n"
|
||||
"The primary node can not be dropped! \n",
|
||||
"Can not drop local host!\n",
|
||||
"GAUSS_35804": "[GAUSS-35804] The dropnode operation can only be executed"
|
||||
" at the primary node. \n ",
|
||||
"GAUSS_35805": "[GAUSS-35805] Input %s. Operation aborted. ",
|
||||
@ -1136,7 +1136,7 @@ class ErrorCode():
|
||||
"It doesn't meet the requirement.! ",
|
||||
"GAUSS_35807": "[GAUSS-35807] The host %s which still exist in the "
|
||||
"cluster can't be connected.\n"
|
||||
"It doesn't meet the requirement.! ",
|
||||
"It doesn't meet the requirement! ",
|
||||
"GAUSS_35808": "[GAUSS-35808] The %s is running switchover/failover!\n"
|
||||
"The dropnode operation can only be executed when there is"
|
||||
" no such operation!",
|
||||
|
@ -229,6 +229,60 @@ class OMCommand():
|
||||
except Exception as e:
|
||||
raise Exception(str(e))
|
||||
|
||||
@staticmethod
|
||||
def doCheckStaus(user, nodeId, cluster_normal_status=None,
|
||||
expected_redistributing=""):
|
||||
"""
|
||||
function: Check cluster status
|
||||
input : user, nodeId, cluster_normal_status, expected_redistributing
|
||||
output: status, output
|
||||
"""
|
||||
try:
|
||||
statusFile = "/home/%s/gauss_check_status_%d.dat" % (
|
||||
user, os.getpid())
|
||||
TempfileManagement.removeTempFile(statusFile)
|
||||
cmd = ClusterCommand.getQueryStatusCmd(user, "", statusFile)
|
||||
(status, output) = subprocess.getstatusoutput(cmd)
|
||||
if status != 0:
|
||||
TempfileManagement.removeTempFile(statusFile)
|
||||
return (status, output)
|
||||
|
||||
clusterStatus = DbClusterStatus()
|
||||
clusterStatus.initFromFile(statusFile)
|
||||
TempfileManagement.removeTempFile(statusFile)
|
||||
except Exception as e:
|
||||
DefaultValue.cleanTmpFile(statusFile)
|
||||
raise Exception(
|
||||
ErrorCode.GAUSS_516["GAUSS_51600"] + "Error: %s." % str(e))
|
||||
status = 0
|
||||
output = ""
|
||||
statusRep = None
|
||||
if nodeId > 0:
|
||||
nodeStatus = clusterStatus.getDbNodeStatusById(nodeId)
|
||||
if nodeStatus is None:
|
||||
raise Exception(ErrorCode.GAUSS_516["GAUSS_51619"] % nodeId)
|
||||
|
||||
status = 0 if nodeStatus.isNodeHealthy() else 1
|
||||
statusRep = nodeStatus.getNodeStatusReport()
|
||||
else:
|
||||
status = 0 if clusterStatus.isAllHealthy(cluster_normal_status) \
|
||||
and (clusterStatus.redistributing ==
|
||||
expected_redistributing or
|
||||
expected_redistributing == "") else 1
|
||||
statusRep = clusterStatus.getClusterStatusReport()
|
||||
output += "cluster_state : %s\n" % clusterStatus.clusterStatus
|
||||
output += "redistributing : %s\n" % clusterStatus.redistributing
|
||||
output += "node_count : %d\n" % statusRep.nodeCount
|
||||
output += "Datanode State\n"
|
||||
output += " primary : %d\n" % statusRep.dnPrimary
|
||||
output += " standby : %d\n" % statusRep.dnStandby
|
||||
output += " secondary : %d\n" % statusRep.dnDummy
|
||||
output += " building : %d\n" % statusRep.dnBuild
|
||||
output += " abnormal : %d\n" % statusRep.dnAbnormal
|
||||
output += " down : %d\n" % statusRep.dnDown
|
||||
|
||||
return (status, output)
|
||||
|
||||
@staticmethod
|
||||
def getClusterStatus(user, isExpandScene=False):
|
||||
"""
|
||||
|
@ -790,7 +790,7 @@ class ParallelBaseOM(object):
|
||||
|
||||
return output.strip()
|
||||
|
||||
def killKernalSnapshotThread(self, coorInst):
|
||||
def killKernalSnapshotThread(self, dnInst):
|
||||
"""
|
||||
function: kill snapshot thread in Kernel,
|
||||
avoid dead lock with redistribution)
|
||||
@ -801,7 +801,7 @@ class ParallelBaseOM(object):
|
||||
killSnapshotSQL = "select * from kill_snapshot();"
|
||||
|
||||
(status, output) = ClusterCommand.remoteSQLCommand(
|
||||
killSnapshotSQL, self.user, coorInst.hostname, coorInst.port,
|
||||
killSnapshotSQL, self.user, dnInst.hostname, dnInst.port,
|
||||
False, DefaultValue.DEFAULT_DB_NAME)
|
||||
if (status != 0):
|
||||
raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] %
|
||||
@ -886,7 +886,7 @@ class ParallelBaseOM(object):
|
||||
self.sshTool.scpFiles(scpFile, caPath, hostList)
|
||||
self.logger.debug("Successfully generated grpc CA files.")
|
||||
|
||||
def genCipherAndRandFile(self, hostList=None):
|
||||
def genCipherAndRandFile(self, hostList=None, initPwd=None):
|
||||
self.logger.debug("Encrypting cipher and rand files.")
|
||||
if hostList is None:
|
||||
hostList = []
|
||||
@ -894,8 +894,11 @@ class ParallelBaseOM(object):
|
||||
binPath = os.path.join(appPath, "bin")
|
||||
retry = 0
|
||||
while True:
|
||||
sshpwd = getpass.getpass("Please enter password for database:")
|
||||
sshpwd_check = getpass.getpass("Please repeat for database:")
|
||||
if not initPwd:
|
||||
sshpwd = getpass.getpass("Please enter password for database:")
|
||||
sshpwd_check = getpass.getpass("Please repeat for database:")
|
||||
else:
|
||||
sshpwd = sshpwd_check = initPwd
|
||||
if sshpwd_check != sshpwd:
|
||||
sshpwd = ""
|
||||
sshpwd_check = ""
|
||||
@ -910,6 +913,7 @@ class ParallelBaseOM(object):
|
||||
(status, output) = subprocess.getstatusoutput(cmd)
|
||||
sshpwd = ""
|
||||
sshpwd_check = ""
|
||||
initPwd = ""
|
||||
if status != 0:
|
||||
self.logger.error(
|
||||
ErrorCode.GAUSS_503["GAUSS_50322"] % "database"
|
||||
|
@ -79,7 +79,7 @@ gs_check = ["-?", "--help", "-V", "--version", "-e:", "-i:",
|
||||
"--ShrinkNodes=", "--nodegroup-name=",
|
||||
"--skip-root-items", "--set"]
|
||||
gs_sshexkey = ["-?", "--help", "-V", "--version",
|
||||
"-f:", "--skip-hostname-set", "-l:"]
|
||||
"-f:", "--skip-hostname-set", "-l:", "-h:", "-W:"]
|
||||
gs_backup = ["-?", "--help", "-V", "--version", "--backup-dir=",
|
||||
"--parameter", "--force",
|
||||
"--binary", "--all", "-l:", "-h:", "-t:", "-X:"]
|
||||
@ -104,6 +104,9 @@ gs_om_start = ["-t:", "-?", "--help", "-V", "--version", "-h:", "-I:",
|
||||
"--security-mode="]
|
||||
gs_om_stop = ["-t:", "-?", "--help", "-V", "--version", "-h:", "-I:", "-m:",
|
||||
"--az=", "-l:", "--mode=", "--nodeId=", "--time-out=", "-D:"]
|
||||
gs_om_restart= ["-t:", "-?", "--help", "-V", "--version", "-h:", "-I:",
|
||||
"--time-out=", "--az=", "-l:", "--nodeId=", "-D:",
|
||||
"--security-mode="]
|
||||
gs_om_view = ["-t:", "-?", "--help", "-V", "--version", "-o:", "-l:"]
|
||||
gs_om_query = ["-t:", "-?", "--help", "-V", "--version", "-o:", "-l:"]
|
||||
gs_om_status = ["-t:", "-?", "--help", "-V", "--version", "-h:", "-o:",
|
||||
@ -146,6 +149,7 @@ ParameterDict = {"preinstall": gs_preinstall,
|
||||
"auto_rollback": gs_upgradectl_auto_rollback,
|
||||
"start": gs_om_start,
|
||||
"stop": gs_om_stop,
|
||||
"restart": gs_om_restart,
|
||||
"status": gs_om_status,
|
||||
"generateconf": gs_om_generateconf,
|
||||
"cert": gs_om_cert,
|
||||
@ -166,7 +170,7 @@ ParameterDict = {"preinstall": gs_preinstall,
|
||||
special_list = ["gs_om", "backup", "upgradectl"]
|
||||
|
||||
# The -t parameter list
|
||||
action_om = ["start", "stop", "status", "generateconf", "kerberos",
|
||||
action_om = ["start", "stop", "status", "restart","generateconf", "kerberos",
|
||||
"cert", "view", "query", "refreshconf"]
|
||||
action_upgradectl = ["chose-strategy", "auto-upgrade", "auto-rollback",
|
||||
"commit-upgrade"]
|
||||
|
@ -67,10 +67,16 @@ class Kernel(BaseComponent):
|
||||
"""
|
||||
|
||||
def start(self, time_out=DefaultValue.TIMEOUT_CLUSTER_START,
|
||||
security_mode="off"):
|
||||
security_mode="off", cluster_number=None):
|
||||
"""
|
||||
"""
|
||||
cmd = "%s/gs_ctl start -D %s " % (self.binPath, self.instInfo.datadir)
|
||||
if cluster_number:
|
||||
cmd = "%s/gs_ctl start -o '-u %s' -D %s " % (
|
||||
self.binPath, int(float(cluster_number) * 1000),
|
||||
self.instInfo.datadir)
|
||||
else:
|
||||
cmd = "%s/gs_ctl start -D %s " % (
|
||||
self.binPath, self.instInfo.datadir)
|
||||
if self.instInfo.instanceType == DefaultValue.MASTER_INSTANCE:
|
||||
if len(self.instInfo.peerInstanceInfos) > 0:
|
||||
cmd += "-M primary"
|
||||
|
@ -236,7 +236,8 @@ class CheckResult(object):
|
||||
for itemResult in self._items:
|
||||
resultDic['name'] = itemResult.name
|
||||
resultDic['category'] = itemResult.category
|
||||
resultDic['std'] = itemResult.standard.decode('utf-8', 'ignore')
|
||||
resultDic['std'] = "" if itemResult.standard.strip() == "" \
|
||||
else itemResult.standard.decode('utf-8', 'ignore')
|
||||
resultDic['rst'] = itemResult.rst
|
||||
resultDic['analysis'] = itemResult.analysis
|
||||
resultDic['suggestion'] = itemResult.suggestion
|
||||
|
@ -66,8 +66,8 @@ class CheckNICModel(BaseItem):
|
||||
cmd = "lspci |grep %s" % PCIAddr
|
||||
(status, output) = subprocess.getstatusoutput(cmd)
|
||||
self.result.raw += "%s\n" % (output)
|
||||
if (status == 0 and len(output.split(':')) == 3):
|
||||
modelInfo = output.split(':')[2].split('(')[0]
|
||||
if status == 0 and len(output.split(':')) >= 3:
|
||||
modelInfo = ':'.join(output.split(':')[2:]).split('(')[0]
|
||||
self.result.val += "model: %s\n" % (modelInfo.strip())
|
||||
else:
|
||||
self.result.val += "Failed to get NIC %s model" \
|
||||
|
@ -465,7 +465,7 @@ class OperCommon:
|
||||
"""
|
||||
self.logger.log(
|
||||
"[gs_dropnode]Start to parse parameter config file on %s." % host)
|
||||
resultDict = {'replStr': '', 'syncStandbyStr': '', 'pghbaStr': ''}
|
||||
resultDict = {'replStr': '', 'syncStandbyStr': '*', 'pghbaStr': ''}
|
||||
pgConfName = os.path.join(dirDn, 'postgresql.conf')
|
||||
pghbaConfName = os.path.join(dirDn, 'pg_hba.conf')
|
||||
|
||||
@ -527,7 +527,9 @@ class OperCommon:
|
||||
output_dn_nospace = list_output1
|
||||
init_no -= 1
|
||||
count_dn += 1
|
||||
if count_dn == 0 or list_output1 == '':
|
||||
if count_dn == 0:
|
||||
return output_result
|
||||
if list_output1 == '':
|
||||
return ''
|
||||
if list_output1 != '*':
|
||||
output_result = output.replace(output_dn, list_output1)
|
||||
@ -601,7 +603,7 @@ class OperCommon:
|
||||
sqlvalue += "ALTER SYSTEM SET replconninfo%s = '%s';" % (
|
||||
i, replValue[:-1].split('|')[count])
|
||||
count += 1
|
||||
if not singleLeft and syncStandbyValue != '':
|
||||
if not singleLeft and syncStandbyValue != '*':
|
||||
sqlvalue += "ALTER SYSTEM SET synchronous_standby_names = '%s';" \
|
||||
% syncStandbyValue
|
||||
if singleLeft:
|
||||
|
@ -175,9 +175,10 @@ class ExpansionImpl():
|
||||
logPath = self.context.clusterInfoDict["logPath"]
|
||||
corePath = self.context.clusterInfoDict["corePath"]
|
||||
toolPath = self.context.clusterInfoDict["toolPath"]
|
||||
mppdbconfig = ""
|
||||
tmpMppdbPath = DefaultValue.getEnv("PGHOST")
|
||||
if not tmpMppdbPath:
|
||||
tmpMppdbPath = toolPath
|
||||
if tmpMppdbPath:
|
||||
mppdbconfig = '<PARAM name="tmpMppdbPath" value="%s" />' % tmpMppdbPath
|
||||
|
||||
xmlConfig = """\
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
@ -189,7 +190,7 @@ class ExpansionImpl():
|
||||
<PARAM name="gaussdbAppPath" value="{appPath}" />
|
||||
<PARAM name="gaussdbLogPath" value="{logPath}" />
|
||||
<PARAM name="gaussdbToolPath" value="{toolPath}" />
|
||||
<PARAM name="tmpMppdbPath" value="{mppdbPath}" />
|
||||
{mappdbConfig}
|
||||
<PARAM name="corePath" value="{corePath}"/>
|
||||
<PARAM name="clusterType" value="single-inst"/>
|
||||
</CLUSTER>
|
||||
@ -210,7 +211,7 @@ class ExpansionImpl():
|
||||
""".format(nodeName=nodeName,backIp=backIp,appPath=appPath,
|
||||
logPath=logPath,toolPath=toolPath,corePath=corePath,
|
||||
sshIp=sshIp,port=port,dataNode=dataNode,azName=self.context.azName,
|
||||
mppdbPath=tmpMppdbPath)
|
||||
mappdbConfig=mppdbconfig)
|
||||
return xmlConfig
|
||||
|
||||
def changeUser(self):
|
||||
@ -221,11 +222,15 @@ class ExpansionImpl():
|
||||
GaussLog.exitWithError(ErrorCode.GAUSS_503["GAUSS_50300"] % user)
|
||||
|
||||
user_name = pw_record.pw_name
|
||||
user_uid = pw_record.pw_uid
|
||||
user_gid = pw_record.pw_gid
|
||||
env = os.environ.copy()
|
||||
user_uid = pw_record.pw_uid
|
||||
user_gid = pw_record.pw_gid
|
||||
os.setgid(user_gid)
|
||||
os.setuid(user_uid)
|
||||
os.environ["HOME"] = pw_record.pw_dir
|
||||
os.environ["USER"] = user_name
|
||||
os.environ["LOGNAME"] = user_name
|
||||
os.environ["SHELL"] = pw_record.pw_shell
|
||||
|
||||
|
||||
def initSshConnect(self, host, user='root'):
|
||||
|
||||
@ -583,25 +588,34 @@ retry for %s times" % start_retry_num)
|
||||
"""
|
||||
self.logger.debug("Start to generate and send cluster static file.\n")
|
||||
|
||||
primaryHosts = self.getPrimaryHostName()
|
||||
command = "gs_om -t generateconf -X %s --distribute" % self.context.xmlFile
|
||||
sshTool = SshTool([primaryHosts])
|
||||
resultMap, outputCollect = sshTool.getSshStatusOutput(command,
|
||||
[primaryHosts], self.envFile)
|
||||
self.logger.debug(outputCollect)
|
||||
self.cleanSshToolFile(sshTool)
|
||||
primaryHost = self.getPrimaryHostName()
|
||||
result = self.commonGsCtl.queryOmCluster(primaryHost, self.envFile)
|
||||
for nodeName in self.context.nodeNameList:
|
||||
nodeInfo = self.context.clusterInfoDict[nodeName]
|
||||
nodeIp = nodeInfo["backIp"]
|
||||
dataNode = nodeInfo["dataNode"]
|
||||
exist_reg = r"(.*)%s[\s]*%s(.*)%s(.*)" % (nodeName, nodeIp, dataNode)
|
||||
if not re.search(exist_reg, result) and nodeIp not in self.context.newHostList:
|
||||
self.logger.debug("The node ip [%s] will not be added to cluster." % nodeIp)
|
||||
dbNode = self.context.clusterInfo.getDbNodeByName(nodeName)
|
||||
self.context.clusterInfo.dbNodes.remove(dbNode)
|
||||
|
||||
toolPath = self.context.clusterInfoDict["toolPath"]
|
||||
appPath = self.context.clusterInfoDict["appPath"]
|
||||
|
||||
nodeNameList = self.context.nodeNameList
|
||||
|
||||
for hostName in nodeNameList:
|
||||
hostSsh = SshTool([hostName])
|
||||
toolPath = self.context.clusterInfoDict["toolPath"]
|
||||
appPath = self.context.clusterInfoDict["appPath"]
|
||||
srcFile = "%s/script/static_config_files/cluster_static_config_%s" \
|
||||
% (toolPath, hostName)
|
||||
static_config_dir = "%s/script/static_config_files" % toolPath
|
||||
if not os.path.exists(static_config_dir):
|
||||
os.makedirs(static_config_dir)
|
||||
|
||||
for dbNode in self.context.clusterInfo.dbNodes:
|
||||
hostName = dbNode.name
|
||||
staticConfigPath = "%s/script/static_config_files/cluster_static_config_%s" % \
|
||||
(toolPath, hostName)
|
||||
self.context.clusterInfo.saveToStaticConfig(staticConfigPath, dbNode.id)
|
||||
srcFile = staticConfigPath
|
||||
if not os.path.exists(srcFile):
|
||||
GaussLog.exitWithError("Generate static file [%s] not found." \
|
||||
% srcFile)
|
||||
GaussLog.exitWithError("Generate static file [%s] not found." % srcFile)
|
||||
hostSsh = SshTool([hostName])
|
||||
targetFile = "%s/bin/cluster_static_config" % appPath
|
||||
hostSsh.scpFiles(srcFile, targetFile, [hostName], self.envFile)
|
||||
self.cleanSshToolFile(hostSsh)
|
||||
@ -611,11 +625,11 @@ retry for %s times" % start_retry_num)
|
||||
|
||||
# Single-node database need start cluster after expansion
|
||||
if self.isSingleNodeInstance:
|
||||
primaryHost = self.getPrimaryHostName()
|
||||
self.logger.debug("Single-Node instance need restart.\n")
|
||||
self.commonGsCtl.queryOmCluster(primaryHosts, self.envFile)
|
||||
self.commonGsCtl.queryOmCluster(primaryHost, self.envFile)
|
||||
|
||||
# if primary database not normal, restart it
|
||||
primaryHost = self.getPrimaryHostName()
|
||||
dataNode = self.context.clusterInfoDict[primaryHost]["dataNode"]
|
||||
insType, dbStat = self.commonGsCtl.queryInstanceStatus(primaryHost,
|
||||
dataNode, self.envFile)
|
||||
@ -633,7 +647,7 @@ retry for %s times" % start_retry_num)
|
||||
self.commonGsCtl.startInstanceWithMode(hostName, dataNode,
|
||||
MODE_STANDBY, self.envFile)
|
||||
|
||||
self.commonGsCtl.startOmCluster(primaryHosts, self.envFile)
|
||||
self.commonGsCtl.startOmCluster(primaryHost, self.envFile)
|
||||
|
||||
def setGUCOnClusterHosts(self, hostNames=[]):
|
||||
"""
|
||||
@ -835,6 +849,63 @@ standby nodes.")
|
||||
"""
|
||||
self.checkUserAndGroupExists()
|
||||
self.checkXmlFileAccessToUser()
|
||||
self.checkClusterStatus()
|
||||
self.validNodeInStandbyList()
|
||||
|
||||
def checkClusterStatus(self):
|
||||
"""
|
||||
Check whether the cluster status is normal before expand.
|
||||
"""
|
||||
self.logger.debug("Start to check cluster status.\n")
|
||||
|
||||
curHostName = socket.gethostname()
|
||||
command = "su - %s -c 'source %s;gs_om -t status --detail'" % \
|
||||
(self.user, self.envFile)
|
||||
sshTool = SshTool([curHostName])
|
||||
resultMap, outputCollect = sshTool.getSshStatusOutput(command,
|
||||
[curHostName], self.envFile)
|
||||
if outputCollect.find("Primary Normal") == -1:
|
||||
GaussLog.exitWithError("Unable to query current cluster status. " + \
|
||||
"Please import environment variables or " +\
|
||||
"check whether the cluster status is normal.")
|
||||
|
||||
self.logger.debug("The primary database is normal.\n")
|
||||
|
||||
def validNodeInStandbyList(self):
|
||||
"""
|
||||
check if the node has been installed in the cluster.
|
||||
"""
|
||||
self.logger.debug("Start to check if the nodes in standby list\n")
|
||||
|
||||
curHostName = socket.gethostname()
|
||||
command = "su - %s -c 'source %s;gs_om -t status --detail'" % \
|
||||
(self.user, self.envFile)
|
||||
sshTool = SshTool([curHostName])
|
||||
resultMap, outputCollect = sshTool.getSshStatusOutput(command,
|
||||
[curHostName], self.envFile)
|
||||
self.logger.debug(outputCollect)
|
||||
|
||||
newHosts = self.context.newHostList
|
||||
standbyHosts = []
|
||||
existHosts = []
|
||||
while len(newHosts) > 0:
|
||||
hostIp = newHosts.pop()
|
||||
nodeName = self.context.backIpNameMap[hostIp]
|
||||
nodeInfo = self.context.clusterInfoDict[nodeName]
|
||||
dataNode = nodeInfo["dataNode"]
|
||||
exist_reg = r"(.*)%s[\s]*%s(.*)" % (nodeName, hostIp)
|
||||
if not re.search(exist_reg, outputCollect):
|
||||
standbyHosts.append(hostIp)
|
||||
else:
|
||||
existHosts.append(hostIp)
|
||||
self.context.newHostList = standbyHosts
|
||||
if len(existHosts) > 0:
|
||||
self.logger.log("The nodes [%s] are already in the cluster. Skip expand these nodes." \
|
||||
% ",".join(existHosts))
|
||||
self.cleanSshToolFile(sshTool)
|
||||
if len(standbyHosts) == 0:
|
||||
self.logger.log("There is no node can be expanded.")
|
||||
sys.exit(0)
|
||||
|
||||
def checkXmlFileAccessToUser(self):
|
||||
"""
|
||||
|
@ -347,7 +347,8 @@ class InstallImpl:
|
||||
self.configZenithInst()
|
||||
self.context.logger.log("encrypt cipher and rand files "
|
||||
"for database.")
|
||||
self.context.genCipherAndRandFile()
|
||||
initPasswd = self.getPasswdFromInitParam()
|
||||
self.context.genCipherAndRandFile(None, initPasswd)
|
||||
self.context.logger.log("begin to create CA cert files")
|
||||
self.context.createServerCa()
|
||||
if not self.context.localMode:
|
||||
@ -360,6 +361,32 @@ class InstallImpl:
|
||||
self.context.logger.log("Cluster installation is completed.",
|
||||
"constant")
|
||||
|
||||
def getPasswdFromInitParam(self):
|
||||
"""
|
||||
function: get passwd from init-parameter
|
||||
return: passwd
|
||||
get passwd from --gsinit-parameter. if the passwd has been assigned,
|
||||
the database will install with non-interactive.
|
||||
"""
|
||||
if len(self.context.dbInitParam) == 0:
|
||||
return None
|
||||
passwd = None
|
||||
pwdIndex = -1
|
||||
for idx,param in enumerate(self.context.dbInitParam):
|
||||
if param.startswith("--pwpasswd="):
|
||||
passwd = param[11:]
|
||||
pwdIndex = idx
|
||||
break
|
||||
elif param.startswith("-w="):
|
||||
passwd = param[3:]
|
||||
pwdIndex = idx
|
||||
break
|
||||
|
||||
#remove initpasswd from dbInitParam. otherwise it will be printed in log.
|
||||
if pwdIndex > -1:
|
||||
self.context.dbInitParam.pop(pwdIndex)
|
||||
return passwd
|
||||
|
||||
def configZenithInst(self):
|
||||
"""
|
||||
function: config zenith inst
|
||||
|
@ -32,6 +32,7 @@ from gspylib.common.ErrorCode import ErrorCode
|
||||
from gspylib.os.gsfile import g_file
|
||||
from gspylib.os.gsfile import g_Platform
|
||||
from gspylib.common.VersionInfo import VersionInfo
|
||||
import impl.upgrade.UpgradeConst as Const
|
||||
|
||||
sys.path.append(sys.path[0] + "/../../../lib/")
|
||||
DefaultValue.doConfigForParamiko()
|
||||
@ -414,6 +415,10 @@ class PostUninstallImpl:
|
||||
g_file.removeDirectory(path)
|
||||
path = "%s/sctp_patch" % (self.clusterToolPath)
|
||||
g_file.removeDirectory(path)
|
||||
path = "%s/%s" % (Const.UPGRADE_SQL_FILE, self.clusterToolPath)
|
||||
g_file.removeFile(path)
|
||||
path = "%s/%s" % (Const.UPGRADE_SQL_SHA, self.clusterToolPath)
|
||||
g_file.removeFile(path)
|
||||
self.logger.debug(
|
||||
"Deleting environmental software of local nodes.")
|
||||
|
||||
|
@ -53,6 +53,19 @@ ACTION_INPLACE_RESTORE = "inplace_restore"
|
||||
ACTION_CHECK_GUC = "check_guc"
|
||||
ACTION_BACKUP_HOTPATCH = "backup_hotpatch"
|
||||
ACTION_ROLLBACK_HOTPATCH = "rollback_hotpatch"
|
||||
ACTION_UPGRADE_SQL_FOLDER = "prepare_upgrade_sql_folder"
|
||||
ACTION_BACKUP_OLD_CLUSTER_DB_AND_REL = "backup_old_cluster_db_and_rel"
|
||||
ACTION_UPDATE_CATALOG = "update_catalog"
|
||||
ACTION_BACKUP_OLD_CLUSTER_CATALOG_PHYSICAL_FILES = \
|
||||
"backup_old_cluster_catalog_physical_files"
|
||||
ACTION_RESTORE_OLD_CLUSTER_CATALOG_PHYSICAL_FILES = \
|
||||
"restore_old_cluster_catalog_physical_files"
|
||||
ACTION_CLEAN_OLD_CLUSTER_CATALOG_PHYSICAL_FILES = \
|
||||
"clean_old_cluster_catalog_physical_files"
|
||||
ACTION_REPLACE_PG_PROC_FILES = "replace_pg_proc_files"
|
||||
ACTION_CREATE_PG_PROC_MAPPING_FILE = "create_pg_proc_mapping_file"
|
||||
ACTION_CREATE_NEW_CSV_FILE = "create_new_csv_file"
|
||||
ACTION_RESTORE_DYNAMIC_CONFIG_FILE = "restore_dynamic_config_file"
|
||||
|
||||
OPTION_PRECHECK = "before"
|
||||
OPTION_POSTCHECK = "after"
|
||||
@ -61,7 +74,7 @@ GREY_UPGRADE_STEP_FILE = "upgrade_step.csv"
|
||||
CLUSTER_CMSCONF_FILE = "cluster_cmsconf.json"
|
||||
CLUSTER_CNSCONF_FILE = "cluster_cnconf.json"
|
||||
READONLY_MODE = "read_only_mode"
|
||||
|
||||
TMP_DYNAMIC_DN_INFO = "upgrade_gauss_dn_status.dat"
|
||||
#step flag
|
||||
BINARY_UPGRADE_NO_NEED_ROLLBACK = -2
|
||||
INVALID_UPRADE_STEP = -1
|
||||
@ -95,6 +108,11 @@ BACKUP_DIR_LIST = ['global', 'pg_clog', 'pg_xlog', 'pg_multixact',
|
||||
'pg_replslot', 'pg_notify', 'pg_subtrans', 'pg_cbm',
|
||||
'pg_twophase']
|
||||
|
||||
|
||||
BACKUP_DIR_LIST_BASE = ['global', 'pg_clog', 'pg_csnlog']
|
||||
BACKUP_DIR_LIST_64BIT_XID = ['pg_multixact', 'pg_replslot', 'pg_notify',
|
||||
'pg_subtrans', 'pg_twophase']
|
||||
|
||||
FIRST_GREY_UPGRADE_NUM = 92
|
||||
|
||||
UPGRADE_PRECOMMIT_NUM = 0.001
|
||||
@ -115,6 +133,7 @@ UPGRADE_SCHEMA = "on_upgrade_69954349032535120"
|
||||
RECORD_NODE_STEP = "record_node_step"
|
||||
READ_STEP_FROM_FILE_FLAG = "read_step_from_file_flag"
|
||||
RECORD_UPGRADE_DIR = "record_app_directory"
|
||||
XLOG_BACKUP_INFO = "xlog_backup_info.json"
|
||||
OLD = "old"
|
||||
NEW = "new"
|
||||
# upgrade sql sha file and sql file
|
||||
@ -124,3 +143,4 @@ UPGRADE_SQL_FILE = "upgrade_sql.tar.gz"
|
||||
COMBIN_NUM = 30
|
||||
ON_INPLACE_UPGRADE = "IsInplaceUpgrade"
|
||||
MAX_APP_SIZE = 2000
|
||||
UPGRADE_VERSION_64bit_xid = 91.208
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1295,7 +1295,8 @@ Common options:
|
||||
cmd = "su - root -c 'source %s;echo $GAUSS_ENV' 2>/dev/null" \
|
||||
% self.mpprcFile
|
||||
else:
|
||||
cmd = "su - %s -c 'echo $GAUSS_ENV' 2>/dev/null" % self.user
|
||||
cmd = "su - %s -c 'source ~/.bashrc;echo $GAUSS_ENV' 2>/dev/null" \
|
||||
% self.user
|
||||
status, output = subprocess.getstatusoutput(cmd)
|
||||
if status != 0:
|
||||
self.logger.debug(
|
||||
|
@ -46,6 +46,7 @@ class Start(LocalBaseOM):
|
||||
self.logger = None
|
||||
self.installPath = ""
|
||||
self.security_mode = ""
|
||||
self.cluster_number = None
|
||||
|
||||
def usage(self):
|
||||
"""
|
||||
@ -72,7 +73,8 @@ General options:
|
||||
"""
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "U:D:R:l:t:h?",
|
||||
["help", "security-mode="])
|
||||
["help", "security-mode=",
|
||||
"cluster_number="])
|
||||
except getopt.GetoptError as e:
|
||||
GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50000"] % str(e))
|
||||
|
||||
@ -96,6 +98,8 @@ General options:
|
||||
sys.exit(0)
|
||||
elif key == "--security-mode":
|
||||
self.security_mode = value
|
||||
elif key == "--cluster_number":
|
||||
self.cluster_number = value
|
||||
else:
|
||||
GaussLog.exitWithError(ErrorCode.GAUSS_500["GAUSS_50000"]
|
||||
% key)
|
||||
@ -134,7 +138,10 @@ General options:
|
||||
for dn in self.dnCons:
|
||||
if self.dataDir != "" and dn.instInfo.datadir != self.dataDir:
|
||||
continue
|
||||
dn.start(self.time_out, self.security_mode)
|
||||
if self.cluster_number:
|
||||
dn.start(self.time_out, self.security_mode, self.cluster_number)
|
||||
else:
|
||||
dn.start(self.time_out, self.security_mode)
|
||||
isDataDirCorrect = True
|
||||
|
||||
if not isDataDirCorrect:
|
||||
|
@ -36,6 +36,7 @@ from gspylib.os.gsnetwork import g_network
|
||||
from gspylib.os.gsservice import g_service
|
||||
from gspylib.common.LocalBaseOM import LocalBaseOM
|
||||
from gspylib.os.gsfile import g_Platform
|
||||
import impl.upgrade.UpgradeConst as Const
|
||||
|
||||
ACTION_CLEAN_SYSLOG_CONFIG = 'clean_syslog_config'
|
||||
ACTION_CLEAN_TOOL_ENV = 'clean_tool_env'
|
||||
@ -361,6 +362,10 @@ class Postuninstall(LocalBaseOM):
|
||||
g_file.removeDirectory(path)
|
||||
path = "%s/unixodbc" % self.clusterToolPath
|
||||
g_file.removeDirectory(path)
|
||||
path = "%s/%s" % (self.clusterToolPath, Const.UPGRADE_SQL_FILE)
|
||||
g_file.removeFile(path)
|
||||
path = "%s/%s" % (self.clusterToolPath, Const.UPGRADE_SQL_SHA)
|
||||
g_file.removeFile(path)
|
||||
self.logger.debug(
|
||||
"Successfully cleaned the environmental software and variable.")
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -106,7 +106,7 @@ function fn_get_openGauss_tar()
|
||||
then
|
||||
url="https://opengauss.obs.cn-south-1.myhuaweicloud.com/1.1.0/${system_arch}/openGauss-1.1.0-${system_name}-64bit-all.tar.gz"
|
||||
echo "Downloading openGauss tar from official website at ${install_tar}"
|
||||
wget $url --timeout=30 --tries=3 && tar -zxvf openGauss-1.1.0-${system_name}-64bit-all.tar.gz
|
||||
wget $url --timeout=30 --tries=3 && tar -zxf openGauss-1.1.0-${system_name}-64bit-all.tar.gz
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "wget error. The $install_tar need openGauss-1.1.0-${system_name}-64bit-om.tar.gz"
|
||||
|
Loading…
x
Reference in New Issue
Block a user