oceanbase

Форк
0
/
ob_tenant_timezone_mgr.cpp 
386 строк · 13.2 Кб
1
/**
2
 * Copyright (c) 2021 OceanBase
3
 * OceanBase CE is licensed under Mulan PubL v2.
4
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
5
 * You may obtain a copy of Mulan PubL v2 at:
6
 *          http://license.coscl.org.cn/MulanPubL-2.0
7
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
8
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
9
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
10
 * See the Mulan PubL v2 for more details.
11
 */
12

13
#define USING_LOG_PREFIX SERVER_OMT
14
#include "ob_tenant_timezone_mgr.h"
15
#include "lib/thread/thread_mgr.h"
16
#include "observer/ob_sql_client_decorator.h"
17
#include "observer/ob_server_struct.h"
18
#include "share/ob_time_zone_info_manager.h"
19
#include "share/schema/ob_multi_version_schema_service.h"
20
#include "lib/hash/ob_hashset.h"
21
#include "observer/ob_server.h"
22

23
using namespace oceanbase::common;
24

25

26
namespace oceanbase {
27
namespace omt {
28

29
void ObTenantTimezoneMgr::AddTenantTZTask::runTimerTask()
30
{
31
  int ret = OB_SUCCESS;
32
  if (OB_ISNULL(tenant_tz_mgr_)) {
33
    ret = OB_ERR_UNEXPECTED;
34
    LOG_ERROR("update all tenant task, tenant tz mgr is null", K(ret));
35
  } else if (OB_FAIL(tenant_tz_mgr_->update_timezone_map())) {
36
    LOG_WARN("tenant timezone mgr update tenant timezone map failed", K(ret));
37
  }
38
}
39

40
void ObTenantTimezoneMgr::DeleteTenantTZTask::runTimerTask()
41
{
42
  int ret = OB_SUCCESS;
43
  if (OB_ISNULL(tenant_tz_mgr_)) {
44
    ret = OB_ERR_UNEXPECTED;
45
    LOG_ERROR("delete tenant task, tenant tz mgr is null", K(ret));
46
  } else if (OB_FAIL(tenant_tz_mgr_->remove_nonexist_tenant())) {
47
    LOG_WARN("remove nonexist tenants failed", K(ret));
48
  }
49
}
50

51
int ObTenantTimezoneMgr::UpdateTenantTZOp::operator() (common::hash::HashMapPair<uint64_t, ObTenantTimezone*> &entry)
52
{
53
  int ret = OB_SUCCESS;
54
  ObTenantTimezone &tenant_tz = *entry.second;
55
  if (OB_FAIL(tenant_tz.get_tz_mgr().fetch_time_zone_info())) {
56
    LOG_WARN("fail to update time zone info", K(ret));
57
  }
58
  return OB_SUCCESS;
59
}
60

61
void ObTenantTimezoneMgr::UpdateTenantTZTask::runTimerTask()
62
{
63
  int ret = OB_SUCCESS;
64
  UpdateTenantTZOp update_op;
65
  if (OB_ISNULL(tenant_tz_mgr_)) {
66
    ret = OB_ERR_UNEXPECTED;
67
    LOG_ERROR("delete tenant task, tenant tz mgr is null", K(ret));
68
  } else if (OB_FAIL(tenant_tz_mgr_->timezone_map_.foreach_refactored(update_op))) {
69
    LOG_WARN("update tenant time zone failed", K(ret));
70
  }
71
}
72

73
ObTenantTimezoneMgr::ObTenantTimezoneMgr()
74
    : allocator_("TenantTZ"), is_inited_(false), self_(), sql_proxy_(nullptr),
75
      rwlock_(ObLatchIds::TIMEZONE_LOCK),
76
      timezone_map_(), add_task_(this), delete_task_(this), update_task_(this),
77
      usable_(false),
78
      schema_service_(nullptr)
79
{
80
  tenant_tz_map_getter_ = ObTenantTimezoneMgr::get_tenant_timezone_default;
81
}
82

83
ObTenantTimezoneMgr::~ObTenantTimezoneMgr()
84
{
85
}
86

87
ObTenantTimezoneMgr &ObTenantTimezoneMgr::get_instance()
88
{
89
  static ObTenantTimezoneMgr ob_tenant_timezone_mgr;
90
  return ob_tenant_timezone_mgr;
91
}
92

93
int ObTenantTimezoneMgr::init(ObMySQLProxy &sql_proxy, const ObAddr &server,
94
                              share::schema::ObMultiVersionSchemaService &schema_service)
95
{
96
  int ret = OB_SUCCESS;
97
  sql_proxy_ = &sql_proxy;
98
  self_ = server;
99
  schema_service_ = &schema_service;
100
  is_inited_ = true;
101
  if (OB_FAIL(add_tenant_timezone(OB_SYS_TENANT_ID))) {
102
    LOG_WARN("add tenant timezone info failed", K(ret));
103
  } else {
104
    tenant_tz_map_getter_ = ObTenantTimezoneMgr::get_tenant_timezone_static;
105
  }
106
  return ret;
107
}
108

109
int ObTenantTimezoneMgr::start()
110
{
111
  int ret = OB_SUCCESS;
112
  const int64_t delay = SLEEP_USECONDS;
113
  const bool repeat = true;
114
  const bool immediate = true;
115
  if (OB_FAIL(TG_START(lib::TGDefIDs::TIMEZONE_MGR))) {
116
    LOG_WARN("fail to start timer", K(ret));
117
  } else if (OB_FAIL(TG_SCHEDULE(lib::TGDefIDs::TIMEZONE_MGR, add_task_, delay, repeat, immediate))) {
118
    LOG_WARN("schedual time zone mgr failed", K(ret));
119
  } else if (OB_FAIL(TG_SCHEDULE(lib::TGDefIDs::TIMEZONE_MGR, delete_task_, delay, repeat, immediate))) {
120
    LOG_WARN("schedual time zone mgr failed", K(ret));
121
  } else if (OB_FAIL(TG_SCHEDULE(lib::TGDefIDs::TIMEZONE_MGR, update_task_, delay, repeat, immediate))) {
122
    LOG_WARN("schedual time zone mgr failed", K(ret));
123
  }
124
  return ret;
125
}
126

127
void ObTenantTimezoneMgr::init(tenant_timezone_map_getter tz_map_getter)
128
{
129
  tenant_tz_map_getter_ = tz_map_getter;
130
  is_inited_ = true;
131
}
132

133
void ObTenantTimezoneMgr::stop()
134
{
135
  TG_STOP(lib::TGDefIDs::TIMEZONE_MGR);
136
}
137

138
void ObTenantTimezoneMgr::wait()
139
{
140
  TG_WAIT(lib::TGDefIDs::TIMEZONE_MGR);
141
}
142

143
void ObTenantTimezoneMgr::destroy()
144
{
145
  TG_DESTROY(lib::TGDefIDs::TIMEZONE_MGR);
146
  timezone_map_.destroy();
147
}
148

149
int ObTenantTimezoneMgr::add_tenant_timezone(uint64_t tenant_id)
150
{
151
  int ret = OB_SUCCESS;
152
  ObTenantTimezone *const *timezone = nullptr;
153
  DRWLock::WRLockGuard guard(rwlock_);
154
  if (! is_inited_) {
155
    ret = OB_NOT_INIT;
156
    LOG_WARN("tenant timezone mgr not inited", K(ret));
157
  } else if (is_virtual_tenant_id(tenant_id)
158
      || OB_NOT_NULL(timezone = timezone_map_.get(tenant_id))) {
159
  } else {
160
    ObTenantTimezone *new_timezone = nullptr;
161
    new_timezone = OB_NEW(ObTenantTimezone, "TenantTZ", OBSERVER.get_mysql_proxy(), tenant_id);
162
    if (OB_ISNULL(new_timezone)) {
163
      ret = OB_ALLOCATE_MEMORY_FAILED;
164
      LOG_WARN("alloc new tenant timezone failed", K(ret));
165
    } else if(OB_FAIL(new_timezone->init())) {
166
      LOG_WARN("new tenant timezone init failed", K(ret));
167
    } else if (OB_FAIL(timezone_map_.set_refactored(tenant_id, new_timezone, 1))) {
168
      LOG_WARN("add new tenant timezone failed", K(ret));
169
    } else {
170
      LOG_INFO("add tenant timezone success!", K(tenant_id), K(sizeof(ObTenantTimezone)));
171
    }
172
    if (OB_FAIL(ret)) {
173
      ob_delete(new_timezone);
174
    }
175
  }
176
  return ret;
177
}
178

179
int ObTenantTimezoneMgr::del_tenant_timezone(uint64_t tenant_id)
180
{
181
  int ret = OB_SUCCESS;
182
  ObTenantTimezone *timezone = nullptr;
183
  DRWLock::WRLockGuard guard(rwlock_);
184
  if (is_virtual_tenant_id(tenant_id)) {
185
  } else if (OB_FAIL(timezone_map_.get_refactored(tenant_id, timezone))) {
186
    if (OB_HASH_NOT_EXIST == ret) {
187
      ret = OB_SUCCESS;
188
    } else {
189
      LOG_WARN("get tenant timezone failed", K(tenant_id), K(ret));
190
    }
191
  } else if (OB_ISNULL(timezone)) {
192
    ret = OB_ERR_UNEXPECTED;
193
    LOG_WARN("time zone is null", K(ret), K(tenant_id));
194
  } else if (OB_FAIL(timezone_map_.erase_refactored(tenant_id))) {
195
    LOG_WARN("erase tenant timezone failed", K(ret), K(tenant_id));
196
  } else {
197
    LOG_INFO("drop tenant tz push back succeed", K(timezone->get_tenant_id()));
198
    ob_delete(timezone);
199
  }
200
  return ret;
201
}
202

203
int ObTenantTimezoneMgr::get_tenant_timezone_inner(const uint64_t tenant_id,
204
                                              ObTZMapWrap &timezone_wrap,
205
                                              ObTimeZoneInfoManager *&tz_info_mgr)
206
{
207
  int ret = OB_SUCCESS;
208
  ObTenantTimezone *timezone = nullptr;
209
  DRWLock::RDLockGuard guard(rwlock_);
210
  if (OB_FAIL(timezone_map_.get_refactored(tenant_id, timezone))) {
211
    if (OB_HASH_NOT_EXIST != ret) {
212
      LOG_WARN("timezone map get refactored failed", K(ret));
213
    }
214
  } else if (OB_ISNULL(timezone)) {
215
    ret = OB_ERR_UNEXPECTED;
216
    LOG_WARN("tenant tz is null", K(ret));
217
  } else {
218
    timezone_wrap.set_tz_map(timezone->get_tz_map());
219
    tz_info_mgr = &(timezone->get_tz_mgr());
220
  }
221
  return ret;
222
}
223

224
// Get the tenant_list, if it contains tenant_id, then create the tenant_timezone of the tenant.
225
int ObTenantTimezoneMgr::refresh_tenant_timezone(const uint64_t tenant_id)
226
{
227
  int ret = OB_SUCCESS;
228
  bool is_exist = false;
229
  if (OB_LIKELY(OB_INVALID_ID != tenant_id)) {
230
    share::schema::ObSchemaGetterGuard sys_schema_guard;
231
    if (OB_ISNULL(schema_service_)) {
232
      ret = OB_NOT_INIT;
233
      LOG_WARN("not init", K(ret));
234
    } else if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID,
235
                                                                sys_schema_guard))) {
236
      LOG_WARN("get sys tenant schema guard failed", K(ret));
237
    } else if (OB_FAIL(sys_schema_guard.check_tenant_exist(tenant_id, is_exist))) {
238
      LOG_WARN("get tenant ids failed", K(ret));
239
    }
240
  }
241
  if (OB_FAIL(ret)) {
242
  } else if (is_exist && OB_FAIL(add_tenant_timezone(tenant_id))) {
243
    LOG_WARN("add tenant timezone failed", K(ret));
244
  }
245
  return ret;
246
}
247

248
int ObTenantTimezoneMgr::get_tenant_timezone(const uint64_t tenant_id,
249
                                             ObTZMapWrap &timezone_wrap,
250
                                             ObTimeZoneInfoManager *&tz_info_mgr)
251
{
252
  int ret = OB_SUCCESS;
253
  if (OB_FAIL(get_tenant_timezone_inner(tenant_id, timezone_wrap, tz_info_mgr))) {
254
    if (OB_HASH_NOT_EXIST == ret) {
255
      // For newly created tenants, if the tenant_list is not refreshed regularly, refresh it once.
256
      if (OB_FAIL(refresh_tenant_timezone(tenant_id))) {
257
        LOG_WARN("update timezone map failed", K(ret));
258
      } else if (OB_FAIL(get_tenant_timezone_inner(tenant_id, timezone_wrap, tz_info_mgr))) {
259
        if (OB_HASH_NOT_EXIST == ret) {
260
          //After brushing to the latest tenant_list, it is not found yet, return to the timezone of the system tenant
261
          if (OB_FAIL(get_tenant_timezone_inner(OB_SYS_TENANT_ID, timezone_wrap, tz_info_mgr))) {
262
            LOG_ERROR("get tenant time zone failed", K(ret), K(tenant_id));
263
          }
264
        } else {
265
          LOG_WARN("get tenant time zone failed", K(ret), K(tenant_id));
266
        }
267
      }
268
    } else {
269
      LOG_WARN("failed to get tenant timezone", K(ret), K(tenant_id));
270
    }
271
  }
272
  return ret;
273
}
274

275
int ObTenantTimezoneMgr::remove_nonexist_tenant()
276
{
277
  int ret = OB_SUCCESS;
278
  ObArray<uint64_t> remove_tenant_ids;
279
  {
280
    TenantTimezoneMap::const_iterator it = timezone_map_.begin();
281
    share::schema::ObSchemaGetterGuard sys_schema_guard;
282
    if (OB_ISNULL(schema_service_)) {
283
      ret = OB_NOT_INIT;
284
      LOG_WARN("not init", K(ret));
285
    } else if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID,
286
                                                                sys_schema_guard))) {
287
      LOG_WARN("get sys tenant schema guard failed", K(ret));
288
    }
289
    for(; OB_SUCC(ret) && it != timezone_map_.end(); it++) {
290
      bool is_dropped = false;
291
      if (OB_FAIL(sys_schema_guard.check_if_tenant_has_been_dropped(it->first, is_dropped))) {
292
        LOG_WARN("check if tenant has been dropped failed", K(ret));
293
      } else if (is_dropped && OB_FAIL(remove_tenant_ids.push_back(it->first))) {
294
        LOG_WARN("push back failed", K(ret));
295
      }
296
    }
297
  }
298
  for (int64_t i = 0; OB_SUCC(ret) && i < remove_tenant_ids.count(); i++) {
299
    if (OB_FAIL(del_tenant_timezone(remove_tenant_ids.at(i)))) {
300
      LOG_WARN("del tenant timezone failed", K(ret));
301
    }
302
  }
303

304
  return ret;
305
}
306

307
int ObTenantTimezoneMgr::add_new_tenants(const common::ObIArray<uint64_t> &latest_tenant_ids)
308
{
309
  int ret = OB_SUCCESS;
310
  ObTenantTimezone *timezone = nullptr;
311
  for (int64_t i = 0; i < latest_tenant_ids.count(); i++) {
312
    uint64_t tenant_id = latest_tenant_ids.at(i);
313
    if (OB_FAIL(timezone_map_.get_refactored(tenant_id, timezone))) {
314
      if (OB_HASH_NOT_EXIST == ret) {
315
        if (OB_FAIL(add_tenant_timezone(tenant_id))) {
316
          LOG_WARN("add tenant timezone failed", K(ret));
317
        }
318
      } else {
319
        LOG_WARN("get tenant timezone failed", K(ret));
320
      }
321
    }
322
  }
323
  return ret;
324
}
325

326
// get tenant list and update local tenant timezone map periodically
327
// only add new tenant here
328
int ObTenantTimezoneMgr::update_timezone_map()
329
{
330
  int ret = OB_SUCCESS;
331
  ObArray<uint64_t> latest_tenant_ids;
332
  {
333
    share::schema::ObSchemaGetterGuard sys_schema_guard;
334
    if (OB_ISNULL(schema_service_)) {
335
      ret = OB_NOT_INIT;
336
      LOG_WARN("not init", K(ret));
337
    } else if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID,
338
                                                                sys_schema_guard))) {
339
      LOG_WARN("get sys tenant schema guard failed", K(ret));
340
    } else if (OB_FAIL(sys_schema_guard.get_tenant_ids(latest_tenant_ids))) {
341
      LOG_WARN("get tenant ids failed", K(ret));
342
    }
343
  }
344
  if (OB_FAIL(ret)) {
345
  } else if (OB_FAIL(add_new_tenants(latest_tenant_ids))) {
346
    LOG_WARN("add new tenants failed", K(ret));
347
  }
348
  return ret;
349
}
350
int ObTenantTimezoneMgr::get_tenant_timezone_static(const uint64_t tenant_id,
351
                                                        ObTZMapWrap &timezone_wrap)
352
{
353
   ObTimeZoneInfoManager *tz_info_mgr = NULL;
354
  return get_instance().get_tenant_timezone(tenant_id, timezone_wrap, tz_info_mgr);
355
}
356

357
int ObTenantTimezoneMgr::get_tenant_tz(const uint64_t tenant_id,
358
                                      ObTZMapWrap &timezone_wrap)
359
{
360
  int ret = OB_SUCCESS;
361
  if (OB_ISNULL(tenant_tz_map_getter_)) {
362
    ret = OB_ERR_UNEXPECTED;
363
    LOG_ERROR("tenant tz map getter is null", K(ret), K(tenant_id));
364
  } else if (OB_FAIL(tenant_tz_map_getter_(tenant_id, timezone_wrap))) {
365
    LOG_WARN("get tenant tz map failed", K(ret), K(tenant_id));
366
  }
367
  return ret;
368
}
369

370
int ObTenantTimezoneMgr::get_tenant_timezone_default(const uint64_t tenant_id,
371
                                                      ObTZMapWrap &timezone_wrap)
372
{
373
  int ret = OB_SUCCESS;
374
  static ObTZInfoMap tz_map;
375
  UNUSED(tenant_id);
376
  if (OB_UNLIKELY(! tz_map.is_inited()) &&
377
      OB_FAIL(tz_map.init(SET_USE_500("TzMapStatic")))) {
378
    LOG_WARN("init time zone info map failed", K(ret));
379
  } else {
380
    timezone_wrap.set_tz_map(&tz_map);
381
  }
382
  return ret;
383
}
384

385
} //omt
386
} //oceanbase
387

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.