Skip to content

Commit 23cb913

Browse files
authored
V2.10.0 (#205)
1 parent b00c72b commit 23cb913

File tree

351 files changed

+17031
-4150
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

351 files changed

+17031
-4150
lines changed

_cmd.py

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
from optparse import OptionParser, BadOptionError, Option, IndentedHelpFormatter
3131

3232
from core import ObdHome
33-
from _stdio import IO, FormtatText
33+
from _stdio import IO, FormatText
3434
from _lock import LockMode
3535
from _types import Capacity
3636
from tool import DirectoryUtil, FileUtil, NetUtil, COMMAND_ENV
@@ -226,17 +226,22 @@ def parse_command(self):
226226
self.parser.allow_undefine = self.dev_mode
227227
return super(ObdCommand, self).parse_command()
228228

229+
def _init_log(self):
230+
trace_id = uuid()
231+
log_dir = os.path.join(self.OBD_PATH, 'log')
232+
DirectoryUtil.mkdir(log_dir)
233+
log_path = os.path.join(log_dir, 'obd')
234+
ROOT_IO.init_trace_logger(log_path, 'obd', trace_id)
235+
ROOT_IO.exit_msg = '''Trace ID: {trace_id}
236+
If you want to view detailed obd logs, please run: obd display-trace {trace_id}'''.format(trace_id=trace_id)
237+
229238
def do_command(self):
230239
self.parse_command()
231240
self.init_home()
232-
trace_id = uuid()
233241
ret = False
234242
try:
235-
log_dir = os.path.join(self.OBD_PATH, 'log')
236-
DirectoryUtil.mkdir(log_dir)
237-
log_path = os.path.join(log_dir, 'obd')
238-
if self.enable_log:
239-
ROOT_IO.init_trace_logger(log_path, 'obd', trace_id)
243+
if self.has_trace and self.enable_log:
244+
self._init_log()
240245
ROOT_IO.track_limit += 1
241246
ROOT_IO.verbose('cmd: %s' % self.cmds)
242247
ROOT_IO.verbose('opts: %s' % self.opts)
@@ -245,7 +250,7 @@ def do_command(self):
245250
obd.set_cmds(self.cmds)
246251
ret = self._do_command(obd)
247252
if not ret:
248-
ROOT_IO.print(DOC_LINK_MSG)
253+
ROOT_IO.exit_msg = DOC_LINK_MSG + "\n" + ROOT_IO.exit_msg
249254
except NotImplementedError:
250255
ROOT_IO.exception('command \'%s\' is not implemented' % self.prev_cmd)
251256
except LockError:
@@ -257,9 +262,6 @@ def do_command(self):
257262
except:
258263
e = sys.exc_info()[1]
259264
ROOT_IO.exception('Running Error: %s' % e)
260-
if self.has_trace:
261-
ROOT_IO.print('Trace ID: %s' % trace_id)
262-
ROOT_IO.print('If you want to view detailed obd logs, please run: obd display-trace %s' % trace_id)
263265
return ret
264266

265267
def _do_command(self, obd):
@@ -859,7 +861,7 @@ def _do_command(self, obd):
859861
res = obd.deploy_cluster(self.cmds[0])
860862
self.background_telemetry_task(obd)
861863
if res:
862-
obd.stdio.print(FormtatText.success('Please execute ` obd cluster start %s ` to start' % self.cmds[0]))
864+
obd.stdio.print(FormatText.success('Please execute ` obd cluster start %s ` to start' % self.cmds[0]))
863865
return res
864866
else:
865867
return self._show_help()
@@ -900,6 +902,7 @@ class ClusterComponentDeleteCommand(ClusterMirrorCommand):
900902

901903
def __init__(self):
902904
super(ClusterComponentDeleteCommand, self).__init__('del', 'Add components for cluster')
905+
self.parser.add_option('-f', '--force', action='store_true', help="Force delete components.", default=False)
903906
self.parser.add_option('--ignore-standby', '--igs', action='store_true', help="Force kill the observer while standby tenant in others cluster exists.")
904907

905908
def init(self, cmd, args):
@@ -1129,6 +1132,7 @@ def __init__(self):
11291132
self.parser.add_option('--tablegroup', type='string', help="Tenant tablegroup.")
11301133
self.parser.add_option('--primary-zone', type='string', help="Tenant primary zone. [RANDOM].", default='RANDOM')
11311134
self.parser.add_option('--locality', type='string', help="Tenant locality.")
1135+
self.parser.add_option('--time-zone', type='string', help="Tenant time zone. The default tenant time_zone is [+08:00].")
11321136
self.parser.add_option('-s', '--variables', type='string', help="Set the variables for the system tenant. [ob_tcp_invited_nodes='%'].", default="ob_tcp_invited_nodes='%'")
11331137
self.parser.add_option('-o', '--optimize', type='string', help="Specify scenario optimization when creating a tenant, the default is consistent with the cluster dimension.\n{express_oltp, complex_oltp, olap, htap, kv}\nSupported since version 4.3.")
11341138

@@ -1406,7 +1410,7 @@ def __init__(self):
14061410
self.parser.add_option('--sysbench-script-dir', type='string', help='The directory of the sysbench lua script file. [/usr/sysbench/share/sysbench]', default='/usr/sysbench/share/sysbench')
14071411
self.parser.add_option('--table-size', type='int', help='Number of data initialized per table. [20000]', default=20000)
14081412
self.parser.add_option('--tables', type='int', help='Number of initialization tables. [30]', default=30)
1409-
self.parser.add_option('--threads', type='int', help='Number of threads to use. [16]', default=16)
1413+
self.parser.add_option('--threads', type='string', help='Number of threads to use. [16]', default='16')
14101414
self.parser.add_option('--time', type='int', help='Limit for total execution time in seconds. [60]', default=60)
14111415
self.parser.add_option('--interval', type='int', help='Periodically report intermediate statistics with a specified time interval in seconds. 0 disables intermediate reports. [10]', default=10)
14121416
self.parser.add_option('--events', type='int', help='Limit for total number of events.')
@@ -1447,6 +1451,8 @@ def __init__(self):
14471451
self.parser.add_option('-O', '--optimization', type='int', help='Optimization level {0/1/2}. [1] 0 - No optimization. 1 - Optimize some of the parameters which do not need to restart servers. 2 - Optimize all the parameters and maybe RESTART SERVERS for better performance.', default=1)
14481452
self.parser.add_option('--test-only', action='store_true', help='Only testing SQLs are executed. No initialization is executed.')
14491453
self.parser.add_option('-S', '--skip-cluster-status-check', action='store_true', help='Skip cluster status check', default=False)
1454+
self.parser.add_option('--direct-load', action='store_true', help="Enable load data by direct feature.")
1455+
self.parser.add_option('--parallel', type='int', help='The degree of parallelism for loading data. [max_cpu * unit_count]')
14501456

14511457
def _do_command(self, obd):
14521458
if self.cmds:
@@ -1605,9 +1611,10 @@ def __init__(self):
16051611
super(CommandsCommand, self).__init__('command', 'Common tool commands')
16061612
self.parser.add_option('-c', '--components', type='string', help='The components used by the command. The first component in the configuration will be used by default in interactive commands, and all available components will be used by default in non-interactive commands.')
16071613
self.parser.add_option('-s', '--servers', type='string', help='The servers used by the command. The first server in the configuration will be used by default in interactive commands, and all available servers will be used by default in non-interactive commands.')
1614+
self.parser.undefine_warn = False
16081615

16091616
def _do_command(self, obd):
1610-
if len(self.cmds) == 2:
1617+
if len(self.cmds) in [2, 3]:
16111618
return obd.commands(self.cmds[0], self.cmds[1], self.opts)
16121619
else:
16131620
return self._show_help()

_deploy.py

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import hashlib
2929
from copy import deepcopy
3030
from enum import Enum
31+
from datetime import datetime
3132

3233
from ruamel.yaml.comments import CommentedMap
3334

@@ -628,9 +629,15 @@ def del_depend(self, name, component_name):
628629

629630
def get_depend_servers(self, name):
630631
if name not in self._depends:
631-
return None
632+
return []
632633
cluster_config = self._depends[name]
633634
return deepcopy(cluster_config.original_servers)
635+
636+
def get_be_depend_servers(self, name):
637+
if name not in self._be_depends:
638+
return []
639+
cluster_config = self._be_depends[name]
640+
return deepcopy(cluster_config.original_servers)
634641

635642
def get_depend_added_servers(self, name):
636643
if name not in self._depends:
@@ -1033,11 +1040,12 @@ class DeployInstallMode(object):
10331040

10341041
class DeployInfo(object):
10351042

1036-
def __init__(self, name, status, components=None, config_status=DeployConfigStatus.UNCHNAGE):
1043+
def __init__(self, name, status, components=None, config_status=DeployConfigStatus.UNCHNAGE, create_date=None):
10371044
self.status = status
10381045
self.name = name
10391046
self.components = components if components else {}
10401047
self.config_status = config_status
1048+
self.create_date = create_date
10411049

10421050
def __str__(self):
10431051
info = ['%s (%s)' % (self.name, self.status.value)]
@@ -1218,19 +1226,23 @@ def scale_out(self, config_path):
12181226
source_data = self.yaml_loader.load(f)
12191227
for key in source_data:
12201228
if key in ['user', 'unuse_lib_repository', 'auto_create_tenant']:
1221-
self.stdio.error(err.EC_COMPONENT_CHANGE_CONFIG.format(key))
1229+
self.stdio.error(err.EC_COMPONENT_CHANGE_CONFIG.format(message=key))
12221230
ret = False
12231231
elif issubclass(type(source_data[key]), dict):
12241232
new_depends = source_data[key].get('depends', [])
1233+
if key not in self.components:
1234+
self.stdio.error(err.EC_COMPONENT_NOT_EXISTS.format(component=key))
1235+
ret = False
1236+
break
12251237
if new_depends and new_depends != self.components[key].depends:
12261238
self.stdio.error(err.EC_COMPONENT_CHANGE_CONFIG.format(message='depends:{}'.format(key)))
12271239
ret = False
12281240
# temp _depends
12291241
depends[key] = self.components[key].depends
1230-
1242+
12311243
if not self._merge_component(key, source_data[key]):
12321244
ret = False
1233-
1245+
12341246
for comp in depends:
12351247
conf = self.components[comp]
12361248
for name in depends[comp]:
@@ -1243,7 +1255,7 @@ def scale_out(self, config_path):
12431255
ret = False
12441256
return ret
12451257

1246-
def add_components(self, config_path):
1258+
def add_components(self, config_path, ignore_exist=False):
12471259
ret = True
12481260
depends = {}
12491261
try:
@@ -1255,6 +1267,8 @@ def add_components(self, config_path):
12551267
ret = False
12561268
elif issubclass(type(source_data[key]), dict):
12571269
if key in self.components:
1270+
if ignore_exist:
1271+
continue
12581272
self.stdio.error(err.EC_COMPONENT_EXISTS.format(component=key))
12591273
ret = False
12601274
continue
@@ -1578,6 +1592,7 @@ def deploy_info(self):
15781592
getattr(DeployStatus, data['status'], DeployStatus.STATUS_CONFIGURED),
15791593
ConfigUtil.get_value_from_dict(data, 'components', OrderedDict()),
15801594
getattr(DeployConfigStatus, ConfigUtil.get_value_from_dict(data, 'config_status', '_'), DeployConfigStatus.UNCHNAGE),
1595+
ConfigUtil.get_value_from_dict(data, 'create_date', None),
15811596
)
15821597
except:
15831598
self._info = DeployInfo(self.name, DeployStatus.STATUS_CONFIGURED)
@@ -1654,6 +1669,7 @@ def dump_deploy_info(self):
16541669
'components': self.deploy_info.components,
16551670
'status': self.deploy_info.status.name,
16561671
'config_status': self.deploy_info.config_status.name,
1672+
'create_date': self.deploy_info.create_date,
16571673
}
16581674
yaml.dump(data, f)
16591675
return True
@@ -1664,6 +1680,8 @@ def dump_deploy_info(self):
16641680
def _update_deploy_status(self, status):
16651681
old = self.deploy_info.status
16661682
self.deploy_info.status = status
1683+
if old == DeployStatus.STATUS_DEPLOYED and status == DeployStatus.STATUS_RUNNING:
1684+
self.deploy_info.create_date = datetime.now().strftime('%Y-%m-%d')
16671685
if self.dump_deploy_info():
16681686
return True
16691687
self.deploy_info.status = old

_errno.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ class InitDirFailedErrorMessage(object):
139139
EC_COMPONENT_FAILED_TO_MERGE_CONFIG = OBDErrorCodeTemplate(1023, 'Failed to merge config: {message}')
140140
EC_COMPONENT_NO_REMAINING_COMPS = OBDErrorCodeTemplate(1024, 'The cluster will have no remaining components. If you are absolutely sure about DELETING ALL COMPONENTS, please use "obd cluster destroy <deploy>" command to completely destroy the cluster')
141141
EC_COMPONENT_PASSWD_ERROR = OBDErrorCodeTemplate(1025, '({ip}) {component} {key} invalid. (Rule: {rule})')
142+
EC_RUNNING_CLUSTER_NO_REDEPLOYED = OBDErrorCodeTemplate(1026, 'Could not modify {key} when the cluster is in the working status(`production_mode` is True, not support this operation).')
143+
EC_COMPONENT_DIR_NOT_EMPTY = OBDErrorCodeTemplate(1027, 'If you are sure the directory can be emptied, run `obd cluster deploy -f {deploy_name}` to perform forced deployment.')
142144

143145
WC_ULIMIT_CHECK = OBDErrorCodeTemplate(1007, '({server}) The recommended number of {key} is {need} (Current value: {now})')
144146
WC_AIO_NOT_ENOUGH = OBDErrorCodeTemplate(1011, '({ip}) The recommended value of fs.aio-max-nr is 1048576 (Current value: {current})')
@@ -160,6 +162,8 @@ class InitDirFailedErrorMessage(object):
160162
EC_OBSERVER_FAILED_TO_REGISTER_WITH_DETAILS = OBDErrorCodeTemplate(2005, 'Failed to register cluster. {appname} may have been registered in {obconfig_url}.')
161163
EC_OBSERVER_MULTI_NET_DEVICE = OBDErrorCodeTemplate(2006, '{ip} has more than one network interface. Please set `devname` for ({server})')
162164
EC_OBSERVER_PING_FAILED = OBDErrorCodeTemplate(2007, '{ip1} {devname} fail to ping {ip2}. Please check configuration `devname`')
165+
EC_OBSERVER_PING_NOT_FOUND = OBDErrorCodeTemplate(2007, '/usr/bin/ping: No such file or directory. You can run `sudo yum install iputils` or `sudo apt-get install iputils-ping`.')
166+
EC_OBSERVER_PING_FAILED_SUID = OBDErrorCodeTemplate(2007, 'If the error message `operation not permitted` appears, please check the ping file permissions. You can try running `sudo chmod u+s /usr/bin/ping`')
163167
EC_OBSERVER_PING_FAILED_WITH_NO_DEVNAME = OBDErrorCodeTemplate(2007, '{ip1} fail to ping {ip2}. Please check your network')
164168
EC_OBSERVER_TIME_OUT_OF_SYNC = OBDErrorCodeTemplate(2008, 'Cluster clocks are out of sync')
165169
EC_OBSERVER_PRODUCTION_MODE_LIMIT = OBDErrorCodeTemplate(2009, '({server}): when production_mode is True, {key} can not be less then {limit}')
@@ -180,6 +184,7 @@ class InitDirFailedErrorMessage(object):
180184
# obagent
181185
EC_OBAGENT_RELOAD_FAILED = OBDErrorCodeTemplate(4000, 'Fail to reload {server}')
182186
EC_OBAGENT_SEND_CONFIG_FAILED = OBDErrorCodeTemplate(4001, 'Fail to send config file to {server}')
187+
WC_OBAGENT_SERVER_NAME_ERROR = OBDErrorCodeTemplate(4002, '{servers}: Failed to obtain the configuration of the OceanBase database component. \nPlease ensure that the server configurations are consistent between the OBAgent and OceanBase database components.')
183188

184189
# obproxy
185190
EC_OBPROXY_NEED_CONFIG = OBDErrorCodeTemplate(4100, '{server} need config "rs_list" or "obproxy_config_server_url"')
@@ -220,8 +225,9 @@ class InitDirFailedErrorMessage(object):
220225
EC_OCP_SERVER_NOT_ENOUGH_MEMORY_CACHED = OBDErrorCodeTemplate(4364, '({ip}) not enough memory. (Free: {free}, Buff/Cache: {cached}, Need: {need})')
221226
EC_OCP_SERVER_NOT_ENOUGH_MEMORY = OBDErrorCodeTemplate(4364, '({ip}) not enough memory. (Free: {free}, Need: {need})')
222227
EC_OCP_SERVER_NOT_ENOUGH_DISK = OBDErrorCodeTemplate(4365, '({ip}) {disk} not enough disk space. (Avail: {avail}, Need: {need})')
223-
EC_OCP_SERVER_RESOURCE_NOT_ENOUGH = OBDErrorCodeTemplate(4366, 'There is not enough {resource}. (Avail: {avail}, need: {need})')
224-
228+
EC_OCP_SERVER_RESOURCE_NOT_ENOUGH = OBDErrorCodeTemplate(4366, 'There is not enough {resource}. (Avail: {avail}, Need: {need})')
229+
EC_OCP_SERVER_EXIST_METADB_TENANT_MEMORY_NOT_ENOUGH = OBDErrorCodeTemplate(4367, 'The allocated memory for the provided meta database is currently insufficient for creating a tenant. Available: {avail}, Need: {need}.')
230+
EC_OCP_SERVER_NOT_EXIST_METADB_TENANT_MEMORY_NOT_ENOUGH = OBDErrorCodeTemplate(4368, 'The allocated memory for the provided meta database is currently insufficient for creating a tenant. Available: {avail}, Need: {need}(Available = memory_limit [{memory_limit}] - system_memory [{system_memory}] - sys tenant memory [{sys_tenant_memory}]. Need = ocp meta tenant memory [{ocp_meta_tenant_memory}] + ocp_monitor_tenant_memory [{ocp_monitor_tenant_memory}]).')
225231

226232

227233
WC_OCP_EXPRESS_FAILED_TO_GET_DISK_INFO = OBDErrorCodeTemplate(4303, '({ip}) failed to get disk information, skip disk space check')
@@ -300,7 +306,10 @@ class InitDirFailedErrorMessage(object):
300306
SUG_OCP_SERVER_REDUCE_MEM = OBDErrorSuggestionTemplate('Please reduce the `memory_size`', fix_eval=[FixEval(FixEval.DEL, 'memory_size')])
301307
SUG_OCP_SERVER_REDUCE_DISK = OBDErrorSuggestionTemplate('Please reduce the `logging_file_total_size_cap`', fix_eval=[FixEval(FixEval.DEL, 'logging_file_total_size_cap')])
302308
SUG_OCP_SERVER_EDIT_ADMIN_PASSWD_ERROR = OBDErrorSuggestionTemplate('Please edit the `admin_password`, must be 8 to 32 characters in length, containing at least 3 types from digits, lowercase letters, uppercase letters and the following special characters: ~!@#%^&*_-+=|(){{}}[]:;,.?/)', fix_eval=[FixEval(FixEval.DEL, 'admin_password')], auto_fix=True)
309+
SUG_OCP_SERVER_MACHINE_TIME = OBDErrorSuggestionTemplate('Please ensure that the machine time is synchronized with the ob time')
303310
SUG_SUDO_NOPASSWD = OBDErrorSuggestionTemplate('Please execute `bash -c \'echo "{user} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers`\' as root in {ip}.')
311+
SUG_OCP_SERVER_EXIST_METADB_TENANT_NOT_ENOUGH = OBDErrorSuggestionTemplate('Please reduce the ocp meta tenant memory or ocp monitor tenant memory')
312+
SUG_OCP_SERVER_NOT_EXIST_METADB_TENANT_NOT_ENOUGH = OBDErrorSuggestionTemplate('Please increase the meta db memory_limit and reduce the ocp meta tenant memory or ocp monitor tenant memory')
304313
SUG_OB_SYS_USERNAME = OBDErrorSuggestionTemplate('Please delete the "ob_sys_username" parameter.')
305314
SUG_OB_SYS_PASSWORD = OBDErrorSuggestionTemplate('''Please set the "ob_sys_password" for oblogproxy by configuring the "cdcro_password" parameter in the "oceanbase" or "oceanbase-ce" component.''')
306315
SUG_OBAGENT_EDIT_HTTP_BASIC_AUTH_PASSWORD = OBDErrorSuggestionTemplate('Please edit the `http_basic_auth_password`, cannot contain characters other than uppercase letters, lowercase characters, digits, special characters:~^*{{}}[]_-+', fix_eval=[FixEval(FixEval.DEL, 'http_basic_auth_password')], auto_fix=True)

0 commit comments

Comments
 (0)