trove 코드의 주종 전환 yuan'dai'm 소스 코드 분석

openstack trove 코드의 주종전환promote slave to master의 소스 코드 분석:
    def promote_to_replica_source(self, context, instance_id):
        # TODO(atomic77) Promote and eject need to be able to handle the case
        # where a datastore like Postgresql needs to treat the slave to be
        # promoted differently from the old master and the slaves which will
        # be simply reassigned to a new master. See:
        # https://bugs.launchpad.net/trove/+bug/1553339

        def _promote_to_replica_source(old_master, master_candidate,
                                       replica_models):
            # First, we transition from the old master to new as quickly as
            # possible to minimize the scope of unrecoverable error

            # NOTE(zhaochao): we cannot reattach the old master to the new
            # one immediately after the new master is up, because for MariaDB
            # the other replicas are still connecting to the old master, and
            # during reattaching the old master as a slave, new GTID may be
            # created and synced to the replicas. After that, when attaching
            # the replicas to the new master, 'START SLAVE' will fail by
            # 'fatal error 1236' if the binlog of the replica diverged from
            # the new master. So the proper order should be:
            # -1. make the old master read only (and detach floating ips)
            # -2. make sure the new master is up-to-date
            # -3. detach the new master from the old one
            # -4. enable the new master (and attach floating ips)
            # -5. attach the other replicas to the new master
            # -6. attach the old master to the new one
            #     (and attach floating ips)
            # -7. demote the old master
            # What we changed here is the order of the 6th step, previously
            # this step took place right after step 4, which causes failures
            # with MariaDB replications.
            old_master.make_read_only(True)
            latest_txn_id = old_master.get_latest_txn_id()
            master_candidate.wait_for_txn(latest_txn_id)
            master_candidate.detach_replica(old_master, for_failover=True)
            master_candidate.enable_as_master()
            master_candidate.make_read_only(False)

            # At this point, should something go wrong, there
            # should be a working master with some number of working slaves,
            # and possibly some number of "orphaned" slaves

            exception_replicas = []
            error_messages = ""
            for replica in replica_models:
                try:
                    if replica.id != master_candidate.id:
                        replica.detach_replica(old_master, for_failover=True)
                        replica.attach_replica(master_candidate)
                except exception.TroveError as ex:
                    log_fmt = ("Unable to migrate replica %(slave)s from "
                               "old replica source %(old_master)s to "
                               "new source %(new_master)s on promote.")
                    exc_fmt = _("Unable to migrate replica %(slave)s from "
                                "old replica source %(old_master)s to "
                                "new source %(new_master)s on promote.")
                    msg_content = {
                        "slave": replica.id,
                        "old_master": old_master.id,
                        "new_master": master_candidate.id}
                    LOG.error(log_fmt, msg_content)

                    exception_replicas.append(replica)
                    error_messages += "%s (%s)
" % ( exc_fmt % msg_content, ex) # dealing with the old master after all the other replicas # has been migrated. old_master.attach_replica(master_candidate) try: old_master.demote_replication_master() except Exception as ex: log_fmt = "Exception demoting old replica source %s." exc_fmt = _("Exception demoting old replica source %s.") LOG.error(log_fmt, old_master.id) exception_replicas.append(old_master) error_messages += "%s (%s)
" % ( exc_fmt % old_master.id, ex) self._set_task_status([old_master] + replica_models, InstanceTasks.NONE) if exception_replicas: self._set_task_status(exception_replicas, InstanceTasks.PROMOTION_ERROR) msg = (_("promote-to-replica-source %(id)s: The following " "replicas may not have been switched: %(replicas)s:" "
%(err)s") % {"id": master_candidate.id, "replicas": [repl.id for repl in exception_replicas], "err": error_messages}) raise ReplicationSlaveAttachError(msg) LOG.info('Finished to promote %s as master.', instance_id) with EndNotification(context): LOG.info('Promoting %s as replication master', instance_id) master_candidate = BuiltInstanceTasks.load(context, instance_id) old_master = BuiltInstanceTasks.load(context, master_candidate.slave_of_id) replicas = [] for replica_dbinfo in old_master.slaves: if replica_dbinfo.id == instance_id: replica = master_candidate else: replica = BuiltInstanceTasks.load(context, replica_dbinfo.id) replicas.append(replica) try: _promote_to_replica_source(old_master, master_candidate, replicas) except ReplicationSlaveAttachError: raise except Exception: self._set_task_status([old_master] + replicas, InstanceTasks.PROMOTION_ERROR) raise

전환 절차는 다음과 같다. 주종 전환이 적합하다. 주종 다종의 구조이고 플로팅 이 귀속되어 있다.ip의 상황.
  • 전환할 슬레이브에 따라id 실례를 새maste로 가져오기;
  • 모든 슬레이브를 현재의 새로운 마스터로서의 슬레이브id, Replicas 목록에 추가
  • 낡은 마스터id 오래된 마스터 실례 가져오기 다음 정식 전환 단계 시작:promote_to_replica_source(old master,master candidate,replicas) 주의: 다음에 말한 공중망 IP는floating ip
  • 를 가리킨다.
  • 오래된 maste 실례를 읽기 전용으로 설정
  • 구 마스터 실례detach 공중망 ip
  • 새로운 마스터 실례detach 공중망 ip
  • 옛 마스터의 동기화 위치 가져오기
  • 새 마스터 실례가 같은 위치로 동기화될 때까지 기다립니다
  • 신구 마스터 실례의 주종 관계 해제
  • 새 마스터 실례를 마스터 실례로 사용합니다.
  • 새로운 maste 실례attache 공중망 IP
  • 새 마스터 설정readonly는 flase(예: mysql: set 글로벌 read)only = False는 slave 실례를 가져옵니다. 만약 slave 실례의 id가 새로운 maste 실례의 id와 같지 않다면.구maste 해제 주종 관계attache 구의slave에서 새로운maste 실례로 구의maste 실례와 새로운maste 실례 구축 주종 관계구의maste 실례에 공망 ip
  • 추가

    좋은 웹페이지 즐겨찾기