OceanBase中RootServer分析

最近抽时间阅读一下OceanBase的源码,就从RootServer开始吧。

OceanBase的RootServer(以下简称Root)的主要功能有集群管理、数据分布以及副本管理。

今天集中研究集群管理:

1、每个集群内部同一时刻只允许有一台UpdateServer(以下简称Update)对外提供写服务,Root通过租约机制选择唯一的主Update,看一看这部分的源码。

    //OceanBase中UpdateServer数据结构
    struct ObUps
    {
      common::ObServer addr_;
      int32_t inner_port_;
      ObUpsStatus stat_;
      common::ObiRole obi_role_;
      int64_t log_seq_num_;
      int64_t lease_;
      int32_t ms_read_percentage_;
      int32_t cs_read_percentage_;
      bool did_renew_received_;
      ObUps()
        :inner_port_(0), stat_(UPS_STAT_OFFLINE),
         log_seq_num_(0), lease_(0),
         ms_read_percentage_(0), cs_read_percentage_(0),
         did_renew_received_(false)
      {
      }
      void reset();
      void convert_to(common::ObUpsInfo &ups_info) const;
    };

 

//选择Master部分
int ObUpsManager::select_ups_master_with_highest_lsn()
{
  int ret = OB_ERROR;
  if (-1 != ups_master_idx_)
  {
    TBSYS_LOG(WARN, "cannot select master when there is already one");
    ret = OB_UPS_MASTER_EXISTS;
  }
  else
  {
    int64_t highest_lsn = -1;
    int master_idx = -1;
    for (int32_t i = 0; i < MAX_UPS_COUNT; ++i)
    {
      if (UPS_STAT_OFFLINE != ups_array_[i].stat_)
      {
		//取log_seq_num_最大的作为Master
        if (ups_array_[i].log_seq_num_ > highest_lsn)
        {
          highest_lsn = ups_array_[i].log_seq_num_;
          master_idx = i;
        }
      }
    } // end for
    if (-1 == master_idx)
    {
      TBSYS_LOG(WARN, "no master selected");
    }
    else
    {
      change_ups_stat(master_idx, UPS_STAT_MASTER);
      ups_master_idx_ = master_idx;
      TBSYS_LOG(INFO, "new ups master selected, master=%s lsn=%ld",
          ups_array_[ups_master_idx_].addr_.to_cstring(),
          ups_array_[ups_master_idx_].log_seq_num_);
      ObUps ups(ups_array_[ups_master_idx_]);
      refresh_inner_table(ROLE_CHANGE, ups, "null");
      reset_ups_read_percent();
      ret = OB_SUCCESS;
    }
  }
  return ret;
}
//生成租约部分代码
int ObUpsManager::grant_lease(bool did_force /*=false*/)
{
  int ret = OB_SUCCESS;
  //对UpdateServer列表加锁保护
  tbsys::CThreadGuard guard(&ups_array_mutex_);
  ObServer master;
  if (has_master())
  {
    master = ups_array_[ups_master_idx_].addr_;
  }
  int64_t now = tbsys::CTimeUtil::getTime();
  for (int32_t i = 0; i < MAX_UPS_COUNT; ++i)
  {
    if (UPS_STAT_OFFLINE != ups_array_[i].stat_)
    {
      //当快到租约到期时间或者强制更新租约的时候(重新选择出Master之后需要强制更新租约)
      if (need_grant(now, ups_array_[i]) || did_force)
      {
        ups_array_[i].did_renew_received_ = false;
        //租约到期时间变成当前时间加上租约持续时间
        ups_array_[i].lease_ = now + lease_duration_us_;
        
        //生成新的心跳包消息
        ObMsgUpsHeartbeat msg;
        msg.ups_master_ = master;
        msg.self_lease_ = ups_array_[i].lease_;
        msg.obi_role_ = obi_role_;
        msg.schema_version_ = schema_version_;
        msg.config_version_ = config_version_;
        //向所有的UpdateServer发送心跳包消息
        //此处涉及到rpc调用,源码在ob_root_rpc_stub.cpp中
        int ret2 = send_granting_msg(ups_array_[i].addr_, msg);
        if (OB_SUCCESS != ret2)
        {
          TBSYS_LOG(WARN, "grant lease to ups error, err=%d ups=%s",
                    ret2, ups_array_[i].addr_.to_cstring());
          // don't remove the ups right now
        }
      }
      else
      {
        TBSYS_LOG(DEBUG, "did_renew_received=%c ups=%s", ups_array_[i].did_renew_received_?'Y':'N',
                  ups_array_[i].addr_.to_cstring());
      }
    }
  }
  return ret;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值