def test_invalid(self): """Test parsing invalid versions of connection strings. If the connection string is invalid, a FormatError should be thrown. """ for spec in self.invalid_specificers: try: parse_connection(spec) except FormatError: pass except: self.fail("Unexpected exception thrown.") else: self.fail("Exception not thrown for: '%s'." % spec)
def get_connection_dictionary(conn_info): """Get the connection dictionary. The method accepts one of the following types for conn_info: - dictionary containing connection information including: (user, passwd, host, port, socket) - connection string in the form: user:pass@host:port:socket or login-path:port:socket - an instance of the Server class conn_info[in] Connection information Returns dict - dictionary for connection (user, passwd, host, port, socket) """ if conn_info is None: return conn_info conn_val = {} if isinstance(conn_info, dict): conn_val = conn_info elif isinstance(conn_info, Server): # get server's dictionary conn_val = conn_info.get_connection_values() elif isinstance(conn_info, basestring): # parse the string conn_val = parse_connection(conn_info, None) else: raise UtilError("Cannot determine connection information type.") return conn_val
def test_valid(self): """Test parsing valid versions of connection strings. """ for source, expected in self.valid_specifiers: result = _spec(parse_connection(source)) frm = "{0}: was {1}, expected {2}" msg = frm.format(source, result, expected) self.assertEqual(expected, result, msg)
def test_connection(self, test_num, test_data): if self.debug: print "\nTest case %s - %s" % (test_num+1, test_data[0]) try: self.conn_vals = parse_connection("root@%s:3306" % test_data[1]) except FormatError, e: if test_data[3]: # This expected. self.results.append("FAIL") else: raise MUTLibError("Test Case %s: Parse failed! Error: %s" % \ (test_num+1, e))
def test_connection(self, test_num, test_data): if self.debug: print "\nTest case %s - %s" % (test_num + 1, test_data[0]) try: self.conn_vals = parse_connection("root@%s:3306" % test_data[1]) except FormatError, e: if test_data[3]: # This expected. self.results.append("FAIL") else: raise MUTLibError("Test Case %s: Parse failed! Error: %s" % \ (test_num+1, e))
def execute(self, connections, **kwrds): """Execute the search for processes, queries, or connections This method searches for processes, queriers, or connections to either kill or display the matches for one or more servers. connections[in] list of connection parameters kwrds[in] dictionary of options output file stream to display information default = sys.stdout connector connector to use default = mysql.connector format format for display default = GRID """ output = kwrds.get('output', sys.stdout) connector = kwrds.get('connector', mysql.connector) format = kwrds.get('format', "grid") headers = ("Connection", "Id", "User", "Host", "Db", "Command", "Time", "State", "Info") entries = [] # Build SQL statement for info in connections: conn = parse_connection(info) if not conn: msg = "'%s' is not a valid connection specifier" % (info,) raise FormatError(msg) info = conn connection = connector.connect(**info) cursor = connection.cursor() cursor.execute(self.__select) for row in cursor: if KILL_QUERY in self.__actions: cursor.execute("KILL {0}".format(row[0])) if KILL_CONNECTION in self.__actions: cursor.execute("KILL {0}".format(row[0])) if PRINT_PROCESS in self.__actions: entries.append(tuple([_spec(info)] + list(row))) # If output is None, nothing is printed if len(entries) > 0 and output: entries.sort(key = lambda fifth:fifth[5]) print_list(output, format, headers, entries) elif PRINT_PROCESS in self.__actions: raise EmptyResultError("No matches found")
def execute(self, connections, **kwrds): """Execute the search for processes, queries, or connections This method searches for processes, queriers, or connections to either kill or display the matches for one or more servers. connections[in] list of connection parameters kwrds[in] dictionary of options output file stream to display information default = sys.stdout connector connector to use default = mysql.connector format format for display default = GRID """ output = kwrds.get('output', sys.stdout) connector = kwrds.get('connector', mysql.connector) format = kwrds.get('format', "grid") headers = ("Connection", "Id", "User", "Host", "Db", "Command", "Time", "State", "Info") entries = [] # Build SQL statement for info in connections: conn = parse_connection(info) if not conn: msg = "'%s' is not a valid connection specifier" % (info, ) raise FormatError(msg) info = conn connection = connector.connect(**info) cursor = connection.cursor() cursor.execute(self.__select) for row in cursor: if KILL_QUERY in self.__actions: cursor.execute("KILL {0}".format(row[0])) if KILL_CONNECTION in self.__actions: cursor.execute("KILL {0}".format(row[0])) if PRINT_PROCESS in self.__actions: entries.append(tuple([_spec(info)] + list(row))) # If output is None, nothing is printed if len(entries) > 0 and output: entries.sort(key=lambda fifth: fifth[5]) print_list(output, format, headers, entries) elif PRINT_PROCESS in self.__actions: raise EmptyResultError("No matches found")
def execute(self, connections, output=sys.stdout, connector=mysql.connector, **kwrds): """Execute the search for objects This method searches for objects that match a search criteria for one or more servers. connections[in] list of connection parameters output[in] file stream to display information default = sys.stdout connector[in] connector to use default = mysql.connector kwrds[in] dictionary of options format format for display default = GRID """ from mysql.utilities.exception import FormatError, EmptyResultError format = kwrds.get('format', "grid") entries = [] for info in connections: conn = parse_connection(info) if not conn: msg = "'%s' is not a valid connection specifier" % (info, ) raise FormatError(msg) info = conn connection = connector.connect(**info) cursor = connection.cursor() cursor.execute(self.__sql) entries.extend( [tuple([_spec(info)] + list(row)) for row in cursor]) headers = ["Connection"] headers.extend(col[0].title() for col in cursor.description) if len(entries) > 0 and output: print_list(output, format, headers, entries) else: msg = "Nothing matches '%s' in any %s" % ( self.__pattern, _join_words(self.__types, conjunction="or")) raise EmptyResultError(msg)
def run(self): # Test parse_connection with login-paths con_tests = ["test_user@localhost", "test_mylogin", "test_user@localhost:1000", "test_mylogin:1000", "test_user@localhost:1000:/my.socket", "test_mylogin:1000:/my.socket", "test_user@localhost:/my.socket", "test_mylogin:/my.socket"] for test in con_tests: con_dic = parse_connection(test) self.results.append(con_dic) # Test parse_user_password with login-paths user_pass_tests = ["test_user", "test_mylogin", "test_user:"******"user_x:", "user_x:pass_y"] for test in user_pass_tests: user_pass = parse_user_password(test) self.results.append(user_pass) return True
def run(self): # Test parse_connection with login-paths con_tests = [ "test_user@localhost", "test_mylogin", "test_user@localhost:1000", "test_mylogin:1000", "test_user@localhost:1000:/my.socket", "test_mylogin:1000:/my.socket", "test_user@localhost:/my.socket", "test_mylogin:/my.socket" ] for test in con_tests: con_dic = parse_connection(test) self.results.append(con_dic) # Test parse_user_password with login-paths user_pass_tests = [ "test_user", "test_mylogin", "test_user:"******"user_x:", "user_x:pass_y" ] for test in user_pass_tests: user_pass = parse_user_password(test) self.results.append(user_pass) return True
def execute(self, connections, output=sys.stdout, connector=mysql.connector, **kwrds): """Execute the search for objects This method searches for objects that match a search criteria for one or more servers. connections[in] list of connection parameters output[in] file stream to display information default = sys.stdout connector[in] connector to use default = mysql.connector kwrds[in] dictionary of options format format for display default = GRID """ from mysql.utilities.exception import FormatError, EmptyResultError format = kwrds.get('format', "grid") entries = [] for info in connections: conn = parse_connection(info) if not conn: msg = "'%s' is not a valid connection specifier" % (info,) raise FormatError(msg) info = conn connection = connector.connect(**info) cursor = connection.cursor() cursor.execute(self.__sql) entries.extend([tuple([_spec(info)] + list(row)) for row in cursor]) headers = ["Connection"] headers.extend(col[0].title() for col in cursor.description) if len(entries) > 0 and output: print_list(output, format, headers, entries) else: msg = "Nothing matches '%s' in any %s" % (self.__pattern, _join_words(self.__types, conjunction="or")) raise EmptyResultError(msg)
print("WARNING: The --candidates option is used only with the " "failover and elect commands.") opt.candidates = None if (opt.candidates or opt.new_master) and command in ['stop', 'start', 'reset']: print("WARNING: The --new-master and --candidates options are not " "used with the stop, start, and reset commands.") opt.candidates = None if opt.format and command not in ['health', 'gtid']: print("WARNING: The --format option is used only with the health " "and gtid commands.") if opt.new_master: try: new_master_val = parse_connection(opt.new_master, None, opt) except FormatError: _, err, _ = sys.exc_info() parser.error("New master connection values invalid: %s." % err) except UtilError: _, err, _ = sys.exc_info() parser.error("New master connection values invalid: %s." % err.errmsg) else: new_master_val = None # Parse the master, slaves, and candidates connection parameters try: master_val, slaves_val, candidates_val = parse_failover_connections(opt) except UtilRplError: _, e, _ = sys.exc_info() print("ERROR: %s" % e.errmsg)
"run_all_tests": opt.run_all_tests, "width": opt.width, "no_object_check": opt.no_object_check, "no_diff": opt.no_diff, "no_row_count": opt.no_row_count, "no_data": opt.no_data, "format": opt.format, "toggle_binlog": opt.toggle_binlog, "changes-for": opt.changes_for, "reverse": opt.reverse, } # Parse server connection values server2_values = None try: server1_values = parse_connection(opt.server1, None, options) except FormatError: _, err, _ = sys.exc_info() parser.error("Server1 connection values invalid: %s." % err) except UtilError: _, err, _ = sys.exc_info() parser.error("Server1 connection values invalid: %s." % err.errmsg) if opt.server2: try: server2_values = parse_connection(opt.server2, None, options) except FormatError: _, err, _ = sys.exc_info() parser.error("Server2 connection values invalid: %s." % err) except UtilError: _, err, _ = sys.exc_info()
# Warn if quiet and verbosity are both specified check_verbosity(opt) # Set options for database operations. options = { "quiet": opt.quiet, "verbosity": opt.verbosity, "difftype": opt.difftype, "force": opt.force, "width": opt.width } # Parse server connection values try: server1_values = parse_connection(opt.server1) except: parser.error("Server1 connection values invalid or cannot be parsed.") if opt.server2 is not None: try: server2_values = parse_connection(opt.server2) except: parser.error("Server2 connection values invalid or cannot be parsed.") else: server2_values = None # run the diff diff_failed = False for argument in args: m_obj = re.match("(\w+)(?:\.(\w+))?:(\w+)(?:\.(\w+))?", argument) if not m_obj:
"debug": opt.verbosity >= 3, "file_per_tbl": opt.file_per_tbl, "exclude_patterns": opt.exclude, "all": opt.all, "use_regexp": opt.use_regexp, "locking": opt.locking, "rpl_user": opt.rpl_user, "rpl_mode": opt.rpl_mode, "rpl_file": opt.rpl_file, "comment_rpl": opt.comment_rpl, "export": opt.export, } # Parse server connection values try: server_values = parse_connection(opt.server) except: parser.error("Server connection values invalid or cannot be parsed.") # Build list of databases to copy db_list = [] for db in args: db_list.append(db) try: # record start time if opt.verbosity >= 3: start_test = time.time() # Export all databases specified export_databases(server_values, db_list, options)
def show_server_info(servers, options): """Show server information for a list of servers This method will gather information about a running server. If the show_defaults option is specified, the method will also read the configuration file and return a list of the server default settings. If the format option is set, the output will be in the format specified. If the no_headers option is set, the output will not have a header row (no column names) except for format = vertical. If the basedir and start options are set, the method will attempt to start the server in read only mode to get the information. Specifying only basedir will not start the server. The extra start option is designed to make sure the user wants to start the offline server. The user may not wish to do this if there are certain error conditions and/or logs in place that may be overwritten. servers[in] list of server connections in the form <user>:<password>@<host>:<port>:<socket> options[in] dictionary of options (no_headers, format, basedir, start, show_defaults) Returns tuple ((server information), defaults) """ from mysql.utilities.common.server import test_connect from mysql.utilities.common.format import print_list no_headers = options.get("no_headers", False) format = options.get("format", "grid") show_defaults = options.get("show_defaults", False) basedir = options.get("basedir", None) datadir = options.get("datadir", None) start = options.get("start", False) verbosity = options.get("verbosity", 0) show_servers = options.get("show_servers", 0) if show_servers: if os.name == 'nt': ports = options.get("ports", "3306:3333") start, end = ports.split(":") _show_running_servers(start, end) else: _show_running_servers() defaults_rows = [] rows = [] server_val = {} get_defaults = True for server in servers: server_alive = True server_started = False if not test_connect(server): if basedir is None or datadir is None: raise UtilError("Server is offline. To connection, " "you must provide basedir, datadir, " "and the start option") else: if start: try: server_val = parse_connection(server) except: raise UtilError("Source connection values in" "valid or cannot be parsed.") res = _start_server(server_val, basedir, datadir, options) server_started = True else: server_alive = False if server_alive: info, defaults = _server_info(server, get_defaults, options) if info is not None: rows.append(info) if defaults is not None and len(defaults_rows) == 0: defaults_rows = defaults get_defaults = False if server_started: # Need to stop the server! res = _stop_server(server_val, basedir, options) print_list(sys.stdout, format, _COLUMNS, rows, no_headers) if show_defaults and len(defaults_rows) > 0: for row in defaults_rows: print " %s" % row
"run_all_tests": opt.run_all_tests, "width": opt.width, "no_object_check": opt.no_object_check, "no_diff": opt.no_diff, "no_row_count": opt.no_row_count, "no_data": opt.no_data, "format": opt.format, "toggle_binlog": opt.toggle_binlog, "changes-for": opt.changes_for, "reverse": opt.reverse, } # Parse server connection values server2_values = None try: server1_values = parse_connection(opt.server1) if opt.server2 is not None: server2_values = parse_connection(opt.server2) except FormatError as details: parser.error(details) # Operations to perform: # 1) databases exist # 2) check object counts # 3) check object differences # 4) check row counts among the tables # 5) check table data consistency res = True check_failed = False for db in args:
} # Expand user paths and resolve relative paths if opt.new_data and opt.new_data[0] == '~': options['new_data'] = os.path.expanduser(opt.new_data) if opt.basedir and opt.basedir[0] == '~': options['basedir'] = os.path.expanduser(opt.basedir) if opt.new_data and opt.new_data[0] == '.': options['new_data'] = os.path.abspath(opt.new_data) if opt.basedir and opt.basedir[0] == '.': options['basedir'] = os.path.abspath(opt.basedir) # Parse source connection values if we have a running server if opt.basedir is None: try: conn = parse_connection(opt.server) except exception.FormatError: _, err, _ = sys.exc_info() parser.error("Server connection values invalid: %s." % err) except exception.UtilError: _, err, _ = sys.exc_info() parser.error("Server connection values invalid: %s." % err.errmsg) else: conn = None try: res = serverclone.clone_server(conn, options) except exception.UtilError: _, e, _ = sys.exc_info() print("ERROR: %s" % e.errmsg) sys.exit(1)
"all": opt.all, "locking": opt.locking, "use_regexp": opt.use_regexp, "rpl_user": opt.rpl_user, "rpl_mode": opt.rpl_mode, "verbosity": opt.verbosity, "skip_gtid": opt.skip_gtid, } # Parse source connection values try: # Create a basic configuration reader first for optimization purposes. # I.e., to avoid repeating the execution of some methods in further # parse_connection methods (like, searching my_print_defaults tool). config_reader = MyDefaultsReader(options, False) source_values = parse_connection(opt.source, config_reader, options) except FormatError: _, err, _ = sys.exc_info() parser.error("Source connection values invalid: %s." % err) except UtilError: _, err, _ = sys.exc_info() parser.error("Source connection values invalid: %s." % err.errmsg) # Parse destination connection values try: dest_values = parse_connection(opt.destination, config_reader, options) except FormatError: _, err, _ = sys.exc_info() parser.error("Destination connection values invalid: %s." % err) except UtilError: _, err, _ = sys.exc_info()
"threads" : opt.threads, "debug" : opt.verbosity == 3, "exclude_patterns" : opt.exclude, "new_engine" : opt.new_engine, "def_engine" : opt.def_engine, "all" : opt.all, "locking" : opt.locking, "use_regexp" : opt.use_regexp, "rpl_user" : opt.rpl_user, "rpl_mode" : opt.rpl_mode, "verbosity" : opt.verbosity, } # Parse source connection values try: source_values = parse_connection(opt.source) except: parser.error("Source connection values invalid or cannot be parsed.") # Parse destination connection values try: dest_values = parse_connection(opt.destination) except: parser.error("Destination connection values invalid or cannot be parsed.") # Check to see if attempting to use --rpl on the same server if (opt.rpl_mode or opt.rpl_user) and source_values == dest_values: parser.error("You cannot use the --rpl option for copying on the " "same server.") # Check replication options
"all" : opt.all, "locking" : opt.locking, "use_regexp" : opt.use_regexp, "rpl_user" : opt.rpl_user, "rpl_mode" : opt.rpl_mode, "verbosity" : opt.verbosity, "skip_gtid" : opt.skip_gtid, } # Parse source connection values try: # Create a basic configuration reader first for optimization purposes. # I.e., to avoid repeating the execution of some methods in further # parse_connection methods (like, searching my_print_defaults tool). config_reader = MyDefaultsReader(options, False) source_values = parse_connection(opt.source, config_reader, options) except FormatError: _, err, _ = sys.exc_info() parser.error("Source connection values invalid: %s." % err) except UtilError: _, err, _ = sys.exc_info() parser.error("Source connection values invalid: %s." % err.errmsg) # Parse destination connection values try: dest_values = parse_connection(opt.destination, config_reader, options) except FormatError: _, err, _ = sys.exc_info() parser.error("Destination connection values invalid: %s." % err) except UtilError: _, err, _ = sys.exc_info()
# all option parser.add_option("-a", "--all", action="store_true", dest="do_all", default=False, help="show all usage including empty " "databases") # Add verbosity mode add_verbosity(parser, True) # Now we process the rest of the arguments. opt, args = parser.parse_args() # Parse source connection values try: source_values = parse_connection(opt.server, None, opt) except FormatError: _, err, _ = sys.exc_info() parser.error("Source connection values invalid: %s." % err) except UtilError: _, err, _ = sys.exc_info() parser.error("Source connection values invalid: %s." % err.errmsg) try: conn_options = { 'version' : "5.1.30", } servers = connect_servers(source_values, None) except UtilError: _, e, _ = sys.exc_info() parser.error(e.errmsg)
if opt.stop_test: print(" Stop test = '%s%%'" % opt.stop_test) server_list = Server_list([], opt.start_port, opt.utildir, verbose_mode) basedir = None # Print status of connections print("\nServers:") if not opt.servers: print(" No servers specified.") else: i = 0 for server in opt.servers: try: conn_val = parse_connection(server) except: parser.error("Problem parsing server connection '%s'" % server) i += 1 # Fail if port and socket are both None if conn_val["port"] is None and conn_val["unix_socket"] is None: parser.error("You must specify either a port or a socket " \ "in the server string: \n %s" % server) sys.stdout.write(" Connecting to %s as user %s on port %s: " % (conn_val["host"], conn_val["user"], conn_val["port"])) sys.stdout.flush() if conn_val["port"] is not None:
# Now we process the rest of the arguments. opt, args = parser.parse_args() # Fail is --discover-slaves-login not specified if opt.discover is None: parser.error("The --discover-slaves-login is required to test slave " "connectivity.") # Fail if recurse specified and max-depth is invalid if opt.recurse and opt.max_depth is not None: if opt.max_depth < 0: parser.error("The --max-depth option needs to be >= 0.") # Parse master connection values try: m_values = parse_connection(opt.master, None, opt) except FormatError: _, err, _ = sys.exc_info() parser.error("Master connection values invalid: %s." % err) except UtilError: _, err, _ = sys.exc_info() parser.error("Master connection values invalid: %s." % err.errmsg) # Create dictionary of options options = { 'quiet' : opt.quiet, 'prompt' : opt.prompt, 'num_retries' : opt.num_retries, 'recurse' : opt.recurse, 'show_list' : opt.show_list, 'format' : opt.format,
action="store_true", default=False, dest="from_beginning", help="start replication from the first event recorded in " "the binary logging of the master." "Not valid with --master-log-file or --master-log-pos.") # Add verbosity add_verbosity(parser) # Now we process the rest of the arguments. opt, args = parser.parse_args() # Parse source connection values try: m_values = parse_connection(opt.master, None, opt) except FormatError: _, err, _ = sys.exc_info() parser.error("Master connection values invalid: %s." % err) except UtilError: _, err, _ = sys.exc_info() parser.error("Master connection values invalid: %s." % err.errmsg) # Parse source connection values try: s_values = parse_connection(opt.slave, None, opt) except FormatError: _, err, _ = sys.exc_info() parser.error("Slave connection values invalid: %s." % err) except UtilError: _, err, _ = sys.exc_info()
opt, args = parser.parse_args() # Fail if dump and quiet set if opt.quiet and opt.dump: parser.error("You cannot use --quiet and --dump together.") # Warn if quiet and verbosity are both specified check_verbosity(opt) # Fail if no arguments and no options. if (len(args) == 0 or opt is None) and not opt.list_users: parser.error("No arguments found. Use --help for available options.") # Parse source connection values try: source_values = parse_connection(opt.source) except: parser.error("Source connection values invalid or cannot be parsed.") if opt.list_users: PERMITTED_FORMATS = ("GRID", "TAB", "CSV", "VERTICAL") if opt.list_format.upper() not in PERMITTED_FORMATS: print "WARNING : '%s' is not a valid list format. Using default." % \ opt.list_format opt.list_format = "GRID" else: opt.list_format = opt.list_format.upper() userclone.show_users(source_values, opt.verbosity, opt.list_format) else:
add_verbosity(parser, True) # Now we process the rest of the arguments. opt, args = parser.parse_args() # Fail if format specified is invalid try: opt.format = check_format_option(opt.format).upper() except UtilError, e: parser.error(e.errmsg) from mysql.utilities.common.server import connect_servers # Parse source connection values try: source_values = parse_connection(opt.server) except: parser.error("Source connection values invalid or cannot be parsed.") try: conn_options = { 'version' : "5.1.30", } servers = connect_servers(source_values, None, conn_options) except UtilError, e: parser.error(e.errmsg) try: res = servers[0].show_server_variable("datadir") datadir = res[0][1] except UtilError, e:
opt, args = parser.parse_args() # Fail if dump and quiet set if opt.quiet and opt.dump: parser.error("You cannot use --quiet and --dump together.") # Warn if quiet and verbosity are both specified check_verbosity(opt) # Fail if no arguments and no options. if (len(args) == 0 or opt is None) and not opt.list_users: parser.error("No arguments found. Use --help for available options.") # Parse source connection values try: source_values = parse_connection(opt.source, None, opt) except FormatError: _, err, _ = sys.exc_info() parser.error("Source connection values invalid: %s." % err) except UtilError: _, err, _ = sys.exc_info() parser.error("Source connection values invalid: %s." % err.errmsg) if opt.list_users: userclone.show_users(source_values, opt.verbosity, opt.format, opt.dump) else: # Make sure we have the base user plus at least one new user if len(args) < 2 and not opt.dump: parser.error("Wrong parameter combination or no new users.") base_user = args[0]
def _server_info(server_val, get_defaults=False, options={}): """Show information about a running server This method gathers information from a running server. This information is returned as a tuple to be displayed to the user in a format specified. The information returned includes the following: * server connection information * version number of the server * data directory path * base directory path * plugin directory path * configuration file location and name * current binary log file * current binary log position * current relay log file * current relay log position server_val[in] the server connection values or a connected server get_defaults[in] if True, get the default settings for the server options[in] options for connecting to the server Return tuple - information about server """ import tempfile from mysql.utilities.common.server import connect_servers from mysql.utilities.common.tools import get_tool_path verbosity = options.get("verbosity", 0) # Parse source connection values source_values = parse_connection(server_val, None, options) # Connect to the server conn_options = { 'version' : "5.1.30", } servers = connect_servers(source_values, None, conn_options) server = servers[0] rows = server.exec_query("SHOW VARIABLES LIKE 'basedir'") if rows: basedir = rows[0][1] else: raise UtilError("Unable to determine basedir of running server.") my_def_search = [] my_def_path = get_tool_path(basedir, "my_print_defaults") if os.name == "posix": my_def_search = ["/etc/my.cnf", "/etc/mysql/my.cnf", os.path.join(basedir, "my.cnf"), "~/.my.cnf"] else: my_def_search = ["c:\windows\my.ini","c:\my.ini", "c:\my.cnf", os.path.join(os.curdir, "my.ini")] my_def_search.append(os.path.join(os.curdir, "my.cnf")) # Make 'key' value server_id = source_values['host'] # Use string mapping because port is an integer server_id += ":%s" % source_values['port'] if source_values.get('socket', None) is not None: server_id += ":" + source_values.get('socket') defaults = [] if get_defaults: if verbosity > 0: file = tempfile.TemporaryFile() else: file = open(os.devnull, "w+b") subprocess.call([my_def_path, "mysqld"], stdout=file) file.seek(0) defaults.append("\nDefaults for server " + server_id) for line in file.readlines(): defaults.append(line.rstrip()) # Get server version version = None try: res = server.show_server_variable('version') version = res[0][1] except: raise UtilError("Cannot get version for server " + server_id) # Find config file config_file = "" for search_path in my_def_search: if os.path.exists(search_path): if len(config_file) > 0: config_file += ", " + search_path else: config_file = search_path # Find datadir, basedir, plugin-dir, binary log, relay log res = server.show_server_variable("datadir") datadir = res[0][1] res = server.show_server_variable("basedir") basedir = res[0][1] res = server.show_server_variable("plugin_dir") plugin_dir = res[0][1] binlog, binlog_pos = _get_binlog(server) relay_log, relay_log_pos = _get_relay_log(server) server.disconnect() return ((server_id, version, datadir, basedir, plugin_dir, config_file, binlog, binlog_pos, relay_log, relay_log_pos), defaults)
"single": not opt.bulk_insert, "import_type": opt.import_type, "dryrun": opt.dryrun, "do_drop": opt.do_drop, "quiet": opt.quiet, "verbosity": opt.verbosity, "debug": opt.verbosity >= 3, "new_engine": opt.new_engine, "def_engine": opt.def_engine, "skip_rpl": opt.skip_rpl, "skip_gtid": opt.skip_gtid, } # Parse server connection values try: server_values = parse_connection(opt.server, None, options) except FormatError: _, err, _ = sys.exc_info() parser.error("Server connection values invalid: %s." % err) except UtilError: _, err, _ = sys.exc_info() parser.error("Server connection values invalid: %s." % err.errmsg) # Build list of files to import file_list = [] for file_name in args: file_list.append(file_name) try: # record start time if opt.verbosity >= 3:
type = "int", help="display width", default=PRINT_WIDTH) # Add suppress to suppress warning messages parser.add_option("--suppress", action="store_true", dest="suppress", default=False, help="suppress warning messages") # Add verbosity add_verbosity(parser, True) # Now we process the rest of the arguments. opt, args = parser.parse_args() # Parse source connection values try: m_values = parse_connection(opt.master) except FormatError, e: parser.error("Master connection values invalid or cannot be parsed.") # Parse source connection values try: s_values = parse_connection(opt.slave) except FormatError, e: parser.error("Slave connection values invalid or cannot be parsed.") # Create dictionary of options options = { 'verbosity' : opt.verbosity, 'pedantic' : False, 'quiet' : opt.quiet, 'suppress' : opt.suppress,
# Check to make sure at least one table specified. if len(args) == 0: parser.error("You must specify at least one table or database to check.") PERMITTED_FORMATS = ("SQL", "GRID", "TAB", "CSV", "VERTICAL") if opt.index_format.upper() not in PERMITTED_FORMATS: print "WARNING : '%s' is not a valid index format. Using default." % \ opt.index_format opt.index_format = "GRID" else: opt.index_format = opt.index_format.upper() # Parse source connection values try: source_values = parse_connection(opt.server) except: parser.error("Source connection values invalid or cannot be parsed.") # Check best, worst for validity best = None if opt.best is not None: try: best = int(opt.best) except: best = -1 if best is not None and best < 0: parser.error("The --best parameter must be an integer > 1") worst = None if opt.worst is not None:
opt, args = parser.parse_args() # Fail if dump and quiet set if opt.quiet and opt.dump: parser.error("You cannot use --quiet and --dump together.") # Warn if quiet and verbosity are both specified check_verbosity(opt) # Fail if no arguments and no options. if (len(args) == 0 or opt is None) and not opt.list_users: parser.error("No arguments found. Use --help for available options.") # Parse source connection values try: source_values = parse_connection(opt.source, None, opt) except FormatError: _, err, _ = sys.exc_info() parser.error("Source connection values invalid: %s." % err) except UtilError: _, err, _ = sys.exc_info() parser.error("Source connection values invalid: %s." % err.errmsg) if opt.list_users: userclone.show_users(source_values, opt.verbosity, opt.format, opt.dump) else: # Make sure we have the base user plus at least one new user if len(args) < 2 and not opt.dump: parser.error("Wrong parameter combination or no new users.")
# Add quiet parser.add_option("-q", "--quiet", action="store_true", dest="quiet", help="turn off all messages for quiet execution.") # Now we process the rest of the arguments. opt, args = parser.parse_args() # Fail if recurse specified and max-depth is invalid if opt.recurse and opt.max_depth is not None: if opt.max_depth < 0: parser.error("The --max-depth option needs to be >= 0.") # Parse master connection values try: m_values = parse_connection(opt.master) except FormatError, e: parser.error("Master connection values invalid or cannot be parsed.") # Create dictionary of options options = { 'quiet' : opt.quiet, 'prompt' : opt.prompt, 'num_retries' : opt.num_retries, 'recurse' : opt.recurse, 'show_list' : opt.show_list, 'format' : opt.format, 'max_depth' : opt.max_depth, } try:
def _server_info(server_val, get_defaults=False, options={}): """Show information about a running server This method gathers information from a running server. This information is returned as a tuple to be displayed to the user in a format specified. The information returned includes the following: * server connection information * version number of the server * data directory path * base directory path * plugin directory path * configuration file location and name * current binary log file * current binary log position * current relay log file * current relay log position server_val[in] the server connection values or a connected server get_defaults[in] if True, get the default settings for the server options[in] options for connecting to the server Return tuple - information about server """ import tempfile from mysql.utilities.common.server import connect_servers from mysql.utilities.common.tools import get_tool_path verbosity = options.get("verbosity", 0) # Parse source connection values source_values = parse_connection(server_val) # Connect to the server conn_options = { 'version' : "5.1.30", } servers = connect_servers(source_values, None, conn_options) server = servers[0] rows = server.exec_query("SHOW VARIABLES LIKE 'basedir'") if rows: basedir = rows[0][1] else: raise UtilError("Unable to determine basedir of running server.") my_def_search = [] my_def_path = get_tool_path(basedir, "my_print_defaults") if os.name == "posix": my_def_search = ["/etc/my.cnf", "/etc/mysql/my.cnf", os.path.join(basedir, "my.cnf"), "~/.my.cnf"] else: my_def_search = ["c:\windows\my.ini","c:\my.ini", "c:\my.cnf", os.path.join(os.curdir, "my.ini")] my_def_search.append(os.path.join(os.curdir, "my.cnf")) # Make 'key' value server_id = source_values['host'] # Use string mapping because port is an integer server_id += ":%s" % source_values['port'] if source_values.get('socket', None) is not None: server_id += ":" + source_values.get('socket') defaults = [] if get_defaults: if verbosity > 0: file = tempfile.TemporaryFile() else: file = open(os.devnull, "w+b") subprocess.call([my_def_path, "mysqld"], stdout=file) file.seek(0) defaults.append("\nDefaults for server " + server_id) for line in file.readlines(): defaults.append(line.rstrip()) # Get server version version = None try: res = server.show_server_variable('version') version = res[0][1] except: raise UtilError("Cannot get version for server " + server_id) # Find config file config_file = "" for search_path in my_def_search: if os.path.exists(search_path): if len(config_file) > 0: config_file += ", " + search_path else: config_file = search_path # Find datadir, basedir, plugin-dir, binary log, relay log res = server.show_server_variable("datadir") datadir = res[0][1] res = server.show_server_variable("basedir") basedir = res[0][1] res = server.show_server_variable("plugin_dir") plugin_dir = res[0][1] binlog, binlog_pos = _get_binlog(server) relay_log, relay_log_pos = _get_relay_log(server) server.disconnect() return ((server_id, version, datadir, basedir, plugin_dir, config_file, binlog, binlog_pos, relay_log, relay_log_pos), defaults)
'basedir': opt.basedir, 'delete': opt.delete, } # Expand user paths and resolve relative paths if opt.new_data and opt.new_data[0] == '~': options['new_data'] = os.path.expanduser(opt.new_data) if opt.basedir and opt.basedir[0] == '~': options['basedir'] = os.path.expanduser(opt.basedir) if opt.new_data and opt.new_data[0] == '.': options['new_data'] = os.path.abspath(opt.new_data) if opt.basedir and opt.basedir[0] == '.': options['basedir'] = os.path.abspath(opt.basedir) # Parse source connection values if we have a running server if opt.basedir is None: try: conn = parse_connection(opt.server) except: parser.error("Source connection values invalid or cannot be parsed.") else: conn = None try: res = serverclone.clone_server(conn, options) except exception.UtilError, e: print "ERROR:", e.errmsg exit(1) exit()
check_verbosity(opt) # Set options for database operations. options = { "quiet" : opt.quiet, "verbosity" : opt.verbosity, "difftype" : opt.difftype, "force" : opt.force, "width" : opt.width, "changes-for" : opt.changes_for, "reverse" : opt.reverse, } # Parse server connection values try: server1_values = parse_connection(opt.server1, None, options) except FormatError: _, err, _ = sys.exc_info() parser.error("Server1 connection values invalid: %s." % err) except UtilError: _, err, _ = sys.exc_info() parser.error("Server1 connection values invalid: %s." % err.errmsg) if opt.server2 is not None: try: server2_values = parse_connection(opt.server2, None, options) except FormatError: _, err, _ = sys.exc_info() parser.error("Server2 connection values invalid: %s." % err) except UtilError: _, err, _ = sys.exc_info() parser.error("Server2 connection values invalid: %s." % err.errmsg)
def show_server_info(servers, options): """Show server information for a list of servers This method will gather information about a running server. If the show_defaults option is specified, the method will also read the configuration file and return a list of the server default settings. If the format option is set, the output will be in the format specified. If the no_headers option is set, the output will not have a header row (no column names) except for format = vertical. If the basedir and start options are set, the method will attempt to start the server in read only mode to get the information. Specifying only basedir will not start the server. The extra start option is designed to make sure the user wants to start the offline server. The user may not wish to do this if there are certain error conditions and/or logs in place that may be overwritten. servers[in] list of server connections in the form <user>:<password>@<host>:<port>:<socket> options[in] dictionary of options (no_headers, format, basedir, start, show_defaults) Returns tuple ((server information), defaults) """ from mysql.utilities.common.server import test_connect from mysql.utilities.common.format import print_list no_headers = options.get("no_headers", False) format = options.get("format", "grid") show_defaults = options.get("show_defaults", False) basedir = options.get("basedir", None) datadir = options.get("datadir", None) start = options.get("start", False) verbosity = options.get("verbosity", 0) show_servers = options.get("show_servers", 0) if show_servers: if os.name == 'nt': ports = options.get("ports", "3306:3333") start, end = ports.split(":") _show_running_servers(start, end) else: _show_running_servers() defaults_rows = [] rows = [] server_val = {} get_defaults = True for server in servers: new_server = None try: test_connect(server, True) except UtilError as util_error: if util_error.errmsg.startswith("Server connection values invalid:"): raise util_error # If we got an exception it may means that the server is offline # in that case we will try to turn a clone to extract the info # if the user passed the necessary parameters. pattern = ".*?: (.*?)\((.*)\)" res = re.match(pattern, util_error.errmsg, re.S) if not res: er = ["error: <%s>" % util_error.errmsg] else: er = res.groups() if (re.search("refused", "".join(er)) or re.search("Can't connect to local MySQL server through socket", "".join(er))): er = ["Server is offline. To connect, " "you must also provide "] opts = ["basedir", "datadir", "start"] for opt in tuple(opts): try: if locals()[opt] is not None: opts.remove(opt) except KeyError: pass if opts: er.append(", ".join(opts[0:-1])) if len(opts) > 1: er.append(" and the ") er.append(opts[-1]) er.append(" option") raise UtilError("".join(er)) if not start: raise UtilError("".join(er)) else: try: server_val = parse_connection(server, None, options) except: raise UtilError("Source connection values invalid" " or cannot be parsed.") new_server = _start_server(server_val, basedir, datadir, options) info, defaults = _server_info(server, get_defaults, options) if info: rows.append(info) if defaults and len(defaults_rows) == 0: defaults_rows = defaults get_defaults = False if new_server: # Need to stop the server! new_server.disconnect() res = _stop_server(server_val, basedir, options) print_list(sys.stdout, format, _COLUMNS, rows, no_headers) if show_defaults and len(defaults_rows) > 0: for row in defaults_rows: print " %s" % row
print "WARNING: The --candidates option is used only with the " + \ "failover and elect commands." opt.candidates = None if (opt.candidates or opt.new_master) and command in ['stop', 'start', 'reset']: print "WARNING: The --new-master and --candidates options are not " + \ "used with the stop, start, and reset commands." opt.candidates = None if opt.format and command not in ['health', 'gtid']: print "WARNING: The --format option is used only with the health " + \ "and gtid commands." if opt.new_master: try: new_master_val = parse_connection(opt.new_master) except FormatError, e: parser.error("New master connection values invalid or cannot be parsed.") else: new_master_val = None # Parse the master, slaves, and candidates connection parameters try: master_val, slaves_val, candidates_val = parse_failover_connections(opt) except UtilRplError, e: print "ERROR:", e.errmsg exit(1) # Create dictionary of options options = { 'new_master' : new_master_val,
if opt.stop_test: print(" Stop test = '%s%%'" % opt.stop_test) server_list = Server_list([], opt.start_port, opt.utildir, verbose_mode) basedir = None # Print status of connections print("\nServers:") if not opt.servers: print(" No servers specified.") else: i = 0 for server in opt.servers: try: conn_val = parse_connection(server) except: parser.error("Problem parsing server connection '%s'" % server) i += 1 # Fail if port and socket are both None if conn_val["port"] is None and conn_val["unix_socket"] is None: parser.error("You must specify either a port or a socket " \ "in the server string: \n %s" % server) sys.stdout.write( " Connecting to %s as user %s on port %s: " % (conn_val["host"], conn_val["user"], conn_val["port"])) sys.stdout.flush() if conn_val["port"] is not None:
# Add start from beginning option parser.add_option("-b", "--start-from-beginning", action="store_true", default=False, dest="from_beginning", help="start replication from the first event recorded in " "the binary logging of the master." "Not valid with --master-log-file or --master-log-pos.") # Add verbosity add_verbosity(parser) # Now we process the rest of the arguments. opt, args = parser.parse_args() # Parse source connection values try: m_values = parse_connection(opt.master) except: parser.error("Master connection values invalid or cannot be parsed.") # Parse source connection values try: s_values = parse_connection(opt.slave) except: parser.error("Slave connection values invalid or cannot be parsed.") # Check required --master-log-file for --master-log-pos if (opt.master_log_pos >= 0 and opt.master_log_file is None): parser.error("You must specify a master log file to use the master " "log file position option.") if ((opt.master_log_pos >= 0) or (opt.master_log_file is not None)) and \
# The --audit-log-name is required if a command specified. if command_requires_log_name(command) and not opt.log_name: parser.error("The --audit-log-name option is required for the %s command." % command) if opt.log_name and (not opt.file_stats and not command_requires_log_name(command)): parser.error("The --audit-log-name option requires --file-stats and/or " "a valid command.") # Attempt to parse the --server option server_values = None if opt.server: try: server_values = parse_connection(opt.server, None, opt) except FormatError: _, err, _ = sys.exc_info() parser.error("Server connection values invalid: %s." % err) except UtilError: _, err, _ = sys.exc_info() parser.error("Server connection values invalid: %s." % err.errmsg) # Check for copy prerequisites if command and command == "COPY" and not opt.copy_location: parser.error("You must specify the --copy-to option for copying a log " "file.") # The --copy-to option requires the command COPY if opt.copy_location and not (command == "COPY"): parser.error("The --copy-to option can only be used with the COPY "
"failover and elect commands.") opt.candidates = None if (opt.candidates or opt.new_master) and command in ['stop', 'start', 'reset']: print("WARNING: The --new-master and --candidates options are not " "used with the stop, start, and reset commands.") opt.candidates = None if opt.format and command not in ['health', 'gtid']: print("WARNING: The --format option is used only with the health " "and gtid commands.") if opt.new_master: try: new_master_val = parse_connection(opt.new_master, None, opt) except FormatError: _, err, _ = sys.exc_info() parser.error("New master connection values invalid: %s." % err) except UtilError: _, err, _ = sys.exc_info() parser.error("New master connection values invalid: %s." % err.errmsg) else: new_master_val = None # Parse the master, slaves, and candidates connection parameters try: master_val, slaves_val, candidates_val = parse_failover_connections(opt) except UtilRplError: _, e, _ = sys.exc_info() print("ERROR: %s" % e.errmsg)