tscSystem.c 10.8 KB
Newer Older
H
hzcheng 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 *
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the GNU Affero General Public License, version 3
 * or later ("AGPL"), as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

S
slguan 已提交
16
#include "os.h"
H
hzcheng 已提交
17
#include "taosmsg.h"
18
#include "tref.h"
H
hzcheng 已提交
19
#include "trpc.h"
S
TD-2371  
Shengliang Guan 已提交
20
#include "tnote.h"
H
hzcheng 已提交
21 22 23
#include "tsystem.h"
#include "ttimer.h"
#include "tutil.h"
S
slguan 已提交
24
#include "tsched.h"
S
slguan 已提交
25
#include "tscLog.h"
26
#include "tscUtil.h"
H
hzcheng 已提交
27
#include "tsclient.h"
S
slguan 已提交
28 29 30 31
#include "tglobal.h"
#include "tconfig.h"
#include "ttimezone.h"
#include "tlocale.h"
S
slguan 已提交
32

H
hzcheng 已提交
33
// global, not configurable
34 35
SCacheObj *tscMetaCache;       // table meta cache
SHashObj  *tscHashMap;         // hash map to keep the global vgroup info
36
SHashObj  *tscTableMetaInfo;       // table meta info
37
int     tscObjRef = -1;
38 39 40
void   *tscTmr;
void   *tscQhandle;
void   *tscCheckDiskUsageTmr;
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
41
int     tscRefId = -1;
42
int     tscNumOfObj = 0;       // number of sqlObj in current process.
H
hzcheng 已提交
43

44
static pthread_once_t tscinit = PTHREAD_ONCE_INIT;
L
lihui 已提交
45

46
void tscCheckDiskUsage(void *UNUSED_PARAM(para), void* UNUSED_PARAM(param)) {
S
slguan 已提交
47 48 49 50
  taosGetDisk();
  taosTmrReset(tscCheckDiskUsage, 1000, NULL, tscTmr, &tscCheckDiskUsageTmr);
}

51
int32_t tscInitRpc(const char *user, const char *secretEncrypt, void **pDnodeConn) {
S
slguan 已提交
52 53
  SRpcInit rpcInit;

54
  if (*pDnodeConn == NULL) {
S
slguan 已提交
55 56
    memset(&rpcInit, 0, sizeof(rpcInit));
    rpcInit.localPort = 0;
J
jtao1735 已提交
57
    rpcInit.label = "TSC";
58
    rpcInit.numOfThreads = 1;  // every DB connection has only one thread
S
slguan 已提交
59
    rpcInit.cfp = tscProcessMsgFromServer;
60
    rpcInit.sessions = tsMaxConnections;
S
slguan 已提交
61
    rpcInit.connType = TAOS_CONN_CLIENT;
62
    rpcInit.user = (char *)user;
H
hzcheng 已提交
63
    rpcInit.idleTime = 2000;
S
slguan 已提交
64
    rpcInit.ckey = "key";
S
Shengliang Guan 已提交
65
    rpcInit.spi = 1;
66
    rpcInit.secret = (char *)secretEncrypt;
S
slguan 已提交
67

68 69 70
    *pDnodeConn = rpcOpen(&rpcInit);
    if (*pDnodeConn == NULL) {
      tscError("failed to init connection to TDengine");
S
slguan 已提交
71
      return -1;
72
    } else {
73
      tscDebug("dnodeConn:%p is created, user:%s", *pDnodeConn, user);
S
slguan 已提交
74 75 76 77 78 79
    }
  }

  return 0;
}

S
Shengliang Guan 已提交
80
void taos_init_imp(void) {
H
Haojun Liao 已提交
81
  char temp[128]  = {0};
82
  
83
  errno = TSDB_CODE_SUCCESS;
H
hzcheng 已提交
84
  srand(taosGetTimestampSec());
L
lihui 已提交
85
  deltaToUtcInitOnce();
H
hzcheng 已提交
86 87 88 89

  if (tscEmbedded == 0) {

    // Read global configuration.
S
slguan 已提交
90 91
    taosInitGlobalCfg();
    taosReadGlobalLogCfg();
H
hzcheng 已提交
92 93

    // For log directory
94 95 96
    if (mkdir(tsLogDir, 0755) != 0 && errno != EEXIST) {
      printf("failed to create log dir:%s\n", tsLogDir);
    }
H
hzcheng 已提交
97

S
slguan 已提交
98
    sprintf(temp, "%s/taoslog", tsLogDir);
H
hzcheng 已提交
99
    if (taosInitLog(temp, tsNumOfLogLines, 10) < 0) {
S
slguan 已提交
100
      printf("failed to open log file in directory:%s\n", tsLogDir);
H
hzcheng 已提交
101 102
    }

S
slguan 已提交
103
    taosReadGlobalCfg();
S
TD-1663  
Shengliang Guan 已提交
104
    taosCheckGlobalCfg();
S
TD-2371  
Shengliang Guan 已提交
105
    taosInitNotes();
H
hzcheng 已提交
106

107
    rpcInit();
108 109
    tscDebug("starting to initialize TAOS client ...");
    tscDebug("Local End Point is:%s", tsLocalEp);
H
hzcheng 已提交
110 111
  }

L
lihui 已提交
112
  taosSetCoreDump();
113
  tscInitMsgsFp();
114
  int queueSize = tsMaxConnections*2;
H
hzcheng 已提交
115

116
  double factor = (tscEmbedded == 0)? 2.0:4.0;
117
  int32_t tscNumOfThreads = (int)(tsNumOfCores * tsNumOfThreadsPerCore / factor);
H
Haojun Liao 已提交
118 119 120
  if (tscNumOfThreads < 2) {
    tscNumOfThreads = 2;
  }
H
hzcheng 已提交
121 122

  tscQhandle = taosInitScheduler(queueSize, tscNumOfThreads, "tsc");
S
slguan 已提交
123 124 125 126
  if (NULL == tscQhandle) {
    tscError("failed to init scheduler");
    return;
  }
H
hzcheng 已提交
127

128
  tscTmr = taosTmrInit(tsMaxConnections * 2, 200, 60000, "TSC");
S
slguan 已提交
129 130
  if(0 == tscEmbedded){
    taosTmrReset(tscCheckDiskUsage, 10, NULL, tscTmr, &tscCheckDiskUsageTmr);      
S
slguan 已提交
131
  }
H
hzcheng 已提交
132

133
  int64_t refreshTime = 10; // 10 seconds by default
H
Haojun Liao 已提交
134
  if (tscMetaCache == NULL) {
135
    tscMetaCache = taosCacheInit(TSDB_DATA_TYPE_BINARY, refreshTime, false, NULL, "tableMeta");
H
Haojun Liao 已提交
136 137
    tscObjRef  = taosOpenRef(40960, tscFreeRegisteredSqlObj);
    tscHashMap = taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
138 139
    tscTableMetaInfo = taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
    tscDebug("TableMeta:%p", tscTableMetaInfo);
140
  }
H
hzcheng 已提交
141

陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
142 143
  tscRefId = taosOpenRef(200, tscCloseTscObj);

H
Haojun Liao 已提交
144 145 146 147
  // in other language APIs, taos_cleanup is not available yet.
  // So, to make sure taos_cleanup will be invoked to clean up the allocated
  // resource to suppress the valgrind warning.
  atexit(taos_cleanup);
148
  tscDebug("client is initialized successfully");
H
hzcheng 已提交
149 150 151 152
}

void taos_init() { pthread_once(&tscinit, taos_init_imp); }

H
Haojun Liao 已提交
153
// this function may be called by user or system, or by both simultaneously.
S
Shengliang Guan 已提交
154
void taos_cleanup(void) {
H
Haojun Liao 已提交
155
  tscDebug("start to cleanup client environment");
H
Haojun Liao 已提交
156

H
Haojun Liao 已提交
157 158 159
  void* m = tscMetaCache;
  if (m != NULL && atomic_val_compare_exchange_ptr(&tscMetaCache, m, 0) == m) {
    taosCacheCleanup(m);
160
  }
H
Haojun Liao 已提交
161

162 163 164
  int refId = atomic_exchange_32(&tscObjRef, -1);
  if (refId != -1) {
    taosCloseRef(refId);
H
Haojun Liao 已提交
165 166 167 168 169
  }

  m = tscQhandle;
  if (m != NULL && atomic_val_compare_exchange_ptr(&tscQhandle, m, 0) == m) {
    taosCleanUpScheduler(m);
170
  }
H
Haojun Liao 已提交
171

陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
172
  taosCloseRef(tscRefId);
H
Haojun Liao 已提交
173
  taosCleanupKeywordsTable();
S
slguan 已提交
174
  taosCloseLog();
175
  if (tscEmbedded == 0) rpcCleanup();
H
Haojun Liao 已提交
176 177 178 179 180

  m = tscTmr;
  if (m != NULL && atomic_val_compare_exchange_ptr(&tscTmr, m, 0) == m) {
    taosTmrCleanUp(m);
  }
181 182
}

weixin_48148422's avatar
weixin_48148422 已提交
183
static int taos_options_imp(TSDB_OPTION option, const char *pStr) {
S
slguan 已提交
184
  SGlobalCfg *cfg = NULL;
H
hzcheng 已提交
185 186 187

  switch (option) {
    case TSDB_OPTION_CONFIGDIR:
S
slguan 已提交
188
      cfg = taosGetConfigOption("configDir");
H
hjxilinx 已提交
189 190
      assert(cfg != NULL);
    
S
slguan 已提交
191
      if (cfg->cfgStatus <= TAOS_CFG_CSTATUS_OPTION) {
B
Bomin Zhang 已提交
192
        tstrncpy(configDir, pStr, TSDB_FILENAME_LEN);
S
slguan 已提交
193
        cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION;
194
        tscInfo("set config file directory:%s", pStr);
H
hzcheng 已提交
195
      } else {
weixin_48148422's avatar
weixin_48148422 已提交
196 197
        tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg->option, pStr,
                tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
H
hzcheng 已提交
198 199
      }
      break;
S
slguan 已提交
200

H
hzcheng 已提交
201
    case TSDB_OPTION_SHELL_ACTIVITY_TIMER:
S
slguan 已提交
202
      cfg = taosGetConfigOption("shellActivityTimer");
H
hjxilinx 已提交
203 204
      assert(cfg != NULL);
    
S
slguan 已提交
205
      if (cfg->cfgStatus <= TAOS_CFG_CSTATUS_OPTION) {
weixin_48148422's avatar
weixin_48148422 已提交
206
        tsShellActivityTimer = atoi(pStr);
H
hzcheng 已提交
207 208
        if (tsShellActivityTimer < 1) tsShellActivityTimer = 1;
        if (tsShellActivityTimer > 3600) tsShellActivityTimer = 3600;
S
slguan 已提交
209
        cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION;
210
        tscInfo("set shellActivityTimer:%d", tsShellActivityTimer);
H
hzcheng 已提交
211
      } else {
weixin_48148422's avatar
weixin_48148422 已提交
212
        tscWarn("config option:%s, input value:%s, is configured by %s, use %d", cfg->option, pStr,
213
                tsCfgStatusStr[cfg->cfgStatus], *(int32_t *)cfg->ptr);
H
hzcheng 已提交
214 215
      }
      break;
S
slguan 已提交
216

H
hzcheng 已提交
217
    case TSDB_OPTION_LOCALE: {  // set locale
S
slguan 已提交
218
      cfg = taosGetConfigOption("locale");
H
hjxilinx 已提交
219 220
      assert(cfg != NULL);
  
H
hzcheng 已提交
221 222
      size_t len = strlen(pStr);
      if (len == 0 || len > TSDB_LOCALE_LEN) {
223
        tscInfo("Invalid locale:%s, use default", pStr);
H
hzcheng 已提交
224 225 226
        return -1;
      }

S
slguan 已提交
227
      if (cfg->cfgStatus <= TAOS_CFG_CSTATUS_OPTION) {
H
hzcheng 已提交
228 229
        char sep = '.';

S
slguan 已提交
230 231
        if (strlen(tsLocale) == 0) { // locale does not set yet
          char* defaultLocale = setlocale(LC_CTYPE, "");
S
Shengliang Guan 已提交
232
          tstrncpy(tsLocale, defaultLocale, TSDB_LOCALE_LEN);
S
slguan 已提交
233 234 235
        }

        // set the user specified locale
H
hzcheng 已提交
236 237 238
        char *locale = setlocale(LC_CTYPE, pStr);

        if (locale != NULL) {
239
          tscInfo("locale set, prev locale:%s, new locale:%s", tsLocale, locale);
S
slguan 已提交
240
          cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION;
S
slguan 已提交
241
        } else { // set the user-specified localed failed, use default LC_CTYPE as current locale
S
slguan 已提交
242
          locale = setlocale(LC_CTYPE, tsLocale);
243
          tscInfo("failed to set locale:%s, current locale:%s", pStr, tsLocale);
H
hzcheng 已提交
244 245
        }

S
Shengliang Guan 已提交
246
        tstrncpy(tsLocale, locale, TSDB_LOCALE_LEN);
H
hzcheng 已提交
247 248 249 250 251 252 253 254

        char *charset = strrchr(tsLocale, sep);
        if (charset != NULL) {
          charset += 1;

          charset = taosCharsetReplace(charset);

          if (taosValidateEncodec(charset)) {
S
slguan 已提交
255
            if (strlen(tsCharset) == 0) {
256
              tscInfo("charset set:%s", charset);
S
slguan 已提交
257
            } else {
258
              tscInfo("charset changed from %s to %s", tsCharset, charset);
S
slguan 已提交
259 260
            }

S
Shengliang Guan 已提交
261
            tstrncpy(tsCharset, charset, TSDB_LOCALE_LEN);
S
slguan 已提交
262
            cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION;
S
slguan 已提交
263

H
hzcheng 已提交
264
          } else {
265
            tscInfo("charset:%s is not valid in locale, charset remains:%s", charset, tsCharset);
H
hzcheng 已提交
266
          }
S
slguan 已提交
267

H
hzcheng 已提交
268
          free(charset);
S
slguan 已提交
269
        } else { // it may be windows system
270
          tscInfo("charset remains:%s", tsCharset);
H
hzcheng 已提交
271 272
        }
      } else {
weixin_48148422's avatar
weixin_48148422 已提交
273 274
        tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg->option, pStr,
                tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
H
hzcheng 已提交
275 276 277 278 279 280
      }
      break;
    }

    case TSDB_OPTION_CHARSET: {
      /* set charset will override the value of charset, assigned during system locale changed */
S
slguan 已提交
281
      cfg = taosGetConfigOption("charset");
H
hjxilinx 已提交
282 283
      assert(cfg != NULL);
      
H
hzcheng 已提交
284 285
      size_t len = strlen(pStr);
      if (len == 0 || len > TSDB_LOCALE_LEN) {
286
        tscInfo("failed to set charset:%s", pStr);
H
hzcheng 已提交
287 288 289
        return -1;
      }

S
slguan 已提交
290
      if (cfg->cfgStatus <= TAOS_CFG_CSTATUS_OPTION) {
H
hzcheng 已提交
291
        if (taosValidateEncodec(pStr)) {
S
slguan 已提交
292
          if (strlen(tsCharset) == 0) {
293
            tscInfo("charset is set:%s", pStr);
S
slguan 已提交
294
          } else {
295
            tscInfo("charset changed from %s to %s", tsCharset, pStr);
S
slguan 已提交
296 297
          }

S
Shengliang Guan 已提交
298
          tstrncpy(tsCharset, pStr, TSDB_LOCALE_LEN);
S
slguan 已提交
299
          cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION;
H
hzcheng 已提交
300
        } else {
301
          tscInfo("charset:%s not valid", pStr);
H
hzcheng 已提交
302 303
        }
      } else {
weixin_48148422's avatar
weixin_48148422 已提交
304 305
        tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg->option, pStr,
                tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
H
hzcheng 已提交
306 307 308 309 310 311
      }

      break;
    }

    case TSDB_OPTION_TIMEZONE:
S
slguan 已提交
312
      cfg = taosGetConfigOption("timezone");
H
hjxilinx 已提交
313 314
      assert(cfg != NULL);
    
S
slguan 已提交
315
      if (cfg->cfgStatus <= TAOS_CFG_CSTATUS_OPTION) {
S
Shengliang Guan 已提交
316
        tstrncpy(tsTimezone, pStr, TSDB_TIMEZONE_LEN);
H
hzcheng 已提交
317
        tsSetTimeZone();
S
slguan 已提交
318
        cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION;
319
        tscDebug("timezone set:%s, input:%s by taos_options", tsTimezone, pStr);
H
hzcheng 已提交
320
      } else {
weixin_48148422's avatar
weixin_48148422 已提交
321 322
        tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg->option, pStr,
                tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
H
hzcheng 已提交
323 324
      }
      break;
325

H
hzcheng 已提交
326
    default:
H
hjxilinx 已提交
327
      // TODO return the correct error code to client in the format for taos_errstr()
H
hzcheng 已提交
328 329 330 331 332 333
      tscError("Invalid option %d", option);
      return -1;
  }

  return 0;
}
weixin_48148422's avatar
weixin_48148422 已提交
334 335 336 337 338 339

int taos_options(TSDB_OPTION option, const void *arg, ...) {
  static int32_t lock = 0;

  for (int i = 1; atomic_val_compare_exchange_32(&lock, 0, 1) != 0; ++i) {
    if (i % 1000 == 0) {
340
      tscInfo("haven't acquire lock after spin %d times.", i);
weixin_48148422's avatar
weixin_48148422 已提交
341 342 343 344 345 346 347 348
      sched_yield();
    }
  }

  int ret = taos_options_imp(option, (const char*)arg);

  atomic_store_32(&lock, 0);
  return ret;
L
lihui 已提交
349
}