提交 2b6f415a 编写于 作者: S Shengliang Guan

remove invalid tests

上级 f469521f
/*
* 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/>.
*/
#define _DEFAULT_SOURCE
#include <malloc.h>
#include "../../../include/client/taos.h"
#include "os.h"
#include "tcache.h"
#include "tulog.h"
#include "tutil.h"
#define MAX_REFRESH_TIME_SEC 2
#define MAX_RANDOM_POINTS 20000
#define GREEN "\033[1;32m"
#define NC "\033[0m"
int32_t tsKeepTimeInSec = 3;
int32_t tsNumOfRows = 1000000;
int32_t tsSizeOfRow = 64 * 1024;
void * tsCacheObj = NULL;
int32_t destroyTimes = 0;
typedef int64_t CacheTestKey;
typedef struct CacheTestRow {
int32_t index;
void ** ppRow;
void * data;
} CacheTestRow;
CacheTestRow *initRow(int32_t index) {
CacheTestRow *row = calloc(sizeof(CacheTestRow), 1);
row->index = index;
row->data = malloc(tsSizeOfRow * sizeof(int8_t));
return row;
}
void detroyRow(void *data) {
CacheTestRow *row = *(CacheTestRow **)data;
free(row->data);
free(row);
destroyTimes++;
if (destroyTimes % 50000 == 0) {
pPrint("%s ===> destroyTimes:%d %s", GREEN, destroyTimes, NC);
}
}
void initCache() {
tsCacheObj = taosCacheInit(TSDB_DATA_TYPE_BIGINT, MAX_REFRESH_TIME_SEC, true, detroyRow, "cachetest");
}
void putRowInCache() {
for (int index = 0; index < tsNumOfRows; ++index) {
CacheTestRow *row = initRow(index);
uint64_t key = (uint64_t)row;
void **ppRow = taosCachePut(tsCacheObj, &key, sizeof(int64_t), &row, sizeof(int64_t), tsKeepTimeInSec * 1000);
row->ppRow = ppRow;
taosCacheRelease(tsCacheObj, (void **)&ppRow, false);
}
}
void cleanupCache() {
taosCacheCleanup(tsCacheObj);
}
void initGetMemory() {
osInit();
taos_init();
}
float getProcMemory() {
float procMemoryUsedMB = 0;
taosGetProcMemory(&procMemoryUsedMB);
return procMemoryUsedMB;
}
void doTest() {
initCache();
pPrint("%s initialize procMemory %f MB %s", GREEN, getProcMemory(), NC);
putRowInCache();
pPrint("%s insert %d rows, procMemory %f MB %s", GREEN, tsNumOfRows, getProcMemory(), NC);
int32_t sleepMs = (MAX_REFRESH_TIME_SEC * 3) * 1000 + tsKeepTimeInSec * 1000;
taosMsleep(sleepMs);
pPrint("%s after sleep %d ms, procMemory %f MB %s", GREEN, sleepMs, getProcMemory(), NC);
cleanupCache();
taosMsleep(sleepMs);
pPrint("%s after cleanup cache, procMemory %f MB %s", GREEN, getProcMemory(), NC);
malloc_trim(0);
taosMsleep(sleepMs);
pPrint("%s after malloc_trim, procMemory %f MB %s", GREEN, getProcMemory(), NC);
}
void printHelp() {
char indent[10] = " ";
printf("Used to test the performance of cache\n");
printf("%s%s\n", indent, "-k");
printf("%s%s%s%d\n", indent, indent, "KeepTimeInSec, default is ", tsKeepTimeInSec);
printf("%s%s\n", indent, "-n");
printf("%s%s%s%d\n", indent, indent, "NumOfRows, default is ", tsNumOfRows);
printf("%s%s\n", indent, "-s");
printf("%s%s%s%d\n", indent, indent, "SizeOfData, default is ", tsSizeOfRow);
exit(EXIT_SUCCESS);
}
void parseArgument(int argc, char *argv[]) {
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
printHelp();
exit(0);
} else if (strcmp(argv[i], "-k") == 0) {
tsKeepTimeInSec = atoi(argv[++i]);
} else if (strcmp(argv[i], "-n") == 0) {
tsNumOfRows = atoi(argv[++i]);
} else if (strcmp(argv[i], "-s") == 0) {
tsSizeOfRow = atoi(argv[++i]);
} else {
}
}
pPrint("%s KeepTimeInSec:%d %s", GREEN, tsKeepTimeInSec, NC);
pPrint("%s NumOfRows:%d %s", GREEN, tsNumOfRows, NC);
pPrint("%s SizeOfData:%d %s", GREEN, tsSizeOfRow, NC);
}
int main(int argc, char *argv[]) {
initGetMemory();
parseArgument(argc, argv);
doTest();
}
/*
* 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/>.
*/
#define _DEFAULT_SOURCE
#include "../../../include/client/taos.h"
#include "hash.h"
#include "os.h"
#include "taoserror.h"
#include "tglobal.h"
#include "tulog.h"
#include "tutil.h"
#define MAX_RANDOM_POINTS 20000
#define GREEN "\033[1;32m"
#define NC "\033[0m"
char dbName[32] = "db";
char stableName[64] = "st";
int32_t numOfThreads = 30;
int32_t numOfTables = 100000;
int32_t replica = 1;
int32_t numOfColumns = 2;
TAOS * con = NULL;
typedef struct {
int32_t tableBeginIndex;
int32_t tableEndIndex;
int32_t threadIndex;
char dbName[32];
char stableName[64];
float createTableSpeed;
pthread_t thread;
} SThreadInfo;
void shellParseArgument(int argc, char *argv[]);
void *threadFunc(void *param);
void createDbAndSTable();
int main(int argc, char *argv[]) {
shellParseArgument(argc, argv);
taos_init();
createDbAndSTable();
pPrint("%d threads are spawned to create table", numOfThreads);
pthread_attr_t thattr;
pthread_attr_init(&thattr);
pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
SThreadInfo *pInfo = (SThreadInfo *)calloc(numOfThreads, sizeof(SThreadInfo));
int32_t numOfTablesPerThread = numOfTables / numOfThreads;
numOfTables = numOfTablesPerThread * numOfThreads;
for (int i = 0; i < numOfThreads; ++i) {
pInfo[i].tableBeginIndex = i * numOfTablesPerThread;
pInfo[i].tableEndIndex = (i + 1) * numOfTablesPerThread;
pInfo[i].threadIndex = i;
strcpy(pInfo[i].dbName, dbName);
strcpy(pInfo[i].stableName, stableName);
pthread_create(&(pInfo[i].thread), &thattr, threadFunc, (void *)(pInfo + i));
}
taosMsleep(300);
for (int i = 0; i < numOfThreads; i++) {
pthread_join(pInfo[i].thread, NULL);
}
float createTableSpeed = 0;
for (int i = 0; i < numOfThreads; ++i) {
createTableSpeed += pInfo[i].createTableSpeed;
}
pPrint("%s total speed:%.1f tables/second, threads:%d %s", GREEN, createTableSpeed, numOfThreads, NC);
pthread_attr_destroy(&thattr);
free(pInfo);
taos_close(con);
}
void createDbAndSTable() {
pPrint("start to create db and stable");
char qstr[64000];
con = taos_connect(NULL, "root", "taosdata", NULL, 0);
if (con == NULL) {
pError("failed to connect to DB, reason:%s", taos_errstr(con));
exit(1);
}
sprintf(qstr, "create database if not exists %s replica %d", dbName, replica);
TAOS_RES *pSql = taos_query(con, qstr);
int32_t code = taos_errno(pSql);
if (code != 0) {
pError("failed to create database:%s, sql:%s, code:%d reason:%s", dbName, qstr, taos_errno(con), taos_errstr(con));
exit(0);
}
taos_free_result(pSql);
sprintf(qstr, "use %s", dbName);
pSql = taos_query(con, qstr);
code = taos_errno(pSql);
if (code != 0) {
pError("failed to use db, code:%d reason:%s", taos_errno(con), taos_errstr(con));
exit(0);
}
taos_free_result(pSql);
int len = sprintf(qstr, "create table if not exists %s(ts timestamp", stableName);
for (int32_t f = 0; f < numOfColumns - 1; ++f) {
len += sprintf(qstr + len, ", f%d double", f);
}
sprintf(qstr + len, ") tags(t int)");
pSql = taos_query(con, qstr);
code = taos_errno(pSql);
if (code != 0) {
pError("failed to create stable, code:%d reason:%s", taos_errno(con), taos_errstr(con));
exit(0);
}
taos_free_result(pSql);
}
void *threadFunc(void *param) {
SThreadInfo *pInfo = (SThreadInfo *)param;
char qstr[65000];
int code;
sprintf(qstr, "use %s", pInfo->dbName);
TAOS_RES *pSql = taos_query(con, qstr);
taos_free_result(pSql);
int64_t startMs = taosGetTimestampMs();
for (int32_t t = pInfo->tableBeginIndex; t < pInfo->tableEndIndex; ++t) {
sprintf(qstr, "create table if not exists %s%d using %s tags(%d)", stableName, t, stableName, t);
TAOS_RES *pSql = taos_query(con, qstr);
code = taos_errno(pSql);
if (code != 0) {
pError("failed to create table %s%d, reason:%s", stableName, t, tstrerror(code));
}
taos_free_result(pSql);
}
float createTableSpeed = 0;
for (int i = 0; i < numOfThreads; ++i) {
createTableSpeed += pInfo[i].createTableSpeed;
}
int64_t endMs = taosGetTimestampMs();
int32_t totalTables = pInfo->tableEndIndex - pInfo->tableBeginIndex;
float seconds = (endMs - startMs) / 1000.0;
float speed = totalTables / seconds;
pInfo->createTableSpeed = speed;
pPrint("thread:%d, time:%.2f sec, speed:%.1f tables/second, ", pInfo->threadIndex, seconds, speed);
return 0;
}
void printHelp() {
char indent[10] = " ";
printf("Used to test the performance while create table\n");
printf("%s%s\n", indent, "-c");
printf("%s%s%s%s\n", indent, indent, "Configuration directory, default is ", configDir);
printf("%s%s\n", indent, "-d");
printf("%s%s%s%s\n", indent, indent, "The name of the database to be created, default is ", dbName);
printf("%s%s\n", indent, "-s");
printf("%s%s%s%s\n", indent, indent, "The name of the super table to be created, default is ", stableName);
printf("%s%s\n", indent, "-t");
printf("%s%s%s%d\n", indent, indent, "numOfThreads, default is ", numOfThreads);
printf("%s%s\n", indent, "-n");
printf("%s%s%s%d\n", indent, indent, "numOfTables, default is ", numOfTables);
printf("%s%s\n", indent, "-r");
printf("%s%s%s%d\n", indent, indent, "replica, default is ", replica);
printf("%s%s\n", indent, "-columns");
printf("%s%s%s%d\n", indent, indent, "numOfColumns, default is ", numOfColumns);
exit(EXIT_SUCCESS);
}
void shellParseArgument(int argc, char *argv[]) {
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
printHelp();
exit(0);
} else if (strcmp(argv[i], "-d") == 0) {
strcpy(dbName, argv[++i]);
} else if (strcmp(argv[i], "-c") == 0) {
strcpy(configDir, argv[++i]);
} else if (strcmp(argv[i], "-s") == 0) {
strcpy(stableName, argv[++i]);
} else if (strcmp(argv[i], "-t") == 0) {
numOfThreads = atoi(argv[++i]);
} else if (strcmp(argv[i], "-n") == 0) {
numOfTables = atoi(argv[++i]);
} else if (strcmp(argv[i], "-r") == 0) {
replica = atoi(argv[++i]);
} else if (strcmp(argv[i], "-columns") == 0) {
numOfColumns = atoi(argv[++i]);
} else {
}
}
pPrint("%s dbName:%s %s", GREEN, dbName, NC);
pPrint("%s stableName:%s %s", GREEN, stableName, NC);
pPrint("%s configDir:%s %s", GREEN, configDir, NC);
pPrint("%s numOfTables:%d %s", GREEN, numOfTables, NC);
pPrint("%s numOfThreads:%d %s", GREEN, numOfThreads, NC);
pPrint("%s numOfColumns:%d %s", GREEN, numOfColumns, NC);
pPrint("%s replica:%d %s", GREEN, replica, NC);
pPrint("%s start create table performace test %s", GREEN, NC);
}
/*
* 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/>.
*/
#define _DEFAULT_SOURCE
#include "../../../include/client/taos.h"
#include "hash.h"
#include "os.h"
#include "tulog.h"
#include "tutil.h"
typedef struct HashTestRow {
int32_t keySize;
char key[100];
} HashTestRow;
int main(int argc, char *argv[]) {
_hash_fn_t hashFp = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
void * hashHandle = taosHashInit(100, hashFp, true, HASH_ENTRY_LOCK);
pPrint("insert 3 rows to hash");
for (int32_t t = 0; t < 3; ++t) {
HashTestRow row = {0};
row.keySize = sprintf(row.key, "0.db.st%d", t);
taosHashPut(hashHandle, row.key, row.keySize, &row, sizeof(HashTestRow));
}
pPrint("start iterator");
HashTestRow *row = taosHashIterate(hashHandle, NULL);
while (row) {
pPrint("drop key:%s", row->key);
taosHashRemove(hashHandle, row->key, row->keySize);
pPrint("get rows from hash");
for (int32_t t = 0; t < 3; ++t) {
HashTestRow r = {0};
r.keySize = sprintf(r.key, "0.db.st%d", t);
void *result = taosHashGet(hashHandle, r.key, r.keySize);
pPrint("get key:%s result:%p", r.key, result);
}
//Before getting the next iterator, the object just deleted can be obtained
row = taosHashIterate(hashHandle, row);
}
pPrint("stop iterator");
taosHashCancelIterate(hashHandle, row);
pPrint("get rows from hash");
for (int32_t t = 0; t < 3; ++t) {
HashTestRow r = {0};
r.keySize = sprintf(r.key, "0.db.st%d", t);
void *result = taosHashGet(hashHandle, r.key, r.keySize);
pPrint("get key:%s result:%p", r.key, result);
}
return 0;
}
\ No newline at end of file
/*
* 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/>.
*/
#define _DEFAULT_SOURCE
#include "../../../include/client/taos.h"
#include "hash.h"
#include "os.h"
#include "tulog.h"
#include "tutil.h"
#define MAX_RANDOM_POINTS 20000
#define GREEN "\033[1;32m"
#define NC "\033[0m"
int32_t capacity = 128;
int32_t q1Times = 10;
int32_t q2Times = 10;
int32_t keyNum = 100000;
int32_t printInterval = 1000;
void * hashHandle;
pthread_t thread;
typedef struct HashTestRow {
int32_t keySize;
char key[100];
} HashTestRow;
void shellParseArgument(int argc, char *argv[]);
void testHashPerformance() {
int64_t initialMs = taosGetTimestampMs();
_hash_fn_t hashFp = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
hashHandle = taosHashInit(128, hashFp, true, HASH_NO_LOCK);
int64_t startMs = taosGetTimestampMs();
float seconds = (startMs - initialMs) / 1000.0;
pPrint("initial time %.2f sec", seconds);
for (int32_t t = 1; t <= keyNum; ++t) {
HashTestRow row = {0};
row.keySize = sprintf(row.key, "0.db.st%d", t);
for (int32_t q = 0; q < q1Times; q++) {
taosHashGet(hashHandle, row.key, row.keySize);
}
taosHashPut(hashHandle, row.key, row.keySize, &row, sizeof(HashTestRow));
for (int32_t q = 0; q < q2Times; q++) {
taosHashGet(hashHandle, row.key, row.keySize);
}
// test iterator
{
HashTestRow *row = taosHashIterate(hashHandle, NULL);
while (row) {
taosHashGet(hashHandle, row->key, row->keySize);
row = taosHashIterate(hashHandle, row);
}
}
if (t % printInterval == 0) {
int64_t endMs = taosGetTimestampMs();
int64_t hashSize = taosHashGetSize(hashHandle);
float seconds = (endMs - startMs) / 1000.0;
float speed = printInterval / seconds;
pPrint("time:%.2f sec, speed:%.1f rows/second, hashSize:%ld", seconds, speed, hashSize);
startMs = endMs;
}
}
int64_t endMs = taosGetTimestampMs();
int64_t hashSize = taosHashGetSize(hashHandle);
seconds = (endMs - initialMs) / 1000.0;
float speed = hashSize / seconds;
pPrint("total time:%.2f sec, avg speed:%.1f rows/second, hashSize:%ld", seconds, speed, hashSize);
taosHashCleanup(hashHandle);
}
void *multiThreadFunc(void *param) {
for (int i = 0; i < 100; ++i) {
taosMsleep(1000);
HashTestRow *row = taosHashIterate(hashHandle, NULL);
while (row) {
taosHashGet(hashHandle, row->key, row->keySize);
row = taosHashIterate(hashHandle, row);
}
int64_t hashSize = taosHashGetSize(hashHandle);
pPrint("i:%d hashSize:%ld", i, hashSize);
}
return NULL;
}
void multiThreadTest() {
pthread_attr_t thattr;
pthread_attr_init(&thattr);
pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
// Start threads to write
pthread_create(&thread, &thattr, multiThreadFunc, NULL);
}
int main(int argc, char *argv[]) {
shellParseArgument(argc, argv);
multiThreadTest();
testHashPerformance();
pthread_join(thread, NULL);
}
void printHelp() {
char indent[10] = " ";
printf("Used to test the performance of cache\n");
printf("%s%s\n", indent, "-k");
printf("%s%s%s%d\n", indent, indent, "key num, default is ", keyNum);
printf("%s%s\n", indent, "-p");
printf("%s%s%s%d\n", indent, indent, "print interval while put into hash, default is ", printInterval);
printf("%s%s\n", indent, "-c");
printf("%s%s%s%d\n", indent, indent, "the initial capacity of hash ", capacity);
printf("%s%s\n", indent, "-q1");
printf("%s%s%s%d\n", indent, indent, "query times before put into hash", q1Times);
printf("%s%s\n", indent, "-q2");
printf("%s%s%s%d\n", indent, indent, "query times after put into hash", q2Times);
exit(EXIT_SUCCESS);
}
void shellParseArgument(int argc, char *argv[]) {
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
printHelp();
exit(0);
} else if (strcmp(argv[i], "-k") == 0) {
keyNum = atoi(argv[++i]);
} else if (strcmp(argv[i], "-p") == 0) {
printInterval = atoi(argv[++i]);
} else if (strcmp(argv[i], "-c") == 0) {
capacity = atoi(argv[++i]);
} else if (strcmp(argv[i], "-q1") == 0) {
q1Times = atoi(argv[++i]);
} else if (strcmp(argv[i], "-q2") == 0) {
q2Times = atoi(argv[++i]);
} else {
}
}
pPrint("%s capacity:%d %s", GREEN, capacity, NC);
pPrint("%s printInterval:%d %s", GREEN, printInterval, NC);
pPrint("%s q1Times:%d %s", GREEN, q1Times, NC);
pPrint("%s q2Times:%d %s", GREEN, q2Times, NC);
pPrint("%s keyNum:%d %s", GREEN, keyNum, NC);
}
/*
* 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/>.
*/
#include "os.h"
#include "os.h"
#include "tglobal.h"
#include "taoserror.h"
#include "httpSystem.h"
void signal_handler(int signum) {
httpStopSystem();
httpCleanUpSystem();
exit(EXIT_SUCCESS);
}
int main(int argc, char *argv[]) {
struct sigaction act;
act.sa_handler = signal_handler;
sigaction(SIGTERM, &act, NULL);
sigaction(SIGHUP, &act, NULL);
sigaction(SIGINT, &act, NULL);
sigaction(SIGABRT, &act, NULL);
// Initialize the system
if (httpInitSystem() < 0) {
exit(EXIT_FAILURE);
}
if (httpStartSystem() < 0) {
exit(EXIT_FAILURE);
}
while (1) {
sleep(1000);
}
}
/*
* 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/>.
*/
#define _DEFAULT_SOURCE
#include "../../../include/client/taos.h"
#include "os.h"
#include "tglobal.h"
#include "ttimer.h"
#include "tulog.h"
#include "tutil.h"
#define MAX_RANDOM_POINTS 20000
#define GREEN "\033[1;32m"
#define NC "\033[0m"
void taos_error(TAOS *taos);
void* taos_execute(void *param);
typedef struct {
pthread_t pid;
int index;
} ThreadObj;
int threadNum = 1;
int rowNum = 1000;
int replica = 1;
void printHelp() {
char indent[10] = " ";
printf("Used to test the performance of TDengine\n After writing one row of data to all tables, write the next row\n");
printf("%s%s\n", indent, "-r");
printf("%s%s%s%d\n", indent, indent, "Number of records to write table, default is ", rowNum);
printf("%s%s\n", indent, "-t");
printf("%s%s%s%d\n", indent, indent, "Number of threads to be used, default is ", threadNum);
printf("%s%s\n", indent, "-replica");
printf("%s%s%s%d\n", indent, indent, "Database parameters replica, default is ", replica);
exit(EXIT_SUCCESS);
}
void shellParseArgument(int argc, char *argv[]) {
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
printHelp();
exit(0);
} else if (strcmp(argv[i], "-r") == 0) {
rowNum = atoi(argv[++i]);
} else if (strcmp(argv[i], "-t") == 0) {
threadNum = atoi(argv[++i]);
} else if (strcmp(argv[i], "-replica") == 0) {
replica = atoi(argv[++i]);
} else {
}
}
pPrint("%s rowNum:%d %s", GREEN, rowNum, NC);
pPrint("%s threadNum:%d %s", GREEN, threadNum, NC);
pPrint("%s replica:%d %s", GREEN, replica, NC);
}
int main(int argc, char *argv[]) {
shellParseArgument(argc, argv);
taos_init();
ThreadObj *threads = calloc(threadNum, sizeof(ThreadObj));
for (int i = 0; i < threadNum; ++i) {
ThreadObj * pthread = threads + i;
pthread_attr_t thattr;
pthread->index = i;
pthread_attr_init(&thattr);
pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
pthread_create(&pthread->pid, &thattr, taos_execute, pthread);
}
for (int i = 0; i < threadNum; i++) {
pthread_join(threads[i].pid, NULL);
}
printf("all finished\n");
return 0;
}
void taos_error(TAOS *con) {
fprintf(stderr, "TDengine error: %s\n", taos_errstr(con));
taos_close(con);
exit(1);
}
void* taos_execute(void *param) {
ThreadObj *pThread = (ThreadObj *)param;
char fqdn[TSDB_FQDN_LEN];
uint16_t port;
taosGetFqdnPortFromEp(tsFirst, fqdn, &port);
void *taos = taos_connect(fqdn, "root", "taosdata", NULL, port);
if (taos == NULL) taos_error(taos);
char sql[1024] = {0};
sprintf(sql, "create database if not exists db replica %d", replica);
taos_query(taos, sql);
sprintf(sql, "create table if not exists db.t%d (ts timestamp, i int, j float, k double)", pThread->index);
taos_query(taos, sql);
int64_t timestamp = 1530374400000L;
sprintf(sql, "insert into db.t%d values(%ld, %d, %d, %d)", pThread->index, timestamp, 0, 0, 0);
TAOS_RES *pSql = taos_query(taos, sql);
int code = taos_errno(pSql);
if (code != 0)
{
printf("error code:%d, sql:%s\n", code, sql);
taos_free_result(pSql);
taos_close(taos);
return NULL;
}
int affectrows = taos_affected_rows(taos);
if (affectrows != 1)
{
printf("affect rows:%d, sql:%s\n", affectrows, sql);
taos_free_result(pSql);
taos_close(taos);
return NULL;
}
taos_free_result(pSql);
pSql = NULL;
timestamp -= 1000;
int total_affect_rows = affectrows;
for (int i = 1; i < rowNum; ++i) {
sprintf(sql, "import into db.t%d values(%ld, %d, %d, %d)", pThread->index, timestamp, i, i, i);
pSql = taos_query(taos, sql);
code = taos_errno(pSql);
if (code != 0)
{
printf("error code:%d, sql:%s\n", code, sql);
taos_free_result(pSql);
pSql = NULL;
taos_close(taos);
return NULL;
}
int affectrows = taos_affected_rows(taos);
if (affectrows != 1) {
printf("affect rows:%d, sql:%s\n", affectrows, sql);
taos_free_result(pSql);
pSql = NULL;
taos_close(taos);
}
total_affect_rows += affectrows;
taos_free_result(pSql);
pSql = NULL;
timestamp -= 1000;
}
printf("thread:%d run finished total_affect_rows:%d\n", pThread->index, total_affect_rows);
taos_close(taos);
return NULL;
}
/*
* 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/>.
*/
#define _DEFAULT_SOURCE
#include "../../../include/client/taos.h"
#include "os.h"
#include "osTime.h"
#include "tglobal.h"
#include "ttimer.h"
#include "tulog.h"
#include "tutil.h"
#define MAX_RANDOM_POINTS 20000
#define GREEN "\033[1;32m"
#define NC "\033[0m"
typedef struct {
int64_t rowsPerTable;
int64_t pointsPerTable;
int64_t tableBeginIndex;
int64_t tableEndIndex;
int threadIndex;
char dbName[32];
char stableName[64];
pthread_t thread;
} SInfo;
void *syncTest(void *param);
void generateRandomPoints();
void shellParseArgument(int argc, char *argv[]);
void createDbAndTable();
void insertData();
int32_t randomData[MAX_RANDOM_POINTS];
int64_t rowsPerTable = 1000000;
int64_t pointsPerTable = 1;
int64_t numOfThreads = 10;
int64_t numOfTablesPerThread = 100;
char dbName[32] = "db";
char stableName[64] = "st";
int64_t totalUs = 0;
int64_t reqNum = 0;
int64_t maxUs = 0;
int64_t minUs = 100000000;
int main(int argc, char *argv[]) {
shellParseArgument(argc, argv);
generateRandomPoints();
taos_init();
createDbAndTable();
insertData();
int64_t avgUs = totalUs / reqNum;
pError("%s totalUs:%ld, avgUs:%ld maxUs:%ld minUs:%ld reqNum:%ld %s\n", GREEN, totalUs, avgUs, maxUs, minUs, reqNum, NC);
}
int32_t query(void *con, char *qstr) {
int64_t begin = taosGetTimestampUs();
TAOS_RES *pSql = taos_query(con, qstr);
int32_t code = taos_errno(pSql);
if (code != 0) {
pError("failed to exec sql:%s, code:%d reason:%s", qstr, taos_errno(con), taos_errstr(con));
exit(0);
}
taos_free_result(pSql);
int64_t us = taosGetTimestampUs() - begin;
maxUs = MAX(us, maxUs);
minUs = MIN(us, minUs);
atomic_add_fetch_64(&totalUs, us);
atomic_add_fetch_64(&reqNum, 1);
if (reqNum > 100000) {
int64_t avgUs = totalUs / reqNum;
if (us > avgUs * 100) {
pError("sql:%s", qstr);
pError("%s totalUs:%ld, avgUs:%ld maxUs:%ld minUs:%ld reqNum:%ld %s\n", GREEN, totalUs, avgUs, maxUs, minUs,
reqNum, NC);
taosMsleep(1000);
exit(0);
}
}
return code;
}
void createDbAndTable() {
pPrint("start to create table");
TAOS * con;
struct timeval systemTime;
int64_t st, et;
char qstr[64000];
char fqdn[TSDB_FQDN_LEN];
uint16_t port;
taosGetFqdnPortFromEp(tsFirst, fqdn, &port);
con = taos_connect(fqdn, "root", "taosdata", NULL, port);
if (con == NULL) {
pError("failed to connect to DB, reason:%s", taos_errstr(con));
exit(1);
}
sprintf(qstr, "create database if not exists %s", dbName);
if (query(con, qstr)) {
pError("failed to create database:%s, code:%d reason:%s", dbName, taos_errno(con), taos_errstr(con));
exit(0);
}
sprintf(qstr, "use %s", dbName);
if (query(con, qstr)) {
pError("failed to use db, code:%d reason:%s", taos_errno(con), taos_errstr(con));
exit(0);
}
gettimeofday(&systemTime, NULL);
st = systemTime.tv_sec * 1000000 + systemTime.tv_usec;
int64_t totalTables = numOfTablesPerThread * numOfThreads;
if (strcmp(stableName, "no") != 0) {
int len = sprintf(qstr, "create table if not exists %s(ts timestamp", stableName);
for (int64_t f = 0; f < pointsPerTable; ++f) {
len += sprintf(qstr + len, ", f%ld double", f);
}
sprintf(qstr + len, ") tags(t int)");
if (query(con, qstr)) {
pError("failed to create stable, code:%d reason:%s", taos_errno(con), taos_errstr(con));
exit(0);
}
for (int64_t t = 0; t < totalTables; ++t) {
sprintf(qstr, "create table if not exists %s%ld using %s tags(%ld)", stableName, t, stableName, t);
if (query(con, qstr)) {
pError("failed to create table %s%" PRId64 ", reason:%s", stableName, t, taos_errstr(con));
exit(0);
}
}
} else {
for (int64_t t = 0; t < totalTables; ++t) {
int len = sprintf(qstr, "create table if not exists %s%ld(ts timestamp", stableName, t);
for (int64_t f = 0; f < pointsPerTable; ++f) {
len += sprintf(qstr + len, ", f%ld double", f);
}
sprintf(qstr + len, ")");
if (query(con, qstr)) {
pError("failed to create table %s%ld, reason:%s", stableName, t, taos_errstr(con));
exit(0);
}
}
}
gettimeofday(&systemTime, NULL);
et = systemTime.tv_sec * 1000000 + systemTime.tv_usec;
pPrint("%.1f seconds to create %ld tables", (et - st) / 1000.0 / 1000.0, totalTables);
}
void insertData() {
struct timeval systemTime;
int64_t st, et;
gettimeofday(&systemTime, NULL);
st = systemTime.tv_sec * 1000000 + systemTime.tv_usec;
pPrint("%" PRId64 " threads are spawned to import data", numOfThreads);
pthread_attr_t thattr;
pthread_attr_init(&thattr);
pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
SInfo *pInfo = (SInfo *)malloc(sizeof(SInfo) * numOfThreads);
// Start threads to write
for (int i = 0; i < numOfThreads; ++i) {
pInfo[i].rowsPerTable = rowsPerTable;
pInfo[i].pointsPerTable = pointsPerTable;
pInfo[i].tableBeginIndex = i * numOfTablesPerThread;
pInfo[i].tableEndIndex = (i + 1) * numOfTablesPerThread;
pInfo[i].threadIndex = i;
strcpy(pInfo[i].dbName, dbName);
strcpy(pInfo[i].stableName, stableName);
pthread_create(&(pInfo[i].thread), &thattr, syncTest, (void *)(pInfo + i));
}
taosMsleep(300);
for (int i = 0; i < numOfThreads; i++) {
pthread_join(pInfo[i].thread, NULL);
}
gettimeofday(&systemTime, NULL);
et = systemTime.tv_sec * 1000000 + systemTime.tv_usec;
double seconds = (et - st) / 1000.0 / 1000.0;
int64_t totalTables = numOfTablesPerThread * numOfThreads;
int64_t totalRows = totalTables * rowsPerTable;
int64_t totalPoints = totalTables * rowsPerTable * pointsPerTable;
double speedOfRows = totalRows / seconds;
double speedOfPoints = totalPoints / seconds;
pPrint(
"%sall threads:%ld finished, use %.1lf seconds, tables:%.ld rows:%ld points:%ld, speed RowsPerSecond:%.1lf "
"PointsPerSecond:%.1lf%s",
GREEN, numOfThreads, seconds, totalTables, totalRows, totalPoints, speedOfRows, speedOfPoints, NC);
pPrint("threads exit");
pthread_attr_destroy(&thattr);
free(pInfo);
}
void *syncTest(void *param) {
TAOS * con;
SInfo * pInfo = (SInfo *)param;
struct timeval systemTime;
int64_t st, et;
char qstr[65000];
int maxBytes = 60000;
pPrint("thread:%d, start to run", pInfo->threadIndex);
char fqdn[TSDB_FQDN_LEN];
uint16_t port;
taosGetFqdnPortFromEp(tsFirst, fqdn, &port);
con = taos_connect(fqdn, "root", "taosdata", NULL, port);
if (con == NULL) {
pError("index:%d, failed to connect to DB, reason:%s", pInfo->threadIndex, taos_errstr(con));
exit(1);
}
sprintf(qstr, "use %s", pInfo->dbName);
query(con, qstr);
gettimeofday(&systemTime, NULL);
st = systemTime.tv_sec * 1000000 + systemTime.tv_usec;
int64_t start = 1587225600000;
int64_t interval = 1000; // 1000 ms
char *sql = qstr;
char inserStr[] = "import into";
int len = sprintf(sql, "%s", inserStr);
for (int64_t table = pInfo->tableBeginIndex; table < pInfo->tableEndIndex; ++table) {
len += sprintf(sql + len, " %s%ld values", pInfo->stableName, table);
for (int64_t row = 0; row < pInfo->rowsPerTable; row++) {
len += sprintf(sql + len, "(%ld", start - row * interval);
for (int64_t point = 0; point < pInfo->pointsPerTable; ++point) {
len += sprintf(sql + len, ",%d", randomData[(123 * table + 456 * row + 789 * point) % MAX_RANDOM_POINTS]);
// len += sprintf(sql + len, ",%ld", row);
}
len += sprintf(sql + len, ")");
if (len > maxBytes) {
if (query(con, qstr)) {
pError("thread:%d, failed to import table:%s%ld row:%ld, reason:%s", pInfo->threadIndex, pInfo->stableName,
table, row, taos_errstr(con));
}
// "insert into"
len = sprintf(sql, "%s", inserStr);
// "insert into st1 values"
if (row != pInfo->rowsPerTable - 1) {
len += sprintf(sql + len, " %s%ld values", pInfo->stableName, table);
}
}
}
}
if (len != strlen(inserStr)) {
query(con, qstr);
}
gettimeofday(&systemTime, NULL);
et = systemTime.tv_sec * 1000000 + systemTime.tv_usec;
int64_t totalTables = pInfo->tableEndIndex - pInfo->tableBeginIndex;
int64_t totalRows = totalTables * pInfo->rowsPerTable;
int64_t totalPoints = totalRows * pInfo->pointsPerTable;
pPrint("thread:%d, import finished, use %.2f seconds, tables:%ld rows:%ld points:%ld", pInfo->threadIndex,
(et - st) / 1000.0 / 1000.0, totalTables, totalRows, totalPoints);
return NULL;
}
void generateRandomPoints() {
for (int r = 0; r < MAX_RANDOM_POINTS; ++r) {
randomData[r] = rand() % 1000;
}
}
void printHelp() {
char indent[10] = " ";
printf("Used to test the performance of TDengine\n After writing all the data in one table, start the next table\n");
printf("%s%s\n", indent, "-d");
printf("%s%s%s%s\n", indent, indent, "The name of the database to be created, default is ", dbName);
printf("%s%s\n", indent, "-s");
printf("%s%s%s%s%s\n", indent, indent, "The name of the super table to be created, default is ", stableName, ", if 'no' then create normal table");
printf("%s%s\n", indent, "-c");
printf("%s%s%s%s\n", indent, indent, "Configuration directory, default is ", configDir);
printf("%s%s\n", indent, "-r");
printf("%s%s%s%ld\n", indent, indent, "Number of records to write to each table, default is ", rowsPerTable);
printf("%s%s\n", indent, "-p");
printf("%s%s%s%" PRId64 "\n", indent, indent, "Number of columns per table, default is ", pointsPerTable);
printf("%s%s\n", indent, "-t");
printf("%s%s%s%" PRId64 "\n", indent, indent, "Number of threads to be used, default is ", numOfThreads);
printf("%s%s\n", indent, "-n");
printf("%s%s%s%" PRId64 "\n", indent, indent, "Number of tables per thread, default is ", numOfTablesPerThread);
exit(EXIT_SUCCESS);
}
void shellParseArgument(int argc, char *argv[]) {
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
printHelp();
exit(0);
} else if (strcmp(argv[i], "-d") == 0) {
strcpy(dbName, argv[++i]);
} else if (strcmp(argv[i], "-c") == 0) {
strcpy(configDir, argv[++i]);
} else if (strcmp(argv[i], "-s") == 0) {
strcpy(stableName, argv[++i]);
} else if (strcmp(argv[i], "-r") == 0) {
rowsPerTable = atoi(argv[++i]);
} else if (strcmp(argv[i], "-p") == 0) {
pointsPerTable = atoi(argv[++i]);
} else if (strcmp(argv[i], "-t") == 0) {
numOfThreads = atoi(argv[++i]);
} else if (strcmp(argv[i], "-n") == 0) {
numOfTablesPerThread = atoi(argv[++i]);
} else {
}
}
pPrint("%srowsPerTable:%" PRId64 "%s", GREEN, rowsPerTable, NC);
pPrint("%spointsPerTable:%" PRId64 "%s", GREEN, pointsPerTable, NC);
pPrint("%snumOfThreads:%" PRId64 "%s", GREEN, numOfThreads, NC);
pPrint("%snumOfTablesPerThread:%" PRId64 "%s", GREEN, numOfTablesPerThread, NC);
pPrint("%sdbName:%s%s", GREEN, dbName, NC);
pPrint("%stableName:%s%s", GREEN, stableName, NC);
pPrint("%sstart to run%s", GREEN, NC);
}
/*
* 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/>.
*/
#define _DEFAULT_SOURCE
#include "../../../include/client/taos.h"
#include "os.h"
#include "tglobal.h"
#include "ttimer.h"
#include "tulog.h"
#include "tutil.h"
#define MAX_RANDOM_POINTS 20000
#define GREEN "\033[1;32m"
#define NC "\033[0m"
typedef struct {
int64_t rowsPerTable;
int64_t pointsPerTable;
int64_t tableBeginIndex;
int64_t tableEndIndex;
int threadIndex;
char dbName[32];
char stableName[64];
float createTableSpeed;
pthread_t thread;
} SInfo;
void *syncTest(void *param);
void generateRandomPoints();
void shellParseArgument(int argc, char *argv[]);
void createDbAndTable();
void insertData();
int32_t randomData[MAX_RANDOM_POINTS];
int64_t rowsPerTable = 1000000000;
int64_t pointsPerTable = 1;
int64_t numOfThreads = 10;
int64_t numOfTablesPerThread = 100;
char dbName[32] = "db";
char stableName[64] = "st";
int32_t cache = 1;
int32_t replica = 3;
int32_t days = 10;
int32_t interval = 1000;
int main(int argc, char *argv[]) {
shellParseArgument(argc, argv);
generateRandomPoints();
taos_init();
createDbAndTable();
insertData();
}
void createDbAndTable() {
pPrint("start to create table");
TAOS_RES * pSql;
TAOS * con;
char qstr[64000];
char fqdn[TSDB_FQDN_LEN];
uint16_t port;
taosGetFqdnPortFromEp(tsFirst, fqdn, &port);
con = taos_connect(fqdn, "root", "taosdata", NULL, port);
if (con == NULL) {
pError("failed to connect to DB, reason:%s", taos_errstr(con));
exit(1);
}
sprintf(qstr, "create database if not exists %s cache %d replica %d days %d", dbName, cache, replica, days);
pSql = taos_query(con, qstr);
int32_t code = taos_errno(pSql);
if (code != 0) {
pError("failed to create database:%s, sql:%s, code:%d reason:%s", dbName, qstr, taos_errno(con), taos_errstr(con));
exit(0);
}
taos_free_result(pSql);
sprintf(qstr, "use %s", dbName);
pSql = taos_query(con, qstr);
code = taos_errno(pSql);
if (code != 0) {
pError("failed to use db, code:%d reason:%s", taos_errno(con), taos_errstr(con));
exit(0);
}
taos_free_result(pSql);
if (strcmp(stableName, "no") != 0) {
int len = sprintf(qstr, "create table if not exists %s(ts timestamp", stableName);
for (int64_t f = 0; f < pointsPerTable; ++f) {
len += sprintf(qstr + len, ", f%ld double", f);
}
sprintf(qstr + len, ") tags(t int)");
pSql = taos_query(con, qstr);
code = taos_errno(pSql);
if (code != 0) {
pError("failed to create stable, code:%d reason:%s", taos_errno(con), taos_errstr(con));
exit(0);
}
taos_free_result(pSql);
}
}
void insertData() {
struct timeval systemTime;
int64_t st, et;
gettimeofday(&systemTime, NULL);
st = systemTime.tv_sec * 1000000 + systemTime.tv_usec;
pPrint("%" PRId64 " threads are spawned to insert data", numOfThreads);
pthread_attr_t thattr;
pthread_attr_init(&thattr);
pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
SInfo *pInfo = (SInfo *)calloc(numOfThreads, sizeof(SInfo));
// Start threads to write
for (int i = 0; i < numOfThreads; ++i) {
pInfo[i].rowsPerTable = rowsPerTable;
pInfo[i].pointsPerTable = pointsPerTable;
pInfo[i].tableBeginIndex = i * numOfTablesPerThread;
pInfo[i].tableEndIndex = (i + 1) * numOfTablesPerThread;
pInfo[i].threadIndex = i;
strcpy(pInfo[i].dbName, dbName);
strcpy(pInfo[i].stableName, stableName);
pthread_create(&(pInfo[i].thread), &thattr, syncTest, (void *)(pInfo + i));
}
taosMsleep(300);
for (int i = 0; i < numOfThreads; i++) {
pthread_join(pInfo[i].thread, NULL);
}
gettimeofday(&systemTime, NULL);
et = systemTime.tv_sec * 1000000 + systemTime.tv_usec;
double seconds = (et - st) / 1000.0 / 1000.0;
int64_t totalTables = numOfTablesPerThread * numOfThreads;
int64_t totalRows = totalTables * rowsPerTable;
int64_t totalPoints = totalTables * rowsPerTable * pointsPerTable;
double speedOfRows = totalRows / seconds;
double speedOfPoints = totalPoints / seconds;
float createTableSpeed = 0;
for (int i = 0; i < numOfThreads; ++i) {
createTableSpeed += pInfo[i].createTableSpeed;
}
pPrint(
"%sall threads:%ld finished, use %.1lf seconds, tables:%.ld rows:%ld points:%ld, speed RowsPerSecond:%.1lf "
"PointsPerSecond:%.1lf CreateTableSpeed:%.1f t/s %s",
GREEN, numOfThreads, seconds, totalTables, totalRows, totalPoints, speedOfRows, speedOfPoints, createTableSpeed, NC);
pPrint("threads exit");
pthread_attr_destroy(&thattr);
free(pInfo);
}
void *syncTest(void *param) {
TAOS * con;
SInfo * pInfo = (SInfo *)param;
struct timeval systemTime;
int64_t st, et;
char qstr[65000];
int maxBytes = 60000;
int code;
pPrint("thread:%d, start to run", pInfo->threadIndex);
char fqdn[TSDB_FQDN_LEN];
uint16_t port;
taosGetFqdnPortFromEp(tsFirst, fqdn, &port);
con = taos_connect(fqdn, "root", "taosdata", NULL, port);
if (con == NULL) {
pError("index:%d, failed to connect to DB, reason:%s", pInfo->threadIndex, taos_errstr(con));
exit(1);
}
sprintf(qstr, "use %s", pInfo->dbName);
taos_query(con, qstr);
gettimeofday(&systemTime, NULL);
st = systemTime.tv_sec * 1000000 + systemTime.tv_usec;
if (strcmp(stableName, "no") != 0) {
for (int64_t t = pInfo->tableBeginIndex; t < pInfo->tableEndIndex; ++t) {
sprintf(qstr, "create table if not exists %s%ld using %s tags(%ld)", stableName, t, stableName, t);
TAOS_RES *pSql = taos_query(con, qstr);
code = taos_errno(pSql);
if (code != 0) {
pError("failed to create table %s%" PRId64 ", reason:%s", stableName, t, taos_errstr(con));
exit(0);
}
taos_free_result(pSql);
}
} else {
for (int64_t t = pInfo->tableBeginIndex; t < pInfo->tableEndIndex; ++t) {
int len = sprintf(qstr, "create table if not exists %s%ld(ts timestamp", stableName, t);
for (int64_t f = 0; f < pointsPerTable; ++f) {
len += sprintf(qstr + len, ", f%ld double", f);
}
sprintf(qstr + len, ")");
TAOS_RES *pSql = taos_query(con, qstr);
code = taos_errno(pSql);
if (code != 0) {
pError("failed to create table %s%ld, reason:%s", stableName, t, taos_errstr(con));
exit(0);
}
taos_free_result(pSql);
}
}
gettimeofday(&systemTime, NULL);
et = systemTime.tv_sec * 1000000 + systemTime.tv_usec;
float seconds = (et - st) / 1000.0 / 1000.0;
int64_t tables = pInfo->tableEndIndex - pInfo->tableBeginIndex;
pInfo->createTableSpeed = (float)tables / seconds;
pPrint("thread:%d, %.1f seconds to create %ld tables, speed:%.1f", pInfo->threadIndex, seconds, tables,
pInfo->createTableSpeed);
if (pInfo->rowsPerTable == 0) return NULL;
gettimeofday(&systemTime, NULL);
st = systemTime.tv_sec * 1000000 + systemTime.tv_usec;
int64_t start = 1430000000000;
interval = 1000; // 1000 ms
char *sql = qstr;
char inserStr[] = "insert into";
int len = sprintf(sql, "%s", inserStr);
for (int64_t row = 0; row < pInfo->rowsPerTable; row++) {
for (int64_t table = pInfo->tableBeginIndex; table < pInfo->tableEndIndex; ++table) {
len += sprintf(sql + len, " %s%ld values", pInfo->stableName, table);
len += sprintf(sql + len, "(%ld", start + row * interval);
for (int64_t point = 0; point < pInfo->pointsPerTable; ++point) {
len += sprintf(sql + len, ",%d", randomData[(123 * table + 456 * row + 789 * point) % MAX_RANDOM_POINTS]);
// len += sprintf(sql + len, ",%ld", row);
}
len += sprintf(sql + len, ")");
if (len > maxBytes) {
TAOS_RES *pSql = taos_query(con, qstr);
int32_t code = taos_errno(pSql);
if (code != 0) {
pError("thread:%d, failed to insert table:%s%ld row:%ld, reason:%s", pInfo->threadIndex, pInfo->stableName,
table, row, taos_errstr(con));
}
taos_free_result(pSql);
// "insert into"
len = sprintf(sql, "%s", inserStr);
}
}
}
if (len != strlen(inserStr)) {
TAOS_RES *pSql = taos_query(con, qstr);
taos_free_result(pSql);
}
gettimeofday(&systemTime, NULL);
et = systemTime.tv_sec * 1000000 + systemTime.tv_usec;
int64_t totalTables = pInfo->tableEndIndex - pInfo->tableBeginIndex;
int64_t totalRows = totalTables * pInfo->rowsPerTable;
int64_t totalPoints = totalRows * pInfo->pointsPerTable;
pPrint("thread:%d, insert finished, use %.2f seconds, tables:%ld rows:%ld points:%ld", pInfo->threadIndex,
(et - st) / 1000.0 / 1000.0, totalTables, totalRows, totalPoints);
return NULL;
}
void generateRandomPoints() {
for (int r = 0; r < MAX_RANDOM_POINTS; ++r) {
randomData[r] = rand() % 1000;
}
}
void printHelp() {
char indent[10] = " ";
printf("Used to test the performance of TDengine\n After writing one row of data to all tables, write the next row\n");
printf("%s%s\n", indent, "-d");
printf("%s%s%s%s\n", indent, indent, "The name of the database to be created, default is ", dbName);
printf("%s%s\n", indent, "-s");
printf("%s%s%s%s%s\n", indent, indent, "The name of the super table to be created, default is ", stableName, ", if 'no' then create normal table");
printf("%s%s\n", indent, "-c");
printf("%s%s%s%s\n", indent, indent, "Configuration directory, default is ", configDir);
printf("%s%s\n", indent, "-r");
printf("%s%s%s%ld\n", indent, indent, "Number of records to write to each table, default is ", rowsPerTable);
printf("%s%s\n", indent, "-p");
printf("%s%s%s%" PRId64 "\n", indent, indent, "Number of columns per table, default is ", pointsPerTable);
printf("%s%s\n", indent, "-t");
printf("%s%s%s%" PRId64 "\n", indent, indent, "Number of threads to be used, default is ", numOfThreads);
printf("%s%s\n", indent, "-n");
printf("%s%s%s%" PRId64 "\n", indent, indent, "Number of tables per thread, default is ", numOfTablesPerThread);
printf("%s%s\n", indent, "-replica");
printf("%s%s%s%d\n", indent, indent, "Database parameters replica, default is ", replica);
printf("%s%s\n", indent, "-cache");
printf("%s%s%s%d\n", indent, indent, "Database parameters replica, default is ", cache);
printf("%s%s\n", indent, "-days");
printf("%s%s%s%d\n", indent, indent, "Database parameters days, default is ", days);
printf("%s%s\n", indent, "-interval");
printf("%s%s%s%d\n", indent, indent, "Interval of each rows in ms, default is ", interval);
exit(EXIT_SUCCESS);
}
void shellParseArgument(int argc, char *argv[]) {
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
printHelp();
exit(0);
} else if (strcmp(argv[i], "-d") == 0) {
strcpy(dbName, argv[++i]);
} else if (strcmp(argv[i], "-c") == 0) {
strcpy(configDir, argv[++i]);
} else if (strcmp(argv[i], "-s") == 0) {
strcpy(stableName, argv[++i]);
} else if (strcmp(argv[i], "-r") == 0) {
rowsPerTable = atoi(argv[++i]);
} else if (strcmp(argv[i], "-p") == 0) {
pointsPerTable = atoi(argv[++i]);
} else if (strcmp(argv[i], "-t") == 0) {
numOfThreads = atoi(argv[++i]);
} else if (strcmp(argv[i], "-n") == 0) {
numOfTablesPerThread = atoi(argv[++i]);
} else if (strcmp(argv[i], "-replica") == 0) {
replica = atoi(argv[++i]);
} else if (strcmp(argv[i], "-cache") == 0) {
cache = atoi(argv[++i]);
} else if (strcmp(argv[i], "-days") == 0) {
days = atoi(argv[++i]);
} else if (strcmp(argv[i], "-interval") == 0) {
interval = atoi(argv[++i]);
} else {
}
}
pPrint("%srowsPerTable:%" PRId64 "%s", GREEN, rowsPerTable, NC);
pPrint("%spointsPerTable:%" PRId64 "%s", GREEN, pointsPerTable, NC);
pPrint("%snumOfThreads:%" PRId64 "%s", GREEN, numOfThreads, NC);
pPrint("%snumOfTablesPerThread:%" PRId64 "%s", GREEN, numOfTablesPerThread, NC);
pPrint("%scache:%" PRId32 "%s", GREEN, cache, NC);
pPrint("%stables:%" PRId32 "%s", GREEN, replica, NC);
pPrint("%sdbName:%s%s", GREEN, dbName, NC);
pPrint("%stableName:%s%s", GREEN, stableName, NC);
pPrint("%sstart to run%s", GREEN, NC);
}
/*
* 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/>.
*/
#define _DEFAULT_SOURCE
#include "../../../include/client/taos.h"
#include "os.h"
#include "tglobal.h"
#include "ttimer.h"
#include "tulog.h"
#include "tutil.h"
#define MAX_RANDOM_POINTS 20000
#define GREEN "\033[1;32m"
#define NC "\033[0m"
typedef struct {
int64_t rowsPerTable;
int64_t pointsPerTable;
int64_t tableBeginIndex;
int64_t tableEndIndex;
int threadIndex;
char dbName[32];
char stableName[64];
pthread_t thread;
} SInfo;
void *syncTest(void *param);
void generateRandomPoints();
void shellParseArgument(int argc, char *argv[]);
void createDbAndTable();
void insertData();
int32_t randomData[MAX_RANDOM_POINTS];
int64_t rowsPerTable = 10000;
int64_t pointsPerTable = 1;
int64_t numOfThreads = 1;
int64_t numOfTablesPerThread = 1;
char dbName[32] = "db";
char stableName[64] = "st";
int32_t cache = 16;
int32_t tables = 5000;
int main(int argc, char *argv[]) {
shellParseArgument(argc, argv);
generateRandomPoints();
taos_init();
createDbAndTable();
insertData();
}
void createDbAndTable() {
pPrint("start to create table");
TAOS_RES * pSql;
TAOS * con;
struct timeval systemTime;
int64_t st, et;
char qstr[64000];
char fqdn[TSDB_FQDN_LEN];
uint16_t port;
taosGetFqdnPortFromEp(tsFirst, fqdn, &port);
con = taos_connect(fqdn, "root", "taosdata", NULL, port);
if (con == NULL) {
pError("failed to connect to DB, reason:%s", taos_errstr(con));
exit(1);
}
sprintf(qstr, "create database if not exists %s cache %d maxtables %d", dbName, cache, tables);
pSql = taos_query(con, qstr);
int32_t code = taos_errno(pSql);
if (code != 0) {
pError("failed to create database:%s, sql:%s, code:%d reason:%s", dbName, qstr, taos_errno(con), taos_errstr(con));
exit(0);
}
sprintf(qstr, "use %s", dbName);
pSql = taos_query(con, qstr);
code = taos_errno(pSql);
if (code != 0) {
pError("failed to use db, code:%d reason:%s", taos_errno(con), taos_errstr(con));
exit(0);
}
taos_free_result(pSql);
gettimeofday(&systemTime, NULL);
st = systemTime.tv_sec * 1000000 + systemTime.tv_usec;
int64_t totalTables = numOfTablesPerThread * numOfThreads;
if (strcmp(stableName, "no") != 0) {
int len = sprintf(qstr, "create table if not exists %s(ts timestamp", stableName);
for (int64_t f = 0; f < pointsPerTable; ++f) {
len += sprintf(qstr + len, ", f%ld double", f);
}
sprintf(qstr + len, ") tags(t int)");
pSql = taos_query(con, qstr);
code = taos_errno(pSql);
if (code != 0) {
pError("failed to create stable, code:%d reason:%s", taos_errno(con), taos_errstr(con));
exit(0);
}
taos_free_result(pSql);
for (int64_t t = 0; t < totalTables; ++t) {
sprintf(qstr, "create table if not exists %s%ld using %s tags(%ld)", stableName, t, stableName, t);
pSql = taos_query(con, qstr);
code = taos_errno(pSql);
if (code != 0) {
pError("failed to create table %s%" PRId64 ", reason:%s", stableName, t, taos_errstr(con));
exit(0);
}
taos_free_result(pSql);
}
} else {
for (int64_t t = 0; t < totalTables; ++t) {
int len = sprintf(qstr, "create table if not exists %s%ld(ts timestamp", stableName, t);
for (int64_t f = 0; f < pointsPerTable; ++f) {
len += sprintf(qstr + len, ", f%ld double", f);
}
sprintf(qstr + len, ")");
pSql = taos_query(con, qstr);
code = taos_errno(pSql);
if (code != 0) {
pError("failed to create table %s%ld, reason:%s", stableName, t, taos_errstr(con));
exit(0);
}
taos_free_result(pSql);
}
}
gettimeofday(&systemTime, NULL);
et = systemTime.tv_sec * 1000000 + systemTime.tv_usec;
float seconds = (et - st) / 1000.0 / 1000.0;
pPrint("%.1f seconds to create %ld tables, speed:%.1f", seconds, totalTables, totalTables / seconds);
taos_close(con);
}
void insertData() {
struct timeval systemTime;
int64_t st, et;
gettimeofday(&systemTime, NULL);
st = systemTime.tv_sec * 1000000 + systemTime.tv_usec;
if (rowsPerTable <= 0) {
pPrint("not insert data for rowsPerTable is :%" PRId64, rowsPerTable);
exit(0);
} else {
pPrint("%" PRId64 " threads are spawned to insert data", numOfThreads);
}
pthread_attr_t thattr;
pthread_attr_init(&thattr);
pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
SInfo *pInfo = (SInfo *)malloc(sizeof(SInfo) * numOfThreads);
// Start threads to write
for (int i = 0; i < numOfThreads; ++i) {
pInfo[i].rowsPerTable = rowsPerTable;
pInfo[i].pointsPerTable = pointsPerTable;
pInfo[i].tableBeginIndex = i * numOfTablesPerThread;
pInfo[i].tableEndIndex = (i + 1) * numOfTablesPerThread;
pInfo[i].threadIndex = i;
strcpy(pInfo[i].dbName, dbName);
strcpy(pInfo[i].stableName, stableName);
pthread_create(&(pInfo[i].thread), &thattr, syncTest, (void *)(pInfo + i));
}
taosMsleep(300);
for (int i = 0; i < numOfThreads; i++) {
pthread_join(pInfo[i].thread, NULL);
}
gettimeofday(&systemTime, NULL);
et = systemTime.tv_sec * 1000000 + systemTime.tv_usec;
double seconds = (et - st) / 1000.0 / 1000.0;
int64_t totalTables = numOfTablesPerThread * numOfThreads;
int64_t totalRows = totalTables * rowsPerTable;
int64_t totalPoints = totalTables * rowsPerTable * pointsPerTable;
double speedOfRows = totalRows / seconds;
double speedOfPoints = totalPoints / seconds;
pPrint(
"%sall threads:%ld finished, use %.1lf seconds, tables:%.ld rows:%ld points:%ld, speed RowsPerSecond:%.1lf "
"PointsPerSecond:%.1lf%s",
GREEN, numOfThreads, seconds, totalTables, totalRows, totalPoints, speedOfRows, speedOfPoints, NC);
pPrint("threads exit");
pthread_attr_destroy(&thattr);
free(pInfo);
}
void *syncTest(void *param) {
TAOS * con;
SInfo * pInfo = (SInfo *)param;
struct timeval systemTime;
int64_t st, et;
char qstr[65000];
int maxBytes = 60000;
pPrint("thread:%d, start to run", pInfo->threadIndex);
char fqdn[TSDB_FQDN_LEN];
uint16_t port;
taosGetFqdnPortFromEp(tsFirst, fqdn, &port);
con = taos_connect(fqdn, "root", "taosdata", NULL, port);
if (con == NULL) {
pError("index:%d, failed to connect to DB, reason:%s", pInfo->threadIndex, taos_errstr(con));
exit(1);
}
sprintf(qstr, "use %s", pInfo->dbName);
taos_query(con, qstr);
gettimeofday(&systemTime, NULL);
st = systemTime.tv_sec * 1000000 + systemTime.tv_usec;
int64_t start = 1430000000000;
int64_t interval = 1000; // 1000 ms
char *sql = qstr;
char inserStr[] = "insert into";
int len = sprintf(sql, "%s", inserStr);
for (int64_t table = pInfo->tableBeginIndex; table < pInfo->tableEndIndex; ++table) {
len += sprintf(sql + len, " %s%ld values", pInfo->stableName, table);
for (int64_t row = 0; row < pInfo->rowsPerTable; row++) {
len += sprintf(sql + len, "(%ld", start + row * interval);
for (int64_t point = 0; point < pInfo->pointsPerTable; ++point) {
len += sprintf(sql + len, ",%d", randomData[(123 * table + 456 * row + 789 * point) % MAX_RANDOM_POINTS]);
// len += sprintf(sql + len, ",%ld", row);
}
len += sprintf(sql + len, ")");
if (len > maxBytes) {
TAOS_RES *pSql = taos_query(con, qstr);
int32_t code = taos_errno(pSql);
if (code != 0) {
pError("thread:%d, failed to insert table:%s%ld row:%ld, reason:%s", pInfo->threadIndex, pInfo->stableName,
table, row, taos_errstr(con));
}
taos_free_result(pSql);
// "insert into"
len = sprintf(sql, "%s", inserStr);
// "insert into st1 values"
if (row != pInfo->rowsPerTable - 1) {
len += sprintf(sql + len, " %s%ld values", pInfo->stableName, table);
}
}
}
}
if (len != strlen(inserStr)) {
taos_query(con, qstr);
}
gettimeofday(&systemTime, NULL);
et = systemTime.tv_sec * 1000000 + systemTime.tv_usec;
int64_t totalTables = pInfo->tableEndIndex - pInfo->tableBeginIndex;
int64_t totalRows = totalTables * pInfo->rowsPerTable;
int64_t totalPoints = totalRows * pInfo->pointsPerTable;
pPrint("thread:%d, insert finished, use %.2f seconds, tables:%ld rows:%ld points:%ld", pInfo->threadIndex,
(et - st) / 1000.0 / 1000.0, totalTables, totalRows, totalPoints);
return NULL;
}
void generateRandomPoints() {
for (int r = 0; r < MAX_RANDOM_POINTS; ++r) {
randomData[r] = rand() % 1000;
}
}
void printHelp() {
char indent[10] = " ";
printf("Used to test the performance of TDengine\n After writing all the data in one table, start the next table\n");
printf("%s%s\n", indent, "-d");
printf("%s%s%s%s\n", indent, indent, "The name of the database to be created, default is ", dbName);
printf("%s%s\n", indent, "-s");
printf("%s%s%s%s%s\n", indent, indent, "The name of the super table to be created, default is ", stableName, ", if 'no' then create normal table");
printf("%s%s\n", indent, "-c");
printf("%s%s%s%s\n", indent, indent, "Configuration directory, default is ", configDir);
printf("%s%s\n", indent, "-r");
printf("%s%s%s%ld\n", indent, indent, "Number of records to write to each table, default is ", rowsPerTable);
printf("%s%s\n", indent, "-p");
printf("%s%s%s%" PRId64 "\n", indent, indent, "Number of columns per table, default is ", pointsPerTable);
printf("%s%s\n", indent, "-t");
printf("%s%s%s%" PRId64 "\n", indent, indent, "Number of threads to be used, default is ", numOfThreads);
printf("%s%s\n", indent, "-n");
printf("%s%s%s%" PRId64 "\n", indent, indent, "Number of tables per thread, default is ", numOfTablesPerThread);
printf("%s%s\n", indent, "-tables");
printf("%s%s%s%d\n", indent, indent, "Database parameters tables, default is ", tables);
printf("%s%s\n", indent, "-cache");
printf("%s%s%s%d\n", indent, indent, "Database parameters cache, default is ", cache);
exit(EXIT_SUCCESS);
}
void shellParseArgument(int argc, char *argv[]) {
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
printHelp();
exit(0);
} else if (strcmp(argv[i], "-d") == 0) {
strcpy(dbName, argv[++i]);
} else if (strcmp(argv[i], "-c") == 0) {
strcpy(configDir, argv[++i]);
} else if (strcmp(argv[i], "-s") == 0) {
strcpy(stableName, argv[++i]);
} else if (strcmp(argv[i], "-r") == 0) {
rowsPerTable = atoi(argv[++i]);
} else if (strcmp(argv[i], "-p") == 0) {
pointsPerTable = atoi(argv[++i]);
} else if (strcmp(argv[i], "-t") == 0) {
numOfThreads = atoi(argv[++i]);
} else if (strcmp(argv[i], "-n") == 0) {
numOfTablesPerThread = atoi(argv[++i]);
} else if (strcmp(argv[i], "-tables") == 0) {
tables = atoi(argv[++i]);
} else if (strcmp(argv[i], "-cache") == 0) {
cache = atoi(argv[++i]);
} else {
}
}
pPrint("%srowsPerTable:%" PRId64 "%s", GREEN, rowsPerTable, NC);
pPrint("%spointsPerTable:%" PRId64 "%s", GREEN, pointsPerTable, NC);
pPrint("%snumOfThreads:%" PRId64 "%s", GREEN, numOfThreads, NC);
pPrint("%snumOfTablesPerThread:%" PRId64 "%s", GREEN, numOfTablesPerThread, NC);
pPrint("%scache:%" PRId32 "%s", GREEN, cache, NC);
pPrint("%stables:%" PRId32 "%s", GREEN, tables, NC);
pPrint("%sdbName:%s%s", GREEN, dbName, NC);
pPrint("%stableName:%s%s", GREEN, stableName, NC);
pPrint("%sstart to run%s", GREEN, NC);
}
/*
* 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/>.
*/
#define _DEFAULT_SOURCE
#include "../../../include/client/taos.h"
#include "hash.h"
#include "os.h"
#include "taoserror.h"
#include "tglobal.h"
#include "tulog.h"
#include "tutil.h"
#define MAX_RANDOM_POINTS 20000
#define GREEN "\033[1;32m"
#define NC "\033[0m"
#define MAX_DB_NUM 100
void * con;
char dbNames[MAX_DB_NUM][48];
int32_t dbNum = 0;
void parseArgument(int argc, char *argv[]);
void connDb();
void getDbNames();
void printDbNames();
void queryTables(char *dbName);
void checkTables(char *dbName);
int main(int argc, char *argv[]) {
parseArgument(argc, argv);
taos_init();
connDb();
getDbNames();
printDbNames();
for (int dbIndex = 0; dbIndex < dbNum; ++dbIndex) {
queryTables((char*)(dbNames[dbIndex]));
checkTables((char*)(dbNames[dbIndex]));
}
pPrint("all %d database is checked", dbNum);
}
void connDb() {
con = taos_connect(NULL, "root", "taosdata", NULL, 0);
if (con == NULL) {
pError("failed to connect to DB, reason:%s", taos_errstr(con));
exit(0);
}
}
void getDbNames() {
if (dbNum != 0) return;
char * qstr = "show databases";
TAOS_RES *result = taos_query(con, qstr);
int32_t code = taos_errno(result);
if (result == NULL || code != 0) {
pError("failed to exec sql:%s, code:0x%x reason:%s", qstr, code & 0XFFFF, tstrerror(code));
exit(0);
}
TAOS_ROW row;
int num_fields = taos_num_fields(result);
if (num_fields <= 0) return;
while ((row = taos_fetch_row(result))) {
char * dbName = (char*)dbNames[dbNum];
int32_t *length = taos_fetch_lengths(result);
int len = length[0];
memcpy(dbName, (char *)row[0], len);
dbName[len] = 0;
dbNum++;
}
taos_free_result(result);
}
void printDbNames() {
for (int dbIndex = 0; dbIndex < dbNum; ++dbIndex) {
pPrint("db:%d %s", dbIndex, dbNames[dbIndex]);
}
}
void queryTables(char *dbName) {
char qstr[1024];
char fileName[1024];
char ts[35] = {0};
int32_t precision = 1000;
sprintf(qstr, "show %s.tables", dbName);
sprintf(fileName, "%s_tables.txt", dbName);
TAOS_RES *result = taos_query(con, qstr);
int32_t code = taos_errno(result);
if (result == NULL || code != 0) {
pError("failed to exec sql:%s, code:0x%x reason:%s", qstr, code & 0XFFFF, tstrerror(code));
exit(0);
}
FILE *fp = fopen(fileName, "w");
if (!fp) return;
TAOS_ROW row;
int32_t rows = 0;
while ((row = taos_fetch_row(result))) {
char tableName[256] = {0};
int32_t *length = taos_fetch_lengths(result);
int len = length[0];
memcpy(tableName, (char *)row[0], len);
tableName[len] = 0;
int64_t t = *((int64_t *)row[1]);
time_t tt = t / 1000;
struct tm *ptm = localtime(&tt);
int32_t tl = (int32_t)strftime(ts, 35, "%Y-%m-%d %H:%M:%S", ptm);
snprintf(ts + tl, 5, ".%03ld", t % precision);
// fprintf(fp, "%s %s\n", tableName, ts);
fprintf(fp, "%s.%s\n", dbName, tableName);
rows++;
}
taos_free_result(result);
fclose(fp);
pPrint("db:%s has %d tables, write to %s", dbName, rows, fileName);
}
void checkTables(char *dbName) {
char qstr[1024];
char fileName1[1024];
char fileName2[1024];
sprintf(qstr, "show %s.tables", dbName);
sprintf(fileName1, "%s_tables.txt", dbName);
sprintf(fileName2, "%s_count.txt", dbName);
FILE *fp1 = fopen(fileName1, "r");
if (!fp1) return;
FILE *fp2 = fopen(fileName2, "w");
if (!fp2) return;
int32_t successRows = 0;
int32_t failedRows = 0;
char tbName[256];
while (!feof(fp1)) {
int size = fscanf(fp1, "%s", tbName);
if (size <= 0) {
break;
}
sprintf(qstr, "select count(*) from %s", tbName);
TAOS_RES *result = taos_query(con, qstr);
int32_t code = taos_errno(result);
if (result == NULL || code != 0) {
pError("failed to exec sql:%s, code:0x%x reason:%s", qstr, code & 0XFFFF, tstrerror(code));
fprintf(fp2, "%s failed to exec sql:%s, code:0x%x reason:%s", tbName, qstr, code & 0XFFFF, tstrerror(code));
taos_free_result(result);
failedRows++;
continue;
}
TAOS_ROW row;
int64_t count = 0;
while ((row = taos_fetch_row(result))) {
count = *((int64_t *)row[0]);
}
fprintf(fp2, "%s %" PRId64 "\n", tbName, count);
successRows++;
if (successRows % 1000 == 0) {
pPrint("query %d tables", successRows);
}
taos_free_result(result);
}
fclose(fp1);
fclose(fp2);
pPrint("db:%s query tables, success:%d failed:%d write to %s", dbName, successRows, failedRows, fileName2);
}
void printHelp() {
char indent[10] = " ";
printf("Used to checkTables\n");
printf("%s%s\n", indent, "-c");
printf("%s%s%s%s\n", indent, indent, "Configuration directory, default is ", configDir);
printf("%s%s\n", indent, "-d");
printf("%s%s%s%s\n", indent, indent, "The name of the database to be checked, default is ", "all");
exit(EXIT_SUCCESS);
}
void parseArgument(int argc, char *argv[]) {
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
printHelp();
exit(0);
} else if (strcmp(argv[i], "-d") == 0) {
strcpy(dbNames[0], argv[++i]);
dbNum++;
} else if (strcmp(argv[i], "-c") == 0) {
strcpy(configDir, argv[++i]);
} else {
}
}
pPrint("%s configDir:%s %s", GREEN, configDir, NC);
pPrint("%s start to checkTables %s", GREEN, NC);
}
/*
* 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/>.
*/
#define _DEFAULT_SOURCE
#include "../../../include/client/taos.h"
#include "os.h"
#include "tglobal.h"
#include "ttimer.h"
#include "tulog.h"
#include "tutil.h"
#define MAX_RANDOM_POINTS 20000
#define GREEN "\033[1;32m"
#define NC "\033[0m"
typedef struct {
int64_t startTimeMs;
int64_t endTimeMs;
int threadIndex;
pthread_t thread;
} SInfo;
void *syncTest(void *param);
void shellParseArgument(int argc, char *argv[]);
void queryData();
int numOfThreads = 10;
int useGlobalConn = 1;
int requestPerThread = 10000;
char requestSql[10240] = "show dnodes";
TAOS *globalConn;
int main(int argc, char *argv[]) {
shellParseArgument(argc, argv);
taos_init();
queryData();
}
void queryData() {
struct timeval systemTime;
int64_t st, et;
char fqdn[TSDB_FQDN_LEN];
uint16_t port;
if (useGlobalConn) {
taosGetFqdnPortFromEp(tsFirst, fqdn, &port);
globalConn = taos_connect(fqdn, "root", "taosdata", NULL, port);
if (globalConn == NULL) {
pError("failed to connect to DB, reason:%s", taos_errstr(globalConn));
exit(1);
}
}
pPrint("%d threads are spawned to query", numOfThreads);
gettimeofday(&systemTime, NULL);
st = systemTime.tv_sec * 1000000 + systemTime.tv_usec;
pthread_attr_t thattr;
pthread_attr_init(&thattr);
pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
SInfo *pInfo = (SInfo *)malloc(sizeof(SInfo) * numOfThreads);
// Start threads to write
for (int i = 0; i < numOfThreads; ++i) {
pInfo[i].threadIndex = i;
pthread_create(&(pInfo[i].thread), &thattr, syncTest, (void *)(pInfo + i));
}
taosMsleep(300);
for (int i = 0; i < numOfThreads; i++) {
pthread_join(pInfo[i].thread, NULL);
}
gettimeofday(&systemTime, NULL);
et = systemTime.tv_sec * 1000000 + systemTime.tv_usec;
double totalTimeMs = (et - st) / 1000.0;
int totalReq = requestPerThread * numOfThreads;
float rspTime = totalTimeMs / requestPerThread;
float qps = totalReq / (totalTimeMs / 1000);
pPrint("%s threads:%d, totalTime %.1fms totalReq:%d qps:%.1f rspTime:%.3fms %s", GREEN, numOfThreads, totalTimeMs,
totalReq, qps, rspTime, NC);
pthread_attr_destroy(&thattr);
free(pInfo);
}
void *syncTest(void *param) {
TAOS * con;
SInfo * pInfo = (SInfo *)param;
char fqdn[TSDB_FQDN_LEN];
uint16_t port;
if (useGlobalConn) {
pPrint("thread:%d, start to run use global connection", pInfo->threadIndex);
con = globalConn;
} else {
pPrint("thread:%d, start to run, and create new conn", pInfo->threadIndex);
taosGetFqdnPortFromEp(tsFirst, fqdn, &port);
con = taos_connect(fqdn, "root", "taosdata", NULL, port);
if (con == NULL) {
pError("index:%d, failed to connect to DB, reason:%s", pInfo->threadIndex, taos_errstr(con));
exit(1);
}
}
for (int i = 0; i < requestPerThread; ++i) {
void *tres = taos_query(con, requestSql);
TAOS_ROW row = taos_fetch_row(tres);
if (row == NULL) {
taos_free_result(tres);
exit(0);
}
do {
row = taos_fetch_row(tres);
} while (row != NULL);
taos_free_result(tres);
}
return NULL;
}
void printHelp() {
char indent[10] = " ";
printf("Used to test the query performance of TDengine\n");
printf("%s%s\n", indent, "-c");
printf("%s%s%s%s\n", indent, indent, "Configuration directory, default is ", configDir);
printf("%s%s\n", indent, "-s");
printf("%s%s%s%s\n", indent, indent, "The sql to be executed, default is ", requestSql);
printf("%s%s\n", indent, "-r");
printf("%s%s%s%d\n", indent, indent, "Request per thread, default is ", requestPerThread);
printf("%s%s\n", indent, "-t");
printf("%s%s%s%d\n", indent, indent, "Number of threads to be used, default is ", numOfThreads);
printf("%s%s\n", indent, "-g");
printf("%s%s%s%d\n", indent, indent, "Whether to share connections between threads, default is ", useGlobalConn);
exit(EXIT_SUCCESS);
}
void shellParseArgument(int argc, char *argv[]) {
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
printHelp();
exit(0);
} else if (strcmp(argv[i], "-c") == 0) {
strcpy(configDir, argv[++i]);
} else if (strcmp(argv[i], "-s") == 0) {
strcpy(requestSql, argv[++i]);
} else if (strcmp(argv[i], "-r") == 0) {
requestPerThread = atoi(argv[++i]);
} else if (strcmp(argv[i], "-t") == 0) {
numOfThreads = atoi(argv[++i]);
} else if (strcmp(argv[i], "-g") == 0) {
useGlobalConn = atoi(argv[++i]);
} else {
}
}
pPrint("%s sql:%s %s", GREEN, requestSql, NC);
pPrint("%s requestPerThread:%d %s", GREEN, requestPerThread, NC);
pPrint("%s numOfThreads:%d %s", GREEN, numOfThreads, NC);
pPrint("%s useGlobalConn:%d %s", GREEN, useGlobalConn, NC);
pPrint("%s start to run %s", GREEN, NC);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册