提交 0fda7c08 编写于 作者: O obdev 提交者: OB-robot

[CP] fix tenant timezone mgr bug

上级 39c3a048
......@@ -32,7 +32,7 @@ namespace oceanbase {
namespace common {
int check_and_get_tz_info(ObTime &ob_time, const ObTimeConvertCtx &cvrt_ctx, const ObTimeZoneInfo *&tz_info,
ObTimeZoneInfoPos *&literal_tz_info, ObTZInfoIDPosMap *&tz_id_pos_map);
ObTimeZoneInfoPos &literal_tz_info);
ObTimeConverter::ObTimeConverter()
{}
......@@ -680,12 +680,11 @@ int ObTimeConverter::calc_tz_offset_by_tz_name(const ObTimeConvertCtx &cvrt_ctx,
int ret = OB_SUCCESS;
int64_t usec = ob_time.parts_[DT_DATE] * USECS_PER_DAY + ob_time_to_time(ob_time);
const ObTimeZoneInfo *tz_info = NULL;
ObTimeZoneInfoPos *literal_tz_info = NULL;
ObTZInfoIDPosMap *tz_id_pos_map = NULL;
ObTimeZoneInfoPos literal_tz_info;
int32_t tz_id = OB_INVALID_INDEX;
int32_t tran_type_id = OB_INVALID_INDEX;
int32_t offset_min = 0;
if (OB_FAIL(check_and_get_tz_info(ob_time, cvrt_ctx, tz_info, literal_tz_info, tz_id_pos_map))) {
if (OB_FAIL(check_and_get_tz_info(ob_time, cvrt_ctx, tz_info, literal_tz_info))) {
LOG_WARN("fail to check time zone info", K(ob_time));
} else if (OB_ISNULL(tz_info)) {
ret = OB_ERR_UNEXPECTED;
......@@ -699,11 +698,6 @@ int ObTimeConverter::calc_tz_offset_by_tz_name(const ObTimeConvertCtx &cvrt_ctx,
ob_time.transition_type_id_ = tran_type_id;
}
if (NULL != literal_tz_info && NULL != tz_id_pos_map) {
tz_id_pos_map->revert(literal_tz_info);
tz_id_pos_map = NULL;
literal_tz_info = NULL;
}
return ret;
}
......@@ -1237,7 +1231,7 @@ int ObTimeConverter::extract_offset_from_otimestamp(
int ret = OB_SUCCESS;
if (in_value.time_ctx_.store_tz_id_) {
ObTZInfoMap *tz_info_map = NULL;
ObTimeZoneInfoPos *literal_tz_info = NULL;
ObTimeZoneInfoPos literal_tz_info;
ObString tz_name_str;
ObString tz_abbr_str;
int32_t offset_sec = 0;
......@@ -1250,11 +1244,10 @@ int ObTimeConverter::extract_offset_from_otimestamp(
} else if (OB_FAIL(tz_info_map->get_tz_info_by_id(in_value.time_ctx_.tz_id_, literal_tz_info))) {
LOG_WARN("fail to get_tz_info_by_id", "tz_id", in_value.time_ctx_.tz_id_, K(ret));
ret = OB_ERR_INVALID_TIMEZONE_REGION_ID;
} else if (OB_FAIL(
literal_tz_info->get_timezone_offset(in_value.time_ctx_.tran_type_id_, tz_abbr_str, offset_sec))) {
} else if (OB_FAIL(literal_tz_info.get_timezone_offset(in_value.time_ctx_.tran_type_id_, tz_abbr_str, offset_sec))) {
LOG_WARN("fail to get_timezone_offset", K(in_value), K(ret));
ret = OB_ERR_INVALID_TIMEZONE_REGION_ID;
} else if (OB_FAIL(literal_tz_info->get_tz_name(tz_name_str))) {
} else if (OB_FAIL(literal_tz_info.get_tz_name(tz_name_str))) {
LOG_WARN("fail to get_tz_name", K(tz_name_str), K(ret));
} else if (OB_FAIL(ob_time.set_tz_name(tz_name_str))) {
LOG_WARN("fail to set_tz_name", K(tz_name_str), K(ret));
......@@ -1268,9 +1261,6 @@ int ObTimeConverter::extract_offset_from_otimestamp(
}
LOG_DEBUG("extract_offset_from_otimestamp", K(ob_time), K(offset_min), K(offset_sec), K(ret));
if (NULL != tz_info_map && NULL != literal_tz_info) {
tz_info_map->free_tz_info_pos(literal_tz_info);
}
} else {
offset_min = in_value.time_ctx_.get_offset_min();
ob_time.parts_[DT_OFFSET_MIN] = offset_min;
......@@ -4842,8 +4832,10 @@ int ObTimeConverter::ob_time_to_str_format(
return ret;
}
int check_and_get_tz_info(ObTime &ob_time, const ObTimeConvertCtx &cvrt_ctx, const ObTimeZoneInfo *&tz_info,
ObTimeZoneInfoPos *&literal_tz_info, ObTZInfoIDPosMap *&tz_id_pos_map)
int check_and_get_tz_info(ObTime &ob_time,
const ObTimeConvertCtx &cvrt_ctx,
const ObTimeZoneInfo *&tz_info,
ObTimeZoneInfoPos &literal_tz_info)
{
int ret = OB_SUCCESS;
ObTZInfoMap *tz_info_map = NULL;
......@@ -4859,12 +4851,9 @@ int check_and_get_tz_info(ObTime &ob_time, const ObTimeConvertCtx &cvrt_ctx, con
LOG_WARN("tz_info_map is NULL", K(ret));
} else if (OB_FAIL(tz_info_map->get_tz_info_by_name(ob_time.get_tz_name_str(), literal_tz_info))) {
LOG_WARN("fail to get_tz_info_by_name", K(ob_time), K(ret));
tz_info_map->id_map_.revert(literal_tz_info);
literal_tz_info = NULL;
} else {
literal_tz_info->set_error_on_overlap_time(cvrt_ctx.tz_info_->is_error_on_overlap_time());
tz_info = literal_tz_info;
tz_id_pos_map = &(tz_info_map->id_map_);
literal_tz_info.set_error_on_overlap_time(cvrt_ctx.tz_info_->is_error_on_overlap_time());
tz_info = &literal_tz_info;
}
} else { // use session tz_info
tz_info = cvrt_ctx.tz_info_;
......@@ -4882,25 +4871,18 @@ int ObTimeConverter::ob_time_to_datetime(ObTime &ob_time, const ObTimeConvertCtx
// so we don't handle leap second and shift things, delete all related codes.
int64_t usec = ob_time.parts_[DT_DATE] * USECS_PER_DAY + ob_time_to_time(ob_time);
const ObTimeZoneInfo *tz_info = NULL;
ObTimeZoneInfoPos *literal_tz_info = NULL;
ObTZInfoIDPosMap *tz_id_pos_map = NULL;
ObTimeZoneInfoPos literal_tz_info;
if (usec > DATETIME_MAX_VAL || usec < DATETIME_MIN_VAL) {
ret = OB_DATETIME_FUNCTION_OVERFLOW;
LOG_WARN("datetime filed overflow", K(ret), K(usec));
} else {
value = usec;
if (OB_FAIL(check_and_get_tz_info(ob_time, cvrt_ctx, tz_info, literal_tz_info, tz_id_pos_map))) {
if (OB_FAIL(check_and_get_tz_info(ob_time, cvrt_ctx, tz_info, literal_tz_info))) {
LOG_WARN("fail to check_and_get_tz_info", K(ob_time), K(ret));
} else if (OB_FAIL(sub_timezone_offset(tz_info, cvrt_ctx.is_timestamp_, ob_time.get_tzd_abbr_str(), value))) {
LOG_WARN("failed to adjust value with time zone offset", K(ret));
}
}
if (NULL != literal_tz_info && NULL != tz_id_pos_map) {
tz_id_pos_map->revert(literal_tz_info);
tz_id_pos_map = NULL;
literal_tz_info = NULL;
}
}
return ret;
}
......
......@@ -39065,23 +39065,10 @@ uint64_t ObTZNameKey::hash(uint64_t seed) const
void ObTZMapWrap::set_tz_map(const common::ObTZInfoMap* timezone_info_map)
{
if (OB_NOT_NULL(tz_info_map_)) {
tz_info_map_->dec_ref_count();
}
ObTZInfoMap* non_const_tz_map = const_cast<ObTZInfoMap*>(timezone_info_map);
if (!OB_ISNULL(timezone_info_map)) {
non_const_tz_map->inc_ref_count();
}
tz_info_map_ = non_const_tz_map;
}
ObTZMapWrap::~ObTZMapWrap()
{
if (!OB_ISNULL(tz_info_map_)) {
tz_info_map_->dec_ref_count();
}
}
// just for unittest
int ObTimeZoneInfo::set_timezone(const ObString& str)
{
......@@ -39785,6 +39772,12 @@ int ObTZInfoMap::reset()
return ret;
}
void ObTZInfoMap::destroy()
{
id_map_.destroy();
name_map_.destroy();
}
static bool print_tz_info(ObTZIDKey& key, ObTimeZoneInfoPos* tz_info)
{
int ret = OB_SUCCESS;
......@@ -39807,7 +39800,49 @@ int ObTZInfoMap::print_tz_info_map()
return ret;
}
int ObTZInfoMap::get_tz_info_by_id(const int64_t tz_id, ObTimeZoneInfoPos*& tz_info_by_id)
int ObTZInfoMap::get_tz_info_by_id(const int64_t tz_id, ObTimeZoneInfoPos &tz_info_by_id)
{
int ret = OB_SUCCESS;
ObTimeZoneInfoPos *tmp_tz_info = NULL;
if (OB_FAIL(id_map_.get(tz_id, tmp_tz_info))) {
LOG_WARN("fail to get tz_info_by_id, should not happened", K(tz_id), K(ret));
} else if (OB_FAIL(tz_info_by_id.assign(*tmp_tz_info))) {
LOG_WARN("assign time zone info pos failed", K(ret));
} else {
LOG_DEBUG("succ to get tz_info_by_id", K(tz_id), KPC(tmp_tz_info), K(ret));
}
if (NULL != tmp_tz_info) {
id_map_.revert(tmp_tz_info);
}
return ret;
}
int ObTZInfoMap::get_tz_info_by_name(const ObString &tz_name, ObTimeZoneInfoPos &tz_info_by_name)
{
int ret = OB_SUCCESS;
ObTZNameIDInfo *name_id_info = NULL;
if (OB_FAIL(name_map_.get(ObTZNameKey(tz_name), name_id_info))) {
LOG_WARN("fail to get get_tz_info_by_name", K(tz_name), K(ret));
} else if (OB_FAIL(get_tz_info_by_id(name_id_info->tz_id_, tz_info_by_name))) {
LOG_WARN("fail to get get_tz_info_by_name", KPC(name_id_info), K(ret));
} else {
LOG_DEBUG("succ to get get_tz_info_by_name", K(tz_name), KPC(name_id_info), K(tz_info_by_name), K(ret));
}
if (OB_ENTRY_NOT_EXIST == ret) {
ret = OB_ERR_UNKNOWN_TIME_ZONE;
}
if (NULL != name_id_info) {
name_map_.revert(name_id_info);
name_id_info = NULL;
}
return ret;
}
// get value pointer of id_map_, only used for updating ObTimeZoneInfoPos by ObTimeZoneInfoManager.
int ObTZInfoMap::get_tz_info_by_id(const int64_t tz_id, ObTimeZoneInfoPos *&tz_info_by_id)
{
int ret = OB_SUCCESS;
if (OB_NOT_NULL(tz_info_by_id)) {
......@@ -39815,16 +39850,14 @@ int ObTZInfoMap::get_tz_info_by_id(const int64_t tz_id, ObTimeZoneInfoPos*& tz_i
LOG_WARN("tz_info_by_id should be null here", K(ret));
} else if (OB_FAIL(id_map_.get(tz_id, tz_info_by_id))) {
LOG_WARN("fail to get tz_info_by_id, should not happened", K(tz_id), K(ret));
} else {
LOG_DEBUG("succ to get tz_info_by_id", K(tz_id), KPC(tz_info_by_id), K(ret));
}
return ret;
}
int ObTZInfoMap::get_tz_info_by_name(const ObString& tz_name, ObTimeZoneInfoPos*& tz_info_by_name)
int ObTZInfoMap::get_tz_info_by_name(const ObString &tz_name, ObTimeZoneInfoPos *&tz_info_by_name)
{
int ret = OB_SUCCESS;
ObTZNameIDInfo* name_id_info = NULL;
ObTZNameIDInfo *name_id_info = NULL;
if (OB_NOT_NULL(tz_info_by_name)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("v should be null here", K(ret));
......@@ -39832,14 +39865,10 @@ int ObTZInfoMap::get_tz_info_by_name(const ObString& tz_name, ObTimeZoneInfoPos*
LOG_WARN("fail to get get_tz_info_by_name", K(tz_name), K(ret));
} else if (OB_FAIL(get_tz_info_by_id(name_id_info->tz_id_, tz_info_by_name))) {
LOG_WARN("fail to get get_tz_info_by_name", KPC(name_id_info), K(ret));
} else {
LOG_DEBUG("succ to get get_tz_info_by_name", K(tz_name), KPC(name_id_info), KPC(tz_info_by_name), K(ret));
}
if (OB_ENTRY_NOT_EXIST == ret) {
ret = OB_ERR_UNKNOWN_TIME_ZONE;
}
if (NULL != name_id_info) {
name_map_.revert(name_id_info);
name_id_info = NULL;
......@@ -39848,7 +39877,7 @@ int ObTZInfoMap::get_tz_info_by_name(const ObString& tz_name, ObTimeZoneInfoPos*
return ret;
}
void ObTimeZoneInfoWrap::set_tz_info_map(const ObTZInfoMap* tz_info_map)
void ObTimeZoneInfoWrap::set_tz_info_map(const ObTZInfoMap *tz_info_map)
{
tz_info_pos_.set_tz_info_map(tz_info_map);
tz_info_offset_.set_tz_info_map(tz_info_map);
......@@ -39889,18 +39918,8 @@ int ObTimeZoneInfoWrap::init_time_zone(const ObString& str_val, const int64_t cu
ObString tz_name(no_sp_len, str_val.ptr());
tz_name = tz_name.trim();
ObTimeZoneInfoPos* tmp_tz_info = NULL;
if (OB_FAIL(tz_info_map.get_tz_info_by_name(tz_name, tmp_tz_info))) {
if (OB_FAIL(tz_info_map.get_tz_info_by_name(tz_name, tz_info_pos_))) {
LOG_WARN("fail to get time zone info", K(tz_name), K(ret));
} else if (OB_ISNULL(tmp_tz_info)) {
ret = OB_ERR_NULL_VALUE;
LOG_WARN("tmp_tz_info is null", K(tz_name), K(ret));
} else if (OB_FAIL(tz_info_pos_.assign(*tmp_tz_info))) {
LOG_WARN("fail to assign time zone info", KPC(tmp_tz_info), K(ret));
}
if (NULL != tmp_tz_info) {
tz_info_map.free_tz_info_pos(tmp_tz_info);
}
if (OB_ENTRY_NOT_EXIST == ret) {
......@@ -237,7 +237,8 @@ class ObTZMapWrap {
public:
ObTZMapWrap() : tz_info_map_(nullptr)
{}
~ObTZMapWrap();
~ObTZMapWrap()
{}
const ObTZInfoMap* get_tz_map() const
{
return tz_info_map_;
......@@ -691,37 +692,20 @@ typedef common::ObLinkHashMap<ObTZNameKey, ObTZNameIDInfo, ObTZNameIDAlloc> ObTZ
class ObTZInfoMap {
public:
ObTZInfoMap() : inited_(false), id_map_(), name_map_(), ref_count_(0)
ObTZInfoMap() : inited_(false), id_map_(), name_map_()
{}
~ObTZInfoMap()
{}
int init(const lib::ObLabel& label);
int reset();
void destroy();
int print_tz_info_map();
bool is_inited()
{
return inited_;
}
int get_tz_info_by_id(const int64_t tz_id, ObTimeZoneInfoPos*& tz_info_by_id);
int get_tz_info_by_name(const common::ObString& tz_name, ObTimeZoneInfoPos*& tz_info_by_name);
void free_tz_info_pos(ObTimeZoneInfoPos*& tz_info)
{
id_map_.revert(tz_info);
tz_info = NULL;
}
void inc_ref_count()
{
ATOMIC_INC(&ref_count_);
}
void dec_ref_count()
{
ATOMIC_DEC(&ref_count_);
}
int64_t get_ref_count()
{
return ATOMIC_LOAD64(&ref_count_);
}
bool is_inited() { return inited_; }
int get_tz_info_by_id(const int64_t tz_id, ObTimeZoneInfoPos &tz_info_by_id);
int get_tz_info_by_name(const common::ObString &tz_name, ObTimeZoneInfoPos &tz_info_by_name);
int get_tz_info_by_id(const int64_t tz_id, ObTimeZoneInfoPos *&tz_info_by_id);
int get_tz_info_by_name(const common::ObString &tz_name, ObTimeZoneInfoPos *&tz_info_by_name);
void free_tz_info_pos(ObTimeZoneInfoPos *&tz_info) { id_map_.revert(tz_info); tz_info = NULL; }
public:
bool inited_;
ObTZInfoIDPosMap id_map_;
......@@ -729,7 +713,6 @@ public:
private:
DISALLOW_COPY_AND_ASSIGN(ObTZInfoMap);
int64_t ref_count_;
};
class ObTimeZoneInfoWrap {
......
......@@ -32,89 +32,42 @@ ObTenantTimezone::ObTenantTimezone() : tenant_id_(OB_INVALID_TENANT_ID)
{}
ObTenantTimezone::ObTenantTimezone(uint64_t tenant_id)
: is_inited_(false),
tenant_id_(tenant_id),
tenant_tz_mgr_(nullptr),
update_tz_task_(),
tz_info_mgr_(nullptr),
tz_info_map_(nullptr),
ref_count_(0),
update_task_not_exist_(false)
{}
: is_inited_(false), tenant_id_(tenant_id), tenant_tz_mgr_(nullptr),
tz_info_mgr_(nullptr), tz_info_map_(nullptr), update_task_not_exist_(false)
{
}
ObTenantTimezone::~ObTenantTimezone()
{
if (is_inited_) {
ob_delete(tz_info_map_);
ob_delete(tz_info_mgr_);
}
}
int ObTenantTimezone::init(ObTenantTimezoneMgr* tz_mgr)
{
int ret = OB_SUCCESS;
tenant_tz_mgr_ = tz_mgr;
if (OB_FAIL(update_tz_task_.init(tz_mgr, this))) {
LOG_ERROR("init tenant time zone updata task failed", K_(tenant_id), K(ret));
is_inited_ = true;
tz_info_map_ = OB_NEW(ObTZInfoMap, "TZInfoMap");
tz_info_mgr_ = OB_NEW(ObTimeZoneInfoManager, "TZInfoMgr", OBSERVER.get_common_rpc_proxy(),
OBSERVER.get_mysql_proxy(), OBSERVER.get_root_service(),
*tz_info_map_, tenant_id_);
if (OB_ISNULL(tz_info_map_) || OB_ISNULL(tz_info_mgr_)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("fail to allocate mem for tz_info", K(ret), K(tz_info_map_), K(tz_info_mgr_));
} else if (OB_FAIL(tz_info_map_->init("TZInfoMap"))) {
LOG_WARN("fail to init tz_info_map_", K(ret));
} else if (OB_FAIL(tz_info_mgr_->init())) {
LOG_WARN("fail to init tz_info_mgr_", K(ret));
} else {
is_inited_ = true;
tz_info_map_ = OB_NEW(ObTZInfoMap, ObModIds::OMT);
tz_info_mgr_ = OB_NEW(ObTimeZoneInfoManager,
ObModIds::OMT,
OBSERVER.get_common_rpc_proxy(),
OBSERVER.get_mysql_proxy(),
OBSERVER.get_root_service(),
*tz_info_map_,
tenant_id_);
if (OB_ISNULL(tz_info_map_) || OB_ISNULL(tz_info_mgr_)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("fail to allocate mem for tz_info", K(ret), K(tz_info_map_), K(tz_info_mgr_));
} else if (OB_FAIL(tz_info_map_->init(ObModIds::OB_HASH_BUCKET_TIME_ZONE_INFO_MAP))) {
LOG_WARN("fail to init tz_info_map_", K(ret));
} else if (OB_FAIL(tz_info_mgr_->init())) {
LOG_WARN("fail to init tz_info_mgr_", K(ret));
} else {
LOG_INFO("tenant timezone init", K(tz_info_map_), K(tenant_id_));
}
LOG_INFO("tenant timezone init", K(tz_info_map_), K(tenant_id_));
}
return ret;
}
void ObTenantTimezone::TenantTZUpdateTask::runTimerTask()
void ObTenantTimezone::destroy()
{
int ret = OB_SUCCESS;
if (task_lock_.trylock()) {
if (!tenant_tz_mgr_->get_start_refresh()) {
const int64_t delay = 1 * 1000 * 1000;
const bool repeat = false;
if (OB_FAIL(TG_SCHEDULE(lib::TGDefIDs::TIMEZONE_MGR, *this, delay, repeat))) {
LOG_WARN("schedule timezone update task failed", K(ret));
}
} else {
const int64_t delay = 5 * 1000 * 1000;
const bool repeat = false;
if (OB_FAIL(tenant_tz_->get_tz_mgr()->fetch_time_zone_info())) {
LOG_WARN("fail to update time zone info", K(ret));
}
if (OB_FAIL(TG_SCHEDULE(lib::TGDefIDs::TIMEZONE_MGR, *this, delay, repeat))) {
LOG_WARN("schedule timezone update task failed", K(ret));
}
}
task_lock_.unlock();
} else {
// deleted already
if (NULL != tz_info_map_) {
tz_info_map_->destroy();
}
}
int ObTenantTimezone::get_ref_count(int64_t& ref_count)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(tz_info_map_)) {
ret = OB_ERR_UNEXPECTED;
} else {
ref_count = tz_info_map_->get_ref_count();
}
return ret;
}
} // namespace omt
} // namespace oceanbase
......@@ -24,33 +24,6 @@ class ObTenantTimezoneMgr;
class ObTenantTimezone {
friend class ObTenantTimezoneMgr;
public:
class TenantTZUpdateTask : public common::ObTimerTask {
public:
TenantTZUpdateTask() : tenant_tz_mgr_(nullptr), tenant_tz_(nullptr), task_lock_()
{}
int init(ObTenantTimezoneMgr* tz_mgr, ObTenantTimezone* timezone)
{
tenant_tz_mgr_ = tz_mgr;
tenant_tz_ = timezone;
return common::OB_SUCCESS;
}
virtual ~TenantTZUpdateTask()
{}
TenantTZUpdateTask(const TenantTZUpdateTask&) = delete;
TenantTZUpdateTask& operator=(const TenantTZUpdateTask&) = delete;
void set_tenant_tz(ObTenantTimezone* timezone)
{
tenant_tz_ = timezone;
}
void runTimerTask(void) override;
ObTenantTimezoneMgr* tenant_tz_mgr_;
ObTenantTimezone* tenant_tz_;
obutil::Mutex task_lock_;
const uint64_t SLEEP_USECONDS = 5000000;
};
friend class TenantTZUpdateTask;
public:
ObTenantTimezone();
ObTenantTimezone(uint64_t tenant_id);
......@@ -61,58 +34,25 @@ public:
int init(ObTenantTimezoneMgr* tz_mgr);
int update_timezone(int64_t tz_version);
bool is_inited()
{
return is_inited_;
}
bool get_update_task_not_exist()
{
return update_task_not_exist_;
}
int get_ref_count(int64_t& ref_count);
uint64_t get_tenant_id() const
{
return tenant_id_;
}
common::ObTZInfoMap* get_tz_map()
{
return tz_info_map_;
}
const TenantTZUpdateTask& get_update_tz_task() const
{
return update_tz_task_;
}
TenantTZUpdateTask& get_update_tz_task()
{
return update_tz_task_;
}
common::ObTimeZoneInfoManager* get_tz_mgr()
{
return tz_info_mgr_;
}
bool is_inited() { return is_inited_; }
bool get_update_task_not_exist() { return update_task_not_exist_; }
int get_ref_count(int64_t &ref_count);
uint64_t get_tenant_id() const { return tenant_id_; }
common::ObTZInfoMap *get_tz_map() { return tz_info_map_; }
common::ObTimeZoneInfoManager *get_tz_mgr() { return tz_info_mgr_; }
void set_update_task_not_exist()
{
update_task_not_exist_ = true;
}
void set_tz_mgr(common::ObTimeZoneInfoManager* tz_mgr)
{
tz_info_mgr_ = tz_mgr;
}
void set_tenant_tz_mgr(ObTenantTimezoneMgr* tz_mgr)
{
tenant_tz_mgr_ = tz_mgr;
};
VIRTUAL_TO_STRING_KV(K_(is_inited), K_(tenant_id), K_(ref_count));
void set_update_task_not_exist() { update_task_not_exist_ = true; }
void set_tz_mgr(common::ObTimeZoneInfoManager *tz_mgr) { tz_info_mgr_ = tz_mgr; }
void set_tenant_tz_mgr(ObTenantTimezoneMgr *tz_mgr) { tenant_tz_mgr_ = tz_mgr; };
void destroy();
VIRTUAL_TO_STRING_KV(K_(is_inited), K_(tenant_id));
private:
bool is_inited_;
uint64_t tenant_id_;
ObTenantTimezoneMgr* tenant_tz_mgr_;
TenantTZUpdateTask update_tz_task_;
common::ObTimeZoneInfoManager* tz_info_mgr_;
common::ObTZInfoMap* tz_info_map_;
uint64_t ref_count_;
ObTenantTimezoneMgr *tenant_tz_mgr_;
common::ObTimeZoneInfoManager *tz_info_mgr_;
common::ObTZInfoMap *tz_info_map_;
bool update_task_not_exist_;
};
......
......@@ -24,7 +24,7 @@ using namespace oceanbase::common;
namespace oceanbase {
namespace omt {
void ObTenantTimezoneMgr::UpdateAllTenantTask::runTimerTask()
void ObTenantTimezoneMgr::AddTenantTZTask::runTimerTask()
{
int ret = OB_SUCCESS;
int64_t delay = SLEEP_USECONDS;
......@@ -54,8 +54,34 @@ void ObTenantTimezoneMgr::DeleteTenantTZTask::runTimerTask()
} else if (tenant_tz_mgr_->get_start_refresh()) {
if (OB_FAIL(tenant_tz_mgr_->remove_nonexist_tenant())) {
LOG_WARN("remove nonexist tenants failed", K(ret));
} else if (OB_FAIL(tenant_tz_mgr_->delete_tenant_timezone())) {
LOG_ERROR("tenant timezone mgr delete tenant timezone failed", K(ret));
}
}
const int64_t delay = SLEEP_USECONDS;
const bool repeat = false;
if (OB_FAIL(TG_SCHEDULE(lib::TGDefIDs::TIMEZONE_MGR, *this, delay, repeat))) {
LOG_ERROR("schedule timezone delete task failed", K(ret));
}
}
void ObTenantTimezoneMgr::UpdateTenantTZOp::operator() (common::hash::HashMapPair<uint64_t, ObTenantTimezone*> &entry)
{
int ret = OB_SUCCESS;
ObTenantTimezone &tenant_tz = *entry.second;
if (OB_FAIL(tenant_tz.get_tz_mgr()->fetch_time_zone_info())) {
LOG_WARN("fail to update time zone info", K(ret));
}
}
void ObTenantTimezoneMgr::UpdateTenantTZTask::runTimerTask()
{
int ret = OB_SUCCESS;
UpdateTenantTZOp update_op;
if (OB_ISNULL(tenant_tz_mgr_)) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("delete tenant task, tenant tz mgr is null", K(ret));
} else if (tenant_tz_mgr_->get_start_refresh()) {
if (OB_FAIL(tenant_tz_mgr_->timezone_map_.foreach_refactored(update_op))) {
LOG_WARN("update tenant time zone failed", K(ret));
}
}
const int64_t delay = SLEEP_USECONDS;
......@@ -66,18 +92,11 @@ void ObTenantTimezoneMgr::DeleteTenantTZTask::runTimerTask()
}
ObTenantTimezoneMgr::ObTenantTimezoneMgr()
: allocator_("TenantTZ"),
is_inited_(false),
self_(),
sql_proxy_(nullptr),
: allocator_("TenantTZ"), is_inited_(false), self_(), sql_proxy_(nullptr),
rwlock_(),
timezone_map_(),
update_task_(this),
delete_task_(this),
start_refresh_(false),
usable_(false),
schema_service_(nullptr),
drop_tenant_tz_(allocator_)
timezone_map_(), add_task_(this), delete_task_(this), update_task_(this),
start_refresh_(false), usable_(false),
schema_service_(nullptr)
{
tenant_tz_map_getter_ = ObTenantTimezoneMgr::get_tenant_timezone_default;
}
......@@ -110,10 +129,12 @@ int ObTenantTimezoneMgr::init(
if (OB_FAIL(ret)) {
} else if (OB_FAIL(add_tenant_timezone(OB_SYS_TENANT_ID))) {
LOG_WARN("add tenant timezone info failed", K(ret));
} else if (OB_FAIL(TG_SCHEDULE(lib::TGDefIDs::TIMEZONE_MGR, update_task_, delay, repeat))) {
} else if (OB_FAIL(TG_SCHEDULE(lib::TGDefIDs::TIMEZONE_MGR, add_task_, delay, repeat))) {
LOG_WARN("schedual time zone mgr failed", K(ret));
} else if (OB_FAIL(TG_SCHEDULE(lib::TGDefIDs::TIMEZONE_MGR, delete_task_, delay, repeat))) {
LOG_WARN("schedual time zone mgr failed", K(ret));
} else if (OB_FAIL(TG_SCHEDULE(lib::TGDefIDs::TIMEZONE_MGR, update_task_, delay, repeat))) {
LOG_WARN("schedual time zone mgr failed", K(ret));
} else {
tenant_tz_map_getter_ = ObTenantTimezoneMgr::get_tenant_timezone_static;
}
......@@ -141,26 +162,20 @@ int ObTenantTimezoneMgr::add_tenant_timezone(uint64_t tenant_id)
LOG_WARN("tenant timezone mgr not inited", K(ret));
} else if (is_virtual_tenant_id(tenant_id) || OB_NOT_NULL(timezone = timezone_map_.get(tenant_id))) {
} else {
ObTenantTimezone* new_timezone = nullptr;
new_timezone = OB_NEW(ObTenantTimezone, ObModIds::OMT, tenant_id);
ObTenantTimezone *new_timezone = nullptr;
new_timezone = OB_NEW(ObTenantTimezone, "TenantTZ", tenant_id);
if (OB_ISNULL(new_timezone)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("alloc new tenant timezone failed", K(ret));
} else if(OB_FAIL(new_timezone->init(this))) {
LOG_WARN("new tenant timezone init failed", K(ret));
} else if (OB_FAIL(timezone_map_.set_refactored(tenant_id, new_timezone, 1))) {
LOG_WARN("add new tenant timezone failed", K(ret));
} else {
const int64_t delay = 0;
const bool repeat = false;
if (OB_FAIL(new_timezone->init(this))) {
LOG_WARN("new tenant timezone init failed", K(ret));
} else if (OB_FAIL(TG_SCHEDULE(lib::TGDefIDs::TIMEZONE_MGR, new_timezone->update_tz_task_, delay, repeat))) {
LOG_WARN("schedule update time zone task failed", K(delay), K(repeat), K(ret));
} else if (OB_FAIL(timezone_map_.set_refactored(tenant_id, new_timezone, 1))) {
LOG_WARN("add new tenant timezone failed", K(ret));
} else {
LOG_INFO("add tenant timezone success!", K(tenant_id));
}
if (OB_FAIL(ret)) {
ob_delete(new_timezone);
}
LOG_INFO("add tenant timezone success!", K(tenant_id));
}
if (OB_FAIL(ret)) {
ob_delete(new_timezone);
}
}
return ret;
......@@ -183,10 +198,12 @@ int ObTenantTimezoneMgr::del_tenant_timezone(uint64_t tenant_id)
LOG_WARN("time zone is null", K(ret), K(tenant_id));
} else if (OB_FAIL(timezone_map_.erase_refactored(tenant_id))) {
LOG_WARN("erase tenant timezone failed", K(ret), K(tenant_id));
} else if (OB_FAIL(drop_tenant_tz_.push_back(timezone))) {
LOG_WARN("push back timezone failed", K(ret));
} else {
LOG_INFO("drop tenant tz push back succeed", K(timezone->get_tz_map()), K(timezone->get_tenant_id()));
ObTZInfoMap *tz_map = timezone->get_tz_map();
LOG_INFO("drop tenant tz push back succeed", K(timezone->get_tz_map()),
K(timezone->get_tenant_id()));
timezone->destroy();
ob_delete(timezone);
}
return ret;
}
......@@ -333,64 +350,8 @@ int ObTenantTimezoneMgr::update_timezone_map()
}
return ret;
}
// delete all tenant timezone in array drop_tenant_tz_ whose ref_count is zero.
int ObTenantTimezoneMgr::delete_tenant_timezone()
{
int ret = OB_SUCCESS;
FOREACH_X(it, drop_tenant_tz_, OB_SUCC(ret))
{
ObTenantTimezone* tenant_tz = *it;
int64_t ref_count = 0;
if (OB_ISNULL(tenant_tz)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("tenant timezone in array is null", K(ret));
} else if (OB_FAIL(tenant_tz->get_ref_count(ref_count))) {
LOG_WARN("get ref count failed", K(ret));
} else if (0 == ref_count) {
const int try_times = 30;
const int64_t period = 1000;
ObTenantTimezone::TenantTZUpdateTask& task = tenant_tz->get_update_tz_task();
bool locked = false;
// waiting for running task with lock finished
for (int64_t j = 0; j < try_times; ++j) {
if (task.task_lock_.trylock()) {
locked = true;
break;
}
usleep(period);
}
if (!locked) {
} else if (OB_FAIL(TG_CANCEL_R(lib::TGDefIDs::TIMEZONE_MGR, task))) {
LOG_WARN("cancel tenant timezone update task failed", K(ret));
} else {
bool is_exist = true;
for (int64_t j = 0; j < try_times; ++j) {
if (OB_FAIL(TG_TASK_EXIST(lib::TGDefIDs::TIMEZONE_MGR, task, is_exist))) {
LOG_WARN("check task exist failed", K(ret));
} else if (!is_exist) {
break;
} else {
// waiting for running task without lock finished, it should be very soon.
}
usleep(period);
} // for
if (!is_exist) {
if (OB_FAIL(drop_tenant_tz_.erase(it))) {
LOG_WARN("erase failed", K(ret));
} else {
LOG_INFO("ref count is zero, drop tenant timezone", K(tenant_tz->get_tenant_id()));
task.task_lock_.unlock();
ob_delete(tenant_tz);
}
}
}
}
}
return ret;
}
int ObTenantTimezoneMgr::get_tenant_timezone_static(const uint64_t tenant_id, ObTZMapWrap& timezone_wrap)
int ObTenantTimezoneMgr::get_tenant_timezone_static(const uint64_t tenant_id,
ObTZMapWrap &timezone_wrap)
{
ObTimeZoneInfoManager* tz_info_mgr = NULL;
return get_instance().get_tenant_timezone(tenant_id, timezone_wrap, tz_info_mgr);
......@@ -412,7 +373,8 @@ int ObTenantTimezoneMgr::get_tenant_timezone_default(const uint64_t tenant_id, O
int ret = OB_SUCCESS;
static ObTZInfoMap tz_map;
UNUSED(tenant_id);
if (OB_UNLIKELY(!tz_map.is_inited()) && OB_FAIL(tz_map.init(ObModIds::OB_HASH_BUCKET_TIME_ZONE_INFO_MAP))) {
if (OB_UNLIKELY(! tz_map.is_inited()) &&
OB_FAIL(tz_map.init("TzMapStatic"))) {
LOG_WARN("init time zone info map failed", K(ret));
} else {
timezone_wrap.set_tz_map(&tz_map);
......
......@@ -45,14 +45,14 @@ private:
DISALLOW_COPY_AND_ASSIGN(__ObTimezoneContainer);
};
// Obtain all_tenant_ids regularly and update the timezone_map in mgr.
class UpdateAllTenantTask : public common::ObTimerTask {
class AddTenantTZTask : public common::ObTimerTask
{
public:
UpdateAllTenantTask(ObTenantTimezoneMgr* tenant_tz_mgr) : tenant_tz_mgr_(tenant_tz_mgr)
{}
virtual ~UpdateAllTenantTask()
{}
UpdateAllTenantTask(const UpdateAllTenantTask&) = delete;
UpdateAllTenantTask& operator=(const UpdateAllTenantTask&) = delete;
AddTenantTZTask(ObTenantTimezoneMgr *tenant_tz_mgr)
: tenant_tz_mgr_(tenant_tz_mgr) {}
virtual ~AddTenantTZTask() {}
AddTenantTZTask(const AddTenantTZTask &) = delete;
AddTenantTZTask &operator=(const AddTenantTZTask &) = delete;
void runTimerTask(void) override;
int update_tenant_map(common::ObIArray<uint64_t>& latest_tenant_ids);
......@@ -71,9 +71,31 @@ private:
ObTenantTimezoneMgr* tenant_tz_mgr_;
const uint64_t SLEEP_USECONDS = 60000000;
};
friend UpdateAllTenantTask;
class UpdateTenantTZOp
{
public:
UpdateTenantTZOp()
{}
virtual ~UpdateTenantTZOp() = default;
void operator() (common::hash::HashMapPair<uint64_t, ObTenantTimezone*> &entry);
public:
private:
DISALLOW_COPY_AND_ASSIGN(UpdateTenantTZOp);
};
class UpdateTenantTZTask : public common::ObTimerTask
{
public:
UpdateTenantTZTask(ObTenantTimezoneMgr *tenant_tz_mgr) : tenant_tz_mgr_(tenant_tz_mgr) {}
virtual ~UpdateTenantTZTask() {}
UpdateTenantTZTask(const UpdateTenantTZTask &) = delete;
UpdateTenantTZTask &operator=(const UpdateTenantTZTask &) = delete;
void runTimerTask(void) override;
ObTenantTimezoneMgr *tenant_tz_mgr_;
const uint64_t SLEEP_USECONDS = 5000000;
};
friend AddTenantTZTask;
friend DeleteTenantTZTask;
friend UpdateTenantTZTask;
public:
using TenantTimezoneMap = __ObTimezoneContainer<uint64_t, ObTenantTimezone, common::OB_MAX_SERVER_TENANT_CNT>;
typedef int (*tenant_timezone_map_getter)(const uint64_t tenant_id, common::ObTZMapWrap& timezone_wrap);
......@@ -99,27 +121,11 @@ public:
int add_new_tenants(const common::ObIArray<uint64_t>& latest_tenant_ids);
int update_timezone_map();
int delete_tenant_timezone();
int cancel(const ObTenantTimezone::TenantTZUpdateTask& task);
bool is_inited()
{
return is_inited_;
}
bool get_start_refresh()
{
return start_refresh_;
}
void set_start_refresh(bool start)
{
start_refresh_ = start;
}
bool is_usable()
{
return usable_;
}
void set_usable()
{
usable_ = true;
}
bool is_inited() { return is_inited_; }
bool get_start_refresh() { return start_refresh_; }
void set_start_refresh(bool start) { start_refresh_ = start; }
bool is_usable() { return usable_; }
void set_usable() { usable_ = true; }
void destroy();
private:
......@@ -139,14 +145,12 @@ private:
// protect timezone_map_
common::ObLatch rwlock_;
TenantTimezoneMap timezone_map_;
UpdateAllTenantTask update_task_;
AddTenantTZTask add_task_;
DeleteTenantTZTask delete_task_;
UpdateTenantTZTask update_task_;
bool start_refresh_;
bool usable_;
share::schema::ObMultiVersionSchemaService* schema_service_;
// tenants which have been dropped, waiting for ref_count = 0 and delete them.
common::ObList<ObTenantTimezone*, common::ObArenaAllocator> drop_tenant_tz_;
share::schema::ObMultiVersionSchemaService *schema_service_;
public:
// tenant timezone getter, observer and liboblog init it during start up.
tenant_timezone_map_getter tenant_tz_map_getter_;
......
......@@ -209,12 +209,8 @@ int ObTimeZoneInfoManager::fetch_time_zone_info_from_tenant_table(const int64_t
LOG_ERROR("fail to fill tz_info_map", K(ret));
} else {
last_version_ = current_tz_version;
LOG_INFO("success to fetch tz_info map",
K(ret),
K(last_version_),
"new_last_version",
current_tz_version,
K(tz_info_map_.id_map_.size()));
LOG_INFO("success to fetch tz_info map", K(ret), K(last_version_), K(tenant_id_),
"new_last_version", current_tz_version, K(tz_info_map_.id_map_.size()));
}
}
}
......@@ -546,15 +542,10 @@ int ObTimeZoneInfoManager::print_tz_info_map()
int ObTimeZoneInfoManager::find_time_zone_info(const common::ObString& tz_name, ObTimeZoneInfoPos& tz_info)
{
int ret = OB_SUCCESS;
ObTimeZoneInfoPos* tmp_tz_info = NULL;
if (OB_FAIL(tz_info_map_.get_tz_info_by_name(tz_name, tmp_tz_info))) {
if (OB_FAIL(tz_info_map_.get_tz_info_by_name(tz_name, tz_info))) {
LOG_WARN("fail to get time zone info", K(tz_name), K(ret));
} else if (OB_FAIL(tz_info.assign(*tmp_tz_info))) {
LOG_WARN("fail to assign time zone info", KPC(tmp_tz_info), K(ret));
}
tz_info_map_.free_tz_info_pos(tmp_tz_info);
if (OB_ENTRY_NOT_EXIST == ret) {
ret = OB_ERR_UNKNOWN_TIME_ZONE;
}
......
......@@ -104,7 +104,7 @@ int ObExprConvertTZ::parse_string(
LOG_WARN("direct str_to_offset failed");
if (OB_LIKELY(OB_ERR_UNKNOWN_TIME_ZONE == ret)) {
const ObTimeZoneInfo *tz_info = NULL;
ObTimeZoneInfoPos *target_tz_pos = NULL;
ObTimeZoneInfoPos target_tz_pos;
if (OB_ISNULL(tz_info = TZ_INFO(session))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("tz info is null", K(ret), K(session));
......@@ -113,7 +113,7 @@ int ObExprConvertTZ::parse_string(
if (OB_ERR_UNKNOWN_TIME_ZONE == ret && OB_SUCCESS != ret_more) {
ret = ret_more;
}
} else if (OB_FAIL(calc(timestamp_data, *target_tz_pos, input_utc_time))) {
} else if (OB_FAIL(calc(timestamp_data, target_tz_pos, input_utc_time))) {
LOG_WARN("calc failed", K(ret), K(timestamp_data));
}
} else {
......@@ -126,21 +126,19 @@ int ObExprConvertTZ::parse_string(
return ret;
}
int ObExprConvertTZ::find_time_zone_pos(
const ObString &tz_name, const ObTimeZoneInfo &tz_info, ObTimeZoneInfoPos *&tz_info_pos)
int ObExprConvertTZ::find_time_zone_pos(const ObString &tz_name,
const ObTimeZoneInfo &tz_info,
ObTimeZoneInfoPos &tz_info_pos)
{
int ret = OB_SUCCESS;
tz_info_pos = NULL;
ObTZInfoMap *tz_info_map = NULL;
if (OB_ISNULL(tz_info_map = const_cast<ObTZInfoMap *>(tz_info.get_tz_info_map()))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("tz_info_map is NULL", K(ret));
} else if (OB_FAIL(tz_info_map->get_tz_info_by_name(tz_name, tz_info_pos))) {
LOG_WARN("fail to get_tz_info_by_name", K(tz_name), K(ret));
tz_info_map->id_map_.revert(tz_info_pos);
tz_info_pos = NULL;
} else {
tz_info_pos->set_error_on_overlap_time(tz_info.is_error_on_overlap_time());
tz_info_pos.set_error_on_overlap_time(tz_info.is_error_on_overlap_time());
}
return ret;
}
......
......@@ -36,7 +36,7 @@ public:
static int eval_convert_tz(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res);
static int find_time_zone_pos(const ObString &tz_name,
const ObTimeZoneInfo &tz_info,
ObTimeZoneInfoPos *&tz_info_pos);
ObTimeZoneInfoPos &tz_info_pos);
template <typename T>
static int calc_convert_tz(int64_t timestamp_data, const ObString &tz_str_s,//source time zone (input2)
const ObString &tz_str_d,//destination time zone (input3)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册