3680 lines
160 KiB
Python
Executable File
3680 lines
160 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
####====XXXX======######==== I am a splitter ====######======XXXX====####
|
|
#filename:__init__.py
|
|
##!/usr/bin/env python
|
|
## -*- coding: utf-8 -*-
|
|
####====XXXX======######==== I am a splitter ====######======XXXX====####
|
|
#filename:actions.py
|
|
##!/usr/bin/env python
|
|
## -*- coding: utf-8 -*-
|
|
#
|
|
#import time
|
|
#import re
|
|
#import json
|
|
#import traceback
|
|
from my_error import MyError
|
|
import sys
|
|
import mysql.connector
|
|
from mysql.connector import errorcode
|
|
import logging
|
|
import json
|
|
import config
|
|
import opts
|
|
import run_modules
|
|
import actions
|
|
import string
|
|
from MySQLdb import _mysql
|
|
|
|
|
|
def dump_sql_to_file(dump_filename, tenant_id_list):
|
|
# normal_ddls_str = normal_ddl_actions_post.get_normal_ddl_actions_sqls_str()
|
|
# normal_dmls_str = normal_dml_actions_post.get_normal_dml_actions_sqls_str()
|
|
#each_tenant_dmls_str = each_tenant_dml_actions_post.get_each_tenant_dml_actions_sqls_str(tenant_id_list)
|
|
dump_file = open(dump_filename, 'w')
|
|
dump_file.write('# 以下是priv_checker.py脚本中的步骤\n')
|
|
dump_file.write('# 仅供priv_checker.py脚本运行失败需要人肉的时候参考\n')
|
|
dump_file.close()
|
|
|
|
#def print_stats():
|
|
# logging.info('==================================================================================')
|
|
# logging.info('============================== STATISTICS BEGIN ==================================')
|
|
# logging.info('==================================================================================')
|
|
# logging.info('succeed run sql(except sql of special actions): \n\n%s\n', actions.get_succ_sql_list_str())
|
|
# logging.info('commited sql(except sql of special actions): \n\n%s\n', actions.get_commit_sql_list_str())
|
|
# logging.info('==================================================================================')
|
|
# logging.info('=============================== STATISTICS END ===================================')
|
|
# logging.info('==================================================================================')
|
|
#
|
|
#def do_upgrade(my_host, my_port, my_user, my_passwd, my_module_set, upgrade_params):
|
|
# try:
|
|
# conn = mysql.connector.connect(user = my_user,
|
|
# password = my_passwd,
|
|
# host = my_host,
|
|
# port = my_port,
|
|
# database = 'oceanbase',
|
|
# raise_on_warnings = True)
|
|
# cur = conn.cursor(buffered=True)
|
|
# try:
|
|
# query_cur = actions.QueryCursor(cur)
|
|
# # 开始升级前的检查
|
|
# check_before_upgrade(query_cur, upgrade_params)
|
|
# # 获取租户id列表
|
|
# tenant_id_list = actions.fetch_tenant_ids(query_cur)
|
|
# if len(tenant_id_list) <= 0:
|
|
# logging.error('distinct tenant id count is <= 0, tenant_id_count: %d', len(tenant_id_list))
|
|
# raise MyError('no tenant id')
|
|
# logging.info('there has %s distinct tenant ids: [%s]', len(tenant_id_list), ','.join(str(tenant_id) for tenant_id in tenant_id_list))
|
|
# conn.commit()
|
|
#
|
|
# # 获取standby_cluster_info列表
|
|
# standby_cluster_infos = actions.fetch_standby_cluster_infos(conn, query_cur, my_user, my_passwd)
|
|
# # check ddl and dml sync
|
|
# actions.check_ddl_and_dml_sync(conn, query_cur, standby_cluster_infos, tenant_id_list)
|
|
#
|
|
# actions.refresh_commit_sql_list()
|
|
# dump_sql_to_file(upgrade_params.sql_dump_filename, tenant_id_list)
|
|
# logging.info('================succeed to dump sql to file: {0}==============='.format(upgrade_params.sql_dump_filename))
|
|
#
|
|
# if run_modules.MODULE_DDL in my_module_set:
|
|
# logging.info('================begin to run ddl===============')
|
|
# conn.autocommit = True
|
|
# normal_ddl_actions_post.do_normal_ddl_actions(cur)
|
|
# logging.info('================succeed to run ddl===============')
|
|
# conn.autocommit = False
|
|
# # check ddl and dml sync
|
|
# actions.check_ddl_and_dml_sync(conn, query_cur, standby_cluster_infos, tenant_id_list)
|
|
#
|
|
# if run_modules.MODULE_EACH_TENANT_DDL in my_module_set:
|
|
# has_run_ddl = True
|
|
# logging.info('================begin to run each tenant ddl===============')
|
|
# conn.autocommit = True
|
|
# each_tenant_ddl_actions_post.do_each_tenant_ddl_actions(cur, tenant_id_list)
|
|
# logging.info('================succeed to run each tenant ddl===============')
|
|
# conn.autocommit = False
|
|
# # check ddl and dml sync
|
|
# actions.check_ddl_and_dml_sync(conn, query_cur, standby_cluster_infos, tenant_id_list)
|
|
#
|
|
# if run_modules.MODULE_NORMAL_DML in my_module_set:
|
|
# logging.info('================begin to run normal dml===============')
|
|
# normal_dml_actions_post.do_normal_dml_actions(cur)
|
|
# logging.info('================succeed to run normal dml===============')
|
|
# conn.commit()
|
|
# actions.refresh_commit_sql_list()
|
|
# logging.info('================succeed to commit dml===============')
|
|
# # check ddl and dml sync
|
|
# actions.check_ddl_and_dml_sync(conn, query_cur, standby_cluster_infos, tenant_id_list)
|
|
#
|
|
# if run_modules.MODULE_EACH_TENANT_DML in my_module_set:
|
|
# logging.info('================begin to run each tenant dml===============')
|
|
# conn.autocommit = True
|
|
# each_tenant_dml_actions_post.do_each_tenant_dml_actions(cur, tenant_id_list)
|
|
# conn.autocommit = False
|
|
# logging.info('================succeed to run each tenant dml===============')
|
|
# # check ddl and dml sync
|
|
# actions.check_ddl_and_dml_sync(conn, query_cur, standby_cluster_infos, tenant_id_list)
|
|
#
|
|
# if run_modules.MODULE_SPECIAL_ACTION in my_module_set:
|
|
# logging.info('================begin to run special action===============')
|
|
# conn.autocommit = True
|
|
# special_upgrade_action_post.do_special_upgrade(conn, cur, tenant_id_list)
|
|
# conn.autocommit = False
|
|
# actions.refresh_commit_sql_list()
|
|
# logging.info('================succeed to commit special action===============')
|
|
# # check ddl and dml sync
|
|
# actions.check_ddl_and_dml_sync(conn, query_cur, standby_cluster_infos, tenant_id_list)
|
|
# except Exception, e:
|
|
# logging.exception('run error')
|
|
# raise e
|
|
# finally:
|
|
# # 打印统计信息
|
|
# print_stats()
|
|
# # 将回滚sql写到文件中
|
|
# actions.dump_rollback_sql_to_file(upgrade_params.rollback_sql_filename)
|
|
# cur.close()
|
|
# conn.close()
|
|
# except mysql.connector.Error, e:
|
|
# logging.exception('connection error')
|
|
# raise e
|
|
# except Exception, e:
|
|
# logging.exception('normal error')
|
|
# raise e
|
|
#
|
|
#class EachTenantDDLActionPostCreateAllTenantSecurityRecordAudit(BaseEachTenantDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 15
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """select tenant_id, table_id, table_name from __all_table where table_name = '__all_tenant_security_audit_record'""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""select tenant_id, table_id, table_name from __all_table where table_name = '__all_tenant_security_audit_record'""")
|
|
# if len(results) > 0:
|
|
# raise MyError('__all_tenant_security_audit_record already created')
|
|
# def dump_before_do_each_tenant_action(self, tenant_id):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """select tenant_id, table_id, table_name from __all_table where table_name = '__all_tenant_security_audit_record' and tenant_id = {0}""".format(tenant_id))
|
|
# def check_before_do_each_tenant_action(self, tenant_id):
|
|
# (desc, results) = self._query_cursor.exec_query("""select tenant_id, table_id, table_name from __all_table where table_name = '__all_tenant_security_audit_record' and tenant_id = {0}""".format(tenant_id))
|
|
# if len(results) > 0:
|
|
# raise MyError('tenant_id:{0} has already create table __all_tenant_security_audit_record'.format(tenant_id))
|
|
# @staticmethod
|
|
# def get_each_tenant_action_ddl(tenant_id):
|
|
# pure_table_id = 259
|
|
# table_id = (tenant_id << 40) | pure_table_id
|
|
# return """
|
|
# CREATE TABLE `__all_tenant_security_audit_record` (
|
|
# `gmt_create` timestamp(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
|
|
# `gmt_modified` timestamp(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
|
# `tenant_id` bigint(20) NOT NULL,
|
|
# `svr_ip` varchar(46) NOT NULL,
|
|
# `svr_port` bigint(20) NOT NULL,
|
|
# `record_timestamp_us` timestamp(6) NOT NULL,
|
|
# `user_id` bigint(20) unsigned NOT NULL,
|
|
# `user_name` varchar(64) NOT NULL,
|
|
# `effective_user_id` bigint(20) unsigned NOT NULL,
|
|
# `effective_user_name` varchar(64) NOT NULL,
|
|
# `client_ip` varchar(46) NOT NULL,
|
|
# `user_client_ip` varchar(46) NOT NULL,
|
|
# `proxy_session_id` bigint(20) unsigned NOT NULL,
|
|
# `session_id` bigint(20) unsigned NOT NULL,
|
|
# `entry_id` bigint(20) unsigned NOT NULL,
|
|
# `statement_id` bigint(20) unsigned NOT NULL,
|
|
# `trans_id` varchar(512) NOT NULL,
|
|
# `commit_version` bigint(20) NOT NULL,
|
|
# `trace_id` varchar(64) NOT NULL,
|
|
# `db_id` bigint(20) unsigned NOT NULL,
|
|
# `cur_db_id` bigint(20) unsigned NOT NULL,
|
|
# `sql_timestamp_us` timestamp(6) NOT NULL,
|
|
# `audit_id` bigint(20) unsigned NOT NULL,
|
|
# `audit_type` bigint(20) unsigned NOT NULL,
|
|
# `operation_type` bigint(20) unsigned NOT NULL,
|
|
# `action_id` bigint(20) unsigned NOT NULL,
|
|
# `return_code` bigint(20) NOT NULL,
|
|
# `obj_owner_name` varchar(64) DEFAULT NULL,
|
|
# `obj_name` varchar(256) DEFAULT NULL,
|
|
# `new_obj_owner_name` varchar(64) DEFAULT NULL,
|
|
# `new_obj_name` varchar(256) DEFAULT NULL,
|
|
# `auth_privileges` varchar(256) DEFAULT NULL,
|
|
# `auth_grantee` varchar(256) DEFAULT NULL,
|
|
# `logoff_logical_read` bigint(20) unsigned NOT NULL,
|
|
# `logoff_physical_read` bigint(20) unsigned NOT NULL,
|
|
# `logoff_logical_write` bigint(20) unsigned NOT NULL,
|
|
# `logoff_lock_count` bigint(20) unsigned NOT NULL,
|
|
# `logoff_dead_lock` varchar(40) DEFAULT NULL,
|
|
# `logoff_cpu_time_us` bigint(20) unsigned NOT NULL,
|
|
# `logoff_exec_time_us` bigint(20) unsigned NOT NULL,
|
|
# `logoff_alive_time_us` bigint(20) unsigned NOT NULL,
|
|
# `comment_text` varchar(65536) DEFAULT NULL,
|
|
# `sql_bind` varchar(65536) DEFAULT NULL,
|
|
# `sql_text` varchar(65536) DEFAULT NULL,
|
|
# PRIMARY KEY (`tenant_id`, `svr_ip`, `svr_port`, `record_timestamp_us`)
|
|
# ) TABLE_ID = {0} DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'none' REPLICA_NUM = 1
|
|
# BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 10 TABLEGROUP = 'oceanbase'
|
|
# """.format(table_id)
|
|
# @staticmethod
|
|
# def get_each_tenant_rollback_sql(tenant_id):
|
|
# return """select 1"""
|
|
# def dump_after_do_each_tenant_action(self, tenant_id):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """select tenant_id, table_id, table_name from __all_table where table_name = '__all_tenant_security_audit_record' and tenant_id = {0}""".format(tenant_id))
|
|
# def check_after_do_each_tenant_action(self, tenant_id):
|
|
# (desc, results) = self._query_cursor.exec_query("""select tenant_id, table_id, table_name from __all_table where table_name = '__all_tenant_security_audit_record' and tenant_id = {0}""".format(tenant_id))
|
|
# if len(results) != 1:
|
|
# raise MyError('tenant_id:{0} create table __all_tenant_security_audit_record failed'.format(tenant_id))
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """select tenant_id, table_id, table_name from __all_table where table_name = '__all_tenant_security_audit_record'""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""select tenant_id, table_id, table_name from __all_table where table_name = '__all_tenant_security_audit_record'""")
|
|
# if len(results) != len(self.get_tenant_id_list()):
|
|
# raise MyError('there should be {0} rows in __all_table whose table_name is __all_tenant_security_audit_record, but there has {1} rows like that'.format(len(self.get_tenant_id_list()), len(results)))
|
|
#
|
|
#class NormalDDLActionPreAddAllUserType(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 2
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_user""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_user like 'type'""")
|
|
# if len(results) > 0:
|
|
# raise MyError('column oceanbase.__all_user.type already exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_user add column `type` bigint(20) DEFAULT '0'"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_user drop column type"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_user""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_user like 'type'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('failed to add column status for oceanbase.__all_user')
|
|
#
|
|
#class NormalDDLActionPreAddAllUserHistoryType(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 3
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_user_history""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_user_history like 'type'""")
|
|
# if len(results) > 0:
|
|
# raise MyError('column oceanbase.__all_user_history.type already exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_user_history add column `type` bigint(20) DEFAULT '0'"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_user_history drop column type"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_user_history""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_user_history like 'type'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('failed to add column status for oceanbase.__all_user_history')
|
|
#
|
|
#
|
|
#class NormalDDLActionPreAddProfileIdAllUser(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 4
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_user""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_user like 'profile_id'""")
|
|
# if len(results) != 0:
|
|
# raise MyError('profile_id column alread exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_user add column `profile_id` bigint(20) NOT NULL DEFAULT '-1'"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_user drop column profile_id"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_user""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_user like 'profile_id'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('failed to add column for oceanbase.__all_user')
|
|
#
|
|
#class NormalDDLActionPreAddProfileIdAllUserHistory(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 5
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_user_history""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_user_history like 'profile_id'""")
|
|
# if len(results) != 0:
|
|
# raise MyError('profile_id column alread exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_user_history add column `profile_id` bigint(20) DEFAULT '-1'"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_user_history drop column profile_id"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_user_history""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_user_history like 'profile_id'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('failed to add column for oceanbase.__all_user_history')
|
|
#
|
|
#class NormalDDLActionPreModifyAllRootServiceEventHistoryIpColumn(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 6
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_rootservice_event_history""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_rootservice_event_history like 'rs_svr_ip'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('table oceanbase.__all_rootservice_event_history column rs_svr_ip not exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_rootservice_event_history modify column rs_svr_ip varchar(46) default ''"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_rootservice_event_history modify column rs_svr_ip varchar(32) default ''"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_rootservice_event_history""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_rootservice_event_history like 'rs_svr_ip'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('fail to modify column rs_svr_ip for oceanbase.__all_rootservice_event_history')
|
|
#
|
|
#class NormalDDLActionPreModifyAllSStableChecksumIpColumn(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 7
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_sstable_checksum""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_sstable_checksum like 'svr_ip'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('table oceanbase.__all_sstable_checksum column svr_ip not exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_sstable_checksum modify column svr_ip varchar(46) not null"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_sstable_checksum modify column svr_ip varchar(32) not null"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_sstable_checksum""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_sstable_checksum like 'svr_ip'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('fail to modify column svr_ip for oceanbase.__all_sstable_checksum')
|
|
#
|
|
#class NormalDDLActionPreModifyAllClogHistoryInfoV2IpColumn(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 8
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_clog_history_info_v2""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_clog_history_info_v2 like 'svr_ip'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('table oceanbase.__all_clog_history_info_v2 column svr_ip not exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_clog_history_info_v2 modify column svr_ip varchar(46) not null"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_clog_history_info_v2 modify column svr_ip varchar(32) not null"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_clog_history_info_v2""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_clog_history_info_v2 like 'svr_ip'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('fail to modify column svr_ip for oceanbase.__all_clog_history_info_v2')
|
|
#
|
|
#class NormalDDLActionPreModifyAllSysParameterIpColumn(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 9
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_sys_parameter""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_sys_parameter like 'svr_ip'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('table oceanbase.__all_sys_parameter column svr_ip not exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_sys_parameter modify column svr_ip varchar(46) not null"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_sys_parameter modify column svr_ip varchar(32) not null"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_sys_parameter""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_sys_parameter like 'svr_ip'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('fail to modify column svr_ip for oceanbase.__all_sys_parameter')
|
|
#
|
|
#class NormalDDLActionPreModifyAllLocalIndexStatusIpColumn(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 10
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_local_index_status""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_local_index_status like 'svr_ip'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('table oceanbase.__all_local_index_status column svr_ip not exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_local_index_status modify column svr_ip varchar(46) not null"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_local_index_status modify column svr_ip varchar(32) not null"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_local_index_status""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_local_index_status like 'svr_ip'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('fail to modify column svr_ip for oceanbase.__all_local_index_status')
|
|
#
|
|
#class NormalDDLActionPreModifyAllTenantResourceUsageIpColumn(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 11
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_tenant_resource_usage""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_tenant_resource_usage like 'svr_ip'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('table oceanbase.__all_tenant_resource_usage column svr_ip not exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_tenant_resource_usage modify column svr_ip varchar(46) not null"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_tenant_resource_usage modify column svr_ip varchar(32) not null"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_tenant_resource_usage""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_tenant_resource_usage like 'svr_ip'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('fail to modify column svr_ip for oceanbase.__all_tenant_resource_usage')
|
|
#
|
|
#class NormalDDLActionPreModifyAllRootTableIpColumn(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 12
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_root_table""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_root_table like 'svr_ip'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('table oceanbase.__all_root_table column svr_ip not exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_root_table modify column svr_ip varchar(46) not null"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_root_table modify column svr_ip varchar(32) not null"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_root_table""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_root_table like 'svr_ip'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('fail to modify column svr_ip for oceanbase.__all_root_table')
|
|
#
|
|
#class NormalDDLActionPreModifyAllServerEventHistoryIpColumn(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 13
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_server_event_history""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_server_event_history like 'svr_ip'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('table oceanbase.__all_server_event_history column svr_ip not exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_server_event_history modify column svr_ip varchar(46) not null"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_server_event_history modify column svr_ip varchar(32) not null"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_server_event_history""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_server_event_history like 'svr_ip'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('fail to modify column svr_ip for oceanbase.__all_server_event_history')
|
|
#
|
|
#class NormalDDLActionPreModifyAllIndexScheduleTaskIpColumn(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 14
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_index_schedule_task""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_index_schedule_task like 'svr_ip'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('table oceanbase.__all_index_schedule_task column svr_ip not exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_index_schedule_task modify column svr_ip varchar(46) not null"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_index_schedule_task modify column svr_ip varchar(32) not null"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_index_schedule_task""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_index_schedule_task like 'svr_ip'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('fail to modify column svr_ip for oceanbase.__all_index_schedule_task')
|
|
#
|
|
#class NormalDDLActionPreModifyAllMetaTableIpColumn(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 15
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_meta_table""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_meta_table like 'svr_ip'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('table oceanbase.__all_meta_table column svr_ip not exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_meta_table modify column svr_ip varchar(46) not null"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_meta_table modify column svr_ip varchar(32) not null"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_meta_table""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_meta_table like 'svr_ip'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('fail to modify column svr_ip for oceanbase.__all_meta_table')
|
|
#
|
|
#class NormalDDLActionPreModifyAllSqlExecuteTaskIpColumn(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 16
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_sql_execute_task""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_sql_execute_task like 'svr_ip'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('table oceanbase.__all_sql_execute_task column svr_ip not exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_sql_execute_task modify column svr_ip varchar(46) not null"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_sql_execute_task modify column svr_ip varchar(32) not null"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_sql_execute_task""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_sql_execute_task like 'svr_ip'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('fail to modify column svr_ip for oceanbase.__all_sql_execute_task')
|
|
#
|
|
|
|
#
|
|
#class NormalDDLActionPreModifyAllGlobalIndexDataSrcDataPartitionIDColumn(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 39
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_global_index_data_src""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_global_index_data_src like 'data_partition_id,'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('table oceanbase.__all_global_index_data_src column data_partition_id, not exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_global_index_data_src change `data_partition_id,` `data_partition_id` bigint(20) NOT NULL"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_global_index_data_src change `data_partition_id` `data_partition_id,` bigint(20) NOT NULL"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_global_index_data_src""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_global_index_data_src like 'data_partition_id'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('fail to modify column data_partition_id, for oceanbase.__all_global_index_data_src')
|
|
#
|
|
#class NormalDDLActionPreAddAllForeignKeyEnableFlag(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 40
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_foreign_key""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_foreign_key like 'enable_flag'""")
|
|
# if len(results) > 0:
|
|
# raise MyError('column oceanbase.__all_foreign_key.enable_flag already exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_foreign_key add column `enable_flag` tinyint(4) NOT NULL DEFAULT '1'"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_foreign_key drop column enable_flag"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_foreign_key""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_foreign_key like 'enable_flag'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('failed to add column enable_flag for oceanbase.__all_foreign_key')
|
|
#
|
|
#class NormalDDLActionPreAddAllForeignKeyHistoryEnableFlag(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 41
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_foreign_key_history""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_foreign_key_history like 'enable_flag'""")
|
|
# if len(results) > 0:
|
|
# raise MyError('column oceanbase.__all_foreign_key_history.enable_flag already exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_foreign_key_history add column `enable_flag` tinyint(4) DEFAULT '1'"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_foreign_key_history drop column enable_flag"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_foreign_key_history""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_foreign_key_history like 'enable_flag'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('failed to add column enable_flag for oceanbase.__all_foreign_key_history')
|
|
#
|
|
#class NormalDDLActionPreAddAllForeignKeyRefCstType(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 42
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_foreign_key""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_foreign_key like 'ref_cst_type'""")
|
|
# if len(results) > 0:
|
|
# raise MyError('column oceanbase.__all_foreign_key.ref_cst_type already exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_foreign_key add column `ref_cst_type` bigint(20) NOT NULL DEFAULT '0'"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_foreign_key drop column ref_cst_type"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_foreign_key""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_foreign_key like 'ref_cst_type'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('failed to add column ref_cst_type for oceanbase.__all_foreign_key')
|
|
#
|
|
#class NormalDDLActionPreAddAllForeignKeyHistoryRefCstType(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 43
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_foreign_key_history""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_foreign_key_history like 'ref_cst_type'""")
|
|
# if len(results) > 0:
|
|
# raise MyError('column oceanbase.__all_foreign_key_history.ref_cst_type already exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_foreign_key_history add column `ref_cst_type` bigint(20) DEFAULT '0'"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_foreign_key_history drop column ref_cst_type"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_foreign_key_history""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_foreign_key_history like 'ref_cst_type'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('failed to add column ref_cst_type for oceanbase.__all_foreign_key_history')
|
|
#
|
|
#class NormalDDLActionPreAddAllForeignKeyRefCstId(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 44
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_foreign_key""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_foreign_key like 'ref_cst_id'""")
|
|
# if len(results) > 0:
|
|
# raise MyError('column oceanbase.__all_foreign_key.ref_cst_id already exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_foreign_key add column `ref_cst_id` bigint(20) NOT NULL DEFAULT '-1'"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_foreign_key drop column ref_cst_id"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_foreign_key""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_foreign_key like 'ref_cst_id'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('failed to add column ref_cst_id for oceanbase.__all_foreign_key')
|
|
#
|
|
#class NormalDDLActionPreAddAllForeignKeyHistoryRefCstId(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 45
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_foreign_key_history""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_foreign_key_history like 'ref_cst_id'""")
|
|
# if len(results) > 0:
|
|
# raise MyError('column oceanbase.__all_foreign_key_history.ref_cst_id already exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_foreign_key_history add column `ref_cst_id` bigint(20) DEFAULT '-1'"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_foreign_key_history drop column ref_cst_id"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_foreign_key_history""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_foreign_key_history like 'ref_cst_id'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('failed to add column ref_cst_id for oceanbase.__all_foreign_key_history')
|
|
#
|
|
#class NormalDDLActionPreModifyAllSeedParameterSvrIp(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 46
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_seed_parameter""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_seed_parameter like 'svr_ip'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('table oceanbase.__all_seed_parameter column svr_ip not exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_seed_parameter modify column svr_ip varchar(46) not null"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_seed_parameter modify column svr_ip varchar(32) not null"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_seed_parameter""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_seed_parameter like 'svr_ip'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('fail to modify column svr_ip for oceanbase.__all_seed_parameter')
|
|
#
|
|
#class NormalDDLActionPreAddClusterStatus(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 47
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_cluster""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_cluster like 'cluster_status'""")
|
|
# if len(results) != 0:
|
|
# raise MyError('cluster_status column alread exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_cluster add column cluster_status bigint(20) NOT NULL default 1"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_cluster drop column cluster_status"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_cluster""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_cluster like 'cluster_status'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('failed to add column for oceanbase.__all_cluster')
|
|
#
|
|
#class NormalDDLActionPreAllTableAddDropSchemaVersion(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 48
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_table""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_table like 'drop_schema_version'""")
|
|
# if len(results) != 0:
|
|
# raise MyError('cluster_status column alread exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_table add column `drop_schema_version` bigint(20) NOT NULL DEFAULT '-1'"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_table drop column `drop_schema_version`"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_table""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_table like 'drop_schema_version'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('failed to add column for oceanbase.__all_table')
|
|
#
|
|
#class NormalDDLActionPreAllTablegroupAddDropSchemaVersion(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 49
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_tablegroup""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_tablegroup like 'drop_schema_version'""")
|
|
# if len(results) != 0:
|
|
# raise MyError('cluster_status column alread exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_tablegroup add column `drop_schema_version` bigint(20) NOT NULL DEFAULT '-1'"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_tablegroup drop column `drop_schema_version`"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_tablegroup""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_tablegroup like 'drop_schema_version'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('failed to add column for oceanbase.__all_tablegroup')
|
|
#
|
|
#class NormalDDLActionPreAllPartAddDropSchemaVersion(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 50
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_part""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_part like 'drop_schema_version'""")
|
|
# if len(results) != 0:
|
|
# raise MyError('cluster_status column alread exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_part add column `drop_schema_version` bigint(20) NOT NULL DEFAULT '-1'"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_part drop column `drop_schema_version`"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_part""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_part like 'drop_schema_version'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('failed to add column for oceanbase.__all_part')
|
|
#
|
|
#class NormalDDLActionPreAllTableHistoryAddDropSchemaVersion(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 51
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_table_history""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_table_history like 'drop_schema_version'""")
|
|
# if len(results) != 0:
|
|
# raise MyError('cluster_status column alread exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_table_history add column `drop_schema_version` bigint(20) DEFAULT '-1'"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_table_history drop column `drop_schema_version`"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_table_history""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_table_history like 'drop_schema_version'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('failed to add column for oceanbase.__all_table_history')
|
|
#
|
|
#class NormalDDLActionPreAllTablegroupHistoryAddDropSchemaVersion(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 52
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_tablegroup_history""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_tablegroup_history like 'drop_schema_version'""")
|
|
# if len(results) != 0:
|
|
# raise MyError('cluster_status column alread exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_tablegroup_history add column `drop_schema_version` bigint(20) DEFAULT '-1'"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_tablegroup_history drop column `drop_schema_version`"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_tablegroup_history""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_tablegroup_history like 'drop_schema_version'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('failed to add column for oceanbase.__all_tablegroup_history')
|
|
#
|
|
#class NormalDDLActionPreAllPartHistoryAddDropSchemaVersion(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 53
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_part_history""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_part_history like 'drop_schema_version'""")
|
|
# if len(results) != 0:
|
|
# raise MyError('cluster_status column alread exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_part_history add column `drop_schema_version` bigint(20) DEFAULT '-1'"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_part_history drop column `drop_schema_version`"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_part_history""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_part_history like 'drop_schema_version'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('failed to add column for oceanbase.__all_part_history')
|
|
#
|
|
#class NormalDDLActionPreAddBuildingSnapshot(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 54
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_ori_schema_version""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_ori_schema_version like 'building_snapshot'""")
|
|
# if len(results) != 0:
|
|
# raise MyError('building_snapshot column alread exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_ori_schema_version add column building_snapshot bigint(20) NOT NULL default '0'"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_ori_schema_version drop column building_snapshot"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_ori_schema_version""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_ori_schema_version like 'building_snapshot'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('failed to add column for oceanbase.__all_ori_schema_version')
|
|
#
|
|
#class NormalDDLActionPreAddAllRestoreInfo(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 55
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """show tables from oceanbase like '__all_restore_info'""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show tables from oceanbase like '__all_restore_info'""")
|
|
# if len(results) > 0:
|
|
# raise MyError('table oceanbase.__all_restore_info already exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """ CREATE TABLE `__all_restore_info` (
|
|
# `gmt_create` timestamp(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
|
|
# `gmt_modified` timestamp(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
|
# `job_id` bigint(20) NOT NULL,
|
|
# `name` varchar(1024) NOT NULL,
|
|
# `value` varchar(4096) NOT NULL,
|
|
# PRIMARY KEY (`job_id`, `name`)
|
|
# ) TABLE_ID = 1099511628041 DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'none' REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 10 TABLEGROUP = 'oceanbase'
|
|
# """
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """drop table oceanbase.__all_restore_info"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """show tables from oceanbase like '__all_restore_info'""")
|
|
# my_utils.query_and_dump_results(self._query_cursor, """show columns from oceanbase.__all_restore_info""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show tables from oceanbase like '__all_restore_info'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('table oceanbase.__all_restore_info not exists')
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_restore_info""")
|
|
# if len(results) != 5:
|
|
# raise MyError('table oceanbase.__all_restore_info has invalid column descs')
|
|
#
|
|
#class NormalDDLActionPreAddAllFailoverInfo(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 56
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """show tables from oceanbase like '__all_failover_info'""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show tables from oceanbase like '__all_failover_info'""")
|
|
# if len(results) > 0:
|
|
# raise MyError('table oceanbase.__all_failover_info already exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """ CREATE TABLE `__all_failover_info` (
|
|
# `gmt_create` timestamp(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
|
|
# `gmt_modified` timestamp(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
|
# `failover_epoch` bigint(20) NOT NULL,
|
|
# `tenant_id` bigint(20) NOT NULL,
|
|
# `sys_table_scn` bigint(20) NOT NULL,
|
|
# `user_table_scn` bigint(20) NOT NULL,
|
|
# `schema_version` bigint(20) NOT NULL,
|
|
# PRIMARY KEY (`failover_epoch`, `tenant_id`)
|
|
# ) TABLE_ID = 1099511628047 DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'none' REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 10 TABLEGROUP = 'oceanbase'
|
|
# """
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """drop table oceanbase.__all_failover_info"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """show tables from oceanbase like '__all_failover_info'""")
|
|
# my_utils.query_and_dump_results(self._query_cursor, """show columns from oceanbase.__all_failover_info""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show tables from oceanbase like '__all_failover_info'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('table oceanbase.__all_failover_info not exists')
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_failover_info""")
|
|
# if len(results) != 7:
|
|
# raise MyError('table oceanbase.__all_failover_info has invalid column descs')
|
|
#
|
|
#class NormalDDLActionPreAddAllForeignKeyValidateFlag(BaseDDLAction):
|
|
# @staticmethod
|
|
# def get_seq_num():
|
|
# return 57
|
|
# def dump_before_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_foreign_key""")
|
|
# def check_before_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_foreign_key like 'validate_flag'""")
|
|
# if len(results) > 0:
|
|
# raise MyError('column oceanbase.__all_foreign_key.validate_flag already exists')
|
|
# @staticmethod
|
|
# def get_action_ddl():
|
|
# return """alter table oceanbase.__all_foreign_key add column `validate_flag` tinyint(4) NOT NULL DEFAULT '1'"""
|
|
# @staticmethod
|
|
# def get_rollback_sql():
|
|
# return """alter table oceanbase.__all_foreign_key drop column validate_flag"""
|
|
# def dump_after_do_action(self):
|
|
# my_utils.query_and_dump_results(self._query_cursor, """desc oceanbase.__all_foreign_key""")
|
|
# def check_after_do_action(self):
|
|
# (desc, results) = self._query_cursor.exec_query("""show columns from oceanbase.__all_foreign_key like 'validate_flag'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('failed to add column validate_flag for oceanbase.__all_foreign_key')
|
|
#
|
|
# if 'password' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
#
|
|
#def get_opt_module():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'module' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
#
|
|
#def get_opt_log_file():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'log-file' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
##### ---------------end----------------------
|
|
#
|
|
##### --------------start : do_upgrade_pre.py--------------
|
|
def config_logging_module(log_filenamme):
|
|
logging.basicConfig(level=logging.INFO,\
|
|
format='[%(asctime)s] %(levelname)s %(filename)s:%(lineno)d %(message)s',\
|
|
datefmt='%Y-%m-%d %H:%M:%S',\
|
|
filename=log_filenamme,\
|
|
filemode='w')
|
|
# 定义日志打印格式
|
|
formatter = logging.Formatter('[%(asctime)s] %(levelname)s %(filename)s:%(lineno)d %(message)s', '%Y-%m-%d %H:%M:%S')
|
|
#######################################
|
|
# 定义一个Handler打印INFO及以上级别的日志到sys.stdout
|
|
stdout_handler = logging.StreamHandler(sys.stdout)
|
|
stdout_handler.setLevel(logging.INFO)
|
|
# 设置日志打印格式
|
|
stdout_handler.setFormatter(formatter)
|
|
# 将定义好的stdout_handler日志handler添加到root logger
|
|
logging.getLogger('').addHandler(stdout_handler)
|
|
##### ---------------end----------------------
|
|
#
|
|
#
|
|
#
|
|
#
|
|
##### START ####
|
|
## 1. 检查前置版本
|
|
#def check_observer_version(query_cur, upgrade_params):
|
|
# (desc, results) = query_cur.exec_query("""select distinct value from __all_virtual_sys_parameter_stat where name='min_observer_version'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('query results count is not 1')
|
|
# elif cmp(results[0][0], upgrade_params.old_version) < 0 :
|
|
# raise MyError('old observer version is expected equal or higher then: {0}, actual version:{1}'.format(upgrade_params.old_version, results[0][0]))
|
|
# logging.info('check observer version success, version = {0}'.format(results[0][0]))
|
|
#
|
|
## 2. 检查paxos副本是否同步, paxos副本是否缺失
|
|
#def check_paxos_replica(query_cur):
|
|
# # 2.1 检查paxos副本是否同步
|
|
# (desc, results) = query_cur.exec_query("""select count(1) as unsync_cnt from __all_virtual_clog_stat where is_in_sync = 0 and is_offline = 0 and replica_type != 16""")
|
|
# if results[0][0] > 0 :
|
|
# raise MyError('{0} replicas unsync, please check'.format(results[0][0]))
|
|
# # 2.2 检查paxos副本是否有缺失 TODO
|
|
# logging.info('check paxos replica success')
|
|
#
|
|
## 3. 检查是否有做balance, locality变更
|
|
#def check_rebalance_task(query_cur):
|
|
# # 3.1 检查是否有做locality变更
|
|
# (desc, results) = query_cur.exec_query("""select count(1) as cnt from __all_rootservice_job where job_status='INPROGRESS' and return_code is null""")
|
|
# if results[0][0] > 0 :
|
|
# raise MyError('{0} locality tasks is doing, please check'.format(results[0][0]))
|
|
# # 3.2 检查是否有做balance
|
|
# (desc, results) = query_cur.exec_query("""select count(1) as rebalance_task_cnt from __all_virtual_rebalance_task_stat""")
|
|
# if results[0][0] > 0 :
|
|
# raise MyError('{0} rebalance tasks is doing, please check'.format(results[0][0]))
|
|
# logging.info('check rebalance task success')
|
|
#
|
|
## 4. 检查集群状态
|
|
#def check_cluster_status(query_cur):
|
|
# # 4.1 检查是否非合并状态
|
|
# (desc, results) = query_cur.exec_query("""select info from __all_zone where zone='' and name='merge_status'""")
|
|
# if cmp(results[0][0], 'IDLE') != 0 :
|
|
# raise MyError('global status expected = {0}, actual = {1}'.format('IDLE', results[0][0]))
|
|
# logging.info('check cluster status success')
|
|
# # 4.2 检查合并版本是否>=3
|
|
# (desc, results) = query_cur.exec_query("""select cast(value as unsigned) value from __all_zone where zone='' and name='last_merged_version'""")
|
|
# if results[0][0] < 2 :
|
|
# raise MyError('global last_merged_version expected >= 2 actual = {0}'.format(results[0][0]))
|
|
# logging.info('check global last_merged_version success')
|
|
#
|
|
## 5. 检查没有打开enable_separate_sys_clog
|
|
#def check_disable_separate_sys_clog(query_cur):
|
|
# (desc, results) = query_cur.exec_query("""select count(1) from __all_sys_parameter where name like 'enable_separate_sys_clog'""")
|
|
# if results[0][0] > 0 :
|
|
# raise MyError('enable_separate_sys_clog is true, unexpected')
|
|
# logging.info('check separate_sys_clog success')
|
|
#
|
|
## 6. 检查配置宏块的data_seq
|
|
#def check_macro_block_data_seq(query_cur):
|
|
# query_cur.exec_sql("""set ob_query_timeout=1800000000""")
|
|
# row_count = query_cur.exec_sql("""select * from __all_virtual_partition_sstable_macro_info where data_seq < 0 limit 1""")
|
|
# if row_count != 0:
|
|
# raise MyError('check_macro_block_data_seq failed, too old macro block needs full merge')
|
|
# logging.info('check_macro_block_data_seq success')
|
|
#
|
|
## 7.检查所有的表格的sstable checksum method都升级到2
|
|
#def check_sstable_column_checksum_method_new(query_cur):
|
|
# query_cur.exec_sql("""set ob_query_timeout=1800000000""")
|
|
# row_count = query_cur.exec_sql("""select * from __all_table where table_id in (select index_id from __all_sstable_column_checksum where checksum_method = 1 and data_table_id != 0) limit 1""")
|
|
# if row_count != 0:
|
|
# raise MyError('check_sstable_column_checksum_method_new failed, please upgrade column checksum method using progressive compaction')
|
|
# row_count = query_cur.exec_sql("""select column_value from __all_core_table where table_name = '__all_table' and column_name = 'table_id' and column_value in (select index_id from __all_sstable_column_checksum where checksum_method = 1 and data_table_id != 0) limit 1""")
|
|
# if row_count != 0:
|
|
# raise MyError('check_sstable_column_checksum_method_new failed, please upgrade system table column checksum method using progressive compaction')
|
|
# row_count = query_cur.exec_sql("""select index_id from __all_sstable_column_checksum where checksum_method = 1 and index_id = 1099511627777 and data_table_id != 0 limit 1""")
|
|
# if row_count != 0:
|
|
# raise MyError('check_sstable_column_checksum_method_new failed, please upgrade system table column checksum method using progressive compaction')
|
|
# logging.info('check_sstable_column_checksum_method_new success')
|
|
#
|
|
## 8. 检查租户的resource_pool内存规格, 要求F类型unit最小内存大于5G,L类型unit最小内存大于2G.
|
|
#def check_tenant_resource_pool(query_cur):
|
|
# (desc, results) = query_cur.exec_query("""select count(*) from oceanbase.__all_resource_pool a, oceanbase.__all_unit_config b where a.unit_config_id = b.unit_config_id and b.unit_config_id != 100 and a.replica_type=0 and b.min_memory < 5368709120""")
|
|
# if results[0][0] > 0 :
|
|
# raise MyError('{0} tenant resource pool unit config is less than 5G, please check'.format(results[0][0]))
|
|
# (desc, results) = query_cur.exec_query("""select count(*) from oceanbase.__all_resource_pool a, oceanbase.__all_unit_config b where a.unit_config_id = b.unit_config_id and b.unit_config_id != 100 and a.replica_type=5 and b.min_memory < 2147483648""")
|
|
# if results[0][0] > 0 :
|
|
# raise MyError('{0} tenant logonly resource pool unit config is less than 2G, please check'.format(results[0][0]))
|
|
#
|
|
## 9. 检查是否有日志型副本分布在Full类型unit中
|
|
#def check_logonly_replica_unit(query_cur):
|
|
# # 统计all_tnant表中每个tenant的L类型的zone个数
|
|
# (desc, res_tenant_log_zone_cnt) = query_cur.exec_query("""select tenant_id, (char_length(locality) - char_length(replace(locality, 'LOGONLY', ''))) / char_length('LOGONLY') as log_zone_cnt from __all_tenant""")
|
|
# # 统计all_resource_pool中每个tenant的L类型的resource_pool中包含的zone个数
|
|
# (desc, res_respool_log_zone_cnt) = query_cur.exec_query("""select tenant_id, sum(lzone_cnt) as rp_log_zone_cnt from (select tenant_id, ((char_length(zone_list) - char_length(replace(zone_list, ';', ''))) + 1) as lzone_cnt from __all_resource_pool where replica_type=5) as vt group by tenant_id""")
|
|
# # 比较两个数量是否一致,不一致则报错
|
|
# for line in res_tenant_log_zone_cnt:
|
|
# tenant_id = line[0]
|
|
# tenant_log_zone_cnt = line[1]
|
|
# if tenant_log_zone_cnt > 0:
|
|
# is_found = False
|
|
# for rpline in res_respool_log_zone_cnt:
|
|
# rp_tenant_id = rpline[0]
|
|
# rp_log_zone_cnt = rpline[1]
|
|
# if tenant_id == rp_tenant_id:
|
|
# is_found = True
|
|
# if tenant_log_zone_cnt > rp_log_zone_cnt:
|
|
# raise MyError('{0} {1} check_logonly_replica_unit failed, log_type zone count not match with resource_pool'.format(line, rpline))
|
|
# break
|
|
# if is_found == False:
|
|
# raise MyError('{0} check_logonly_replica_unit failed, not found log_type resource_pool for this tenant'.format(line))
|
|
# logging.info('check_logonly_replica_unit success')
|
|
#
|
|
## 10. 检查租户分区数是否超出内存限制
|
|
#def check_tenant_part_num(query_cur):
|
|
# # 统计每个租户在各个server上的分区数量
|
|
# (desc, res_part_num) = query_cur.exec_query("""select svr_ip, svr_port, table_id >> 40 as tenant_id, count(*) as part_num from __all_virtual_clog_stat group by 1,2,3 order by 1,2,3""")
|
|
# # 计算每个租户在每个server上的max_memory
|
|
# (desc, res_unit_memory) = query_cur.exec_query("""select u.svr_ip, u.svr_port, t.tenant_id, uc.max_memory, p.replica_type from __all_unit u, __All_resource_pool p, __all_tenant t, __all_unit_config uc where p.resource_pool_id = u.resource_pool_id and t.tenant_id = p.tenant_id and p.unit_config_id = uc.unit_config_id""")
|
|
# # 查询每个server的memstore_limit_percentage
|
|
# (desc, res_svr_memstore_percent) = query_cur.exec_query("""select svr_ip, svr_port, name, value from __all_virtual_sys_parameter_stat where name = 'memstore_limit_percentage'""")
|
|
# part_static_cost = 128 * 1024
|
|
# part_dynamic_cost = 400 * 1024
|
|
# # 考虑到升级过程中可能有建表的需求,因此预留512个分区
|
|
# part_num_reserved = 512
|
|
# for line in res_part_num:
|
|
# svr_ip = line[0]
|
|
# svr_port = line[1]
|
|
# tenant_id = line[2]
|
|
# part_num = line[3]
|
|
# for uline in res_unit_memory:
|
|
# uip = uline[0]
|
|
# uport = uline[1]
|
|
# utid = uline[2]
|
|
# umem = uline[3]
|
|
# utype = uline[4]
|
|
# if svr_ip == uip and svr_port == uport and tenant_id == utid:
|
|
# for mpline in res_svr_memstore_percent:
|
|
# mpip = mpline[0]
|
|
# mpport = mpline[1]
|
|
# if mpip == uip and mpport == uport:
|
|
# mspercent = int(mpline[3])
|
|
# mem_limit = umem
|
|
# if 0 == utype:
|
|
# # full类型的unit需要为memstore预留内存
|
|
# mem_limit = umem * (100 - mspercent) / 100
|
|
# part_num_limit = mem_limit / (part_static_cost + part_dynamic_cost / 10);
|
|
# if part_num_limit <= 1000:
|
|
# part_num_limit = mem_limit / (part_static_cost + part_dynamic_cost)
|
|
# if part_num >= (part_num_limit - part_num_reserved):
|
|
# raise MyError('{0} {1} {2} exceed tenant partition num limit, please check'.format(line, uline, mpline))
|
|
# break
|
|
# logging.info('check tenant partition num success')
|
|
#
|
|
## 11. 检查存在租户partition,但是不存在unit的observer
|
|
#def check_tenant_resource(query_cur):
|
|
# (desc, res_unit) = query_cur.exec_query("""select tenant_id, svr_ip, svr_port from __all_virtual_partition_info where (tenant_id, svr_ip, svr_port) not in (select tenant_id, svr_ip, svr_port from __all_unit, __all_resource_pool where __all_unit.resource_pool_id = __all_resource_pool.resource_pool_id group by tenant_id, svr_ip, svr_port) group by tenant_id, svr_ip, svr_port""")
|
|
# for line in res_unit:
|
|
# raise MyError('{0} tenant unit not exist but partition exist'.format(line))
|
|
# logging.info("check tenant resource success")
|
|
#
|
|
## 12. 检查系统表(__all_table_history)索引生效情况
|
|
#def check_sys_index_status(query_cur):
|
|
# (desc, results) = query_cur.exec_query("""select count(*) as cnt from __all_table where data_table_id = 1099511627890 and table_id = 1099511637775 and index_type = 1 and index_status = 2""")
|
|
# if len(results) != 1 or results[0][0] != 1:
|
|
# raise MyError("""__all_table_history's index status not valid""")
|
|
# logging.info("""check __all_table_history's index status success""")
|
|
#
|
|
## 14. 检查升级前是否有只读zone
|
|
#def check_readonly_zone(query_cur):
|
|
# (desc, results) = query_cur.exec_query("""select count(*) from __all_zone where name='zone_type' and info='ReadOnly'""")
|
|
# if results[0][0] != 0:
|
|
# raise MyError("""check_readonly_zone failed, ob2.2 not support readonly_zone""")
|
|
# logging.info("""check_readonly_zone success""")
|
|
#
|
|
## 16. 修改永久下线的时间,避免升级过程中缺副本
|
|
#def modify_server_permanent_offline_time(query_cur):
|
|
# query_cur.exec_sql("""alter system set server_permanent_offline_time='72h'""")
|
|
# logging.info("modify server_permanent_offline_time success")
|
|
#
|
|
## 17. 修改安全删除副本时间
|
|
#def modify_replica_safe_remove_time(query_cur):
|
|
# query_cur.exec_sql("""alter system set replica_safe_remove_time='72h'""")
|
|
# logging.info("modify modify_replica_safe_remove_time success")
|
|
#
|
|
## 18. 检查progressive_merge_round都升到1
|
|
#def check_progressive_merge_round(query_cur):
|
|
# (desc, results) = query_cur.exec_query("""select count(*) as cnt from __all_virtual_table where progressive_merge_round = 0 and table_type not in (1,2,4)""")
|
|
# if results[0][0] != 0:
|
|
# raise MyError("""progressive_merge_round should all be 1""")
|
|
# logging.info("""check progressive_merge_round status success""")
|
|
#
|
|
##19. 检查是否有内置用户,角色
|
|
#def check_inner_user_role_exists(query_cur):
|
|
# (desc, results) = query_cur.exec_query(
|
|
# """select count(*)
|
|
# from oceanbase.__all_tenant t, oceanbase.__all_virtual_user u
|
|
# where t.tenant_id = u.tenant_id and
|
|
# t.compatibility_mode=1 and
|
|
# u.user_name in ('DBA','CONNECT','RESOURCE','LBACSYS','ORAAUDITOR');""")
|
|
# if results[0][0] != 0:
|
|
# raise MyError("""check_inner_user_role_exists failed, ob2.2 not support user_name in 'dba' etc... """)
|
|
# logging.info("""check_inner_user_role_exists success""")
|
|
#
|
|
## 19. 从小于224的版本升级上来时,需要确认high_priority_net_thread_count配置项值为0 (224版本开始该值默认为1)
|
|
#def check_high_priority_net_thread_count_before_224(query_cur):
|
|
# # 获取最小版本
|
|
# (desc, results) = query_cur.exec_query("""select distinct value from __all_virtual_sys_parameter_stat where name='min_observer_version'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('distinct observer version exist')
|
|
# elif cmp(results[0][0], "2.2.40") >= 0 :
|
|
# # 最小版本大于等于2.2.40,忽略检查
|
|
# logging.info('cluster version ({0}) is greate than or equal to 2.2.40, need not check standby cluster'.format(results[0][0]))
|
|
# else:
|
|
# # 低于224版本的需要确认配置项值为0
|
|
# logging.info('cluster version is ({0}), need check high_priority_net_thread_count'.format(results[0][0]))
|
|
# (desc, results) = query_cur.exec_query("""select value from __all_sys_parameter where name like 'high_priority_net_thread_count'""")
|
|
# for line in results:
|
|
# thread_cnt = line[0]
|
|
# if thread_cnt > 0:
|
|
# raise MyError('high_priority_net_thread_count is greater than 0, unexpected')
|
|
# logging.info('check high_priority_net_thread_count success')
|
|
#
|
|
## 20. 从小于224的版本升级上来时,要求不能有备库存在
|
|
#def check_standby_cluster(query_cur):
|
|
# # 获取最小版本
|
|
# (desc, results) = query_cur.exec_query("""select distinct value from __all_virtual_sys_parameter_stat where name='min_observer_version'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('distinct observer version exist')
|
|
# elif cmp(results[0][0], "2.2.40") >= 0 :
|
|
# # 最小版本大于等于2.2.40,忽略检查
|
|
# logging.info('cluster version ({0}) is greate than or equal to 2.2.40, need not check standby cluster'.format(results[0][0]))
|
|
# else:
|
|
# logging.info('cluster version is ({0}), need check standby cluster'.format(results[0][0]))
|
|
# (desc, results) = query_cur.exec_query("""select count(*) as cnt from __all_table where table_name = '__all_cluster'""")
|
|
# if results[0][0] == 0:
|
|
# logging.info('cluster ({0}) has no __all_cluster table, no standby cluster'.format(results[0][0]))
|
|
# else:
|
|
# (desc, results) = query_cur.exec_query("""select count(*) as cnt from __all_cluster""")
|
|
# if results[0][0] > 1:
|
|
# raise MyError("""multiple cluster exist in __all_cluster, maybe standby clusters added, not supported""")
|
|
# logging.info('check standby cluster from __all_cluster success')
|
|
#
|
|
## 开始升级前的检查
|
|
#def do_check(my_host, my_port, my_user, my_passwd, upgrade_params):
|
|
# try:
|
|
# conn = mysql.connector.connect(user = my_user,
|
|
# password = my_passwd,
|
|
# host = my_host,
|
|
# port = my_port,
|
|
# database = 'oceanbase',
|
|
# raise_on_warnings = True)
|
|
# conn.autocommit = True
|
|
# cur = conn.cursor(buffered=True)
|
|
# try:
|
|
# query_cur = QueryCursor(cur)
|
|
# check_observer_version(query_cur, upgrade_params)
|
|
# check_paxos_replica(query_cur)
|
|
# check_rebalance_task(query_cur)
|
|
# check_cluster_status(query_cur)
|
|
# check_disable_separate_sys_clog(query_cur)
|
|
# check_macro_block_data_seq(query_cur)
|
|
# check_sstable_column_checksum_method_new(query_cur)
|
|
# check_tenant_resource_pool(query_cur)
|
|
# check_logonly_replica_unit(query_cur)
|
|
# check_tenant_part_num(query_cur)
|
|
# check_tenant_resource(query_cur)
|
|
# check_readonly_zone(query_cur)
|
|
# modify_server_permanent_offline_time(query_cur)
|
|
# modify_replica_safe_remove_time(query_cur)
|
|
# check_progressive_merge_round(query_cur)
|
|
# check_inner_user_role_exists(query_cur)
|
|
# check_high_priority_net_thread_count_before_224(query_cur)
|
|
# check_standby_cluster(query_cur)
|
|
# except Exception, e:
|
|
# logging.exception('run error')
|
|
# raise e
|
|
# finally:
|
|
# cur.close()
|
|
# conn.close()
|
|
# except mysql.connector.Error, e:
|
|
# logging.exception('connection error')
|
|
# raise e
|
|
# except Exception, e:
|
|
# logging.exception('normal error')
|
|
# raise e
|
|
#
|
|
#if __name__ == '__main__':
|
|
# upgrade_params = UpgradeParams()
|
|
# change_opt_defult_value('log-file', upgrade_params.log_filename)
|
|
# parse_options(sys.argv[1:])
|
|
# if not has_no_local_opts():
|
|
# deal_with_local_opts()
|
|
# else:
|
|
# check_db_client_opts()
|
|
# log_filename = get_opt_log_file()
|
|
# upgrade_params.log_filename = log_filename
|
|
# # 日志配置放在这里是为了前面的操作不要覆盖掉日志文件
|
|
# config_logging_module(upgrade_params.log_filename)
|
|
# try:
|
|
# host = get_opt_host()
|
|
# port = int(get_opt_port())
|
|
# user = get_opt_user()
|
|
# password = get_opt_password()
|
|
# logging.info('parameters from cmd: host=\"%s\", port=%s, user=\"%s\", password=\"%s\", log-file=\"%s\"',\
|
|
# host, port, user, password, log_filename)
|
|
# do_check(host, port, user, password, upgrade_params)
|
|
# except mysql.connector.Error, e:
|
|
# logging.exception('mysql connctor error')
|
|
# raise e
|
|
# except Exception, e:
|
|
# logging.exception('normal error')
|
|
# raise e
|
|
#
|
|
####====XXXX======######==== I am a splitter ====######======XXXX====####
|
|
#filename:upgrade_cluster_health_checker.py
|
|
##!/usr/bin/env python
|
|
## -*- coding: utf-8 -*-
|
|
#
|
|
#import sys
|
|
#import os
|
|
#import time
|
|
#import mysql.connector
|
|
#from mysql.connector import errorcode
|
|
#import logging
|
|
#import getopt
|
|
#
|
|
#class UpgradeParams:
|
|
# log_filename = 'upgrade_cluster_health_checker.log'
|
|
#
|
|
##### --------------start : my_error.py --------------
|
|
#class MyError(Exception):
|
|
# def __init__(self, value):
|
|
# self.value = value
|
|
# def __str__(self):
|
|
# return repr(self.value)
|
|
#
|
|
##### --------------start : actions.py 只允许执行查询语句--------------
|
|
#class QueryCursor:
|
|
# __cursor = None
|
|
# def __init__(self, cursor):
|
|
# self.__cursor = cursor
|
|
# def exec_sql(self, sql, print_when_succ = True):
|
|
# try:
|
|
# self.__cursor.execute(sql)
|
|
# rowcount = self.__cursor.rowcount
|
|
# if True == print_when_succ:
|
|
# logging.info('succeed to execute sql: %s, rowcount = %d', sql, rowcount)
|
|
# return rowcount
|
|
# except mysql.connector.Error, e:
|
|
# logging.exception('mysql connector error, fail to execute sql: %s', sql)
|
|
# raise e
|
|
# except Exception, e:
|
|
# logging.exception('normal error, fail to execute sql: %s', sql)
|
|
# raise e
|
|
# def exec_query(self, sql, print_when_succ = True):
|
|
# try:
|
|
# self.__cursor.execute(sql)
|
|
# results = self.__cursor.fetchall()
|
|
# rowcount = self.__cursor.rowcount
|
|
# if True == print_when_succ:
|
|
# logging.info('succeed to execute query: %s, rowcount = %d', sql, rowcount)
|
|
# return (self.__cursor.description, results)
|
|
# except mysql.connector.Error, e:
|
|
# logging.exception('mysql connector error, fail to execute sql: %s', sql)
|
|
# raise e
|
|
# except Exception, e:
|
|
# logging.exception('normal error, fail to execute sql: %s', sql)
|
|
# raise e
|
|
##### ---------------end----------------------
|
|
#
|
|
##### --------------start : opt.py --------------
|
|
#help_str = \
|
|
#"""
|
|
#Help:
|
|
#""" +\
|
|
#sys.argv[0] + """ [OPTIONS]""" +\
|
|
#'\n\n' +\
|
|
#'-I, --help Display this help and exit.\n' +\
|
|
#'-V, --version Output version information and exit.\n' +\
|
|
#'-h, --host=name Connect to host.\n' +\
|
|
#'-P, --port=name Port number to use for connection.\n' +\
|
|
#'-u, --user=name User for login.\n' +\
|
|
#'-p, --password=name Password to use when connecting to server. If password is\n' +\
|
|
#' not given it\'s empty string "".\n' +\
|
|
#'-m, --module=name Modules to run. Modules should be a string combined by some of\n' +\
|
|
#' the following strings: ddl, normal_dml, each_tenant_dml,\n' +\
|
|
#' system_variable_dml, special_action, all. "all" represents\n' +\
|
|
#' that all modules should be run. They are splitted by ",".\n' +\
|
|
#' For example: -m all, or --module=ddl,normal_dml,special_action\n' +\
|
|
#'-l, --log-file=name Log file path. If log file path is not given it\'s ' + os.path.splitext(sys.argv[0])[0] + '.log\n' +\
|
|
#'-t, --timeout=name check timeout, default: 600(s).\n' + \
|
|
#'\n\n' +\
|
|
#'Maybe you want to run cmd like that:\n' +\
|
|
#sys.argv[0] + ' -h 127.0.0.1 -P 3306 -u admin -p admin\n'
|
|
#
|
|
#version_str = """version 1.0.0"""
|
|
#
|
|
#class Option:
|
|
# __g_short_name_set = set([])
|
|
# __g_long_name_set = set([])
|
|
# __short_name = None
|
|
# __long_name = None
|
|
# __is_with_param = None
|
|
# __is_local_opt = None
|
|
# __has_value = None
|
|
# __value = None
|
|
# def __init__(self, short_name, long_name, is_with_param, is_local_opt, default_value = None):
|
|
# if short_name in Option.__g_short_name_set:
|
|
# raise MyError('duplicate option short name: {0}'.format(short_name))
|
|
# elif long_name in Option.__g_long_name_set:
|
|
# raise MyError('duplicate option long name: {0}'.format(long_name))
|
|
# Option.__g_short_name_set.add(short_name)
|
|
# Option.__g_long_name_set.add(long_name)
|
|
# self.__short_name = short_name
|
|
# self.__long_name = long_name
|
|
# self.__is_with_param = is_with_param
|
|
# self.__is_local_opt = is_local_opt
|
|
# self.__has_value = False
|
|
# if None != default_value:
|
|
# self.set_value(default_value)
|
|
# def is_with_param(self):
|
|
# return self.__is_with_param
|
|
# def get_short_name(self):
|
|
# return self.__short_name
|
|
# def get_long_name(self):
|
|
# return self.__long_name
|
|
# def has_value(self):
|
|
# return self.__has_value
|
|
# def get_value(self):
|
|
# return self.__value
|
|
# def set_value(self, value):
|
|
# self.__value = value
|
|
# self.__has_value = True
|
|
# def is_local_opt(self):
|
|
# return self.__is_local_opt
|
|
# def is_valid(self):
|
|
# return None != self.__short_name and None != self.__long_name and True == self.__has_value and None != self.__value
|
|
#
|
|
#g_opts =\
|
|
#[\
|
|
#Option('I', 'help', False, True),\
|
|
#Option('V', 'version', False, True),\
|
|
#Option('h', 'host', True, False),\
|
|
#Option('P', 'port', True, False),\
|
|
#Option('u', 'user', True, False),\
|
|
#Option('p', 'password', True, False, ''),\
|
|
## 要跑哪个模块,默认全跑
|
|
#Option('m', 'module', True, False, 'all'),\
|
|
## 日志文件路径,不同脚本的main函数中中会改成不同的默认值
|
|
#Option('l', 'log-file', True, False),\
|
|
## 一些检查的超时时间,默认是600s
|
|
#Option('t', 'timeout', True, False, '600')
|
|
#]\
|
|
#
|
|
#def change_opt_defult_value(opt_long_name, opt_default_val):
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if opt.get_long_name() == opt_long_name:
|
|
# opt.set_value(opt_default_val)
|
|
# return
|
|
#
|
|
#def has_no_local_opts():
|
|
# global g_opts
|
|
# no_local_opts = True
|
|
# for opt in g_opts:
|
|
# if opt.is_local_opt() and opt.has_value():
|
|
# no_local_opts = False
|
|
# return no_local_opts
|
|
#
|
|
#def check_db_client_opts():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if not opt.is_local_opt() and not opt.has_value():
|
|
# raise MyError('option "-{0}" has not been specified, maybe you should run "{1} --help" for help'\
|
|
# .format(opt.get_short_name(), sys.argv[0]))
|
|
#
|
|
#def parse_option(opt_name, opt_val):
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if opt_name in (('-' + opt.get_short_name()), ('--' + opt.get_long_name())):
|
|
# opt.set_value(opt_val)
|
|
#
|
|
#def parse_options(argv):
|
|
# global g_opts
|
|
# short_opt_str = ''
|
|
# long_opt_list = []
|
|
# for opt in g_opts:
|
|
# if opt.is_with_param():
|
|
# short_opt_str += opt.get_short_name() + ':'
|
|
# else:
|
|
# short_opt_str += opt.get_short_name()
|
|
# for opt in g_opts:
|
|
# if opt.is_with_param():
|
|
# long_opt_list.append(opt.get_long_name() + '=')
|
|
# else:
|
|
# long_opt_list.append(opt.get_long_name())
|
|
# (opts, args) = getopt.getopt(argv, short_opt_str, long_opt_list)
|
|
# for (opt_name, opt_val) in opts:
|
|
# parse_option(opt_name, opt_val)
|
|
# if has_no_local_opts():
|
|
# check_db_client_opts()
|
|
#
|
|
#def deal_with_local_opt(opt):
|
|
# if 'help' == opt.get_long_name():
|
|
# global help_str
|
|
# print help_str
|
|
# elif 'version' == opt.get_long_name():
|
|
# global version_str
|
|
# print version_str
|
|
#
|
|
#def deal_with_local_opts():
|
|
# global g_opts
|
|
# if has_no_local_opts():
|
|
# raise MyError('no local options, can not deal with local options')
|
|
# else:
|
|
# for opt in g_opts:
|
|
# if opt.is_local_opt() and opt.has_value():
|
|
# deal_with_local_opt(opt)
|
|
# # 只处理一个
|
|
# return
|
|
#
|
|
#def get_opt_host():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'host' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
#
|
|
#def get_opt_port():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'port' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
#
|
|
#def get_opt_user():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'user' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
#
|
|
#def get_opt_password():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'password' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
#
|
|
#def get_opt_module():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'module' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
#
|
|
#def get_opt_log_file():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'log-file' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
#
|
|
#def get_opt_timeout():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'timeout' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
##### ---------------end----------------------
|
|
#
|
|
##### --------------start : do_upgrade_pre.py--------------
|
|
#def config_logging_module(log_filenamme):
|
|
# logging.basicConfig(level=logging.INFO,\
|
|
# format='[%(asctime)s] %(levelname)s %(filename)s:%(lineno)d %(message)s',\
|
|
# datefmt='%Y-%m-%d %H:%M:%S',\
|
|
# filename=log_filenamme,\
|
|
# filemode='w')
|
|
# # 定义日志打印格式
|
|
# formatter = logging.Formatter('[%(asctime)s] %(levelname)s %(filename)s:%(lineno)d %(message)s', '%Y-%m-%d %H:%M:%S')
|
|
# #######################################
|
|
# # 定义一个Handler打印INFO及以上级别的日志到sys.stdout
|
|
# stdout_handler = logging.StreamHandler(sys.stdout)
|
|
# stdout_handler.setLevel(logging.INFO)
|
|
# # 设置日志打印格式
|
|
# stdout_handler.setFormatter(formatter)
|
|
# # 将定义好的stdout_handler日志handler添加到root logger
|
|
# logging.getLogger('').addHandler(stdout_handler)
|
|
##### ---------------end----------------------
|
|
#
|
|
##### START ####
|
|
## 1. 检查paxos副本是否同步, paxos副本是否缺失
|
|
#def check_paxos_replica(query_cur):
|
|
# # 2.1 检查paxos副本是否同步
|
|
# (desc, results) = query_cur.exec_query("""select count(1) as unsync_cnt from __all_virtual_clog_stat where is_in_sync = 0 and is_offline = 0 and replica_type != 16""")
|
|
# if results[0][0] > 0 :
|
|
# raise MyError('{0} replicas unsync, please check'.format(results[0][0]))
|
|
# # 2.2 检查paxos副本是否有缺失 TODO
|
|
# logging.info('check paxos replica success')
|
|
#
|
|
## 2. 检查是否有做balance, locality变更
|
|
#def check_rebalance_task(query_cur):
|
|
# # 3.1 检查是否有做locality变更
|
|
# (desc, results) = query_cur.exec_query("""select count(1) as cnt from __all_rootservice_job where job_status='INPROGRESS' and return_code is null""")
|
|
# if results[0][0] > 0 :
|
|
# raise MyError('{0} locality tasks is doing, please check'.format(results[0][0]))
|
|
# # 3.2 检查是否有做balance
|
|
# (desc, results) = query_cur.exec_query("""select count(1) as rebalance_task_cnt from __all_virtual_rebalance_task_stat""")
|
|
# if results[0][0] > 0 :
|
|
# raise MyError('{0} rebalance tasks is doing, please check'.format(results[0][0]))
|
|
# logging.info('check rebalance task success')
|
|
#
|
|
## 3. 检查集群状态
|
|
#def check_cluster_status(query_cur):
|
|
# # 4.1 检查是否非合并状态
|
|
# (desc, results) = query_cur.exec_query("""select info from __all_zone where zone='' and name='merge_status'""")
|
|
# if cmp(results[0][0], 'IDLE') != 0 :
|
|
# raise MyError('global status expected = {0}, actual = {1}'.format('IDLE', results[0][0]))
|
|
# logging.info('check cluster status success')
|
|
# # 4.2 检查合并版本是否>=3
|
|
# (desc, results) = query_cur.exec_query("""select cast(value as unsigned) value from __all_zone where zone='' and name='last_merged_version'""")
|
|
# if results[0][0] < 2:
|
|
# raise MyError('global last_merged_version expected >= 2 actual = {0}'.format(results[0][0]))
|
|
# logging.info('check global last_merged_version success')
|
|
#
|
|
## 4. 检查租户分区数是否超出内存限制
|
|
#def check_tenant_part_num(query_cur):
|
|
# # 统计每个租户在各个server上的分区数量
|
|
# (desc, res_part_num) = query_cur.exec_query("""select svr_ip, svr_port, table_id >> 40 as tenant_id, count(*) as part_num from __all_virtual_clog_stat group by 1,2,3 order by 1,2,3""")
|
|
# # 计算每个租户在每个server上的max_memory
|
|
# (desc, res_unit_memory) = query_cur.exec_query("""select u.svr_ip, u.svr_port, t.tenant_id, uc.max_memory, p.replica_type from __all_unit u, __All_resource_pool p, __all_tenant t, __all_unit_config uc where p.resource_pool_id = u.resource_pool_id and t.tenant_id = p.tenant_id and p.unit_config_id = uc.unit_config_id""")
|
|
# # 查询每个server的memstore_limit_percentage
|
|
# (desc, res_svr_memstore_percent) = query_cur.exec_query("""select svr_ip, svr_port, name, value from __all_virtual_sys_parameter_stat where name = 'memstore_limit_percentage'""")
|
|
# part_static_cost = 128 * 1024
|
|
# part_dynamic_cost = 400 * 1024
|
|
# # 考虑到升级过程中可能有建表的需求,因此预留512个分区
|
|
# part_num_reserved = 512
|
|
# for line in res_part_num:
|
|
# svr_ip = line[0]
|
|
# svr_port = line[1]
|
|
# tenant_id = line[2]
|
|
# part_num = line[3]
|
|
# for uline in res_unit_memory:
|
|
# uip = uline[0]
|
|
# uport = uline[1]
|
|
# utid = uline[2]
|
|
# umem = uline[3]
|
|
# utype = uline[4]
|
|
# if svr_ip == uip and svr_port == uport and tenant_id == utid:
|
|
# for mpline in res_svr_memstore_percent:
|
|
# mpip = mpline[0]
|
|
# mpport = mpline[1]
|
|
# if mpip == uip and mpport == uport:
|
|
# mspercent = int(mpline[3])
|
|
# mem_limit = umem
|
|
# if 0 == utype:
|
|
# # full类型的unit需要为memstore预留内存
|
|
# mem_limit = umem * (100 - mspercent) / 100
|
|
# part_num_limit = mem_limit / (part_static_cost + part_dynamic_cost / 10);
|
|
# if part_num_limit <= 1000:
|
|
# part_num_limit = mem_limit / (part_static_cost + part_dynamic_cost)
|
|
# if part_num >= (part_num_limit - part_num_reserved):
|
|
# raise MyError('{0} {1} {2} exceed tenant partition num limit, please check'.format(line, uline, mpline))
|
|
# break
|
|
# logging.info('check tenant partition num success')
|
|
#
|
|
## 5. 检查存在租户partition,但是不存在unit的observer
|
|
#def check_tenant_resource(query_cur):
|
|
# (desc, res_unit) = query_cur.exec_query("""select tenant_id, svr_ip, svr_port from __all_virtual_partition_info where (tenant_id, svr_ip, svr_port) not in (select tenant_id, svr_ip, svr_port from __all_unit, __all_resource_pool where __all_unit.resource_pool_id = __all_resource_pool.resource_pool_id group by tenant_id, svr_ip, svr_port) group by tenant_id, svr_ip, svr_port""")
|
|
# for line in res_unit:
|
|
# raise MyError('{0} tenant unit not exist but partition exist'.format(line))
|
|
# logging.info("check tenant resource success")
|
|
#
|
|
## 6. 检查progressive_merge_round都升到1
|
|
#def check_progressive_merge_round(query_cur):
|
|
# (desc, results) = query_cur.exec_query("""select count(*) as cnt from __all_virtual_table where progressive_merge_round = 0 and table_type not in (1,2,4) and data_table_id = 0""")
|
|
# if results[0][0] != 0:
|
|
# raise MyError("""progressive_merge_round of main table should all be 1""")
|
|
# (desc, results) = query_cur.exec_query("""select count(*) as cnt from __all_virtual_table where progressive_merge_round = 0 and table_type not in (1,2,4) and data_table_id > 0 and data_table_id in (select table_id from __all_virtual_table where table_type not in (1,2,4) and data_table_id = 0)""")
|
|
# if results[0][0] != 0:
|
|
# raise MyError("""progressive_merge_round of index should all be 1""")
|
|
# logging.info("""check progressive_merge_round status success""")
|
|
#
|
|
## 主库状态检查
|
|
#def check_primary_cluster_sync_status(query_cur, timeout):
|
|
# (desc, res) = query_cur.exec_query("""select current_scn from oceanbase.v$ob_cluster where cluster_role='PRIMARY' and cluster_status='VALID'""")
|
|
# if len(res) != 1:
|
|
# raise MyError('query results count is not 1')
|
|
# query_sql = "select count(*) from oceanbase.v$ob_standby_status where cluster_role != 'PHYSICAL STANDBY' or cluster_status != 'VALID' or current_scn < {0}".format(res[0][0]);
|
|
# times = timeout
|
|
# print times
|
|
# while times > 0 :
|
|
# (desc, res1) = query_cur.exec_query(query_sql)
|
|
# if len(res1) == 1 and res1[0][0] == 0:
|
|
# break;
|
|
# time.sleep(1)
|
|
# times -=1
|
|
# if times == 0:
|
|
# raise MyError("there exists standby cluster not synchronizing, checking primary cluster status failed!!!")
|
|
# else:
|
|
# logging.info("check primary cluster sync status success")
|
|
#
|
|
## 备库状态检查
|
|
#def check_standby_cluster_sync_status(query_cur, timeout):
|
|
# (desc, res) = query_cur.exec_query("""select time_to_usec(now(6)) from dual""")
|
|
# query_sql = "select count(*) from oceanbase.v$ob_cluster where (cluster_role != 'PHYSICAL STANDBY') or (cluster_status != 'VALID') or (current_scn < {0}) or (switchover_status != 'NOT ALLOWED')".format(res[0][0]);
|
|
# times = timeout
|
|
# while times > 0 :
|
|
# (desc, res2) = query_cur.exec_query(query_sql)
|
|
# if len(res2) == 1 and res2[0][0] == 0:
|
|
# break
|
|
# time.sleep(1)
|
|
# times -= 1
|
|
# if times == 0:
|
|
# raise MyError('current standby cluster not synchronizing, please check!!!')
|
|
# else:
|
|
# logging.info("check standby cluster sync status success")
|
|
#
|
|
## 判断是主库还是备库
|
|
#def check_cluster_sync_status(query_cur, timeout):
|
|
# (desc, res) = query_cur.exec_query("""select cluster_role from oceanbase.v$ob_cluster""")
|
|
# if res[0][0] == 'PRIMARY':
|
|
# check_primary_cluster_sync_status(query_cur, timeout)
|
|
# else:
|
|
# check_standby_cluster_sync_status(query_cur, timeout)
|
|
#
|
|
#
|
|
## 开始升级前的检查
|
|
#def do_check(my_host, my_port, my_user, my_passwd, upgrade_params, timeout):
|
|
# try:
|
|
# conn = mysql.connector.connect(user = my_user,
|
|
# password = my_passwd,
|
|
# host = my_host,
|
|
# port = my_port,
|
|
# database = 'oceanbase',
|
|
# raise_on_warnings = True)
|
|
# conn.autocommit = True
|
|
# cur = conn.cursor(buffered=True)
|
|
# try:
|
|
# query_cur = QueryCursor(cur)
|
|
# check_paxos_replica(query_cur)
|
|
# check_rebalance_task(query_cur)
|
|
# check_cluster_status(query_cur)
|
|
# check_tenant_part_num(query_cur)
|
|
# check_tenant_resource(query_cur)
|
|
# check_cluster_sync_status(query_cur, timeout)
|
|
# except Exception, e:
|
|
# logging.exception('run error')
|
|
# raise e
|
|
# finally:
|
|
# cur.close()
|
|
# conn.close()
|
|
# except mysql.connector.Error, e:
|
|
# logging.exception('connection error')
|
|
# raise e
|
|
# except Exception, e:
|
|
# logging.exception('normal error')
|
|
# raise e
|
|
#
|
|
#if __name__ == '__main__':
|
|
# upgrade_params = UpgradeParams()
|
|
# change_opt_defult_value('log-file', upgrade_params.log_filename)
|
|
# parse_options(sys.argv[1:])
|
|
# if not has_no_local_opts():
|
|
# deal_with_local_opts()
|
|
# else:
|
|
# check_db_client_opts()
|
|
# log_filename = get_opt_log_file()
|
|
# upgrade_params.log_filename = log_filename
|
|
# # 日志配置放在这里是为了前面的操作不要覆盖掉日志文件
|
|
# config_logging_module(upgrade_params.log_filename)
|
|
# try:
|
|
# host = get_opt_host()
|
|
# port = int(get_opt_port())
|
|
# user = get_opt_user()
|
|
# password = get_opt_password()
|
|
# timeout = int(get_opt_timeout())
|
|
# logging.info('parameters from cmd: host=\"%s\", port=%s, user=\"%s\", password=\"%s\", log-file=\"%s\", timeout=%s', \
|
|
# host, port, user, password, log_filename, timeout)
|
|
# do_check(host, port, user, password, upgrade_params, timeout)
|
|
# except mysql.connector.Error, e:
|
|
# logging.exception('mysql connctor error')
|
|
# raise e
|
|
# except Exception, e:
|
|
# logging.exception('normal error')
|
|
# raise e
|
|
#
|
|
####====XXXX======######==== I am a splitter ====######======XXXX====####
|
|
#filename:upgrade_post_checker.py
|
|
##!/usr/bin/env python
|
|
## -*- coding: utf-8 -*-
|
|
#
|
|
#import sys
|
|
#import os
|
|
#import time
|
|
#import mysql.connector
|
|
#from mysql.connector import errorcode
|
|
#import logging
|
|
#import getopt
|
|
#
|
|
#class UpgradeParams:
|
|
# log_filename = 'upgrade_post_checker.log'
|
|
# new_version = '3.0.0'
|
|
##### --------------start : my_error.py --------------
|
|
#class MyError(Exception):
|
|
# def __init__(self, value):
|
|
# self.value = value
|
|
# def __str__(self):
|
|
# return repr(self.value)
|
|
#
|
|
##### --------------start : actions.py--------------
|
|
#class QueryCursor:
|
|
# __cursor = None
|
|
# def __init__(self, cursor):
|
|
# self.__cursor = cursor
|
|
# def exec_sql(self, sql, print_when_succ = True):
|
|
# try:
|
|
# self.__cursor.execute(sql)
|
|
# rowcount = self.__cursor.rowcount
|
|
# if True == print_when_succ:
|
|
# logging.info('succeed to execute sql: %s, rowcount = %d', sql, rowcount)
|
|
# return rowcount
|
|
# except mysql.connector.Error, e:
|
|
# logging.exception('mysql connector error, fail to execute sql: %s', sql)
|
|
# raise e
|
|
# except Exception, e:
|
|
# logging.exception('normal error, fail to execute sql: %s', sql)
|
|
# raise e
|
|
# def exec_query(self, sql, print_when_succ = True):
|
|
# try:
|
|
# self.__cursor.execute(sql)
|
|
# results = self.__cursor.fetchall()
|
|
# rowcount = self.__cursor.rowcount
|
|
# if True == print_when_succ:
|
|
# logging.info('succeed to execute query: %s, rowcount = %d', sql, rowcount)
|
|
# return (self.__cursor.description, results)
|
|
# except mysql.connector.Error, e:
|
|
# logging.exception('mysql connector error, fail to execute sql: %s', sql)
|
|
# raise e
|
|
# except Exception, e:
|
|
# logging.exception('normal error, fail to execute sql: %s', sql)
|
|
# raise e
|
|
##### ---------------end----------------------
|
|
#
|
|
##### --------------start : opt.py --------------
|
|
#help_str = \
|
|
#"""
|
|
#Help:
|
|
#""" +\
|
|
#sys.argv[0] + """ [OPTIONS]""" +\
|
|
#'\n\n' +\
|
|
#'-I, --help Display this help and exit.\n' +\
|
|
#'-V, --version Output version information and exit.\n' +\
|
|
#'-h, --host=name Connect to host.\n' +\
|
|
#'-P, --port=name Port number to use for connection.\n' +\
|
|
#'-u, --user=name User for login.\n' +\
|
|
#'-p, --password=name Password to use when connecting to server. If password is\n' +\
|
|
#' not given it\'s empty string "".\n' +\
|
|
#'-m, --module=name Modules to run. Modules should be a string combined by some of\n' +\
|
|
#' the following strings: ddl, normal_dml, each_tenant_dml,\n' +\
|
|
#' system_variable_dml, special_action, all. "all" represents\n' +\
|
|
#' that all modules should be run. They are splitted by ",".\n' +\
|
|
#' For example: -m all, or --module=ddl,normal_dml,special_action\n' +\
|
|
#'-l, --log-file=name Log file path. If log file path is not given it\'s ' + os.path.splitext(sys.argv[0])[0] + '.log\n' +\
|
|
#'\n\n' +\
|
|
#'Maybe you want to run cmd like that:\n' +\
|
|
#sys.argv[0] + ' -h 127.0.0.1 -P 3306 -u admin -p admin\n'
|
|
#
|
|
#version_str = """version 1.0.0"""
|
|
#
|
|
#class Option:
|
|
# __g_short_name_set = set([])
|
|
# __g_long_name_set = set([])
|
|
# __short_name = None
|
|
# __long_name = None
|
|
# __is_with_param = None
|
|
# __is_local_opt = None
|
|
# __has_value = None
|
|
# __value = None
|
|
# def __init__(self, short_name, long_name, is_with_param, is_local_opt, default_value = None):
|
|
# if short_name in Option.__g_short_name_set:
|
|
# raise MyError('duplicate option short name: {0}'.format(short_name))
|
|
# elif long_name in Option.__g_long_name_set:
|
|
# raise MyError('duplicate option long name: {0}'.format(long_name))
|
|
# Option.__g_short_name_set.add(short_name)
|
|
# Option.__g_long_name_set.add(long_name)
|
|
# self.__short_name = short_name
|
|
# self.__long_name = long_name
|
|
# self.__is_with_param = is_with_param
|
|
# self.__is_local_opt = is_local_opt
|
|
# self.__has_value = False
|
|
# if None != default_value:
|
|
# self.set_value(default_value)
|
|
# def is_with_param(self):
|
|
# return self.__is_with_param
|
|
# def get_short_name(self):
|
|
# return self.__short_name
|
|
# def get_long_name(self):
|
|
# return self.__long_name
|
|
# def has_value(self):
|
|
# return self.__has_value
|
|
# def get_value(self):
|
|
# return self.__value
|
|
# def set_value(self, value):
|
|
# self.__value = value
|
|
# self.__has_value = True
|
|
# def is_local_opt(self):
|
|
# return self.__is_local_opt
|
|
# def is_valid(self):
|
|
# return None != self.__short_name and None != self.__long_name and True == self.__has_value and None != self.__value
|
|
#
|
|
#g_opts =\
|
|
#[\
|
|
#Option('I', 'help', False, True),\
|
|
#Option('V', 'version', False, True),\
|
|
#Option('h', 'host', True, False),\
|
|
#Option('P', 'port', True, False),\
|
|
#Option('u', 'user', True, False),\
|
|
#Option('p', 'password', True, False, ''),\
|
|
## 要跑哪个模块,默认全跑
|
|
#Option('m', 'module', True, False, 'all'),\
|
|
## 日志文件路径,不同脚本的main函数中中会改成不同的默认值
|
|
#Option('l', 'log-file', True, False)
|
|
#]\
|
|
#
|
|
#def change_opt_defult_value(opt_long_name, opt_default_val):
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if opt.get_long_name() == opt_long_name:
|
|
# opt.set_value(opt_default_val)
|
|
# return
|
|
#
|
|
#def has_no_local_opts():
|
|
# global g_opts
|
|
# no_local_opts = True
|
|
# for opt in g_opts:
|
|
# if opt.is_local_opt() and opt.has_value():
|
|
# no_local_opts = False
|
|
# return no_local_opts
|
|
#
|
|
#def check_db_client_opts():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if not opt.is_local_opt() and not opt.has_value():
|
|
# raise MyError('option "-{0}" has not been specified, maybe you should run "{1} --help" for help'\
|
|
# .format(opt.get_short_name(), sys.argv[0]))
|
|
#
|
|
#def parse_option(opt_name, opt_val):
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if opt_name in (('-' + opt.get_short_name()), ('--' + opt.get_long_name())):
|
|
# opt.set_value(opt_val)
|
|
#
|
|
#def parse_options(argv):
|
|
# global g_opts
|
|
# short_opt_str = ''
|
|
# long_opt_list = []
|
|
# for opt in g_opts:
|
|
# if opt.is_with_param():
|
|
# short_opt_str += opt.get_short_name() + ':'
|
|
# else:
|
|
# short_opt_str += opt.get_short_name()
|
|
# for opt in g_opts:
|
|
# if opt.is_with_param():
|
|
# long_opt_list.append(opt.get_long_name() + '=')
|
|
# else:
|
|
# long_opt_list.append(opt.get_long_name())
|
|
# (opts, args) = getopt.getopt(argv, short_opt_str, long_opt_list)
|
|
# for (opt_name, opt_val) in opts:
|
|
# parse_option(opt_name, opt_val)
|
|
# if has_no_local_opts():
|
|
# check_db_client_opts()
|
|
#
|
|
#def deal_with_local_opt(opt):
|
|
# if 'help' == opt.get_long_name():
|
|
# global help_str
|
|
# print help_str
|
|
# elif 'version' == opt.get_long_name():
|
|
# global version_str
|
|
# print version_str
|
|
#
|
|
#def deal_with_local_opts():
|
|
# global g_opts
|
|
# if has_no_local_opts():
|
|
# raise MyError('no local options, can not deal with local options')
|
|
# else:
|
|
# for opt in g_opts:
|
|
# if opt.is_local_opt() and opt.has_value():
|
|
# deal_with_local_opt(opt)
|
|
# # 只处理一个
|
|
# return
|
|
#
|
|
#def get_opt_host():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'host' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
#
|
|
#def get_opt_port():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'port' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
#
|
|
#def get_opt_user():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'user' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
#
|
|
#def get_opt_password():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'password' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
#
|
|
#def get_opt_module():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'module' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
#
|
|
#def get_opt_log_file():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'log-file' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
##### ---------------end----------------------
|
|
#
|
|
#def config_logging_module(log_filenamme):
|
|
# logging.basicConfig(level=logging.INFO,\
|
|
# format='[%(asctime)s] %(levelname)s %(filename)s:%(lineno)d %(message)s',\
|
|
# datefmt='%Y-%m-%d %H:%M:%S',\
|
|
# filename=log_filenamme,\
|
|
# filemode='w')
|
|
# # 定义日志打印格式
|
|
# formatter = logging.Formatter('[%(asctime)s] %(levelname)s %(filename)s:%(lineno)d %(message)s', '%Y-%m-%d %H:%M:%S')
|
|
# #######################################
|
|
# # 定义一个Handler打印INFO及以上级别的日志到sys.stdout
|
|
# stdout_handler = logging.StreamHandler(sys.stdout)
|
|
# stdout_handler.setLevel(logging.INFO)
|
|
# # 设置日志打印格式
|
|
# stdout_handler.setFormatter(formatter)
|
|
# # 将定义好的stdout_handler日志handler添加到root logger
|
|
# logging.getLogger('').addHandler(stdout_handler)
|
|
#
|
|
##### STAR
|
|
## 1 检查版本号
|
|
#def check_cluster_version(query_cur):
|
|
# # 一方面配置项生效是个异步生效任务,另一方面是2.2.0之后新增租户级配置项刷新,和系统级配置项刷新复用同一个timer,这里暂且等一下。
|
|
# times = 30
|
|
# sql="select distinct value = '{0}' from oceanbase.__all_virtual_sys_parameter_stat where name='min_observer_version'".format(upgrade_params.new_version)
|
|
# while times > 0 :
|
|
# (desc, results) = query_cur.exec_query(sql)
|
|
# if len(results) == 1 and results[0][0] == 1:
|
|
# break;
|
|
# time.sleep(1)
|
|
# times -=1
|
|
# if times == 0:
|
|
# raise MyError("check cluster version timeout!")
|
|
# else:
|
|
# logging.info("check_cluster_version success")
|
|
#
|
|
#def check_storage_format_version(query_cur):
|
|
# # Specified expected version each time want to upgrade (see OB_STORAGE_FORMAT_VERSION_MAX)
|
|
# expect_version = 4;
|
|
# sql = "select value from oceanbase.__all_zone where zone = '' and name = 'storage_format_version'"
|
|
# times = 180
|
|
# while times > 0 :
|
|
# (desc, results) = query_cur.exec_query(sql)
|
|
# if len(results) == 1 and results[0][0] == expect_version:
|
|
# break
|
|
# time.sleep(10)
|
|
# times -= 1
|
|
# if times == 0:
|
|
# raise MyError("check storage format version timeout! Expected version {0}".format(expect_version))
|
|
# else:
|
|
# logging.info("check expected storage format version '{0}' success".format(expect_version))
|
|
#
|
|
#def upgrade_storage_format_version(conn, cur):
|
|
# try:
|
|
# # enable_ddl
|
|
# sql = "alter system set enable_ddl = true;"
|
|
# logging.info(sql)
|
|
# cur.execute(sql)
|
|
# time.sleep(10)
|
|
#
|
|
# # run job
|
|
# sql = "alter system run job 'UPGRADE_STORAGE_FORMAT_VERSION';"
|
|
# logging.info(sql)
|
|
# cur.execute(sql)
|
|
#
|
|
# except Exception, e:
|
|
# logging.warn("upgrade storage format version failed")
|
|
# raise MyError("upgrade storage format version failed")
|
|
# logging.info("upgrade storage format version finish")
|
|
#
|
|
## 2 检查内部表自检是否成功
|
|
#def check_root_inspection(query_cur):
|
|
# sql = "select count(*) from oceanbase.__all_virtual_upgrade_inspection where info != 'succeed'"
|
|
# times = 180
|
|
# while times > 0 :
|
|
# (desc, results) = query_cur.exec_query(sql)
|
|
# if results[0][0] == 0:
|
|
# break
|
|
# time.sleep(10)
|
|
# times -= 1
|
|
# if times == 0:
|
|
# raise MyError('check root inspection failed!')
|
|
# logging.info('check root inspection success')
|
|
#
|
|
## 3 开ddl
|
|
#def enable_ddl(query_cur):
|
|
# query_cur.exec_sql("""alter system set enable_ddl = true""")
|
|
# logging.info("enable_ddl success")
|
|
#
|
|
## 4 打开rebalance
|
|
#def enable_rebalance(query_cur):
|
|
# query_cur.exec_sql("""alter system set enable_rebalance = true""")
|
|
# logging.info("enable_rebalance success")
|
|
#
|
|
## 5 打开rereplication
|
|
#def enable_rereplication(query_cur):
|
|
# query_cur.exec_sql("""alter system set enable_rereplication = true""")
|
|
# logging.info("enable_rereplication success")
|
|
#
|
|
## 6 打开major freeze
|
|
#def enable_major_freeze(query_cur):
|
|
# query_cur.exec_sql("""alter system set enable_major_freeze=true""")
|
|
# logging.info("enable_major_freeze success")
|
|
#
|
|
## 开始升级后的检查
|
|
#def do_check(my_host, my_port, my_user, my_passwd, upgrade_params):
|
|
# try:
|
|
# conn = mysql.connector.connect(user = my_user,
|
|
# password = my_passwd,
|
|
# host = my_host,
|
|
# port = my_port,
|
|
# database = 'oceanbase',
|
|
# raise_on_warnings = True)
|
|
# conn.autocommit = True
|
|
# cur = conn.cursor(buffered=True)
|
|
# try:
|
|
# query_cur = QueryCursor(cur)
|
|
# try:
|
|
# check_cluster_version(query_cur)
|
|
# #upgrade_storage_format_version(conn, cur)
|
|
# #check_storage_format_version(query_cur)
|
|
# check_root_inspection(query_cur)
|
|
# enable_ddl(query_cur)
|
|
# enable_rebalance(query_cur)
|
|
# enable_rereplication(query_cur )
|
|
# enable_major_freeze(query_cur)
|
|
# except Exception, e:
|
|
# logging.exception('run error')
|
|
# raise e
|
|
# except Exception, e:
|
|
# logging.exception('run error')
|
|
# raise e
|
|
# finally:
|
|
# cur.close()
|
|
# conn.close()
|
|
# except mysql.connector.Error, e:
|
|
# logging.exception('connection error')
|
|
# raise e
|
|
# except Exception, e:
|
|
# logging.exception('normal error')
|
|
# raise e
|
|
#
|
|
#if __name__ == '__main__':
|
|
# upgrade_params = UpgradeParams()
|
|
# change_opt_defult_value('log-file', upgrade_params.log_filename)
|
|
# parse_options(sys.argv[1:])
|
|
# if not has_no_local_opts():
|
|
# deal_with_local_opts()
|
|
# else:
|
|
# check_db_client_opts()
|
|
# log_filename = get_opt_log_file()
|
|
# upgrade_params.log_filename = log_filename
|
|
# # 日志配置放在这里是为了前面的操作不要覆盖掉日志文件
|
|
# config_logging_module(upgrade_params.log_filename)
|
|
# try:
|
|
# host = get_opt_host()
|
|
# port = int(get_opt_port())
|
|
# user = get_opt_user()
|
|
# password = get_opt_password()
|
|
# logging.info('parameters from cmd: host=\"%s\", port=%s, user=\"%s\", password=\"%s\", log-file=\"%s\"',\
|
|
# host, port, user, password, log_filename)
|
|
# do_check(host, port, user, password, upgrade_params)
|
|
# except mysql.connector.Error, e:
|
|
# logging.exception('mysql connctor error')
|
|
# raise e
|
|
# except Exception, e:
|
|
# logging.exception('normal error')
|
|
# raise e
|
|
#
|
|
####====XXXX======######==== I am a splitter ====######======XXXX====####
|
|
#filename:upgrade_rolling_post.py
|
|
##!/usr/bin/env python
|
|
## -*- coding: utf-8 -*-
|
|
#
|
|
#import sys
|
|
#import os
|
|
#import time
|
|
#import mysql.connector
|
|
#from mysql.connector import errorcode
|
|
#import logging
|
|
#import getopt
|
|
#
|
|
#class UpgradeParams:
|
|
# log_filename = 'upgrade_rolling_post.log'
|
|
##### --------------start : my_error.py --------------
|
|
#class MyError(Exception):
|
|
# def __init__(self, value):
|
|
# self.value = value
|
|
# def __str__(self):
|
|
# return repr(self.value)
|
|
#
|
|
##### --------------start : actions.py--------------
|
|
#class QueryCursor:
|
|
# __cursor = None
|
|
# def __init__(self, cursor):
|
|
# self.__cursor = cursor
|
|
# def exec_sql(self, sql, print_when_succ = True):
|
|
# try:
|
|
# self.__cursor.execute(sql)
|
|
# rowcount = self.__cursor.rowcount
|
|
# if True == print_when_succ:
|
|
# logging.info('succeed to execute sql: %s, rowcount = %d', sql, rowcount)
|
|
# return rowcount
|
|
# except mysql.connector.Error, e:
|
|
# logging.exception('mysql connector error, fail to execute sql: %s', sql)
|
|
# raise e
|
|
# except Exception, e:
|
|
# logging.exception('normal error, fail to execute sql: %s', sql)
|
|
# raise e
|
|
# def exec_query(self, sql, print_when_succ = True):
|
|
# try:
|
|
# self.__cursor.execute(sql)
|
|
# results = self.__cursor.fetchall()
|
|
# rowcount = self.__cursor.rowcount
|
|
# if True == print_when_succ:
|
|
# logging.info('succeed to execute query: %s, rowcount = %d', sql, rowcount)
|
|
# return (self.__cursor.description, results)
|
|
# except mysql.connector.Error, e:
|
|
# logging.exception('mysql connector error, fail to execute sql: %s', sql)
|
|
# raise e
|
|
# except Exception, e:
|
|
# logging.exception('normal error, fail to execute sql: %s', sql)
|
|
# raise e
|
|
##### ---------------end----------------------
|
|
#
|
|
##### --------------start : opt.py --------------
|
|
#help_str = \
|
|
#"""
|
|
#Help:
|
|
#""" +\
|
|
#sys.argv[0] + """ [OPTIONS]""" +\
|
|
#'\n\n' +\
|
|
#'-I, --help Display this help and exit.\n' +\
|
|
#'-V, --version Output version information and exit.\n' +\
|
|
#'-h, --host=name Connect to host.\n' +\
|
|
#'-P, --port=name Port number to use for connection.\n' +\
|
|
#'-u, --user=name User for login.\n' +\
|
|
#'-p, --password=name Password to use when connecting to server. If password is\n' +\
|
|
#' not given it\'s empty string "".\n' +\
|
|
#'-m, --module=name Modules to run. Modules should be a string combined by some of\n' +\
|
|
#' the following strings: ddl, normal_dml, each_tenant_dml,\n' +\
|
|
#' system_variable_dml, special_action, all. "all" represents\n' +\
|
|
#' that all modules should be run. They are splitted by ",".\n' +\
|
|
#' For example: -m all, or --module=ddl,normal_dml,special_action\n' +\
|
|
#'-l, --log-file=name Log file path. If log file path is not given it\'s ' + os.path.splitext(sys.argv[0])[0] + '.log\n' +\
|
|
#'\n\n' +\
|
|
#'Maybe you want to run cmd like that:\n' +\
|
|
#sys.argv[0] + ' -h 127.0.0.1 -P 3306 -u admin -p admin\n'
|
|
#
|
|
#version_str = """version 1.0.0"""
|
|
#
|
|
#class Option:
|
|
# __g_short_name_set = set([])
|
|
# __g_long_name_set = set([])
|
|
# __short_name = None
|
|
# __long_name = None
|
|
# __is_with_param = None
|
|
# __is_local_opt = None
|
|
# __has_value = None
|
|
# __value = None
|
|
# def __init__(self, short_name, long_name, is_with_param, is_local_opt, default_value = None):
|
|
# if short_name in Option.__g_short_name_set:
|
|
# raise MyError('duplicate option short name: {0}'.format(short_name))
|
|
# elif long_name in Option.__g_long_name_set:
|
|
# raise MyError('duplicate option long name: {0}'.format(long_name))
|
|
# Option.__g_short_name_set.add(short_name)
|
|
# Option.__g_long_name_set.add(long_name)
|
|
# self.__short_name = short_name
|
|
# self.__long_name = long_name
|
|
# self.__is_with_param = is_with_param
|
|
# self.__is_local_opt = is_local_opt
|
|
# self.__has_value = False
|
|
# if None != default_value:
|
|
# self.set_value(default_value)
|
|
# def is_with_param(self):
|
|
# return self.__is_with_param
|
|
# def get_short_name(self):
|
|
# return self.__short_name
|
|
# def get_long_name(self):
|
|
# return self.__long_name
|
|
# def has_value(self):
|
|
# return self.__has_value
|
|
# def get_value(self):
|
|
# return self.__value
|
|
# def set_value(self, value):
|
|
# self.__value = value
|
|
# self.__has_value = True
|
|
# def is_local_opt(self):
|
|
# return self.__is_local_opt
|
|
# def is_valid(self):
|
|
# return None != self.__short_name and None != self.__long_name and True == self.__has_value and None != self.__value
|
|
#
|
|
#g_opts =\
|
|
#[\
|
|
#Option('I', 'help', False, True),\
|
|
#Option('V', 'version', False, True),\
|
|
#Option('h', 'host', True, False),\
|
|
#Option('P', 'port', True, False),\
|
|
#Option('u', 'user', True, False),\
|
|
#Option('p', 'password', True, False, ''),\
|
|
## 要跑哪个模块,默认全跑
|
|
#Option('m', 'module', True, False, 'all'),\
|
|
## 日志文件路径,不同脚本的main函数中中会改成不同的默认值
|
|
#Option('l', 'log-file', True, False)
|
|
#]\
|
|
#
|
|
#def change_opt_defult_value(opt_long_name, opt_default_val):
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if opt.get_long_name() == opt_long_name:
|
|
# opt.set_value(opt_default_val)
|
|
# return
|
|
#
|
|
#def has_no_local_opts():
|
|
# global g_opts
|
|
# no_local_opts = True
|
|
# for opt in g_opts:
|
|
# if opt.is_local_opt() and opt.has_value():
|
|
# no_local_opts = False
|
|
# return no_local_opts
|
|
#
|
|
#def check_db_client_opts():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if not opt.is_local_opt() and not opt.has_value():
|
|
# raise MyError('option "-{0}" has not been specified, maybe you should run "{1} --help" for help'\
|
|
# .format(opt.get_short_name(), sys.argv[0]))
|
|
#
|
|
#def parse_option(opt_name, opt_val):
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if opt_name in (('-' + opt.get_short_name()), ('--' + opt.get_long_name())):
|
|
# opt.set_value(opt_val)
|
|
#
|
|
#def parse_options(argv):
|
|
# global g_opts
|
|
# short_opt_str = ''
|
|
# long_opt_list = []
|
|
# for opt in g_opts:
|
|
# if opt.is_with_param():
|
|
# short_opt_str += opt.get_short_name() + ':'
|
|
# else:
|
|
# short_opt_str += opt.get_short_name()
|
|
# for opt in g_opts:
|
|
# if opt.is_with_param():
|
|
# long_opt_list.append(opt.get_long_name() + '=')
|
|
# else:
|
|
# long_opt_list.append(opt.get_long_name())
|
|
# (opts, args) = getopt.getopt(argv, short_opt_str, long_opt_list)
|
|
# for (opt_name, opt_val) in opts:
|
|
# parse_option(opt_name, opt_val)
|
|
# if has_no_local_opts():
|
|
# check_db_client_opts()
|
|
#
|
|
#def deal_with_local_opt(opt):
|
|
# if 'help' == opt.get_long_name():
|
|
# global help_str
|
|
# print help_str
|
|
# elif 'version' == opt.get_long_name():
|
|
# global version_str
|
|
# print version_str
|
|
#
|
|
#def deal_with_local_opts():
|
|
# global g_opts
|
|
# if has_no_local_opts():
|
|
# raise MyError('no local options, can not deal with local options')
|
|
# else:
|
|
# for opt in g_opts:
|
|
# if opt.is_local_opt() and opt.has_value():
|
|
# deal_with_local_opt(opt)
|
|
# # 只处理一个
|
|
# return
|
|
#
|
|
#def get_opt_host():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'host' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
#
|
|
#def get_opt_port():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'port' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
#
|
|
#def get_opt_user():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'user' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
#
|
|
#def get_opt_password():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'password' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
#
|
|
#def get_opt_module():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'module' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
#
|
|
#def get_opt_log_file():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'log-file' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
##### ---------------end----------------------
|
|
#
|
|
#def config_logging_module(log_filenamme):
|
|
# logging.basicConfig(level=logging.INFO,\
|
|
# format='[%(asctime)s] %(levelname)s %(filename)s:%(lineno)d %(message)s',\
|
|
# datefmt='%Y-%m-%d %H:%M:%S',\
|
|
# filename=log_filenamme,\
|
|
# filemode='w')
|
|
# # 定义日志打印格式
|
|
# formatter = logging.Formatter('[%(asctime)s] %(levelname)s %(filename)s:%(lineno)d %(message)s', '%Y-%m-%d %H:%M:%S')
|
|
# #######################################
|
|
# # 定义一个Handler打印INFO及以上级别的日志到sys.stdout
|
|
# stdout_handler = logging.StreamHandler(sys.stdout)
|
|
# stdout_handler.setLevel(logging.INFO)
|
|
# # 设置日志打印格式
|
|
# stdout_handler.setFormatter(formatter)
|
|
# # 将定义好的stdout_handler日志handler添加到root logger
|
|
# logging.getLogger('').addHandler(stdout_handler)
|
|
#
|
|
#def run(my_host, my_port, my_user, my_passwd, upgrade_params):
|
|
# try:
|
|
# conn = mysql.connector.connect(user = my_user,
|
|
# password = my_passwd,
|
|
# host = my_host,
|
|
# port = my_port,
|
|
# database = 'oceanbase',
|
|
# raise_on_warnings = True)
|
|
# conn.autocommit = True
|
|
# cur = conn.cursor(buffered=True)
|
|
# try:
|
|
# query_cur = QueryCursor(cur)
|
|
# (desc, results) = query_cur.exec_query("""select distinct value from __all_virtual_sys_parameter_stat where name='min_observer_version'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('distinct observer version not exist')
|
|
# #rolling upgrade 在2.2.50版本后支持
|
|
# elif cmp(results[0][0], "2.2.50") >= 0:
|
|
# query_cur.exec_sql("""ALTER SYSTEM END ROLLING UPGRADE""")
|
|
# logging.info("END ROLLING UPGRADE success")
|
|
# else:
|
|
# logging.info("cluster version ({0}) less than 2.2.50, skip".format(results[0][0]))
|
|
# except Exception, e:
|
|
# logging.exception('run error')
|
|
# raise e
|
|
# finally:
|
|
# cur.close()
|
|
# conn.close()
|
|
# except mysql.connector.Error, e:
|
|
# logging.exception('connection error')
|
|
# raise e
|
|
# except Exception, e:
|
|
# logging.exception('normal error')
|
|
# raise e
|
|
#
|
|
#if __name__ == '__main__':
|
|
# upgrade_params = UpgradeParams()
|
|
# change_opt_defult_value('log-file', upgrade_params.log_filename)
|
|
# parse_options(sys.argv[1:])
|
|
# if not has_no_local_opts():
|
|
# deal_with_local_opts()
|
|
# else:
|
|
# check_db_client_opts()
|
|
# log_filename = get_opt_log_file()
|
|
# upgrade_params.log_filename = log_filename
|
|
# # 日志配置放在这里是为了前面的操作不要覆盖掉日志文件
|
|
# config_logging_module(upgrade_params.log_filename)
|
|
# try:
|
|
# host = get_opt_host()
|
|
# port = int(get_opt_port())
|
|
# user = get_opt_user()
|
|
# password = get_opt_password()
|
|
# logging.info('parameters from cmd: host=\"%s\", port=%s, user=\"%s\", password=\"%s\", log-file=\"%s\"',\
|
|
# host, port, user, password, log_filename)
|
|
# run(host, port, user, password, upgrade_params)
|
|
# except mysql.connector.Error, e:
|
|
# logging.exception('mysql connctor error')
|
|
# raise e
|
|
# except Exception, e:
|
|
# logging.exception('normal error')
|
|
# raise e
|
|
#
|
|
####====XXXX======######==== I am a splitter ====######======XXXX====####
|
|
#filename:upgrade_rolling_pre.py
|
|
##!/usr/bin/env python
|
|
## -*- coding: utf-8 -*-
|
|
#
|
|
#import sys
|
|
#import os
|
|
#import time
|
|
#import mysql.connector
|
|
#from mysql.connector import errorcode
|
|
#import logging
|
|
#import getopt
|
|
#
|
|
#class UpgradeParams:
|
|
# log_filename = 'upgrade_rolling_pre.log'
|
|
##### --------------start : my_error.py --------------
|
|
#class MyError(Exception):
|
|
# def __init__(self, value):
|
|
# self.value = value
|
|
# def __str__(self):
|
|
# return repr(self.value)
|
|
#
|
|
##### --------------start : actions.py--------------
|
|
#class QueryCursor:
|
|
# __cursor = None
|
|
# def __init__(self, cursor):
|
|
# self.__cursor = cursor
|
|
# def exec_sql(self, sql, print_when_succ = True):
|
|
# try:
|
|
# self.__cursor.execute(sql)
|
|
# rowcount = self.__cursor.rowcount
|
|
# if True == print_when_succ:
|
|
# logging.info('succeed to execute sql: %s, rowcount = %d', sql, rowcount)
|
|
# return rowcount
|
|
# except mysql.connector.Error, e:
|
|
# logging.exception('mysql connector error, fail to execute sql: %s', sql)
|
|
# raise e
|
|
# except Exception, e:
|
|
# logging.exception('normal error, fail to execute sql: %s', sql)
|
|
# raise e
|
|
# def exec_query(self, sql, print_when_succ = True):
|
|
# try:
|
|
# self.__cursor.execute(sql)
|
|
# results = self.__cursor.fetchall()
|
|
# rowcount = self.__cursor.rowcount
|
|
# if True == print_when_succ:
|
|
# logging.info('succeed to execute query: %s, rowcount = %d', sql, rowcount)
|
|
# return (self.__cursor.description, results)
|
|
# except mysql.connector.Error, e:
|
|
# logging.exception('mysql connector error, fail to execute sql: %s', sql)
|
|
# raise e
|
|
# except Exception, e:
|
|
# logging.exception('normal error, fail to execute sql: %s', sql)
|
|
# raise e
|
|
##### ---------------end----------------------
|
|
#
|
|
##### --------------start : opt.py --------------
|
|
#help_str = \
|
|
#"""
|
|
#Help:
|
|
#""" +\
|
|
#sys.argv[0] + """ [OPTIONS]""" +\
|
|
#'\n\n' +\
|
|
#'-I, --help Display this help and exit.\n' +\
|
|
#'-V, --version Output version information and exit.\n' +\
|
|
#'-h, --host=name Connect to host.\n' +\
|
|
#'-P, --port=name Port number to use for connection.\n' +\
|
|
#'-u, --user=name User for login.\n' +\
|
|
#'-p, --password=name Password to use when connecting to server. If password is\n' +\
|
|
#' not given it\'s empty string "".\n' +\
|
|
#'-m, --module=name Modules to run. Modules should be a string combined by some of\n' +\
|
|
#' the following strings: ddl, normal_dml, each_tenant_dml,\n' +\
|
|
#' system_variable_dml, special_action, all. "all" represents\n' +\
|
|
#' that all modules should be run. They are splitted by ",".\n' +\
|
|
#' For example: -m all, or --module=ddl,normal_dml,special_action\n' +\
|
|
#'-l, --log-file=name Log file path. If log file path is not given it\'s ' + os.path.splitext(sys.argv[0])[0] + '.log\n' +\
|
|
#'\n\n' +\
|
|
#'Maybe you want to run cmd like that:\n' +\
|
|
#sys.argv[0] + ' -h 127.0.0.1 -P 3306 -u admin -p admin\n'
|
|
#
|
|
#version_str = """version 1.0.0"""
|
|
#
|
|
#class Option:
|
|
# __g_short_name_set = set([])
|
|
# __g_long_name_set = set([])
|
|
# __short_name = None
|
|
# __long_name = None
|
|
# __is_with_param = None
|
|
# __is_local_opt = None
|
|
# __has_value = None
|
|
# __value = None
|
|
# def __init__(self, short_name, long_name, is_with_param, is_local_opt, default_value = None):
|
|
# if short_name in Option.__g_short_name_set:
|
|
# raise MyError('duplicate option short name: {0}'.format(short_name))
|
|
# elif long_name in Option.__g_long_name_set:
|
|
# raise MyError('duplicate option long name: {0}'.format(long_name))
|
|
# Option.__g_short_name_set.add(short_name)
|
|
# Option.__g_long_name_set.add(long_name)
|
|
# self.__short_name = short_name
|
|
# self.__long_name = long_name
|
|
# self.__is_with_param = is_with_param
|
|
# self.__is_local_opt = is_local_opt
|
|
# self.__has_value = False
|
|
# if None != default_value:
|
|
# self.set_value(default_value)
|
|
# def is_with_param(self):
|
|
# return self.__is_with_param
|
|
# def get_short_name(self):
|
|
# return self.__short_name
|
|
# def get_long_name(self):
|
|
# return self.__long_name
|
|
# def has_value(self):
|
|
# return self.__has_value
|
|
# def get_value(self):
|
|
# return self.__value
|
|
# def set_value(self, value):
|
|
# self.__value = value
|
|
# self.__has_value = True
|
|
# def is_local_opt(self):
|
|
# return self.__is_local_opt
|
|
# def is_valid(self):
|
|
# return None != self.__short_name and None != self.__long_name and True == self.__has_value and None != self.__value
|
|
#
|
|
#g_opts =\
|
|
#[\
|
|
#Option('I', 'help', False, True),\
|
|
#Option('V', 'version', False, True),\
|
|
#Option('h', 'host', True, False),\
|
|
#Option('P', 'port', True, False),\
|
|
#Option('u', 'user', True, False),\
|
|
#Option('p', 'password', True, False, ''),\
|
|
## 要跑哪个模块,默认全跑
|
|
#Option('m', 'module', True, False, 'all'),\
|
|
## 日志文件路径,不同脚本的main函数中中会改成不同的默认值
|
|
#Option('l', 'log-file', True, False)
|
|
#]\
|
|
#
|
|
#def change_opt_defult_value(opt_long_name, opt_default_val):
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if opt.get_long_name() == opt_long_name:
|
|
# opt.set_value(opt_default_val)
|
|
# return
|
|
#
|
|
#def has_no_local_opts():
|
|
# global g_opts
|
|
# no_local_opts = True
|
|
# for opt in g_opts:
|
|
# if opt.is_local_opt() and opt.has_value():
|
|
# no_local_opts = False
|
|
# return no_local_opts
|
|
#
|
|
#def check_db_client_opts():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if not opt.is_local_opt() and not opt.has_value():
|
|
# raise MyError('option "-{0}" has not been specified, maybe you should run "{1} --help" for help'\
|
|
# .format(opt.get_short_name(), sys.argv[0]))
|
|
#
|
|
#def parse_option(opt_name, opt_val):
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if opt_name in (('-' + opt.get_short_name()), ('--' + opt.get_long_name())):
|
|
# opt.set_value(opt_val)
|
|
#
|
|
#def parse_options(argv):
|
|
# global g_opts
|
|
# short_opt_str = ''
|
|
# long_opt_list = []
|
|
# for opt in g_opts:
|
|
# if opt.is_with_param():
|
|
# short_opt_str += opt.get_short_name() + ':'
|
|
# else:
|
|
# short_opt_str += opt.get_short_name()
|
|
# for opt in g_opts:
|
|
# if opt.is_with_param():
|
|
# long_opt_list.append(opt.get_long_name() + '=')
|
|
# else:
|
|
# long_opt_list.append(opt.get_long_name())
|
|
# (opts, args) = getopt.getopt(argv, short_opt_str, long_opt_list)
|
|
# for (opt_name, opt_val) in opts:
|
|
# parse_option(opt_name, opt_val)
|
|
# if has_no_local_opts():
|
|
# check_db_client_opts()
|
|
#
|
|
#def deal_with_local_opt(opt):
|
|
# if 'help' == opt.get_long_name():
|
|
# global help_str
|
|
# print help_str
|
|
# elif 'version' == opt.get_long_name():
|
|
# global version_str
|
|
# print version_str
|
|
#
|
|
#def deal_with_local_opts():
|
|
# global g_opts
|
|
# if has_no_local_opts():
|
|
# raise MyError('no local options, can not deal with local options')
|
|
# else:
|
|
# for opt in g_opts:
|
|
# if opt.is_local_opt() and opt.has_value():
|
|
# deal_with_local_opt(opt)
|
|
# # 只处理一个
|
|
# return
|
|
#
|
|
#def get_opt_host():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'host' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
#
|
|
#def get_opt_port():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'port' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
#
|
|
#def get_opt_user():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'user' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
#
|
|
#def get_opt_password():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'password' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
#
|
|
#def get_opt_module():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'module' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
#
|
|
#def get_opt_log_file():
|
|
# global g_opts
|
|
# for opt in g_opts:
|
|
# if 'log-file' == opt.get_long_name():
|
|
# return opt.get_value()
|
|
##### ---------------end----------------------
|
|
#
|
|
#def config_logging_module(log_filenamme):
|
|
# logging.basicConfig(level=logging.INFO,\
|
|
# format='[%(asctime)s] %(levelname)s %(filename)s:%(lineno)d %(message)s',\
|
|
# datefmt='%Y-%m-%d %H:%M:%S',\
|
|
# filename=log_filenamme,\
|
|
# filemode='w')
|
|
# # 定义日志打印格式
|
|
# formatter = logging.Formatter('[%(asctime)s] %(levelname)s %(filename)s:%(lineno)d %(message)s', '%Y-%m-%d %H:%M:%S')
|
|
# #######################################
|
|
# # 定义一个Handler打印INFO及以上级别的日志到sys.stdout
|
|
# stdout_handler = logging.StreamHandler(sys.stdout)
|
|
# stdout_handler.setLevel(logging.INFO)
|
|
# # 设置日志打印格式
|
|
# stdout_handler.setFormatter(formatter)
|
|
# # 将定义好的stdout_handler日志handler添加到root logger
|
|
# logging.getLogger('').addHandler(stdout_handler)
|
|
#
|
|
#def run(my_host, my_port, my_user, my_passwd, upgrade_params):
|
|
# try:
|
|
# conn = mysql.connector.connect(user = my_user,
|
|
# password = my_passwd,
|
|
# host = my_host,
|
|
# port = my_port,
|
|
# database = 'oceanbase',
|
|
# raise_on_warnings = True)
|
|
# conn.autocommit = True
|
|
# cur = conn.cursor(buffered=True)
|
|
# try:
|
|
# query_cur = QueryCursor(cur)
|
|
# (desc, results) = query_cur.exec_query("""select distinct value from __all_virtual_sys_parameter_stat where name='min_observer_version'""")
|
|
# if len(results) != 1:
|
|
# raise MyError('distinct observer version not exist')
|
|
# #rolling upgrade 在2.2.50版本后支持
|
|
# elif cmp(results[0][0], "2.2.50") >= 0:
|
|
# query_cur.exec_sql("""ALTER SYSTEM BEGIN ROLLING UPGRADE""")
|
|
# logging.info("BEGIN ROLLING UPGRADE success")
|
|
# else:
|
|
# logging.info("cluster version ({0}) less than 2.2.50, skip".format(results[0][0]))
|
|
# except Exception, e:
|
|
# logging.exception('run error')
|
|
# raise e
|
|
# finally:
|
|
# cur.close()
|
|
# conn.close()
|
|
# except mysql.connector.Error, e:
|
|
# logging.exception('connection error')
|
|
# raise e
|
|
# except Exception, e:
|
|
# logging.exception('normal error')
|
|
# raise e
|
|
#
|
|
#if __name__ == '__main__':
|
|
# upgrade_params = UpgradeParams()
|
|
# change_opt_defult_value('log-file', upgrade_params.log_filename)
|
|
# parse_options(sys.argv[1:])
|
|
# if not has_no_local_opts():
|
|
# deal_with_local_opts()
|
|
# else:
|
|
# check_db_client_opts()
|
|
# log_filename = get_opt_log_file()
|
|
# upgrade_params.log_filename = log_filename
|
|
# # 日志配置放在这里是为了前面的操作不要覆盖掉日志文件
|
|
# config_logging_module(upgrade_params.log_filename)
|
|
# try:
|
|
# host = get_opt_host()
|
|
# port = int(get_opt_port())
|
|
# user = get_opt_user()
|
|
# password = get_opt_password()
|
|
# logging.info('parameters from cmd: host=\"%s\", port=%s, user=\"%s\", password=\"%s\", log-file=\"%s\"',\
|
|
# host, port, user, password, log_filename)
|
|
# run(host, port, user, password, upgrade_params)
|
|
# except mysql.connector.Error, e:
|
|
# logging.exception('mysql connctor error')
|
|
# raise e
|
|
# except Exception, e:
|
|
# logging.exception('normal error')
|
|
# raise e
|
|
#
|
|
####====XXXX======######==== I am a splitter ====######======XXXX====####
|
|
#filename:upgrade_sys_vars.py
|
|
##!/usr/bin/env python
|
|
## -*- coding: utf-8 -*-
|
|
#
|
|
#import new
|
|
#import time
|
|
#import re
|
|
#import json
|
|
#import traceback
|
|
#import sys
|
|
#import mysql.connector
|
|
#from mysql.connector import errorcode
|
|
#import logging
|
|
#from my_error import MyError
|
|
#import actions
|
|
#from actions import DMLCursor
|
|
#from actions import QueryCursor
|
|
#from sys_vars_dict import sys_var_dict
|
|
#import my_utils
|
|
#
|
|
#
|
|
## 由于用了/*+read_consistency(WEAK) */来查询,因此升级期间不能允许创建或删除租户
|
|
#
|
|
#def calc_diff_sys_var(cur, tenant_id):
|
|
# try:
|
|
# change_tenant(cur, tenant_id)
|
|
# actual_tenant_id = get_actual_tenant_id(tenant_id)
|
|
# cur.execute("""select name, data_type, value, info, flags, min_val, max_val from __all_sys_variable_history where tenant_id=%s and (tenant_id, zone, name, schema_version) in (select tenant_id, zone, name, max(schema_version) from __all_sys_variable_history where tenant_id=%s group by tenant_id, zone, name);"""%(actual_tenant_id, actual_tenant_id))
|
|
# results = cur.fetchall()
|
|
# logging.info('there has %s system variable of tenant id %d', len(results), tenant_id)
|
|
# update_sys_var_list = []
|
|
# update_sys_var_ori_list = []
|
|
# add_sys_var_list = []
|
|
# for r in results:
|
|
# if sys_var_dict.has_key(r[0]):
|
|
# sys_var = sys_var_dict[r[0]]
|
|
# if long(sys_var["data_type"]) != long(r[1]) or sys_var["info"].strip() != r[3].strip() or long(sys_var["flags"]) != long(r[4]) or ("min_val" in sys_var.keys() and sys_var["min_val"] != r[5]) or ("max_val" in sys_var.keys() and sys_var["max_val"] != r[6]):
|
|
# update_sys_var_list.append(sys_var)
|
|
# update_sys_var_ori_list.append(r)
|
|
# for (name, sys_var) in sys_var_dict.items():
|
|
# sys_var_exist = 0
|
|
# for r in results:
|
|
# if r[0] == sys_var["name"]:
|
|
# sys_var_exist = 1
|
|
# break
|
|
# if 0 == sys_var_exist:
|
|
# add_sys_var_list.append(sys_var)
|
|
# # reset
|
|
# sys_tenant_id = 1
|
|
# change_tenant(cur, sys_tenant_id)
|
|
# return (update_sys_var_list, update_sys_var_ori_list, add_sys_var_list)
|
|
# except Exception, e:
|
|
# logging.exception('fail to calc diff sys var')
|
|
# raise e
|
|
#
|
|
#def gen_update_sys_var_sql_for_tenant(tenant_id, sys_var):
|
|
# actual_tenant_id = get_actual_tenant_id(tenant_id)
|
|
# update_sql = 'update oceanbase.__all_sys_variable set data_type = ' + str(sys_var["data_type"])\
|
|
# + ', info = \'' + sys_var["info"].strip() + '\', flags = ' + str(sys_var["flags"])
|
|
# update_sql = update_sql\
|
|
# + ((', min_val = \'' + sys_var["min_val"] + '\'') if "min_val" in sys_var.keys() else '')\
|
|
# + ((', max_val = \'' + sys_var["max_val"] + '\'') if "max_val" in sys_var.keys() else '')
|
|
# update_sql = update_sql + ' where tenant_id = ' + str(actual_tenant_id) + ' and name = \'' + sys_var["name"] + '\''
|
|
# return update_sql
|
|
#
|
|
#def gen_update_sys_var_history_sql_for_tenant(dml_cur, tenant_id, sys_var):
|
|
# try:
|
|
# actual_tenant_id = get_actual_tenant_id(tenant_id)
|
|
# (desc, results) = dml_cur.exec_query("""select schema_version from oceanbase.__all_sys_variable_history
|
|
# where tenant_id = {0} and name = '{1}'
|
|
# order by schema_version desc limit 1"""
|
|
# .format(actual_tenant_id, sys_var["name"]))
|
|
# schema_version = results[0][0]
|
|
# (desc, results) = dml_cur.exec_query("""select value from __all_sys_variable where tenant_id={0} and name='{1}' limit 1"""
|
|
# .format(actual_tenant_id, sys_var["name"]))
|
|
# res_len = len(results)
|
|
# if res_len != 1:
|
|
# logging.error('fail to get value from __all_sys_variable, result count:'+ str(res_len))
|
|
# raise MyError('fail to get value from __all_sys_variable')
|
|
# value = results[0][0]
|
|
# min_val = sys_var["min_val"] if "min_val" in sys_var.keys() else ''
|
|
# max_val = sys_var["max_val"] if "max_val" in sys_var.keys() else ''
|
|
# replace_sql = """replace into oceanbase.__all_sys_variable_history(
|
|
# tenant_id,
|
|
# zone,
|
|
# name,
|
|
# schema_version,
|
|
# is_deleted,
|
|
# data_type,
|
|
# value,
|
|
# info,
|
|
# flags,
|
|
# min_val,
|
|
# max_val)
|
|
# values(%d, '', '%s', %d, 0, %d, '%s', '%s', %d, '%s', '%s')
|
|
# """%(actual_tenant_id, sys_var["name"], schema_version, sys_var["data_type"], value, sys_var["info"], sys_var["flags"], min_val, max_val)
|
|
# return replace_sql
|
|
# except Exception, e:
|
|
# logging.exception('fail to gen replace sys var history sql')
|
|
# raise e
|
|
#
|
|
#def gen_replace_sys_var_history_sql_for_tenant(dml_cur, tenant_id, sys_var):
|
|
# try:
|
|
# actual_tenant_id = get_actual_tenant_id(tenant_id)
|
|
# (desc, results) = dml_cur.exec_query("""select schema_version from oceanbase.__all_sys_variable_history
|
|
# where tenant_id={0} order by schema_version asc limit 1""".format(actual_tenant_id))
|
|
# schema_version = results[0][0]
|
|
# min_val = sys_var["min_val"] if "min_val" in sys_var.keys() else ''
|
|
# max_val = sys_var["max_val"] if "max_val" in sys_var.keys() else ''
|
|
# replace_sql = """replace into oceanbase.__all_sys_variable_history(
|
|
# tenant_id,
|
|
# zone,
|
|
# name,
|
|
# schema_version,
|
|
# is_deleted,
|
|
# data_type,
|
|
# value,
|
|
# info,
|
|
# flags,
|
|
# min_val,
|
|
# max_val)
|
|
# values(%d, '', '%s', %d, 0, %d, '%s', '%s', %d, '%s', '%s')
|
|
# """%(actual_tenant_id, sys_var["name"], schema_version, sys_var["data_type"], sys_var["value"], sys_var["info"], sys_var["flags"], min_val, max_val)
|
|
# return replace_sql
|
|
# except Exception, e:
|
|
# logging.exception('fail to gen replace sys var history sql')
|
|
# raise e
|
|
#
|
|
#
|
|
#def gen_sys_var_update_sqls_for_tenant(query_cur, tenant_id, update_sys_var_list):
|
|
# update_sqls = ''
|
|
# for i in range(0, len(update_sys_var_list)):
|
|
# sys_var = update_sys_var_list[i]
|
|
# if i > 0:
|
|
# update_sqls += '\n'
|
|
# update_sqls += gen_update_sys_var_sql_for_tenant(tenant_id, sys_var) + ';\n'
|
|
# update_sqls += gen_update_sys_var_history_sql_for_tenant(query_cur, tenant_id, sys_var) + ';'
|
|
# return update_sqls
|
|
#
|
|
#def update_sys_vars_for_tenant(dml_cur, tenant_id, update_sys_var_list):
|
|
# try:
|
|
# for i in range(0, len(update_sys_var_list)):
|
|
# sys_var = update_sys_var_list[i]
|
|
# update_sql = gen_update_sys_var_sql_for_tenant(tenant_id, sys_var)
|
|
# rowcount = dml_cur.exec_update(update_sql)
|
|
# if 1 != rowcount:
|
|
# # 以history为准,考虑可重入,此处不校验__all_sys_variable的更新结果
|
|
# logging.info('sys var not change, just skip, sql: %s, tenant_id: %d', update_sql, tenant_id)
|
|
# else:
|
|
# logging.info('succeed to update sys var for tenant, sql: %s, tenant_id: %d', update_sql, tenant_id)
|
|
##replace update sys var to __all_sys_variable_history
|
|
# replace_sql = gen_update_sys_var_history_sql_for_tenant(dml_cur, tenant_id, sys_var)
|
|
# rowcount = dml_cur.exec_update(replace_sql)
|
|
# if 1 != rowcount and 2 != rowcount:
|
|
# logging.error('fail to replace sysvar, replace_sql:%s'%replace_sql)
|
|
# raise MyError('fail to repalce sysvar')
|
|
# else:
|
|
# logging.info('succeed to replace sys var history for tenant, sql: %s, tenant_id: %d', replace_sql, tenant_id)
|
|
# except Exception, e:
|
|
# logging.exception('fail to update for tenant, tenant_id: %d', tenant_id)
|
|
# raise e
|
|
#
|
|
#def gen_add_sys_var_sql_for_tenant(tenant_id, sys_var):
|
|
# actual_tenant_id = get_actual_tenant_id(tenant_id)
|
|
# add_sql = 'replace into oceanbase.__all_sys_variable(tenant_id, zone, name, data_type, value, info, flags, min_val, max_val) values('\
|
|
# + str(actual_tenant_id) +', \'\', \'' + sys_var["name"] + '\', ' + str(sys_var["data_type"]) + ', \'' + sys_var["value"] + '\', \''\
|
|
# + sys_var["info"].strip() + '\', ' + str(sys_var["flags"]) + ', \''
|
|
# add_sql = add_sql + (sys_var["min_val"] if "min_val" in sys_var.keys() else '') + '\', \''\
|
|
# + (sys_var["max_val"] if "max_val" in sys_var.keys() else '') + '\')'
|
|
# return add_sql
|
|
#
|
|
#def gen_sys_var_add_sqls_for_tenant(query_cur, tenant_id, add_sys_var_list):
|
|
# add_sqls = ''
|
|
# for i in range(0, len(add_sys_var_list)):
|
|
# sys_var = add_sys_var_list[i]
|
|
# if i > 0:
|
|
# add_sqls += '\n'
|
|
# add_sqls += gen_add_sys_var_sql_for_tenant(tenant_id, sys_var) + ';\n'
|
|
# add_sqls += gen_replace_sys_var_history_sql_for_tenant(query_cur, tenant_id, sys_var) + ';'
|
|
# return add_sqls
|
|
#
|
|
#def add_sys_vars_for_tenant(dml_cur, tenant_id, add_sys_var_list):
|
|
# try:
|
|
# for i in range(0, len(add_sys_var_list)):
|
|
# sys_var = add_sys_var_list[i]
|
|
# add_sql = gen_add_sys_var_sql_for_tenant(tenant_id, sys_var)
|
|
# rowcount = dml_cur.exec_update(add_sql)
|
|
# if 1 != rowcount:
|
|
# # 以history为准,考虑可重入,此处不校验__all_sys_variable的更新结果
|
|
# logging.info('sys var not change, just skip, sql: %s, tenant_id: %d', update_sql, tenant_id)
|
|
# else:
|
|
# logging.info('succeed to insert sys var for tenant, sql: %s, tenant_id: %d', add_sql, tenant_id)
|
|
# replace_sql = gen_replace_sys_var_history_sql_for_tenant(dml_cur, tenant_id, sys_var)
|
|
# rowcount = dml_cur.exec_update(replace_sql)
|
|
# if 1 != rowcount:
|
|
# logging.error('fail to replace system variable history, sql:%s'%replace_sql)
|
|
# raise MyError('fail to replace system variable history')
|
|
# else:
|
|
# logging.info('succeed to replace sys var for tenant, sql: %s, tenant_id: %d', replace_sql, tenant_id)
|
|
# except Exception, e:
|
|
# logging.exception('fail to add for tenant, tenant_id: %d', tenant_id)
|
|
# raise e
|
|
#
|
|
#
|
|
#def gen_sys_var_special_update_sqls_for_tenant(tenant_id):
|
|
# special_update_sqls = ''
|
|
# return special_update_sqls
|
|
#
|
|
#def special_update_sys_vars_for_tenant(dml_cur, tenant_id, add_sys_var_list, sys_var_name, sys_var_value):
|
|
# try:
|
|
# sys_var = None
|
|
# for i in range(0, len(add_sys_var_list)):
|
|
# if (sys_var_name == add_sys_var_list[i]["name"]):
|
|
# sys_var = add_sys_var_list[i]
|
|
# break;
|
|
#
|
|
# if None == sys_var:
|
|
# logging.info('%s is not new, no need special update again', sys_var_name)
|
|
# return
|
|
#
|
|
# sys_var["value"] = sys_var_value;
|
|
# update_sql = gen_update_sys_var_value_sql_for_tenant(tenant_id, sys_var)
|
|
# rowcount = dml_cur.exec_update(update_sql)
|
|
# if 1 != rowcount:
|
|
# # 以history为准,考虑可重入,此处不校验__all_sys_variable的更新结果
|
|
# logging.info('sys var not change, just skip, sql: %s, tenant_id: %d', update_sql, tenant_id)
|
|
# else:
|
|
# logging.info('succeed to update sys var for tenant, sql: %s, tenant_id: %d', update_sql, tenant_id)
|
|
# #replace update sys var to __all_sys_variable_history
|
|
# replace_sql = gen_update_sys_var_history_sql_for_tenant(dml_cur, tenant_id, sys_var)
|
|
# rowcount = dml_cur.exec_update(replace_sql)
|
|
# if 1 != rowcount and 2 != rowcount:
|
|
# logging.error('fail to replace sysvar, replace_sql:%s'%replace_sql)
|
|
# raise MyError('fail to repalce sysvar')
|
|
# else:
|
|
# logging.info('succeed to replace sys var history for tenant, sql: %s, tenant_id: %d', replace_sql, tenant_id)
|
|
# except Exception, e:
|
|
# logging.exception('fail to add for tenant, tenant_id: %d', tenant_id)
|
|
# raise e
|
|
#
|
|
#def get_sys_vars_upgrade_dmls_str(cur, query_cur, tenant_id_list, update_sys_var_list, add_sys_var_list):
|
|
# ret_str = ''
|
|
# if len(tenant_id_list) <= 0:
|
|
# logging.error('distinct tenant id count is <= 0, tenant_id_count: %d', len(tenant_id_list))
|
|
# raise MyError('invalid arg')
|
|
# for i in range(0, len(tenant_id_list)):
|
|
# tenant_id = tenant_id_list[i]
|
|
# change_tenant(cur, tenant_id)
|
|
# if i > 0:
|
|
# ret_str += '\n'
|
|
# ret_str += gen_sys_var_update_sqls_for_tenant(query_cur, tenant_id, update_sys_var_list)
|
|
# if ret_str != '' and len(add_sys_var_list) > 0:
|
|
# ret_str += '\n'
|
|
# for i in range(0, len(tenant_id_list)):
|
|
# tenant_id = tenant_id_list[i]
|
|
# change_tenant(cur, tenant_id)
|
|
# if i > 0:
|
|
# ret_str += '\n'
|
|
# ret_str += gen_sys_var_add_sqls_for_tenant(query_cur, tenant_id, add_sys_var_list)
|
|
# if ret_str != '' and gen_sys_var_special_update_sqls_for_tenant(tenant_id_list[0]) != '':
|
|
# ret_str += '\n'
|
|
# for i in range(0, len(tenant_id_list)):
|
|
# tenant_id = tenant_id_list[i]
|
|
# change_tenant(cur, tenant_id)
|
|
# if i > 0:
|
|
# ret_str += '\n'
|
|
# ret_str += gen_sys_var_special_update_sqls_for_tenant(tenant_id)
|
|
# sys_tenant_id= 1
|
|
# change_tenant(cur, sys_tenant_id)
|
|
# return ret_str
|
|
#
|
|
#def gen_update_sys_var_value_sql_for_tenant(tenant_id, sys_var):
|
|
# update_sql = ('update oceanbase.__all_sys_variable set value = \'' + str(sys_var["value"])
|
|
# + '\' where tenant_id = ' + str(tenant_id) + ' and name = \'' + sys_var["name"] + '\'')
|
|
# return update_sql
|
|
#
|
|
#def exec_sys_vars_upgrade_dml(cur, tenant_id_list):
|
|
# if len(tenant_id_list) <= 0:
|
|
# logging.error('distinct tenant id count is <= 0, tenant_id_count: %d', len(tenant_id_list))
|
|
# raise MyError('invalid arg')
|
|
# dml_cur = DMLCursor(cur)
|
|
# # 操作前先dump出oceanbase.__all_sys_variable表的所有数据
|
|
# my_utils.query_and_dump_results(dml_cur, """select * from oceanbase.__all_virtual_sys_variable""")
|
|
# # 操作前先dump出oceanbase.__all_sys_variable_history表的所有数据
|
|
# my_utils.query_and_dump_results(dml_cur, """select * from oceanbase.__all_virtual_sys_variable_history""")
|
|
#
|
|
# for i in range(0, len(tenant_id_list)):
|
|
# tenant_id = tenant_id_list[i]
|
|
# # calc diff
|
|
# (update_sys_var_list, update_sys_var_ori_list, add_sys_var_list) = calc_diff_sys_var(cur, tenant_id)
|
|
# logging.info('update system variables list: [%s]', ', '.join(str(sv) for sv in update_sys_var_list))
|
|
# logging.info('update system variables original list: [%s]', ', '.join(str(sv) for sv in update_sys_var_ori_list))
|
|
# logging.info('add system variables list: [%s]', ', '.join(str(sv) for sv in add_sys_var_list))
|
|
# # update
|
|
# change_tenant(cur, tenant_id)
|
|
# update_sys_vars_for_tenant(dml_cur, tenant_id, update_sys_var_list)
|
|
# add_sys_vars_for_tenant(dml_cur, tenant_id, add_sys_var_list)
|
|
# special_update_sys_vars_for_tenant(dml_cur, tenant_id, add_sys_var_list, 'nls_date_format', 'YYYY-MM-DD HH24:MI:SS');
|
|
# special_update_sys_vars_for_tenant(dml_cur, tenant_id, add_sys_var_list, 'nls_timestamp_format', 'YYYY-MM-DD HH24:MI:SS.FF');
|
|
# special_update_sys_vars_for_tenant(dml_cur, tenant_id, add_sys_var_list, 'nls_timestamp_tz_format', 'YYYY-MM-DD HH24:MI:SS.FF TZR TZD');
|
|
# # reset
|
|
# sys_tenant_id = 1
|
|
# change_tenant(cur, sys_tenant_id)
|
|
#
|
|
#def exec_sys_vars_upgrade_dml_in_standby_cluster(standby_cluster_infos):
|
|
# try:
|
|
# for standby_cluster_info in standby_cluster_infos:
|
|
# exec_sys_vars_upgrade_dml_by_cluster(standby_cluster_info)
|
|
# except Exception, e:
|
|
# logging.exception("""exec_sys_vars_upgrade_dml_in_standby_cluster failed""")
|
|
# raise e
|
|
#
|
|
#def exec_sys_vars_upgrade_dml_by_cluster(standby_cluster_info):
|
|
# try:
|
|
#
|
|
# logging.info("exec_sys_vars_upgrade_dml_by_cluster : cluster_id = {0}, ip = {1}, port = {2}"
|
|
# .format(standby_cluster_info['cluster_id'],
|
|
# standby_cluster_info['ip'],
|
|
# standby_cluster_info['port']))
|
|
# logging.info("create connection : cluster_id = {0}, ip = {1}, port = {2}"
|
|
# .format(standby_cluster_info['cluster_id'],
|
|
# standby_cluster_info['ip'],
|
|
# standby_cluster_info['port']))
|
|
# conn = mysql.connector.connect(user = standby_cluster_info['user'],
|
|
# password = standby_cluster_info['pwd'],
|
|
# host = standby_cluster_info['ip'],
|
|
# port = standby_cluster_info['port'],
|
|
# database = 'oceanbase',
|
|
# raise_on_warnings = True)
|
|
# cur = conn.cursor(buffered=True)
|
|
# conn.autocommit = True
|
|
# dml_cur = DMLCursor(cur)
|
|
# query_cur = QueryCursor(cur)
|
|
# is_primary = actions.check_current_cluster_is_primary(conn, query_cur)
|
|
# if is_primary:
|
|
# logging.exception("""primary cluster changed : cluster_id = {0}, ip = {1}, port = {2}"""
|
|
# .format(standby_cluster_info['cluster_id'],
|
|
# standby_cluster_info['ip'],
|
|
# standby_cluster_info['port']))
|
|
# raise e
|
|
#
|
|
# # only update sys tenant in standby cluster
|
|
# tenant_id = 1
|
|
# # calc diff
|
|
# (update_sys_var_list, update_sys_var_ori_list, add_sys_var_list) = calc_diff_sys_var(cur, tenant_id)
|
|
# logging.info('update system variables list: [%s]', ', '.join(str(sv) for sv in update_sys_var_list))
|
|
# logging.info('update system variables original list: [%s]', ', '.join(str(sv) for sv in update_sys_var_ori_list))
|
|
# logging.info('add system variables list: [%s]', ', '.join(str(sv) for sv in add_sys_var_list))
|
|
# # update
|
|
# update_sys_vars_for_tenant(dml_cur, tenant_id, update_sys_var_list)
|
|
# add_sys_vars_for_tenant(dml_cur, tenant_id, add_sys_var_list)
|
|
# special_update_sys_vars_for_tenant(dml_cur, tenant_id, add_sys_var_list, 'nls_date_format', 'YYYY-MM-DD HH24:MI:SS');
|
|
# special_update_sys_vars_for_tenant(dml_cur, tenant_id, add_sys_var_list, 'nls_timestamp_format', 'YYYY-MM-DD HH24:MI:SS.FF');
|
|
# special_update_sys_vars_for_tenant(dml_cur, tenant_id, add_sys_var_list, 'nls_timestamp_tz_format', 'YYYY-MM-DD HH24:MI:SS.FF TZR TZD');
|
|
#
|
|
# cur.close()
|
|
# conn.close()
|
|
#
|
|
# except Exception, e:
|
|
# logging.exception("""exec_sys_vars_upgrade_dml_in_standby_cluster failed :
|
|
# cluster_id = {0}, ip = {1}, port = {2}"""
|
|
# .format(standby_cluster_info['cluster_id'],
|
|
# standby_cluster_info['ip'],
|
|
# standby_cluster_info['port']))
|
|
# raise e
|
|
#
|
|
#
|
|
|
|
|
|
import os
|
|
import sys
|
|
import datetime
|
|
from random import Random
|
|
|
|
#def get_actual_tenant_id(tenant_id):
|
|
# return tenant_id if (1 == tenant_id) else 0;
|
|
|
|
def change_tenant(cur, tenant_id):
|
|
# change tenant
|
|
sql = "alter system change tenant tenant_id = {0};".format(tenant_id)
|
|
logging.info(sql);
|
|
cur.execute(sql);
|
|
# check
|
|
sql = "select effective_tenant_id();"
|
|
cur.execute(sql)
|
|
result = cur.fetchall()
|
|
if (1 != len(result) or 1 != len(result[0])):
|
|
raise MyError("invalid result cnt")
|
|
elif (tenant_id != result[0][0]):
|
|
raise MyError("effective_tenant_id:{0} , tenant_id:{1}".format(result[0][0], tenant_id))
|
|
|
|
|
|
def fetch_tenant_ids(query_cur):
|
|
try:
|
|
tenant_id_list = []
|
|
(desc, results) = query_cur.exec_query("""select distinct tenant_id from oceanbase.__all_tenant where compatibility_mode=1 order by tenant_id desc""")
|
|
for r in results:
|
|
tenant_id_list.append(r[0])
|
|
return tenant_id_list
|
|
except Exception, e:
|
|
logging.exception('fail to fetch distinct tenant ids')
|
|
raise e
|
|
|
|
|
|
class SplitError(Exception):
|
|
def __init__(self, value):
|
|
self.value = value
|
|
def __str__(self):
|
|
return repr(self.value)
|
|
|
|
def random_str(rand_str_len = 8):
|
|
str = ''
|
|
chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
|
|
length = len(chars) - 1
|
|
random = Random()
|
|
for i in range(rand_str_len):
|
|
str += chars[random.randint(0, length)]
|
|
return str
|
|
|
|
def split_py_files(sub_files_dir):
|
|
char_enter = '\n'
|
|
file_splitter_line = '####====XXXX======######==== I am a splitter ====######======XXXX====####'
|
|
sub_filename_line_prefix = '#filename:'
|
|
sub_file_module_end_line = '#sub file module end'
|
|
os.makedirs(sub_files_dir)
|
|
print('succeed to create run dir: ' + sub_files_dir + char_enter)
|
|
cur_file = open(sys.argv[0], 'r')
|
|
cur_file_lines = cur_file.readlines()
|
|
cur_file_lines_count = len(cur_file_lines)
|
|
sub_file_lines = []
|
|
sub_filename = ''
|
|
begin_read_sub_py_file = False
|
|
is_first_splitter_line = True
|
|
i = 0
|
|
while i < cur_file_lines_count:
|
|
if (file_splitter_line + char_enter) != cur_file_lines[i]:
|
|
if begin_read_sub_py_file:
|
|
sub_file_lines.append(cur_file_lines[i])
|
|
else:
|
|
if is_first_splitter_line:
|
|
is_first_splitter_line = False
|
|
else:
|
|
#读完一个子文件了,写到磁盘中
|
|
sub_file = open(sub_files_dir + '/' + sub_filename, 'w')
|
|
for sub_file_line in sub_file_lines:
|
|
sub_file.write(sub_file_line[1:])
|
|
sub_file.close()
|
|
#清空sub_file_lines
|
|
sub_file_lines = []
|
|
#再读取下一行的文件名或者结束标记
|
|
i += 1
|
|
if i >= cur_file_lines_count:
|
|
raise SplitError('invalid line index:' + str(i) + ', lines_count:' + str(cur_file_lines_count))
|
|
elif (sub_file_module_end_line + char_enter) == cur_file_lines[i]:
|
|
print 'succeed to split all sub py files'
|
|
break
|
|
else:
|
|
mark_idx = cur_file_lines[i].find(sub_filename_line_prefix)
|
|
if 0 != mark_idx:
|
|
raise SplitError('invalid sub file name line, mark_idx = ' + str(mark_idx) + ', line = ' + cur_file_lines[i])
|
|
else:
|
|
sub_filename = cur_file_lines[i][len(sub_filename_line_prefix):-1]
|
|
begin_read_sub_py_file = True
|
|
i += 1
|
|
cur_file.close()
|
|
|
|
class UpgradeParams:
|
|
log_filename = config.post_upgrade_log_filename
|
|
sql_dump_filename = config.post_upgrade_sql_filename
|
|
rollback_sql_filename = config.post_upgrade_rollback_sql_filename
|
|
|
|
class QueryCursor:
|
|
_cursor = None
|
|
def __init__(self, cursor):
|
|
self._cursor = Cursor(cursor)
|
|
def exec_query(self, sql, print_when_succ = True):
|
|
try:
|
|
# 这里检查是不是query,不是query就抛错
|
|
check_is_query_sql(sql)
|
|
return self._cursor.exec_query(sql, print_when_succ)
|
|
except Exception, e:
|
|
logging.exception('fail to execute dml query: %s', sql)
|
|
raise e
|
|
|
|
def fetch_user_names(query_cur):
|
|
try:
|
|
user_name_list = []
|
|
(desc, results) = query_cur.exec_query("""select user_name from oceanbase.__all_user where type=0""")
|
|
for r in results:
|
|
user_name_list.append(r[0])
|
|
return user_name_list
|
|
except Exception, e:
|
|
logging.exception('fail to fetch user names')
|
|
raise e
|
|
|
|
def get_priv_info(m_p):
|
|
priv = []
|
|
priv_str = ''
|
|
obj_name=''
|
|
words = m_p.split(" ")
|
|
# build priv list
|
|
i = 1
|
|
while words[i].upper() != 'ON':
|
|
if (words[i].upper() == 'ALL'):
|
|
priv.append('ALL')
|
|
else:
|
|
if (words[i].upper() != 'PRIVILEGES'):
|
|
priv.append(words[i])
|
|
i= i+1
|
|
# Jump 'ON'
|
|
i=i+1
|
|
#print words
|
|
if (words[i] == '*.*'):
|
|
priv_level = 'USER'
|
|
else:
|
|
ind = string.find(words[i], '.*')
|
|
if (ind != -1):
|
|
priv_level = 'DB'
|
|
obj_name = words[i][0: ind]
|
|
else:
|
|
priv_level = 'OBJ'
|
|
obj_name = words[i]
|
|
#jump 'TO'
|
|
i = i + 2
|
|
user_name = words[i]
|
|
|
|
return (priv_level, user_name, priv, obj_name)
|
|
|
|
def owner_priv_to_str(priv):
|
|
priv_str = '';
|
|
i = 0
|
|
while i < len(priv):
|
|
if (string.find(priv[i].uppper(), 'CREATE') == -1):
|
|
if (priv[i].upper() == 'SHOW VIEW'):
|
|
priv_str = 'SELECT ,'
|
|
else:
|
|
priv_str = priv[i] + ' ,'
|
|
i = i + 1
|
|
priv_str = priv_str[0: len(priv_str) -1]
|
|
return priv_str
|
|
|
|
def owner_db_priv_to_str(priv):
|
|
priv_str = ''
|
|
i = 0
|
|
while i < len(priv):
|
|
if (string.find(priv[i].uppper(), 'CREATE') != -1):
|
|
priv_str = priv[i] + ' ,'
|
|
i = i + 1
|
|
priv_str = priv_str[0: len(priv_str) -1]
|
|
return priv_str
|
|
|
|
def other_db_priv_to_str(priv):
|
|
priv_str = ''
|
|
i = 0
|
|
while i < len(priv):
|
|
if (string.find(priv[i].uppper(), 'CREATE') != -1):
|
|
priv_str = 'CREATE TABLE ,'
|
|
elif (string.find(priv[i].upper(), 'CREATE VIEW') != -1):
|
|
priv_str = 'CREATE VIEW ,'
|
|
i = i + 1
|
|
priv_str = priv_str[0: len(priv_str) -1]
|
|
return priv_str
|
|
|
|
def user_priv_to_str(priv):
|
|
priv_str = ''
|
|
i = 0
|
|
while i < len(priv):
|
|
if (string.find(priv[i].upper(), 'SUPER') != -1):
|
|
priv_str = 'ALTER SYSTEM ,'
|
|
elif (string.find(priv[i].upper(), 'CREATE USER') != -1):
|
|
priv_str = 'CREATE USER, ALTER USER, DROP USER,'
|
|
elif (string.find(priv[i].upper(), 'PROCESS') != -1):
|
|
priv_str = 'SHOW PROCESS,'
|
|
i = i + 1
|
|
priv_str = priv_str[0: len(priv_str) -1]
|
|
|
|
owner_db_all_privs = 'CREATE TABLE, CREATE VIEW, CREATE PROCEDURE, CREATE SYNONYM, CREATE SEQUENCE, CREATE TRIGGER, CREATE TYPE '
|
|
|
|
other_db_all_privs = 'create any table, create any view, create any procedure,\
|
|
create any synonym, create any sequence, create any trigger, create any type,\
|
|
alter any table, alter any procedure, alter any sequence,\
|
|
alter any trigger, alter any type, drop any table, drop any view,\
|
|
drop any procedure, drop any synonym, drop any sequence, drop any trigger,\
|
|
drop any type, select any table, insert any table, update any table, delete any table,\
|
|
flashback any table, create any index, alter any index, drop any index,\
|
|
execute any procedure, create public synonym, drop public synonym,\
|
|
select any sequence, execute any type, create tablespace,\
|
|
alter tablespace, drop tablespace '
|
|
|
|
other_obj_all_privs = 'alter, index, select, insert, update, delete '
|
|
|
|
def map_priv(m_p):
|
|
(priv_level, user_name, priv, obj_name) = get_priv_info(m_p)
|
|
#print priv_level, user_name, priv, obj_name
|
|
if priv_level == 'DB':
|
|
if user_name == obj_name:
|
|
if priv[0] == 'ALL':
|
|
return 'GRANT ' + owner_db_all_privs + ' TO ' + user_name
|
|
else:
|
|
priv_str = owner_db_priv_to_str(priv)
|
|
return 'GRANT ' + priv_str + ' TO ' + user_name
|
|
else:
|
|
if priv[0] == 'ALL':
|
|
return 'GRANT ' + other_db_all_privs + ' TO ' + user_name
|
|
else:
|
|
priv_str = other_db_priv_to_str(priv)
|
|
if (priv_str != ''):
|
|
return 'GRANT ' + priv_str + 'TO ' + user_name
|
|
else:
|
|
return '';
|
|
else:
|
|
if priv_level == 'USER':
|
|
if priv[0] == 'ALL':
|
|
return 'GRANT DBA TO ' + user_name
|
|
else:
|
|
priv_str = user_priv_to_str(priv)
|
|
return 'GRANT ' + priv_set + 'TO ' + user_name
|
|
else:
|
|
if user_name == obj_name:
|
|
return ''
|
|
else:
|
|
if priv[0] == 'ALL':
|
|
return 'GRANT ' + other_obj_all_privs + ' TO ' + user_name
|
|
else:
|
|
priv_str = other_priv_to_str(priv)
|
|
return 'GRANT ' + priv_str + 'ON ' + obj_name + 'TO ' + user_name
|
|
|
|
##################################################################
|
|
# check的条件:
|
|
# 1. 存在库级grant并且用户名和库名不一致,并且用户不是SYS, 则check不通过
|
|
#
|
|
#
|
|
#
|
|
##################################################################
|
|
def check_grant_sql(grant_sql):
|
|
(priv_level, user_name, priv, obj_name) = get_priv_info(grant_sql)
|
|
if priv_level == 'DB':
|
|
if user_name != obj_name and user_name.upper() != 'SYS' and user_name.upper() != '\'SYS\'':
|
|
return False
|
|
return True
|
|
|
|
def fetch_user_privs(query_cur, user_name):
|
|
try:
|
|
grant_sql_list = []
|
|
(desc, results) = query_cur.exec_query("""show grants for """ + user_name)
|
|
for r in results:
|
|
grant_sql_list.append(r[0])
|
|
return grant_sql_list
|
|
except Exception, e:
|
|
logging.exception('fail to fetch user privs')
|
|
raise e
|
|
|
|
def check_is_dcl_sql(sql):
|
|
word_list = sql.split()
|
|
if len(word_list) < 1:
|
|
raise MyError('sql is empty, sql="{0}"'.format(sql))
|
|
key_word = word_list[0].lower()
|
|
if 'grant' != key_word and 'revoke' != key_word:
|
|
raise MyError('sql must be dcl, key_word="{0}", sql="{1}"'.format(key_word, sql))
|
|
|
|
class Cursor:
|
|
__cursor = None
|
|
def __init__(self, cursor):
|
|
self.__cursor = cursor
|
|
def exec_sql(self, sql, print_when_succ = True):
|
|
try:
|
|
self.__cursor.execute(sql)
|
|
rowcount = self.__cursor.rowcount
|
|
if True == print_when_succ:
|
|
logging.info('succeed to execute sql: %s, rowcount = %d', sql, rowcount)
|
|
return rowcount
|
|
except mysql.connector.Error, e:
|
|
logging.exception('mysql connector error, fail to execute sql: %s', sql)
|
|
raise e
|
|
except Exception, e:
|
|
logging.exception('normal error, fail to execute sql: %s', sql)
|
|
raise e
|
|
def exec_query(self, sql, print_when_succ = True):
|
|
try:
|
|
self.__cursor.execute(sql)
|
|
results = self.__cursor.fetchall()
|
|
rowcount = self.__cursor.rowcount
|
|
if True == print_when_succ:
|
|
logging.info('succeed to execute query: %s, rowcount = %d', sql, rowcount)
|
|
return (self.__cursor.description, results)
|
|
except mysql.connector.Error, e:
|
|
logging.exception('mysql connector error, fail to execute sql: %s', sql)
|
|
raise e
|
|
except Exception, e:
|
|
logging.exception('normal error, fail to execute sql: %s', sql)
|
|
raise e
|
|
|
|
class DCLCursor:
|
|
_cursor = None
|
|
def __init__(self, cursor):
|
|
self._cursor = Cursor(cursor)
|
|
def exec_dcl(self, sql, print_when_succ = True):
|
|
try:
|
|
# 这里检查是不是ddl,不是ddl就抛错
|
|
check_is_dcl_sql(sql)
|
|
return self._cursor.exec_sql(sql, print_when_succ)
|
|
except Exception, e:
|
|
logging.exception('fail to execute dcl: %s', sql)
|
|
raise e
|
|
|
|
def do_priv_map(my_host, my_port, my_user, my_passwd, upgrade_params):
|
|
try:
|
|
db = _mysql.connect(user = my_user,
|
|
passwd = my_passwd,
|
|
host = my_host,
|
|
port = my_port
|
|
)
|
|
#获取所有的用户
|
|
db.query("select username, userid from dba_users")
|
|
r = db.store_result()
|
|
row = r.fetch_row()
|
|
while row :
|
|
#对每个用户,获取权限
|
|
db.query("show grants for " + row[0][0])
|
|
r2 = db.store_result()
|
|
row2 = r2.fetch_row()
|
|
while row2 :
|
|
#map权限,并执行
|
|
o_p = map_priv(row2[0][0]);
|
|
#print o_p
|
|
if o_p != '':
|
|
try:
|
|
db.query(o_p)
|
|
print 'execute ' + o_p + ' success.!'
|
|
except Exception, e:
|
|
raise e
|
|
row2 = r2.fetch_row()
|
|
row = r.fetch_row()
|
|
db.close()
|
|
|
|
except Exception, e:
|
|
logging.exception('run error')
|
|
raise e
|
|
|
|
def do_priv_map_by_argv(argv):
|
|
upgrade_params = UpgradeParams()
|
|
opts.change_opt_defult_value('log-file', upgrade_params.log_filename)
|
|
opts.parse_options(argv)
|
|
if not opts.has_no_local_opts():
|
|
opts.deal_with_local_opts()
|
|
else:
|
|
opts.check_db_client_opts()
|
|
log_filename = opts.get_opt_log_file()
|
|
upgrade_params.log_filename = log_filename
|
|
# 日志配置放在这里是为了前面的操作不要覆盖掉日志文件
|
|
config_logging_module(upgrade_params.log_filename)
|
|
try:
|
|
host = opts.get_opt_host()
|
|
port = int(opts.get_opt_port())
|
|
user = opts.get_opt_user()
|
|
password = opts.get_opt_password()
|
|
|
|
logging.info('parameters from cmd: host=\"%s\", port=%s, user=\"%s\", password=\"%s\", log-file=\"%s\"',\
|
|
host, port, user, password, log_filename)
|
|
do_priv_map(host, port, user, password, upgrade_params)
|
|
|
|
except Exception, e:
|
|
logging.exception('normal error')
|
|
logging.exception('run error, maybe you can reference ' + upgrade_params.rollback_sql_filename + ' to rollback it')
|
|
raise e
|
|
|
|
|
|
if __name__ == '__main__':
|
|
#cur_filename = sys.argv[0][sys.argv[0].rfind(os.sep)+1:]
|
|
#(cur_file_short_name,cur_file_ext_name1) = os.path.splitext(sys.argv[0])
|
|
#(cur_file_real_name,cur_file_ext_name2) = os.path.splitext(cur_filename)
|
|
#sub_files_dir_suffix = '_extract_files_' + datetime.datetime.now().strftime('%Y_%m_%d_%H_%M_%S_%f') + '_' + random_str()
|
|
#sub_files_dir = cur_file_short_name + sub_files_dir_suffix
|
|
#sub_files_short_dir = cur_file_real_name + sub_files_dir_suffix
|
|
#split_py_files(sub_files_dir)
|
|
#print sub_files_dir, sub_files_short_dir
|
|
#print sys.argv[1:]
|
|
do_priv_map_by_argv(sys.argv[1:])
|
|
#exec('from ' + sub_files_short_dir + '.do_upgrade_post import do_upgrade_by_argv')
|
|
#do_upgrade_by_argv(sys.argv[1:])
|