示例#1
0
    def restore_fabric_server(server,  image, config_file, mysqlclient_binary):
        """Restore the backup from the image to a server within the
        fabric farm and managed by the Fabric server.

        In the current implementation the restore works by restoring the
        .sql file created on the FABRIC server. This will be optimized in future
        implementation. But for the current implementation this suffices.

        :param server: The server on which the backup needs to be restored.
        :param image: The image that needs to be restored.
        :param config_file: The complete path to the fabric configuration file.
        :param mysqlclient_binary: The fully qualified mysqlclient binary.
        """

        assert (isinstance(server, MySQLServer))
        assert (image is None or isinstance(image, BackupImage))

        #Extract the host and the port from the server address.
        host = None
        port = None
        if server.address is not None:
            host, port = _server_utils.split_host_port(
                                                server.address,
                                                MySQLDump.MYSQL_DEFAULT_PORT
                                                )
        MySQLDump.restore_server(host, port, server.user, server.passwd,
                image, config_file, mysqlclient_binary)
示例#2
0
    def restore_fabric_server(server, restore_user, restore_passwd,
                              image, mysqlclient_binary):
        """Restore the backup from the image to a server within the
        fabric farm and managed by the Fabric server.

        In the current implementation the restore works by restoring the
        .sql file created on the FABRIC server. This will be optimized in future
        implementation. But for the current implementation this suffices.

        :param server: The server on which the backup needs to be restored.
        :param restore_user: The user name used for accessing the server.
        :param restore_passwd: The password used for accessing the server.
        :param image: The image that needs to be restored.
        :param mysqlclient_binary: The fully qualified mysqlclient binary.
        """

        assert isinstance(server, MySQLServer)
        assert image is None or isinstance(image, BackupImage)

        #Extract the host and the port from the server address.
        host = None
        port = None
        if server.address is not None:
            host, port = split_host_port(server.address)
        MySQLDump.restore_server(host, port, restore_user, restore_passwd,
                                 image, mysqlclient_binary)
示例#3
0
    def restore_fabric_server(server, image, config_file, mysqlclient_binary):
        """Restore the backup from the image to a server within the
        fabric farm and managed by the Fabric server.

        In the current implementation the restore works by restoring the
        .sql file created on the FABRIC server. This will be optimized in future
        implementation. But for the current implementation this suffices.

        :param server: The server on which the backup needs to be restored.
        :param image: The image that needs to be restored.
        :param config_file: The complete path to the fabric configuration file.
        :param mysqlclient_binary: The fully qualified mysqlclient binary.
        """

        assert isinstance(server, MySQLServer)
        assert image is None or isinstance(image, BackupImage)

        #Extract the host and the port from the server address.
        host = None
        port = None
        if server.address is not None:
            host, port = _server_utils.split_host_port(
                server.address, MySQLDump.MYSQL_DEFAULT_PORT)
        MySQLDump.restore_server(host, port, server.user, server.passwd, image,
                                 config_file, mysqlclient_binary)
示例#4
0
    def backup(server, config_file, mysqldump_binary=None):
        """Perform the backup using mysqldump.

        The backup results in creation a .sql file on the FABRIC server,
        this method needs to be optimized going forward. But for now
        this will suffice.

        :param server: The MySQLServer that needs to be backed up.
        :param config_file: The complete path to the fabric configuration file.
        :param mysqldump_binary: The fully qualified mysqldump binary.
        """
        assert (isinstance(server, MySQLServer))

        #Extract the host and the port from the server address.
        host = None
        port = None
        if server.address is not None:
            host, port = _server_utils.split_host_port(
                            server.address,
                            MySQLDump.MYSQL_DEFAULT_PORT
                         )

        #Form the name of the destination .sql file from the name of the
        #server host and the port number that is being backed up.
        destination = "MySQL_{HOST}_{PORT}.sql".format(
                                                    HOST=host,
                                                    PORT=port)

        mysqldump_command = shlex.split(mysqldump_binary)

        #Setup the MYSQLDump command that is used to backup the server.
        #Append the password parameter if the password is not None.
        mysqldump_command.extend([
            "--defaults-extra-file="+config_file,
            "--all-databases", "--single-transaction",
            "--add-drop-table",
            "--triggers", "--routines",
            "--events",
            "--protocol=tcp",
            "-h" + str(host),
            "-P" + str(port),
            "-u" + str(server.user)])

        #Run the backup command
        with open(destination,"w") as fd_file:
            p = Popen(mysqldump_command, stdout=fd_file, stderr=PIPE)
            _, error_lines = p.communicate()
            if p.returncode:
                MySQLDump.dump_to_log(
                    "Error while taking backup using MySQLDump\n",
                    error_lines
                )
                raise _errors.BackupError(
                    "Error while taking backup using MySQLDump\n, %s",
                    error_lines
                )

        #Return the backup image containing the location of the .sql file.
        return BackupImage(destination)
示例#5
0
    def execute(self, group_id, destn_address, server_id=None, timeout=None,
                synchronous=True):
        """Clone the objects of a given server into a destination server.

        :param group_id: The ID of the source group.
        :param destn_address: The address of the destination MySQL Server.
        :param source_id: The address or UUID of the source MySQL Server.
        :param timeout: Time in seconds after which an error is reported
                        if the destination server is unreachable.
        :param synchronous: Whether one should wait until the execution
                            finishes or not.
        """
        # If the destination server is already part of a Fabric Group, raise
        # an error
        destn_server_uuid = _lookup_uuid(destn_address, timeout)
        _check_server_not_in_any_group(destn_server_uuid)
        host, port = _server_utils.split_host_port(
            destn_address, _backup.MySQLDump.MYSQL_DEFAULT_PORT
        )

        # Fetch information on backup and restore programs.
        config_file = self.config.config_file if self.config.config_file else ""

        mysqldump_binary = _utils.read_config_value(
                                self.config,
                                'sharding',
                                'mysqldump_program'
                            )
        mysqlclient_binary = _utils.read_config_value(
                                self.config,
                                'sharding',
                                'mysqlclient_program'
                            )

        if not _utils.is_valid_binary(mysqldump_binary):
            raise _errors.ServerError(MYSQLDUMP_NOT_FOUND % mysqldump_binary)

        if not _utils.is_valid_binary(mysqlclient_binary):
            raise _errors.ServerError(MYSQLCLIENT_NOT_FOUND % mysqlclient_binary)

        # Fetch a reference to source server.
        if server_id:
            server = _retrieve_server(server_id, group_id)
        else:
            group = _retrieve_group(group_id)
            server = _utils.fetch_backup_server(group)

        # Schedule the clone operation through the executor.
        procedures = _events.trigger(
            BACKUP_SERVER,
            self.get_lockable_objects(),
            str(server.uuid),
            host,
            port,
            mysqldump_binary,
            mysqlclient_binary,
            config_file
        )
        return self.wait_for_procedures(procedures, synchronous)
示例#6
0
def _configure_as_slave(group, server):
    """Configure the server as a slave.
    """
    try:
        ### When master has been already elected, throw CREATE USER into master.
        if group.master:
            master = _server.MySQLServer.fetch(group.master)
            master.connect()
            host, port = split_host_port(server.address)
            master.exec_stmt(_server.MySQLServer.DROP_REPLICATION_USER,
                             {"params": (server.repl_user, host,)})
            master.exec_stmt(_server.MySQLServer.CREATE_REPLICATION_USER,
                             {"params": (server.repl_user, host,
                                         server.repl_pass,)})
            master.exec_stmt(_server.MySQLServer.GRANT_REPLICATION_USER,
                             {"params": (server.repl_user, host,)})
            _services_utils.switch_master(server, master)
        else:
            
            ### When master hasn't been elected yet and adding server is very first server in the group,
            ### throw CREATE USER into server itself.
            _LOGGER.critical(group.servers())

            if len(group.servers()) == 1:
                server.connect()
                host, port = split_host_port(server.address)
                server.exec_stmt(_server.MySQLServer.DROP_REPLICATION_USER,
                                 {"params": (server.repl_user, host,)})
                server.exec_stmt(_server.MySQLServer.CREATE_REPLICATION_USER,
                                 {"params": (server.repl_user, host,
                                             server.repl_pass,)})
                server.exec_stmt(_server.MySQLServer.GRANT_REPLICATION_USER,
                                 {"params": (server.repl_user, host,)})
            else:
                ### This means group has at least 1 server but master doesn't elect yet.
                raise _errors.ServerError("Master server doesn't elect yet")
            
    except _errors.DatabaseError as error:
        msg = "Error trying to configure server ({0}) as slave: {1}.".format(
            server.uuid, error)
        _LOGGER.debug(msg)
        raise _errors.ServerError(msg)
示例#7
0
    def backup(server, backup_user, backup_passwd, mysqldump_binary):
        """Perform the backup using mysqldump.

        The backup results in creation a .sql file on the FABRIC server,
        this method needs to be optimized going forward. But for now
        this will suffice.

        :param server: The MySQLServer that needs to be backed up.
        :param backup_user: The user name used for accessing the server.
        :param backup_passwd: The password used for accessing the server.
        :param mysqldump_binary: The fully qualified mysqldump binary.
        """
        assert isinstance(server, MySQLServer)

        # Extract the host and the port from the server address.
        host = None
        port = None
        if server.address is not None:
            host, port = split_host_port(server.address)

        # Form the name of the destination .sql file from the name of the
        # server host and the port number that is being backed up.
        destination = "MySQL_{HOST}_{PORT}.sql".format(HOST=host, PORT=port)

        command = shlex.split(mysqldump_binary)

        # Setup the mysqldump command that is used to backup the server.
        command.extend(
            [
                # A --no-defaults or --defaults-file option is inserted by
                # run_mysql_client().
                "--all-databases",
                "--single-transaction",
                "--add-drop-table",
                "--triggers",
                "--routines",
                "--events",
                "--protocol=tcp",
                "-h" + str(host),
                "-P" + str(port),
                "-u" + str(backup_user)
                # A -p is appended by run_mysql_client(), if required.
            ]
        )

        # Run the backup command
        with open(destination, "w") as fd_file:
            returncode, error_lines = run_mysql_client(command, backup_passwd, outstream=fd_file)
            if returncode:
                MySQLDump.dump_to_log("Error while taking backup using " + command[0], error_lines)
                raise _errors.BackupError("Error while taking backup using " + command[0], error_lines)

        # Return the backup image containing the location of the .sql file.
        return BackupImage(destination)
示例#8
0
    def execute(self,
                group_id,
                destn_address,
                server_id=None,
                timeout=None,
                synchronous=True):
        """Clone the objects of a given server into a destination server.

        :param group_id: The ID of the source group.
        :param destn_address: The address of the destination MySQL Server.
        :param source_id: The address or UUID of the source MySQL Server.
        :param timeout: Time in seconds after which an error is reported
                        if the destination server is unreachable.
        :param synchronous: Whether one should wait until the execution
                            finishes or not.
        """
        # If the destination server is already part of a Fabric Group, raise
        # an error
        destn_server_uuid = _lookup_uuid(destn_address, timeout)
        _check_server_not_in_any_group(destn_server_uuid)
        host, port = _server_utils.split_host_port(
            destn_address, _backup.MySQLDump.MYSQL_DEFAULT_PORT)

        # Fetch information on backup and restore programs.
        config_file = self.config.config_file if self.config.config_file else ""

        mysqldump_binary = _utils.read_config_value(self.config, 'sharding',
                                                    'mysqldump_program')
        mysqlclient_binary = _utils.read_config_value(self.config, 'sharding',
                                                      'mysqlclient_program')

        if not _utils.is_valid_binary(mysqldump_binary):
            raise _errors.ServerError(MYSQLDUMP_NOT_FOUND % mysqldump_binary)

        if not _utils.is_valid_binary(mysqlclient_binary):
            raise _errors.ServerError(MYSQLCLIENT_NOT_FOUND %
                                      mysqlclient_binary)

        # Fetch a reference to source server.
        if server_id:
            server = _retrieve_server(server_id, group_id)
        else:
            group = _retrieve_group(group_id)
            server = _utils.fetch_backup_server(group)

        # Schedule the clone operation through the executor.
        procedures = _events.trigger(BACKUP_SERVER,
                                     self.get_lockable_objects(),
                                     str(server.uuid), host, port,
                                     mysqldump_binary, mysqlclient_binary,
                                     config_file)
        return self.wait_for_procedures(procedures, synchronous)
    def test_utilities(self):
        """Check MySQLServer's utilities module.
        """
        # Test a function that gets host and port and returns
        # host:port
        address = _server_utils.combine_host_port(None, None, 3306)
        self.assertEqual(address, "unknown host:3306")

        address = _server_utils.combine_host_port("", None, 3306)
        self.assertEqual(address, "unknown host:3306")

        address = _server_utils.combine_host_port(None, "", 3306)
        self.assertEqual(address, "unknown host:3306")

        address = _server_utils.combine_host_port("host", "port", 3306)
        self.assertEqual(address, "host:port")

        address = _server_utils.combine_host_port("host", 1500, 3306)
        self.assertEqual(address, "host:1500")

        address = _server_utils.combine_host_port("127.0.0.1", 1500, 3306)
        self.assertEqual(address, "localhost:1500")

        # Test a function that gets host:port and returns (host, port)
        host_port = _server_utils.split_host_port("", 3306)
        self.assertEqual(host_port, ("", 3306))

        host_port = _server_utils.split_host_port(":", 3306)
        self.assertEqual(host_port, ("", ""))

        host_port = _server_utils.split_host_port("host:", 3306)
        self.assertEqual(host_port, ("host", ""))

        host_port = _server_utils.split_host_port(":port", 3306)
        self.assertEqual(host_port, ("", "port"))

        host_port = _server_utils.split_host_port("host:port", 3306)
        self.assertEqual(host_port, ("host", "port"))
    def test_utilities(self):
        """Check MySQLServer's utilities module.
        """
        # Test a function that gets host and port and returns
        # host:port
        address = _server_utils.combine_host_port(None, None, 3306)
        self.assertEqual(address, "unknown host:3306")

        address = _server_utils.combine_host_port("", None, 3306)
        self.assertEqual(address, "unknown host:3306")

        address = _server_utils.combine_host_port(None, "", 3306)
        self.assertEqual(address, "unknown host:3306")

        address = _server_utils.combine_host_port("host", "port", 3306)
        self.assertEqual(address, "host:port")

        address = _server_utils.combine_host_port("host", 1500, 3306)
        self.assertEqual(address, "host:1500")

        address = _server_utils.combine_host_port("127.0.0.1", 1500, 3306)
        self.assertEqual(address, "localhost:1500")

        # Test a function that gets host:port and returns (host, port)
        host_port = _server_utils.split_host_port("", 3306)
        self.assertEqual(host_port, ("", 3306))

        host_port = _server_utils.split_host_port(":", 3306)
        self.assertEqual(host_port, ("", ""))

        host_port = _server_utils.split_host_port("host:", 3306)
        self.assertEqual(host_port, ("host", ""))

        host_port = _server_utils.split_host_port(":port", 3306)
        self.assertEqual(host_port, ("", "port"))

        host_port = _server_utils.split_host_port("host:port", 3306)
        self.assertEqual(host_port, ("host", "port"))
示例#11
0
def switch_master(slave,
                  master,
                  master_user,
                  master_passwd=None,
                  from_beginning=True,
                  master_log_file=None,
                  master_log_pos=None):
    """Switch slave to a new master by executing the `CHANGE MASTER` command.
    Look up the command in the MySQL Manual for further details.

    This method forms the `CHANGE MASTER` command based on the current
    settings of the slave along with the parameters provided and execute
    it. No prerequisites are checked.

    :param slave: Reference to a slave (MySQL Server).
    :param master: Reference to the master (MySQL Server).
    :param master_user: Replication user.
    :param master_passwd: Replication user password.
    :param from_beginning: If True, start from beginning of logged events.
    :param master_log_file: Master's log file (not needed for GTID).
    :param master_log_pos: master's log file position (not needed for GTID).
    """
    commands = []
    params = []
    master_host, master_port = _server_utils.split_host_port(
        master.address, _server_utils.MYSQL_DEFAULT_PORT)

    commands.append("MASTER_HOST = %s")
    params.append(master_host)
    commands.append("MASTER_PORT = %s")
    params.append(int(master_port))
    commands.append("MASTER_USER = %s")
    params.append(master_user)
    if master_passwd:
        commands.append("MASTER_PASSWORD = %s")
        params.append(master_passwd)
    else:
        commands.append("MASTER_PASSWORD = ''")

    if slave.gtid_enabled:
        commands.append("MASTER_AUTO_POSITION = 1")
    elif not from_beginning:
        commands.append("MASTER_LOG_FILE = %s")
        params.append(master_log_file)
        if master_log_pos >= 0:
            commands.append("MASTER_LOG_POS = %s" % master_log_pos)
            params.append(master_log_pos)

    slave.exec_stmt("CHANGE MASTER TO " + ", ".join(commands),
                    {"params": tuple(params)})
示例#12
0
    def backup(server, config_file, mysqldump_binary=None):
        """Perform the backup using mysqldump.

        The backup results in creation a .sql file on the FABRIC server,
        this method needs to be optimized going forward. But for now
        this will suffice.

        :param server: The MySQLServer that needs to be backed up.
        :param config_file: The complete path to the fabric configuration file.
        :param mysqldump_binary: The fully qualified mysqldump binary.
        """
        assert isinstance(server, MySQLServer)

        #Extract the host and the port from the server address.
        host = None
        port = None
        if server.address is not None:
            host, port = _server_utils.split_host_port(
                server.address, MySQLDump.MYSQL_DEFAULT_PORT)

        #Form the name of the destination .sql file from the name of the
        #server host and the port number that is being backed up.
        destination = "MySQL_{HOST}_{PORT}.sql".format(HOST=host, PORT=port)

        mysqldump_command = shlex.split(mysqldump_binary)

        #Setup the MYSQLDump command that is used to backup the server.
        #Append the password parameter if the password is not None.
        mysqldump_command.extend([
            "--defaults-extra-file=" + config_file, "--all-databases",
            "--single-transaction", "--add-drop-table", "--triggers",
            "--routines", "--events", "--protocol=tcp", "-h" + str(host),
            "-P" + str(port), "-u" + str(server.user)
        ])

        #Run the backup command
        with open(destination, "w") as fd_file:
            p = Popen(mysqldump_command, stdout=fd_file, stderr=PIPE)
            _, error_lines = p.communicate()
            if p.returncode:
                MySQLDump.dump_to_log(
                    "Error while taking backup using MySQLDump\n", error_lines)
                raise _errors.BackupError(
                    "Error while taking backup using MySQLDump\n, %s",
                    error_lines)

        #Return the backup image containing the location of the .sql file.
        return BackupImage(destination)
示例#13
0
def switch_master(slave, master, master_user, master_passwd=None,
                  from_beginning=True, master_log_file=None,
                  master_log_pos=None):
    """Switch slave to a new master by executing the `CHANGE MASTER` command.
    Look up the command in the MySQL Manual for further details.

    This method forms the `CHANGE MASTER` command based on the current
    settings of the slave along with the parameters provided and execute
    it. No prerequisites are checked.

    :param slave: Reference to a slave (MySQL Server).
    :param master: Reference to the master (MySQL Server).
    :param master_user: Replication user.
    :param master_passwd: Replication user password.
    :param from_beginning: If True, start from beginning of logged events.
    :param master_log_file: Master's log file (not needed for GTID).
    :param master_log_pos: master's log file position (not needed for GTID).
    """
    commands = []
    params = []
    master_host, master_port = _server_utils.split_host_port(master.address,
        _server_utils.MYSQL_DEFAULT_PORT)

    commands.append("MASTER_HOST = %s")
    params.append(master_host)
    commands.append("MASTER_PORT = %s")
    params.append(int(master_port))
    commands.append("MASTER_USER = %s")
    params.append(master_user)
    if master_passwd:
        commands.append("MASTER_PASSWORD = %s")
        params.append(master_passwd)
    else:
        commands.append("MASTER_PASSWORD = ''")

    if slave.gtid_enabled:
        commands.append("MASTER_AUTO_POSITION = 1")
    elif not from_beginning:
        commands.append("MASTER_LOG_FILE = %s")
        params.append(master_log_file)
        if master_log_pos >= 0:
            commands.append("MASTER_LOG_POS = %s" % master_log_pos)
            params.append(master_log_pos)

    slave.exec_stmt("CHANGE MASTER TO " + ", ".join(commands),
                    {"params": tuple(params)})
示例#14
0
    def restore_fabric_server(server, restore_user, restore_passwd, image, mysqlclient_binary):
        """Restore the backup from the image to a server within the
        fabric farm and managed by the Fabric server.

        In the current implementation the restore works by restoring the
        .sql file created on the FABRIC server. This will be optimized in future
        implementation. But for the current implementation this suffices.

        :param server: The server on which the backup needs to be restored.
        :param restore_user: The user name used for accessing the server.
        :param restore_passwd: The password used for accessing the server.
        :param image: The image that needs to be restored.
        :param mysqlclient_binary: The fully qualified mysqlclient binary.
        """

        assert isinstance(server, MySQLServer)
        assert image is None or isinstance(image, BackupImage)

        # Extract the host and the port from the server address.
        host = None
        port = None
        if server.address is not None:
            host, port = split_host_port(server.address)
        MySQLDump.restore_server(host, port, restore_user, restore_passwd, image, mysqlclient_binary)
    def setUp(self):
        """Configure the existing environment
        """
        self.manager, self.proxy = tests.utils.setup_xmlrpc()
        self.__options_1 = {
            "uuid" :  _uuid.UUID("{bb75b12b-98d1-414c-96af-9e9d4b179678}"),
            "address"  : "server_1.mysql.com:3060",
        }
        self.__server_1 = MySQLServer(**self.__options_1)
        MySQLServer.add(self.__server_1)
        self.__options_2 = {
            "uuid" :  _uuid.UUID("{aa75a12a-98d1-414c-96af-9e9d4b179678}"),
            "address"  : "server_2.mysql.com:3060",
        }
        self.__server_2 = MySQLServer(**self.__options_2)
        MySQLServer.add(self.__server_2)
        self.__group_1 = Group("GROUPID1", "First description.")
        Group.add(self.__group_1)
        self.__group_1.add_server(self.__server_1)
        self.__group_1.add_server(self.__server_2)

        self.__options_3 = {
            "uuid" :  _uuid.UUID("{cc75b12b-98d1-414c-96af-9e9d4b179678}"),
            "address"  : MySQLInstances().get_address(0),
            "user" : MySQLInstances().user,
            "passwd" : MySQLInstances().passwd,
        }
        uuid_server3 = MySQLServer.discover_uuid(self.__options_3["address"])
        self.__options_3["uuid"] = _uuid.UUID(uuid_server3)
        self.__server_3 = MySQLServer(**self.__options_3)
        MySQLServer.add(self.__server_3)

        self.__options_4 = {
            "uuid" :  _uuid.UUID("{dd75a12a-98d1-414c-96af-9e9d4b179678}"),
            "address"  : "server_4.mysql.com:3060",
        }
        self.__server_4 = MySQLServer(**self.__options_4)
        MySQLServer.add(self.__server_4)
        self.__group_2 = Group("GROUPID2", "Second description.")
        Group.add(self.__group_2)
        self.__group_2.add_server(self.__server_3)
        self.__group_2.add_server(self.__server_4)
        tests.utils.configure_decoupled_master(self.__group_2, self.__server_3)

        self.__options_5 = {
            "uuid" :  _uuid.UUID("{ee75b12b-98d1-414c-96af-9e9d4b179678}"),
            "address"  : MySQLInstances().get_address(2),
            "user" : MySQLInstances().user,
            "passwd" : MySQLInstances().passwd,
        }
        uuid_server5 = MySQLServer.discover_uuid(self.__options_5["address"])
        self.__options_5["uuid"] = _uuid.UUID(uuid_server5)
        self.__server_5 = MySQLServer(**self.__options_5)
        MySQLServer.add(self.__server_5)

        self.__options_6 = {
            "uuid" :  _uuid.UUID("{ff75a12a-98d1-414c-96af-9e9d4b179678}"),
            "address"  : "server_6.mysql.com:3060",
        }
        self.__server_6 = MySQLServer(**self.__options_6)
        MySQLServer.add(self.__server_6)
        self.__group_3 = Group("GROUPID3", "Third description.")
        Group.add(self.__group_3)
        self.__group_3.add_server(self.__server_5)
        self.__group_3.add_server(self.__server_6)
        tests.utils.configure_decoupled_master(self.__group_3, self.__server_5)

        self.__options_1_host,  self.__options_1_port = \
            server_utils.split_host_port(self.__options_1["address"], 13001)
        self.__options_2_host,  self.__options_2_port = \
            server_utils.split_host_port(self.__options_2["address"], 13001)
        self.__options_3_host,  self.__options_3_port = \
            server_utils.split_host_port(self.__options_3["address"], 13001)
        self.__options_4_host,  self.__options_4_port = \
            server_utils.split_host_port(self.__options_4["address"], 13001)
        self.__options_5_host,  self.__options_5_port = \
            server_utils.split_host_port(self.__options_5["address"], 13001)
        self.__options_6_host,  self.__options_6_port = \
            server_utils.split_host_port(self.__options_6["address"], 13001)

        group_4 = Group("GROUPID4", "4TH description.")
        Group.add(group_4)
        group_5 = Group("GROUPID5", "5TH description.")
        Group.add(group_5)
        group_6 = Group("GROUPID6", "6TH description.")
        Group.add(group_6)
        group_7 = Group("GROUPID7", "7TH description.")
        Group.add(group_7)
        group_8 = Group("GROUPID8", "8TH description.")
        Group.add(group_8)
        group_9 = Group("GROUPID9", "9TH description.")
        Group.add(group_9)
        group_10 = Group("GROUPID10", "10TH description.")
        Group.add(group_10)
        group_11 = Group("GROUPID11", "11TH description.")
        Group.add(group_11)
        group_12 = Group("GROUPID12", "12TH description.")
        Group.add(group_12)
        group_13 = Group("GROUPID13", "13TH description.")
        Group.add(group_13)
        group_14 = Group("GROUPID14", "14TH description.")
        Group.add(group_14)

        self.__shard_mapping_list = ShardMapping.list_shard_mapping_defn()
        self.assertEquals( self.__shard_mapping_list,  [])
        self.__shard_mapping_id_1 = ShardMapping.define("RANGE", "GROUPID10")
        self.__shard_mapping_id_2 = ShardMapping.define("RANGE", "GROUPID11")
        self.__shard_mapping_id_3 = ShardMapping.define("RANGE", "GROUPID12")
        #Test with sharding type values in lower case
        self.__shard_mapping_id_4 = ShardMapping.define("range", "GROUPID13")
        self.__shard_mapping_id_5 = ShardMapping.define("range", "GROUPID14")

        self.__shard_mapping_1 = \
            ShardMapping.add(self.__shard_mapping_id_1, "db1.t1", "userID1")
        self.__shard_mapping_2 = \
            ShardMapping.add(self.__shard_mapping_id_2, "db2.t2", "userID2")
        self.__shard_mapping_3 = \
            ShardMapping.add(self.__shard_mapping_id_3, "db3.t3", "userID3")
        self.__shard_mapping_4 = \
            ShardMapping.add(self.__shard_mapping_id_4, "db4.t4", "userID4")

        self.__shard_mapping_5 = \
            ShardMapping.add(self.__shard_mapping_id_5, "prune_db.prune_table",
                             "userID")

        self.__shard_id_1 = Shards.add("GROUPID1", "ENABLED")
        self.__shard_id_2 = Shards.add("GROUPID10", "ENABLED")
        self.__shard_id_3 = Shards.add("GROUPID11", "DISABLED")
        self.__shard_id_4 = Shards.add("GROUPID4", "ENABLED")
        self.__shard_id_5 = Shards.add("GROUPID5", "ENABLED")
        self.__shard_id_6 = Shards.add("GROUPID6", "ENABLED")
        self.__shard_id_7 = Shards.add("GROUPID7", "ENABLED")
        self.__shard_id_8 = Shards.add("GROUPID8", "ENABLED")
        self.__shard_id_9 = Shards.add("GROUPID9", "ENABLED")
        self.__shard_id_10 = Shards.add("GROUPID2", "ENABLED")
        self.__shard_id_11 = Shards.add("GROUPID3", "ENABLED")

        self.__range_sharding_specification_1 = RangeShardingSpecification.add(
            self.__shard_mapping_1.shard_mapping_id,
            0,
            self.__shard_id_1.shard_id
        )
        self.__range_sharding_specification_2 = RangeShardingSpecification.add(
            self.__shard_mapping_1.shard_mapping_id,
            1001,
            self.__shard_id_2.shard_id
        )
        self.__range_sharding_specification_3 = RangeShardingSpecification.add(
            self.__shard_mapping_1.shard_mapping_id,
            2001,
            self.__shard_id_3.shard_id
        )

        self.__range_sharding_specification_4 = RangeShardingSpecification.add(
            self.__shard_mapping_2.shard_mapping_id,
            3001,
            self.__shard_id_4.shard_id
        )
        self.__range_sharding_specification_5 = RangeShardingSpecification.add(
            self.__shard_mapping_2.shard_mapping_id,
            4001,
            self.__shard_id_5.shard_id
        )

        self.__range_sharding_specification_6 = RangeShardingSpecification.add(
            self.__shard_mapping_3.shard_mapping_id,
            6001,
            self.__shard_id_6.shard_id
        )
        self.__range_sharding_specification_7 = RangeShardingSpecification.add(
            self.__shard_mapping_3.shard_mapping_id,
            7001,
            self.__shard_id_7.shard_id
        )

        self.__range_sharding_specification_8 = RangeShardingSpecification.add(
            self.__shard_mapping_4.shard_mapping_id,
            8001,
            self.__shard_id_8.shard_id
        )
        self.__range_sharding_specification_9 = RangeShardingSpecification.add(
            self.__shard_mapping_4.shard_mapping_id,
           10001,
            self.__shard_id_9.shard_id
        )

        self.__range_sharding_specification_10 = RangeShardingSpecification.add(
            self.__shard_mapping_5.shard_mapping_id,
            100,
            self.__shard_id_10.shard_id)
        self.__range_sharding_specification_11 = RangeShardingSpecification.add(
            self.__shard_mapping_5.shard_mapping_id,
            201,
            self.__shard_id_11.shard_id)

        READ_ONLY = MySQLServer.get_mode_idx(MySQLServer.READ_ONLY)
        READ_WRITE = MySQLServer.get_mode_idx(MySQLServer.READ_WRITE)

        SECONDARY = MySQLServer.get_status_idx(MySQLServer.SECONDARY)
        PRIMARY = MySQLServer.get_status_idx(MySQLServer.PRIMARY)

        self.__setofservers = [0, 0, 0,
            [[str(self.__server_1.uuid),
            'GROUPID1', self.__options_1_host,  self.__options_1_port,
            READ_ONLY, SECONDARY, 1.0],
            [str(self.__server_2.uuid),
            'GROUPID1', self.__options_2_host,  self.__options_2_port,
            READ_ONLY, SECONDARY, 1.0],
            [str(self.__server_3.uuid),
            'GROUPID2', self.__options_3_host,  self.__options_3_port,
            READ_WRITE, PRIMARY, 1.0],
            [str(self.__server_4.uuid),
            'GROUPID2', self.__options_4_host,  self.__options_4_port,
            READ_ONLY, SECONDARY, 1.0],
            [str(self.__server_5.uuid),
            'GROUPID3', self.__options_5_host,  self.__options_5_port,
            READ_WRITE, PRIMARY, 1.0],
            [str(self.__server_6.uuid),
            'GROUPID3', self.__options_6_host,  self.__options_6_port,
            READ_ONLY, SECONDARY, 1.0]]]

        self.__setofservers_1 = [0, 0, 0,
                [[str(self.__server_1.uuid),
                'GROUPID1', self.__options_1_host,  self.__options_1_port,
                READ_ONLY, SECONDARY, 1.0],
                [str(self.__server_2.uuid),
                'GROUPID1', self.__options_2_host,  self.__options_2_port,
                READ_ONLY, SECONDARY, 1.0]]]

        self.__setofservers_2 = [0, 0, 0,
                [[str(self.__server_1.uuid),
                'GROUPID1', self.__options_1_host,  self.__options_1_port,
                READ_ONLY, SECONDARY, 1.0],
                [str(self.__server_2.uuid),
                'GROUPID1', self.__options_2_host,  self.__options_2_port,
                READ_ONLY, SECONDARY, 1.0],
                [str(self.__server_3.uuid),
                'GROUPID2', self.__options_3_host,  self.__options_3_port,
                READ_WRITE, PRIMARY, 1.0],
                [str(self.__server_4.uuid),
                'GROUPID2', self.__options_4_host,  self.__options_4_port,
                READ_ONLY, SECONDARY, 1.0]]]

        self.__setofservers_3 = [0, 0, 0,
            [[str(self.__server_1.uuid),
            'GROUPID1', self.__options_1_host,  self.__options_1_port,
            READ_ONLY, SECONDARY, 1.0],
            [str(self.__server_2.uuid),
            'GROUPID1', self.__options_2_host,  self.__options_2_port,
            READ_ONLY, SECONDARY, 1.0],
            [str(self.__server_3.uuid),
            'GROUPID2', self.__options_3_host,  self.__options_3_port,
            READ_WRITE, PRIMARY, 1.0],
            [str(self.__server_4.uuid),
            'GROUPID2', self.__options_4_host,  self.__options_4_port,
            READ_ONLY, SECONDARY, 1.0],
            [str(self.__server_5.uuid),
            'GROUPID3', self.__options_5_host,  self.__options_5_port,
            READ_WRITE, PRIMARY, 1.0],
            [str(self.__server_6.uuid),
            'GROUPID3', self.__options_6_host,  self.__options_6_port,
            READ_ONLY, SECONDARY, 1.0]]]

        self.__setoftables = [0, 0, 0, [['db1', 't1', 'userID1', '1'],
                              ['db2', 't2', 'userID2', '2'],
                              ['db3', 't3', 'userID3', '3'],
                              ['db4', 't4', 'userID4', '4'],
                              ['prune_db', 'prune_table', 'userID', '5']]]
        self.__setoftables_1 = [0, 0, 0, [['db1', 't1', 'userID1', '1']]]
        self.__setoftables_2 = [0, 0, 0, [['db1', 't1', 'userID1', '1'],
                                 ['db2', 't2', 'userID2', '2']]]
        self.__setoftables_3 = [0, 0, 0, [['db1', 't1', 'userID1', '1'],
                                ['db2', 't2', 'userID2', '2'],
                                ['db3', 't3', 'userID3', '3']]]
        self.__setofshardmaps = [0, 0, 0, [['1', 'RANGE', 'GROUPID10'],
                                 ['2', 'RANGE', 'GROUPID11'],
                                 ['3', 'RANGE', 'GROUPID12'],
                                 ['4', 'RANGE', 'GROUPID13'],
                                 ['5', 'RANGE', 'GROUPID14']]]
        self.__setofshardmaps_1 = [0, 0, 0, [['1', 'RANGE', 'GROUPID10']]]
        self.__setofshardmaps_2 = [0, 0, 0, [['1', 'RANGE', 'GROUPID10'],
                                 ['2', 'RANGE', 'GROUPID11']]]
        self.__setofshardmaps_3 = [0, 0, 0, [['1', 'RANGE', 'GROUPID10'],
                                 ['2', 'RANGE', 'GROUPID11'],
                                 ['3', 'RANGE', 'GROUPID12']]]
        self.__setofshardindexes = [0, 0, 0, [['0', '1', '1', 'GROUPID1'],
                                    ['1001', '1', '2', 'GROUPID10'],
                                    ['3001', '2', '4', 'GROUPID4'],
                                    ['4001', '2', '5', 'GROUPID5'],
                                    ['6001', '3', '6', 'GROUPID6'],
                                    ['7001', '3', '7', 'GROUPID7'],
                                    ['8001', '4', '8', 'GROUPID8'],
                                    ['10001', '4', '9', 'GROUPID9'],
                                    ['100', '5', '10', 'GROUPID2'],
                                    ['201', '5', '11', 'GROUPID3']]]
        self.__setofshardindexes_1 = [0, 0, 0, [['0', '1', '1', 'GROUPID1'],
                                      ['1001', '1', '2', 'GROUPID10']]]
        self.__setofshardindexes_3 = [0, 0, 0, [['0', '1', '1', 'GROUPID1'],
                                      ['1001', '1', '2', 'GROUPID10'],
                                      ['3001', '2', '4', 'GROUPID4'],
                                      ['4001', '2', '5', 'GROUPID5'],
                                          ['6001', '3', '6', 'GROUPID6'],
                                          ['7001', '3', '7', 'GROUPID7']]]
        self.__setofshardindexes_5 = [0, 0, 0, [['0', '1', '1', 'GROUPID1'],
                                      ['1001', '1', '2', 'GROUPID10'],
                                      ['3001', '2', '4', 'GROUPID4'],
                                      ['4001', '2', '5', 'GROUPID5'],
                                      ['6001', '3', '6', 'GROUPID6'],
                                      ['7001', '3', '7', 'GROUPID7'],
                                      ['8001', '4', '8', 'GROUPID8'],
                                      ['10001', '4', '9', 'GROUPID9'],
                                      ['100', '5', '10', 'GROUPID2'],
                                      ['201', '5', '11', 'GROUPID3']]]
        self.__shardinginformation_1 = [0, 0, 0, [['db1', 't1', 'userID1', '0',
                                        '1', 'RANGE', 'GROUPID1', 'GROUPID10'],
                                        ['db1', 't1', 'userID1', '1001',
                                        '2', 'RANGE', 'GROUPID10', 'GROUPID10']]]
        self.__shardinginformation_2 = [0, 0, 0, [['db1', 't1', 'userID1', '0',
                                        '1', 'RANGE', 'GROUPID1', 'GROUPID10'],
                                        ['db1', 't1', 'userID1', '1001',
                                        '2', 'RANGE', 'GROUPID10', 'GROUPID10'],
                                        ['db2', 't2', 'userID2', '3001',
                                        '4', 'RANGE', 'GROUPID4', 'GROUPID11'],
                                        ['db2', 't2', 'userID2', '4001',
                                        '5', 'RANGE', 'GROUPID5', 'GROUPID11']]]
        self.__shardinginformation_3 = [0, 0, 0, [['db1', 't1', 'userID1', '0',
                                        '1', 'RANGE', 'GROUPID1', 'GROUPID10'],
                                        ['db1', 't1', 'userID1', '1001',
                                        '2', 'RANGE', 'GROUPID10', 'GROUPID10'],
                                        ['db2', 't2', 'userID2', '3001',
                                        '4','RANGE', 'GROUPID4', 'GROUPID11'],
                                        ['db2', 't2', 'userID2', '4001',
                                        '5', 'RANGE', 'GROUPID5', 'GROUPID11'],
                                        ['db3', 't3', 'userID3', '6001',
                                        '6', 'RANGE', 'GROUPID6', 'GROUPID12'],
                                        ['db3', 't3', 'userID3', '7001',
                                        '7', 'RANGE', 'GROUPID7', 'GROUPID12']]]
示例#16
0
    def setUp(self):
        """Configure the existing environment
        """
        self.manager, self.proxy = tests.utils.setup_xmlrpc()
        self.__options_1 = {
            "uuid": _uuid.UUID("{bb75b12b-98d1-414c-96af-9e9d4b179678}"),
            "address": "server_1.mysql.com:3060",
            "user": MySQLInstances().user,
            "passwd": MySQLInstances().passwd,
        }
        self.__server_1 = MySQLServer(**self.__options_1)
        MySQLServer.add(self.__server_1)
        self.__options_2 = {
            "uuid": _uuid.UUID("{aa75a12a-98d1-414c-96af-9e9d4b179678}"),
            "address": "server_2.mysql.com:3060",
            "user": MySQLInstances().user,
            "passwd": MySQLInstances().passwd,
        }
        self.__server_2 = MySQLServer(**self.__options_2)
        MySQLServer.add(self.__server_2)
        self.__group_1 = Group("GROUPID1", "First description.")
        Group.add(self.__group_1)
        self.__group_1.add_server(self.__server_1)
        self.__group_1.add_server(self.__server_2)

        self.__options_3 = {
            "uuid": _uuid.UUID("{cc75b12b-98d1-414c-96af-9e9d4b179678}"),
            "address": MySQLInstances().get_address(0),
            "user": MySQLInstances().user,
            "passwd": MySQLInstances().passwd,
        }
        uuid_server3 = MySQLServer.discover_uuid(self.__options_3["address"])
        self.__options_3["uuid"] = _uuid.UUID(uuid_server3)
        self.__server_3 = MySQLServer(**self.__options_3)
        MySQLServer.add(self.__server_3)

        self.__options_4 = {
            "uuid": _uuid.UUID("{dd75a12a-98d1-414c-96af-9e9d4b179678}"),
            "address": "server_4.mysql.com:3060",
            "user": MySQLInstances().user,
            "passwd": MySQLInstances().passwd,
        }
        self.__server_4 = MySQLServer(**self.__options_4)
        MySQLServer.add(self.__server_4)
        self.__group_2 = Group("GROUPID2", "Second description.")
        Group.add(self.__group_2)
        self.__group_2.add_server(self.__server_3)
        self.__group_2.add_server(self.__server_4)
        tests.utils.configure_decoupled_master(self.__group_2, self.__server_3)

        self.__options_5 = {
            "uuid": _uuid.UUID("{ee75b12b-98d1-414c-96af-9e9d4b179678}"),
            "address": MySQLInstances().get_address(2),
            "user": MySQLInstances().user,
            "passwd": MySQLInstances().passwd,
        }
        uuid_server5 = MySQLServer.discover_uuid(self.__options_5["address"])
        self.__options_5["uuid"] = _uuid.UUID(uuid_server5)
        self.__server_5 = MySQLServer(**self.__options_5)
        MySQLServer.add(self.__server_5)

        self.__options_6 = {
            "uuid": _uuid.UUID("{ff75a12a-98d1-414c-96af-9e9d4b179678}"),
            "address": "server_6.mysql.com:3060",
            "user": MySQLInstances().user,
            "passwd": MySQLInstances().passwd,
        }
        self.__server_6 = MySQLServer(**self.__options_6)
        MySQLServer.add(self.__server_6)
        self.__group_3 = Group("GROUPID3", "Third description.")
        Group.add(self.__group_3)
        self.__group_3.add_server(self.__server_5)
        self.__group_3.add_server(self.__server_6)
        tests.utils.configure_decoupled_master(self.__group_3, self.__server_5)

        self.__options_1_host,  self.__options_1_port = \
            server_utils.split_host_port(self.__options_1["address"], 13001)
        self.__options_2_host,  self.__options_2_port = \
            server_utils.split_host_port(self.__options_2["address"], 13001)
        self.__options_3_host,  self.__options_3_port = \
            server_utils.split_host_port(self.__options_3["address"], 13001)
        self.__options_4_host,  self.__options_4_port = \
            server_utils.split_host_port(self.__options_4["address"], 13001)
        self.__options_5_host,  self.__options_5_port = \
            server_utils.split_host_port(self.__options_5["address"], 13001)
        self.__options_6_host,  self.__options_6_port = \
            server_utils.split_host_port(self.__options_6["address"], 13001)

        group_4 = Group("GROUPID4", "4TH description.")
        Group.add(group_4)
        group_5 = Group("GROUPID5", "5TH description.")
        Group.add(group_5)
        group_6 = Group("GROUPID6", "6TH description.")
        Group.add(group_6)
        group_7 = Group("GROUPID7", "7TH description.")
        Group.add(group_7)
        group_8 = Group("GROUPID8", "8TH description.")
        Group.add(group_8)
        group_9 = Group("GROUPID9", "9TH description.")
        Group.add(group_9)
        group_10 = Group("GROUPID10", "10TH description.")
        Group.add(group_10)
        group_11 = Group("GROUPID11", "11TH description.")
        Group.add(group_11)
        group_12 = Group("GROUPID12", "12TH description.")
        Group.add(group_12)
        group_13 = Group("GROUPID13", "13TH description.")
        Group.add(group_13)
        group_14 = Group("GROUPID14", "14TH description.")
        Group.add(group_14)

        self.__shard_mapping_list = ShardMapping.list_shard_mapping_defn()
        self.assertEquals(self.__shard_mapping_list, [])
        self.__shard_mapping_id_1 = ShardMapping.define("RANGE", "GROUPID10")
        self.__shard_mapping_id_2 = ShardMapping.define("RANGE", "GROUPID11")
        self.__shard_mapping_id_3 = ShardMapping.define("RANGE", "GROUPID12")
        #Test with sharding type values in lower case
        self.__shard_mapping_id_4 = ShardMapping.define("range", "GROUPID13")
        self.__shard_mapping_id_5 = ShardMapping.define("range", "GROUPID14")

        self.__shard_mapping_1 = \
            ShardMapping.add(self.__shard_mapping_id_1, "db1.t1", "userID1")
        self.__shard_mapping_2 = \
            ShardMapping.add(self.__shard_mapping_id_2, "db2.t2", "userID2")
        self.__shard_mapping_3 = \
            ShardMapping.add(self.__shard_mapping_id_3, "db3.t3", "userID3")
        self.__shard_mapping_4 = \
            ShardMapping.add(self.__shard_mapping_id_4, "db4.t4", "userID4")

        self.__shard_mapping_5 = \
            ShardMapping.add(self.__shard_mapping_id_5, "prune_db.prune_table",
                             "userID")

        self.__shard_id_1 = Shards.add("GROUPID1", "ENABLED")
        self.__shard_id_2 = Shards.add("GROUPID10", "ENABLED")
        self.__shard_id_3 = Shards.add("GROUPID11", "DISABLED")
        self.__shard_id_4 = Shards.add("GROUPID4", "ENABLED")
        self.__shard_id_5 = Shards.add("GROUPID5", "ENABLED")
        self.__shard_id_6 = Shards.add("GROUPID6", "ENABLED")
        self.__shard_id_7 = Shards.add("GROUPID7", "ENABLED")
        self.__shard_id_8 = Shards.add("GROUPID8", "ENABLED")
        self.__shard_id_9 = Shards.add("GROUPID9", "ENABLED")
        self.__shard_id_10 = Shards.add("GROUPID2", "ENABLED")
        self.__shard_id_11 = Shards.add("GROUPID3", "ENABLED")

        self.__range_sharding_specification_1 = RangeShardingSpecification.add(
            self.__shard_mapping_1.shard_mapping_id, 0,
            self.__shard_id_1.shard_id)
        self.__range_sharding_specification_2 = RangeShardingSpecification.add(
            self.__shard_mapping_1.shard_mapping_id, 1001,
            self.__shard_id_2.shard_id)
        self.__range_sharding_specification_3 = RangeShardingSpecification.add(
            self.__shard_mapping_1.shard_mapping_id, 2001,
            self.__shard_id_3.shard_id)

        self.__range_sharding_specification_4 = RangeShardingSpecification.add(
            self.__shard_mapping_2.shard_mapping_id, 3001,
            self.__shard_id_4.shard_id)
        self.__range_sharding_specification_5 = RangeShardingSpecification.add(
            self.__shard_mapping_2.shard_mapping_id, 4001,
            self.__shard_id_5.shard_id)

        self.__range_sharding_specification_6 = RangeShardingSpecification.add(
            self.__shard_mapping_3.shard_mapping_id, 6001,
            self.__shard_id_6.shard_id)
        self.__range_sharding_specification_7 = RangeShardingSpecification.add(
            self.__shard_mapping_3.shard_mapping_id, 7001,
            self.__shard_id_7.shard_id)

        self.__range_sharding_specification_8 = RangeShardingSpecification.add(
            self.__shard_mapping_4.shard_mapping_id, 8001,
            self.__shard_id_8.shard_id)
        self.__range_sharding_specification_9 = RangeShardingSpecification.add(
            self.__shard_mapping_4.shard_mapping_id, 10001,
            self.__shard_id_9.shard_id)

        self.__range_sharding_specification_10 = RangeShardingSpecification.add(
            self.__shard_mapping_5.shard_mapping_id, 100,
            self.__shard_id_10.shard_id)
        self.__range_sharding_specification_11 = RangeShardingSpecification.add(
            self.__shard_mapping_5.shard_mapping_id, 201,
            self.__shard_id_11.shard_id)

        READ_ONLY = MySQLServer.get_mode_idx(MySQLServer.READ_ONLY)
        READ_WRITE = MySQLServer.get_mode_idx(MySQLServer.READ_WRITE)

        SECONDARY = MySQLServer.get_status_idx(MySQLServer.SECONDARY)
        PRIMARY = MySQLServer.get_status_idx(MySQLServer.PRIMARY)

        self.__setofservers = tests.utils.make_servers_result(
            [[
                str(self.__server_1.uuid), 'GROUPID1', self.__options_1_host,
                self.__options_1_port, READ_ONLY, SECONDARY, 1.0
            ],
             [
                 str(self.__server_2.uuid), 'GROUPID1', self.__options_2_host,
                 self.__options_2_port, READ_ONLY, SECONDARY, 1.0
             ],
             [
                 str(self.__server_3.uuid), 'GROUPID2', self.__options_3_host,
                 self.__options_3_port, READ_WRITE, PRIMARY, 1.0
             ],
             [
                 str(self.__server_4.uuid), 'GROUPID2', self.__options_4_host,
                 self.__options_4_port, READ_ONLY, SECONDARY, 1.0
             ],
             [
                 str(self.__server_5.uuid), 'GROUPID3', self.__options_5_host,
                 self.__options_5_port, READ_WRITE, PRIMARY, 1.0
             ],
             [
                 str(self.__server_6.uuid), 'GROUPID3', self.__options_6_host,
                 self.__options_6_port, READ_ONLY, SECONDARY, 1.0
             ]])

        self.__setofservers_1 = tests.utils.make_servers_result(
            [[
                str(self.__server_1.uuid), 'GROUPID1', self.__options_1_host,
                self.__options_1_port, READ_ONLY, SECONDARY, 1.0
            ],
             [
                 str(self.__server_2.uuid), 'GROUPID1', self.__options_2_host,
                 self.__options_2_port, READ_ONLY, SECONDARY, 1.0
             ]])

        self.__setofservers_2 = tests.utils.make_servers_result(
            [[
                str(self.__server_1.uuid), 'GROUPID1', self.__options_1_host,
                self.__options_1_port, READ_ONLY, SECONDARY, 1.0
            ],
             [
                 str(self.__server_2.uuid), 'GROUPID1', self.__options_2_host,
                 self.__options_2_port, READ_ONLY, SECONDARY, 1.0
             ],
             [
                 str(self.__server_3.uuid), 'GROUPID2', self.__options_3_host,
                 self.__options_3_port, READ_WRITE, PRIMARY, 1.0
             ],
             [
                 str(self.__server_4.uuid), 'GROUPID2', self.__options_4_host,
                 self.__options_4_port, READ_ONLY, SECONDARY, 1.0
             ]])

        self.__setofservers_3 = tests.utils.make_servers_result(
            [[
                str(self.__server_1.uuid), 'GROUPID1', self.__options_1_host,
                self.__options_1_port, READ_ONLY, SECONDARY, 1.0
            ],
             [
                 str(self.__server_2.uuid), 'GROUPID1', self.__options_2_host,
                 self.__options_2_port, READ_ONLY, SECONDARY, 1.0
             ],
             [
                 str(self.__server_3.uuid), 'GROUPID2', self.__options_3_host,
                 self.__options_3_port, READ_WRITE, PRIMARY, 1.0
             ],
             [
                 str(self.__server_4.uuid), 'GROUPID2', self.__options_4_host,
                 self.__options_4_port, READ_ONLY, SECONDARY, 1.0
             ],
             [
                 str(self.__server_5.uuid), 'GROUPID3', self.__options_5_host,
                 self.__options_5_port, READ_WRITE, PRIMARY, 1.0
             ],
             [
                 str(self.__server_6.uuid), 'GROUPID3', self.__options_6_host,
                 self.__options_6_port, READ_ONLY, SECONDARY, 1.0
             ]])

        self.__setoftables = tests.utils.make_tables_result(
            [['db1', 't1', 'userID1', '1'], ['db2', 't2', 'userID2', '2'],
             ['db3', 't3', 'userID3', '3'], ['db4', 't4', 'userID4', '4'],
             ['prune_db', 'prune_table', 'userID', '5']])
        self.__setoftables_1 = tests.utils.make_tables_result(
            [['db1', 't1', 'userID1', '1']])
        self.__setoftables_2 = tests.utils.make_tables_result(
            [['db1', 't1', 'userID1', '1'], ['db2', 't2', 'userID2', '2']])
        self.__setoftables_3 = tests.utils.make_tables_result(
            [['db1', 't1', 'userID1', '1'], ['db2', 't2', 'userID2', '2'],
             ['db3', 't3', 'userID3', '3']])
        self.__setofshardmaps = tests.utils.make_mapping_result(
            [['1', 'RANGE', 'GROUPID10'], ['2', 'RANGE', 'GROUPID11'],
             ['3', 'RANGE', 'GROUPID12'], ['4', 'RANGE', 'GROUPID13'],
             ['5', 'RANGE', 'GROUPID14']])
        self.__setofshardmaps_1 = tests.utils.make_mapping_result(
            [['1', 'RANGE', 'GROUPID10']])
        self.__setofshardmaps_2 = tests.utils.make_mapping_result(
            [['1', 'RANGE', 'GROUPID10'], ['2', 'RANGE', 'GROUPID11']])
        self.__setofshardmaps_3 = tests.utils.make_mapping_result(
            [['1', 'RANGE', 'GROUPID10'], ['2', 'RANGE', 'GROUPID11'],
             ['3', 'RANGE', 'GROUPID12']])
        self.__setofshardindexes = tests.utils.make_index_result(
            [['0', '1', '1', 'GROUPID1'], ['1001', '1', '2', 'GROUPID10'],
             ['3001', '2', '4', 'GROUPID4'], ['4001', '2', '5', 'GROUPID5'],
             ['6001', '3', '6', 'GROUPID6'], ['7001', '3', '7', 'GROUPID7'],
             ['8001', '4', '8', 'GROUPID8'], ['10001', '4', '9', 'GROUPID9'],
             ['100', '5', '10', 'GROUPID2'], ['201', '5', '11', 'GROUPID3']])
        self.__setofshardindexes_1 = tests.utils.make_index_result(
            [['0', '1', '1', 'GROUPID1'], ['1001', '1', '2', 'GROUPID10']])
        self.__setofshardindexes_3 = tests.utils.make_index_result(
            [['0', '1', '1', 'GROUPID1'], ['1001', '1', '2', 'GROUPID10'],
             ['3001', '2', '4', 'GROUPID4'], ['4001', '2', '5', 'GROUPID5'],
             ['6001', '3', '6', 'GROUPID6'], ['7001', '3', '7', 'GROUPID7']])
        self.__setofshardindexes_5 = tests.utils.make_index_result(
            [['0', '1', '1', 'GROUPID1'], ['1001', '1', '2', 'GROUPID10'],
             ['3001', '2', '4', 'GROUPID4'], ['4001', '2', '5', 'GROUPID5'],
             ['6001', '3', '6', 'GROUPID6'], ['7001', '3', '7', 'GROUPID7'],
             ['8001', '4', '8', 'GROUPID8'], ['10001', '4', '9', 'GROUPID9'],
             ['100', '5', '10', 'GROUPID2'], ['201', '5', '11', 'GROUPID3']])
        self.__shardinginformation_1 = tests.utils.make_info_result(
            [[
                'db1', 't1', 'userID1', '0', '1', 'RANGE', 'GROUPID1',
                'GROUPID10'
            ],
             [
                 'db1', 't1', 'userID1', '1001', '2', 'RANGE', 'GROUPID10',
                 'GROUPID10'
             ]])
        self.__shardinginformation_2 = tests.utils.make_info_result(
            [[
                'db1', 't1', 'userID1', '0', '1', 'RANGE', 'GROUPID1',
                'GROUPID10'
            ],
             [
                 'db1', 't1', 'userID1', '1001', '2', 'RANGE', 'GROUPID10',
                 'GROUPID10'
             ],
             [
                 'db2', 't2', 'userID2', '3001', '4', 'RANGE', 'GROUPID4',
                 'GROUPID11'
             ],
             [
                 'db2', 't2', 'userID2', '4001', '5', 'RANGE', 'GROUPID5',
                 'GROUPID11'
             ]])
        self.__shardinginformation_3 = tests.utils.make_info_result(
            [[
                'db1', 't1', 'userID1', '0', '1', 'RANGE', 'GROUPID1',
                'GROUPID10'
            ],
             [
                 'db1', 't1', 'userID1', '1001', '2', 'RANGE', 'GROUPID10',
                 'GROUPID10'
             ],
             [
                 'db2', 't2', 'userID2', '3001', '4', 'RANGE', 'GROUPID4',
                 'GROUPID11'
             ],
             [
                 'db2', 't2', 'userID2', '4001', '5', 'RANGE', 'GROUPID5',
                 'GROUPID11'
             ],
             [
                 'db3', 't3', 'userID3', '6001', '6', 'RANGE', 'GROUPID6',
                 'GROUPID12'
             ],
             [
                 'db3', 't3', 'userID3', '7001', '7', 'RANGE', 'GROUPID7',
                 'GROUPID12'
             ]])
示例#17
0
    def execute(self, group_id, destn_address, server_uuid=None,
                synchronous=True):
        """Clone the objects of a given server into a destination server.

        :param group_id: The ID of the source group.
        :param destn_address: The address of the MySQL Server to which
            the clone needs to happen.
        :param server_uuid: The UUID of the source MySQL Server.
        :param synchronous: Whether one should wait until the execution
                            finishes or not.
        """
        #If the destination server is already part of a Fabric Group, raise
        #an error
        if destn_address:
            destn_server_uuid = _server.MySQLServer.\
                discover_uuid(destn_address)
            destn_server = _server.MySQLServer.fetch(destn_server_uuid)
            #we should check for both the presence of the server object
            #and its associated group ID. Checking its association with
            #a group ID would verify that a server that is part of Fabric
            #but is not part of a group can also be cloned into.
            if destn_server and destn_server.group_id:
                raise _errors.ServerError("The Destination server is already "\
                    "part of Group (%s)" % (destn_server.group_id,))

        config_file = self.config.config_file if self.config.config_file else ""

        mysqldump_binary = _utils.read_config_value(
                                self.config,
                                'sharding',
                                'mysqldump_program'
                            )
        mysqlclient_binary = _utils.read_config_value(
                                self.config,
                                'sharding',
                                'mysqlclient_program'
                            )

        if not _utils.is_valid_binary(mysqldump_binary):
            raise _errors.ServerError(MYSQLDUMP_NOT_FOUND % mysqldump_binary)

        if not _utils.is_valid_binary(mysqlclient_binary):
            raise _errors.ServerError(MYSQLCLIENT_NOT_FOUND % mysqlclient_binary)

        if server_uuid:
            server = _server.MySQLServer.fetch(server_uuid)
            if group_id != server.group_id:
                raise _errors.ServerError("The server %s was not found in "\
                                          "group %s" % (server_uuid, group_id, ))
        elif not server_uuid:
            group = _server.Group.fetch(group_id)
            server = _utils.fetch_backup_server(group)
            server_uuid = str(server.uuid)

        host, port = _server_utils.split_host_port(
                                destn_address,
                                _backup.MySQLDump.MYSQL_DEFAULT_PORT
                            )

        procedures = _events.trigger(
            BACKUP_SERVER,
            self.get_lockable_objects(),
            server_uuid,
            host,
            port,
            mysqldump_binary,
            mysqlclient_binary,
            config_file
        )
        return self.wait_for_procedures(procedures, synchronous)
示例#18
0
    def backup(server, backup_user, backup_passwd, mysqldump_binary):
        """Perform the backup using mysqldump.

        The backup results in creation a .sql file on the FABRIC server,
        this method needs to be optimized going forward. But for now
        this will suffice.

        :param server: The MySQLServer that needs to be backed up.
        :param backup_user: The user name used for accessing the server.
        :param backup_passwd: The password used for accessing the server.
        :param mysqldump_binary: The fully qualified mysqldump binary.
        """
        assert isinstance(server, MySQLServer)

        #Extract the host and the port from the server address.
        host = None
        port = None
        if server.address is not None:
            host, port = split_host_port(server.address)

        #Form the name of the destination .sql file from the name of the
        #server host and the port number that is being backed up.
        destination = "MySQL_{HOST}_{PORT}.sql".format(
                                                    HOST=host,
                                                    PORT=port)

        command = shlex.split(mysqldump_binary)

        #Setup the mysqldump command that is used to backup the server.
        command.extend([
            # A --no-defaults or --defaults-file option is inserted by
            # run_mysql_client().
            "--all-databases",
            "--single-transaction",
            "--add-drop-table",
            "--triggers",
            "--routines",
            "--events",
            "--protocol=tcp",
            "-h" + str(host),
            "-P" + str(port),
            "-u" + str(backup_user)
            # A -p is appended by run_mysql_client(), if required.
        ])

        #Run the backup command
        with open(destination, "w") as fd_file:
            returncode, error_lines = run_mysql_client(command, backup_passwd,
                                                       outstream=fd_file)
            if returncode:
                MySQLDump.dump_to_log(
                    "Error while taking backup using " + command[0],
                    error_lines
                )
                raise _errors.BackupError(
                    "Error while taking backup using " + command[0],
                    error_lines
                )

        #Return the backup image containing the location of the .sql file.
        return BackupImage(destination)