Merge branch '3.0' of https://github.com/taosdata/TDengine into enh/tsdb_optimize
This commit is contained in:
commit
e2df5f772e
|
@ -222,7 +222,7 @@ A database including one supertable and two subtables is created as follows:
|
|||
|
||||
```sql
|
||||
DROP DATABASE IF EXISTS tmqdb;
|
||||
CREATE DATABASE tmqdb;
|
||||
CREATE DATABASE tmqdb WAL_RETENTION_PERIOD 3600;
|
||||
CREATE TABLE tmqdb.stb (ts TIMESTAMP, c1 INT, c2 FLOAT, c3 VARCHAR(16)) TAGS(t1 INT, t3 VARCHAR(16));
|
||||
CREATE TABLE tmqdb.ctb0 USING tmqdb.stb TAGS(0, "subtable0");
|
||||
CREATE TABLE tmqdb.ctb1 USING tmqdb.stb TAGS(1, "subtable1");
|
||||
|
|
|
@ -62,7 +62,7 @@ The different database framework specifications for various programming language
|
|||
| **Regular Query** | Support | Support | Support | Support | Support | Support |
|
||||
| **Parameter Binding** | Not Supported | Not Supported | Support | Support | Not Supported | Support |
|
||||
| **Subscription (TMQ) ** | Supported | Support | Support | Not Supported | Not Supported | Support |
|
||||
| **Schemaless** | Not Supported | Not Supported | Not Supported | Not Supported | Not Supported | Not Supported |
|
||||
| **Schemaless** | Supported | Not Supported | Not Supported | Not Supported | Not Supported | Not Supported |
|
||||
| **Bulk Pulling (based on WebSocket) ** | Support | Support | Support | Support | Support | Support |
|
||||
| **DataFrame** | Not Supported | Support | Not Supported | Not Supported | Not Supported | Not Supported |
|
||||
|
||||
|
|
|
@ -223,3 +223,29 @@ Content-Length: 19
|
|||
|
||||
{"version":"1.0.0"}
|
||||
```
|
||||
|
||||
### taoskeeper with Prometheus
|
||||
|
||||
There is `/metrics` api in taoskeeper provide TDengine metric data for Prometheus.
|
||||
|
||||
#### scrape config
|
||||
|
||||
Scrape config in Prometheus specifies a set of targets and parameters describing how to scrape metric data from endpoint. For more information, please reference to [Prometheus documents](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config).
|
||||
|
||||
```
|
||||
# A scrape configuration containing exactly one endpoint to scrape:
|
||||
# Here it's Prometheus itself.
|
||||
scrape_configs:
|
||||
- job_name: "taoskeeper"
|
||||
# metrics_path defaults to '/metrics'
|
||||
# scheme defaults to 'http'.
|
||||
static_configs:
|
||||
- targets: ["localhost:6043"]
|
||||
```
|
||||
|
||||
#### Dashboard
|
||||
|
||||
There is a dashboard named `TaosKeeper Prometheus Dashboard for 3.x`, which provides a monitoring dashboard similar to TInsight.
|
||||
|
||||
In Grafana, click the Dashboard menu and click `import`, enter the dashboard ID `18587` and click the `Load` button. Then finished importing `TaosKeeper Prometheus Dashboard for 3.x` dashboard.
|
||||
|
||||
|
|
|
@ -221,7 +221,7 @@ void Close()
|
|||
|
||||
```sql
|
||||
DROP DATABASE IF EXISTS tmqdb;
|
||||
CREATE DATABASE tmqdb;
|
||||
CREATE DATABASE tmqdb WAL_RETENTION_PERIOD 3600;
|
||||
CREATE TABLE tmqdb.stb (ts TIMESTAMP, c1 INT, c2 FLOAT, c3 VARCHAR(16)) TAGS(t1 INT, t3 VARCHAR(16));
|
||||
CREATE TABLE tmqdb.ctb0 USING tmqdb.stb TAGS(0, "subtable0");
|
||||
CREATE TABLE tmqdb.ctb1 USING tmqdb.stb TAGS(1, "subtable1");
|
||||
|
|
|
@ -61,7 +61,7 @@ TDengine 版本更新往往会增加新的功能特性,列表中的连接器
|
|||
| **普通查询** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
|
||||
| **参数绑定** | 暂不支持 | 暂不支持 | 支持 | 支持 | 暂不支持 | 支持 |
|
||||
| **数据订阅(TMQ)** | 支持 | 支持 | 支持 | 暂不支持 | 暂不支持 | 支持 |
|
||||
| **Schemaless** | 暂不支持 | 暂不支持 | 暂不支持 | 暂不支持 | 暂不支持 | 暂不支持 |
|
||||
| **Schemaless** | 支持 | 暂不支持 | 暂不支持 | 暂不支持 | 暂不支持 | 暂不支持 |
|
||||
| **批量拉取(基于 WebSocket)** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 |
|
||||
| **DataFrame** | 不支持 | 支持 | 不支持 | 不支持 | 不支持 | 不支持 |
|
||||
|
||||
|
|
|
@ -213,3 +213,29 @@ DELETE_MARK time
|
|||
```
|
||||
DELETE_MARK用于删除缓存的窗口状态,也就是删除流计算的中间结果。如果不设置,默认值是10年
|
||||
T = 最新事件时间 - DELETE_MARK
|
||||
|
||||
## 流式计算支持的函数
|
||||
|
||||
1. 所有的 [单行函数](../function/#单行函数) 均可用于流计算。
|
||||
2. 以下 19 个聚合/选择函数 <b>不能</b> 应用在创建流计算的 SQL 语句,[系统信息函数](../function/#系统信息函数) 也不能用于流计算中。此外的其他类型的函数均可用于流计算。
|
||||
|
||||
- [leastsquares](../function/#leastsquares)
|
||||
- [percentile](../function/#percentile)
|
||||
- [top](../function/#leastsquares)
|
||||
- [bottom](../function/#top)
|
||||
- [elapsed](../function/#leastsquares)
|
||||
- [interp](../function/#elapsed)
|
||||
- [derivative](../function/#derivative)
|
||||
- [irate](../function/#irate)
|
||||
- [twa](../function/#twa)
|
||||
- [histogram](../function/#histogram)
|
||||
- [diff](../function/#diff)
|
||||
- [statecount](../function/#statecount)
|
||||
- [stateduration](../function/#stateduration)
|
||||
- [csum](../function/#csum)
|
||||
- [mavg](../function/#mavg)
|
||||
- [sample](../function/#sample)
|
||||
- [tail](../function/#tail)
|
||||
- [unique](../function/#unique)
|
||||
- [mode](../function/#mode)
|
||||
|
||||
|
|
|
@ -226,3 +226,29 @@ Content-Length: 19
|
|||
|
||||
{"version":"1.0.0"}
|
||||
```
|
||||
|
||||
### 集成 Prometheus
|
||||
|
||||
taoskeeper 提供了 `/metrics` 接口,返回了 Prometheus 格式的监控数据,Prometheus 可以从 taoskeeper 抽取监控数据,实现通过 Prometheus 监控 TDengine 的目的。
|
||||
|
||||
#### 抽取配置
|
||||
|
||||
Prometheus 提供了 `scrape_configs` 配置如何从 endpoint 抽取监控数据,通常只需要修改 `static_configs` 中的 targets 配置为 taoskeeper 的 endpoint 地址,更多配置信息请参考 [Prometheus 配置文档](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config)。
|
||||
|
||||
```
|
||||
# A scrape configuration containing exactly one endpoint to scrape:
|
||||
# Here it's Prometheus itself.
|
||||
scrape_configs:
|
||||
- job_name: "taoskeeper"
|
||||
# metrics_path defaults to '/metrics'
|
||||
# scheme defaults to 'http'.
|
||||
static_configs:
|
||||
- targets: ["localhost:6043"]
|
||||
```
|
||||
|
||||
#### Dashboard
|
||||
|
||||
我们提供了 `TaosKeeper Prometheus Dashboard for 3.x` dashboard,提供了和 TDinsight 类似的监控 dashboard。
|
||||
|
||||
在 Grafana Dashboard 菜单点击 `import`,dashboard ID 填写 `18587`,点击 `Load` 按钮即可导入 `TaosKeeper Prometheus Dashboard for 3.x` dashboard。
|
||||
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
#include <time.h>
|
||||
#include "taos.h"
|
||||
|
||||
static int running = 1;
|
||||
static int running = 1;
|
||||
const char* topic_name = "topicname";
|
||||
|
||||
static int32_t msg_process(TAOS_RES* msg) {
|
||||
char buf[1024];
|
||||
|
@ -243,7 +244,7 @@ _end:
|
|||
|
||||
tmq_list_t* build_topic_list() {
|
||||
tmq_list_t* topicList = tmq_list_new();
|
||||
int32_t code = tmq_list_append(topicList, "topicname");
|
||||
int32_t code = tmq_list_append(topicList, topic_name);
|
||||
if (code) {
|
||||
tmq_list_destroy(topicList);
|
||||
return NULL;
|
||||
|
@ -269,6 +270,31 @@ void basic_consume_loop(tmq_t* tmq) {
|
|||
fprintf(stderr, "%d msg consumed, include %d rows\n", msgCnt, totalRows);
|
||||
}
|
||||
|
||||
void consume_repeatly(tmq_t* tmq) {
|
||||
int32_t numOfAssignment = 0;
|
||||
tmq_topic_assignment* pAssign = NULL;
|
||||
|
||||
int32_t code = tmq_get_topic_assignment(tmq, topic_name, &pAssign, &numOfAssignment);
|
||||
if (code != 0) {
|
||||
fprintf(stderr, "failed to get assignment, reason:%s", tmq_err2str(code));
|
||||
}
|
||||
|
||||
// seek to the earliest offset
|
||||
for(int32_t i = 0; i < numOfAssignment; ++i) {
|
||||
tmq_topic_assignment* p = &pAssign[i];
|
||||
|
||||
code = tmq_offset_seek(tmq, topic_name, p->vgId, p->begin);
|
||||
if (code != 0) {
|
||||
fprintf(stderr, "failed to seek to %ld, reason:%s", p->begin, tmq_err2str(code));
|
||||
}
|
||||
}
|
||||
|
||||
free(pAssign);
|
||||
|
||||
// let's do it again
|
||||
basic_consume_loop(tmq);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
int32_t code;
|
||||
|
||||
|
@ -294,10 +320,13 @@ int main(int argc, char* argv[]) {
|
|||
if ((code = tmq_subscribe(tmq, topic_list))) {
|
||||
fprintf(stderr, "Failed to tmq_subscribe(): %s\n", tmq_err2str(code));
|
||||
}
|
||||
|
||||
tmq_list_destroy(topic_list);
|
||||
|
||||
basic_consume_loop(tmq);
|
||||
|
||||
consume_repeatly(tmq);
|
||||
|
||||
code = tmq_consumer_close(tmq);
|
||||
if (code) {
|
||||
fprintf(stderr, "Failed to close consumer: %s\n", tmq_err2str(code));
|
||||
|
|
|
@ -101,6 +101,7 @@ typedef struct TAOS_FIELD_E {
|
|||
#endif
|
||||
|
||||
typedef void (*__taos_async_fn_t)(void *param, TAOS_RES *res, int code);
|
||||
typedef void (*__taos_notify_fn_t)(void *param, void *ext, int type);
|
||||
|
||||
typedef struct TAOS_MULTI_BIND {
|
||||
int buffer_type;
|
||||
|
@ -121,6 +122,10 @@ typedef enum {
|
|||
SET_CONF_RET_ERR_TOO_LONG = -6
|
||||
} SET_CONF_RET_CODE;
|
||||
|
||||
typedef enum {
|
||||
TAOS_NOTIFY_PASSVER = 0,
|
||||
} TAOS_NOTIFY_TYPE;
|
||||
|
||||
#define RET_MSG_LENGTH 1024
|
||||
typedef struct setConfRet {
|
||||
SET_CONF_RET_CODE retCode;
|
||||
|
@ -225,6 +230,8 @@ DLL_EXPORT int taos_get_tables_vgId(TAOS *taos, const char *db, const char *tabl
|
|||
|
||||
DLL_EXPORT int taos_load_table_info(TAOS *taos, const char *tableNameList);
|
||||
|
||||
DLL_EXPORT int taos_set_notify_cb(TAOS *taos, __taos_notify_fn_t fp, void *param, int type);
|
||||
|
||||
/* --------------------------schemaless INTERFACE------------------------------- */
|
||||
|
||||
DLL_EXPORT TAOS_RES *taos_schemaless_insert(TAOS *taos, char *lines[], int numLines, int protocol, int precision);
|
||||
|
@ -262,6 +269,12 @@ DLL_EXPORT tmq_t *tmq_consumer_new(tmq_conf_t *conf, char *errstr, int32_t errst
|
|||
DLL_EXPORT const char *tmq_err2str(int32_t code);
|
||||
|
||||
/* ------------------------TMQ CONSUMER INTERFACE------------------------ */
|
||||
typedef struct tmq_topic_assignment {
|
||||
int32_t vgId;
|
||||
int64_t currentOffset;
|
||||
int64_t begin;
|
||||
int64_t end;
|
||||
} tmq_topic_assignment;
|
||||
|
||||
DLL_EXPORT int32_t tmq_subscribe(tmq_t *tmq, const tmq_list_t *topic_list);
|
||||
DLL_EXPORT int32_t tmq_unsubscribe(tmq_t *tmq);
|
||||
|
@ -270,6 +283,8 @@ DLL_EXPORT TAOS_RES *tmq_consumer_poll(tmq_t *tmq, int64_t timeout);
|
|||
DLL_EXPORT int32_t tmq_consumer_close(tmq_t *tmq);
|
||||
DLL_EXPORT int32_t tmq_commit_sync(tmq_t *tmq, const TAOS_RES *msg);
|
||||
DLL_EXPORT void tmq_commit_async(tmq_t *tmq, const TAOS_RES *msg, tmq_commit_cb *cb, void *param);
|
||||
DLL_EXPORT int32_t tmq_get_topic_assignment(tmq_t *tmq, const char* pTopicName, tmq_topic_assignment **assignment, int32_t *numOfAssignment);
|
||||
DLL_EXPORT int32_t tmq_offset_seek(tmq_t *tmq, const char* pTopicName, int32_t vgId, int64_t offset);
|
||||
|
||||
/* ----------------------TMQ CONFIGURATION INTERFACE---------------------- */
|
||||
|
||||
|
|
|
@ -128,6 +128,7 @@ enum {
|
|||
TMQ_MSG_TYPE__POLL_META_RSP,
|
||||
TMQ_MSG_TYPE__EP_RSP,
|
||||
TMQ_MSG_TYPE__TAOSX_RSP,
|
||||
TMQ_MSG_TYPE__WALINFO_RSP,
|
||||
TMQ_MSG_TYPE__END_RSP,
|
||||
};
|
||||
|
||||
|
|
|
@ -24,6 +24,12 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SLOW_LOG_TYPE_QUERY 0x1
|
||||
#define SLOW_LOG_TYPE_INSERT 0x2
|
||||
#define SLOW_LOG_TYPE_OTHERS 0x4
|
||||
#define SLOW_LOG_TYPE_ALL 0xFFFFFFFF
|
||||
|
||||
|
||||
// cluster
|
||||
extern char tsFirst[];
|
||||
extern char tsSecond[];
|
||||
|
@ -118,6 +124,8 @@ extern int32_t tsRedirectFactor;
|
|||
extern int32_t tsRedirectMaxPeriod;
|
||||
extern int32_t tsMaxRetryWaitTime;
|
||||
extern bool tsUseAdapter;
|
||||
extern int32_t tsSlowLogThreshold;
|
||||
extern int32_t tsSlowLogScope;
|
||||
|
||||
// client
|
||||
extern int32_t tsMinSlidingTime;
|
||||
|
|
|
@ -106,6 +106,7 @@ enum {
|
|||
HEARTBEAT_KEY_DBINFO,
|
||||
HEARTBEAT_KEY_STBINFO,
|
||||
HEARTBEAT_KEY_TMQ,
|
||||
HEARTBEAT_KEY_USER_PASSINFO,
|
||||
};
|
||||
|
||||
typedef enum _mgmt_table {
|
||||
|
@ -634,6 +635,7 @@ typedef struct {
|
|||
int8_t connType;
|
||||
SEpSet epSet;
|
||||
int32_t svrTimestamp;
|
||||
int32_t passVer;
|
||||
char sVer[TSDB_VERSION_LEN];
|
||||
char sDetailVer[128];
|
||||
} SConnectRsp;
|
||||
|
@ -716,6 +718,14 @@ int32_t tSerializeSGetUserAuthRsp(void* buf, int32_t bufLen, SGetUserAuthRsp* pR
|
|||
int32_t tDeserializeSGetUserAuthRsp(void* buf, int32_t bufLen, SGetUserAuthRsp* pRsp);
|
||||
void tFreeSGetUserAuthRsp(SGetUserAuthRsp* pRsp);
|
||||
|
||||
typedef struct SUserPassVersion {
|
||||
char user[TSDB_USER_LEN];
|
||||
int32_t version;
|
||||
} SUserPassVersion;
|
||||
|
||||
typedef SGetUserAuthReq SGetUserPassReq;
|
||||
typedef SUserPassVersion SGetUserPassRsp;
|
||||
|
||||
/*
|
||||
* for client side struct, only column id, type, bytes are necessary
|
||||
* But for data in vnode side, we need all the following information.
|
||||
|
@ -1046,6 +1056,14 @@ int32_t tSerializeSUserAuthBatchRsp(void* buf, int32_t bufLen, SUserAuthBatchRsp
|
|||
int32_t tDeserializeSUserAuthBatchRsp(void* buf, int32_t bufLen, SUserAuthBatchRsp* pRsp);
|
||||
void tFreeSUserAuthBatchRsp(SUserAuthBatchRsp* pRsp);
|
||||
|
||||
typedef struct {
|
||||
SArray* pArray; // Array of SGetUserPassRsp
|
||||
} SUserPassBatchRsp;
|
||||
|
||||
int32_t tSerializeSUserPassBatchRsp(void* buf, int32_t bufLen, SUserPassBatchRsp* pRsp);
|
||||
int32_t tDeserializeSUserPassBatchRsp(void* buf, int32_t bufLen, SUserPassBatchRsp* pRsp);
|
||||
void tFreeSUserPassBatchRsp(SUserPassBatchRsp* pRsp);
|
||||
|
||||
typedef struct {
|
||||
char db[TSDB_DB_FNAME_LEN];
|
||||
STimeWindow timeRange;
|
||||
|
@ -2814,6 +2832,7 @@ typedef struct {
|
|||
} SMqOffset;
|
||||
|
||||
typedef struct {
|
||||
int64_t consumerId;
|
||||
int32_t num;
|
||||
SMqOffset* offsets;
|
||||
} SMqCMCommitOffsetReq;
|
||||
|
@ -2881,6 +2900,14 @@ typedef struct {
|
|||
int32_t tEncodeSTqOffset(SEncoder* pEncoder, const STqOffset* pOffset);
|
||||
int32_t tDecodeSTqOffset(SDecoder* pDecoder, STqOffset* pOffset);
|
||||
|
||||
typedef struct SMqVgOffset {
|
||||
int64_t consumerId;
|
||||
STqOffset offset;
|
||||
} SMqVgOffset;
|
||||
|
||||
int32_t tEncodeMqVgOffset(SEncoder* pEncoder, const SMqVgOffset* pOffset);
|
||||
int32_t tDecodeMqVgOffset(SDecoder* pDecoder, SMqVgOffset* pOffset);
|
||||
|
||||
typedef struct {
|
||||
char name[TSDB_TABLE_FNAME_LEN];
|
||||
char stb[TSDB_TABLE_FNAME_LEN];
|
||||
|
@ -3110,18 +3137,19 @@ typedef struct {
|
|||
int32_t code;
|
||||
int32_t epoch;
|
||||
int64_t consumerId;
|
||||
int64_t walsver;
|
||||
int64_t walever;
|
||||
} SMqRspHead;
|
||||
|
||||
typedef struct {
|
||||
SMsgHead head;
|
||||
char subKey[TSDB_SUBSCRIBE_KEY_LEN];
|
||||
int8_t withTbName;
|
||||
int8_t useSnapshot;
|
||||
int32_t epoch;
|
||||
uint64_t reqId;
|
||||
int64_t consumerId;
|
||||
int64_t timeout;
|
||||
// int64_t currentOffset;
|
||||
SMsgHead head;
|
||||
char subKey[TSDB_SUBSCRIBE_KEY_LEN];
|
||||
int8_t withTbName;
|
||||
int8_t useSnapshot;
|
||||
int32_t epoch;
|
||||
uint64_t reqId;
|
||||
int64_t consumerId;
|
||||
int64_t timeout;
|
||||
STqOffsetVal reqOffset;
|
||||
} SMqPollReq;
|
||||
|
||||
|
@ -3156,43 +3184,9 @@ typedef struct {
|
|||
SSchemaWrapper schema;
|
||||
} SMqSubTopicEp;
|
||||
|
||||
static FORCE_INLINE int32_t tEncodeSMqSubTopicEp(void** buf, const SMqSubTopicEp* pTopicEp) {
|
||||
int32_t tlen = 0;
|
||||
tlen += taosEncodeString(buf, pTopicEp->topic);
|
||||
tlen += taosEncodeString(buf, pTopicEp->db);
|
||||
int32_t sz = taosArrayGetSize(pTopicEp->vgs);
|
||||
tlen += taosEncodeFixedI32(buf, sz);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
SMqSubVgEp* pVgEp = (SMqSubVgEp*)taosArrayGet(pTopicEp->vgs, i);
|
||||
tlen += tEncodeSMqSubVgEp(buf, pVgEp);
|
||||
}
|
||||
tlen += taosEncodeSSchemaWrapper(buf, &pTopicEp->schema);
|
||||
return tlen;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void* tDecodeSMqSubTopicEp(void* buf, SMqSubTopicEp* pTopicEp) {
|
||||
buf = taosDecodeStringTo(buf, pTopicEp->topic);
|
||||
buf = taosDecodeStringTo(buf, pTopicEp->db);
|
||||
int32_t sz;
|
||||
buf = taosDecodeFixedI32(buf, &sz);
|
||||
pTopicEp->vgs = taosArrayInit(sz, sizeof(SMqSubVgEp));
|
||||
if (pTopicEp->vgs == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
SMqSubVgEp vgEp;
|
||||
buf = tDecodeSMqSubVgEp(buf, &vgEp);
|
||||
taosArrayPush(pTopicEp->vgs, &vgEp);
|
||||
}
|
||||
buf = taosDecodeSSchemaWrapper(buf, &pTopicEp->schema);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void tDeleteSMqSubTopicEp(SMqSubTopicEp* pSubTopicEp) {
|
||||
taosMemoryFreeClear(pSubTopicEp->schema.pSchema);
|
||||
pSubTopicEp->schema.nCols = 0;
|
||||
taosArrayDestroy(pSubTopicEp->vgs);
|
||||
}
|
||||
int32_t tEncodeMqSubTopicEp(void** buf, const SMqSubTopicEp* pTopicEp);
|
||||
void* tDecodeMqSubTopicEp(void* buf, SMqSubTopicEp* pTopicEp);
|
||||
void tDeleteMqSubTopicEp(SMqSubTopicEp* pSubTopicEp);
|
||||
|
||||
typedef struct {
|
||||
SMqRspHead head;
|
||||
|
@ -3202,8 +3196,8 @@ typedef struct {
|
|||
void* metaRsp;
|
||||
} SMqMetaRsp;
|
||||
|
||||
int32_t tEncodeSMqMetaRsp(SEncoder* pEncoder, const SMqMetaRsp* pRsp);
|
||||
int32_t tDecodeSMqMetaRsp(SDecoder* pDecoder, SMqMetaRsp* pRsp);
|
||||
int32_t tEncodeMqMetaRsp(SEncoder* pEncoder, const SMqMetaRsp* pRsp);
|
||||
int32_t tDecodeMqMetaRsp(SDecoder* pDecoder, SMqMetaRsp* pRsp);
|
||||
|
||||
typedef struct {
|
||||
SMqRspHead head;
|
||||
|
@ -3218,9 +3212,9 @@ typedef struct {
|
|||
SArray* blockSchema;
|
||||
} SMqDataRsp;
|
||||
|
||||
int32_t tEncodeSMqDataRsp(SEncoder* pEncoder, const SMqDataRsp* pRsp);
|
||||
int32_t tDecodeSMqDataRsp(SDecoder* pDecoder, SMqDataRsp* pRsp);
|
||||
void tDeleteSMqDataRsp(SMqDataRsp* pRsp);
|
||||
int32_t tEncodeMqDataRsp(SEncoder* pEncoder, const SMqDataRsp* pRsp);
|
||||
int32_t tDecodeMqDataRsp(SDecoder* pDecoder, SMqDataRsp* pRsp);
|
||||
void tDeleteMqDataRsp(SMqDataRsp* pRsp);
|
||||
|
||||
typedef struct {
|
||||
SMqRspHead head;
|
||||
|
@ -3256,7 +3250,7 @@ static FORCE_INLINE int32_t tEncodeSMqAskEpRsp(void** buf, const SMqAskEpRsp* pR
|
|||
tlen += taosEncodeFixedI32(buf, sz);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
SMqSubTopicEp* pVgEp = (SMqSubTopicEp*)taosArrayGet(pRsp->topics, i);
|
||||
tlen += tEncodeSMqSubTopicEp(buf, pVgEp);
|
||||
tlen += tEncodeMqSubTopicEp(buf, pVgEp);
|
||||
}
|
||||
return tlen;
|
||||
}
|
||||
|
@ -3271,14 +3265,14 @@ static FORCE_INLINE void* tDecodeSMqAskEpRsp(void* buf, SMqAskEpRsp* pRsp) {
|
|||
}
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
SMqSubTopicEp topicEp;
|
||||
buf = tDecodeSMqSubTopicEp(buf, &topicEp);
|
||||
buf = tDecodeMqSubTopicEp(buf, &topicEp);
|
||||
taosArrayPush(pRsp->topics, &topicEp);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void tDeleteSMqAskEpRsp(SMqAskEpRsp* pRsp) {
|
||||
taosArrayDestroyEx(pRsp->topics, (FDelete)tDeleteSMqSubTopicEp);
|
||||
taosArrayDestroyEx(pRsp->topics, (FDelete)tDeleteMqSubTopicEp);
|
||||
}
|
||||
|
||||
#define TD_AUTO_CREATE_TABLE 0x1
|
||||
|
|
|
@ -302,9 +302,11 @@ enum {
|
|||
TD_DEF_MSG_TYPE(TDMT_VND_TMQ_SUBSCRIBE, "vnode-tmq-subscribe", SMqRebVgReq, SMqRebVgRsp)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_TMQ_DELETE_SUB, "vnode-tmq-delete-sub", SMqVDeleteReq, SMqVDeleteRsp)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_TMQ_COMMIT_OFFSET, "vnode-tmq-commit-offset", STqOffset, STqOffset)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_TMQ_SEEK_TO_OFFSET, "vnode-tmq-seekto-offset", STqOffset, STqOffset)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_TMQ_ADD_CHECKINFO, "vnode-tmq-add-checkinfo", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_TMQ_DEL_CHECKINFO, "vnode-del-checkinfo", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_TMQ_CONSUME, "vnode-tmq-consume", SMqPollReq, SMqDataBlkRsp)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_TMQ_VG_WALINFO, "vnode-tmq-vg-walinfo", SMqPollReq, SMqDataBlkRsp)
|
||||
TD_DEF_MSG_TYPE(TDMT_VND_TMQ_MAX_MSG, "vnd-tmq-max", NULL, NULL)
|
||||
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "tmsg.h"
|
||||
#include "tmsgcb.h"
|
||||
#include "trpc.h"
|
||||
#include "sync.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -73,6 +74,7 @@ int32_t mndStart(SMnode *pMnode);
|
|||
void mndStop(SMnode *pMnode);
|
||||
|
||||
int32_t mndIsCatchUp(SMnode *pMnode);
|
||||
ESyncRole mndGetRole(SMnode *pMnode);
|
||||
|
||||
/**
|
||||
* @brief Get mnode monitor info.
|
||||
|
|
|
@ -29,7 +29,6 @@ extern "C" {
|
|||
#define DS_BUF_FULL 2
|
||||
#define DS_BUF_EMPTY 3
|
||||
|
||||
struct SDataSink;
|
||||
struct SSDataBlock;
|
||||
|
||||
typedef struct SDeleterRes {
|
||||
|
|
|
@ -335,18 +335,17 @@ struct SStreamTask {
|
|||
|
||||
// meta
|
||||
typedef struct SStreamMeta {
|
||||
char* path;
|
||||
TDB* db;
|
||||
TTB* pTaskDb;
|
||||
TTB* pCheckpointDb;
|
||||
SHashObj* pTasks;
|
||||
void* ahandle;
|
||||
TXN* txn;
|
||||
FTaskExpand* expandFunc;
|
||||
int32_t vgId;
|
||||
SRWLatch lock;
|
||||
int8_t walScan;
|
||||
bool quit;
|
||||
char* path;
|
||||
TDB* db;
|
||||
TTB* pTaskDb;
|
||||
TTB* pCheckpointDb;
|
||||
SHashObj* pTasks;
|
||||
void* ahandle;
|
||||
TXN* txn;
|
||||
FTaskExpand* expandFunc;
|
||||
int32_t vgId;
|
||||
SRWLatch lock;
|
||||
int8_t walScan;
|
||||
} SStreamMeta;
|
||||
|
||||
int32_t tEncodeStreamEpInfo(SEncoder* pEncoder, const SStreamChildEpInfo* pInfo);
|
||||
|
@ -359,10 +358,6 @@ void tFreeStreamTask(SStreamTask* pTask);
|
|||
int32_t tAppendDataToInputQueue(SStreamTask* pTask, SStreamQueueItem* pItem);
|
||||
bool tInputQueueIsFull(const SStreamTask* pTask);
|
||||
|
||||
static FORCE_INLINE void streamTaskInputFail(SStreamTask* pTask) {
|
||||
atomic_store_8(&pTask->inputStatus, TASK_INPUT_STATUS__FAILED);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
SMsgHead head;
|
||||
int64_t streamId;
|
||||
|
@ -538,6 +533,7 @@ int32_t streamProcessDispatchRsp(SStreamTask* pTask, SStreamDispatchRsp* pRsp, i
|
|||
int32_t streamProcessRetrieveReq(SStreamTask* pTask, SStreamRetrieveReq* pReq, SRpcMsg* pMsg);
|
||||
// int32_t streamProcessRetrieveRsp(SStreamTask* pTask, SStreamRetrieveRsp* pRsp);
|
||||
|
||||
void streamTaskInputFail(SStreamTask* pTask);
|
||||
int32_t streamTryExec(SStreamTask* pTask);
|
||||
int32_t streamSchedExec(SStreamTask* pTask);
|
||||
int32_t streamTaskOutput(SStreamTask* pTask, SStreamDataBlock* pBlock);
|
||||
|
|
|
@ -250,6 +250,7 @@ void syncPreStop(int64_t rid);
|
|||
void syncPostStop(int64_t rid);
|
||||
int32_t syncPropose(int64_t rid, SRpcMsg* pMsg, bool isWeak, int64_t* seq);
|
||||
int32_t syncIsCatchUp(int64_t rid);
|
||||
ESyncRole syncGetRole(int64_t rid);
|
||||
int32_t syncProcessMsg(int64_t rid, SRpcMsg* pMsg);
|
||||
int32_t syncReconfig(int64_t rid, SSyncCfg* pCfg);
|
||||
int32_t syncBeginSnapshot(int64_t rid, int64_t lastApplyIndex);
|
||||
|
|
|
@ -190,7 +190,7 @@ int32_t walApplyVer(SWal *, int64_t ver);
|
|||
|
||||
// int32_t walDataCorrupted(SWal*);
|
||||
|
||||
// read
|
||||
// wal reader
|
||||
SWalReader *walOpenReader(SWal *, SWalFilterCond *pCond);
|
||||
void walCloseReader(SWalReader *pRead);
|
||||
void walReadReset(SWalReader *pReader);
|
||||
|
@ -198,6 +198,7 @@ int32_t walReadVer(SWalReader *pRead, int64_t ver);
|
|||
int32_t walReadSeekVer(SWalReader *pRead, int64_t ver);
|
||||
int32_t walNextValidMsg(SWalReader *pRead);
|
||||
int64_t walReaderGetCurrentVer(const SWalReader* pReader);
|
||||
void walReaderValidVersionRange(SWalReader* pReader, int64_t *sver, int64_t *ever);
|
||||
|
||||
// only for tq usage
|
||||
void walSetReaderCapacity(SWalReader *pRead, int32_t capacity);
|
||||
|
|
|
@ -103,7 +103,7 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_CHECKSUM_ERROR TAOS_DEF_ERROR_CODE(0, 0x011F) // internal
|
||||
|
||||
#define TSDB_CODE_COMPRESS_ERROR TAOS_DEF_ERROR_CODE(0, 0x0120)
|
||||
#define TSDB_CODE_MSG_NOT_PROCESSED TAOS_DEF_ERROR_CODE(0, 0x0121) //
|
||||
#define TSDB_CODE_MSG_NOT_PROCESSED TAOS_DEF_ERROR_CODE(0, 0x0121)
|
||||
#define TSDB_CODE_CFG_NOT_FOUND TAOS_DEF_ERROR_CODE(0, 0x0122)
|
||||
#define TSDB_CODE_REPEAT_INIT TAOS_DEF_ERROR_CODE(0, 0x0123)
|
||||
#define TSDB_CODE_DUP_KEY TAOS_DEF_ERROR_CODE(0, 0x0124)
|
||||
|
@ -118,9 +118,10 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_MSG_ENCODE_ERROR TAOS_DEF_ERROR_CODE(0, 0x012D)
|
||||
#define TSDB_CODE_NO_ENOUGH_DISKSPACE TAOS_DEF_ERROR_CODE(0, 0x012E)
|
||||
|
||||
#define TSDB_CODE_APP_IS_STARTING TAOS_DEF_ERROR_CODE(0, 0x0130) //
|
||||
#define TSDB_CODE_APP_IS_STOPPING TAOS_DEF_ERROR_CODE(0, 0x0131) //
|
||||
#define TSDB_CODE_IVLD_DATA_FMT TAOS_DEF_ERROR_CODE(0, 0x0132) //
|
||||
#define TSDB_CODE_APP_IS_STARTING TAOS_DEF_ERROR_CODE(0, 0x0130)
|
||||
#define TSDB_CODE_APP_IS_STOPPING TAOS_DEF_ERROR_CODE(0, 0x0131)
|
||||
#define TSDB_CODE_INVALID_DATA_FMT TAOS_DEF_ERROR_CODE(0, 0x0132)
|
||||
#define TSDB_CODE_INVALID_CFG_VALUE TAOS_DEF_ERROR_CODE(0, 0x0133)
|
||||
|
||||
//client
|
||||
#define TSDB_CODE_TSC_INVALID_OPERATION TAOS_DEF_ERROR_CODE(0, 0x0200)
|
||||
|
@ -403,6 +404,8 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_SNODE_ALREADY_DEPLOYED TAOS_DEF_ERROR_CODE(0, 0x040F)
|
||||
#define TSDB_CODE_SNODE_NOT_FOUND TAOS_DEF_ERROR_CODE(0, 0x0410)
|
||||
#define TSDB_CODE_SNODE_NOT_DEPLOYED TAOS_DEF_ERROR_CODE(0, 0x0411)
|
||||
#define TSDB_CODE_MNODE_NOT_CATCH_UP TAOS_DEF_ERROR_CODE(0, 0x0412) // internal
|
||||
#define TSDB_CODE_MNODE_ALREADY_IS_VOTER TAOS_DEF_ERROR_CODE(0, 0x0413) // internal
|
||||
|
||||
// vnode
|
||||
// #define TSDB_CODE_VND_ACTION_IN_PROGRESS TAOS_DEF_ERROR_CODE(0, 0x0500) // 2.x
|
||||
|
@ -437,6 +440,8 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_VND_STOPPED TAOS_DEF_ERROR_CODE(0, 0x0529)
|
||||
#define TSDB_CODE_VND_DUP_REQUEST TAOS_DEF_ERROR_CODE(0, 0x0530)
|
||||
#define TSDB_CODE_VND_QUERY_BUSY TAOS_DEF_ERROR_CODE(0, 0x0531)
|
||||
#define TSDB_CODE_VND_NOT_CATCH_UP TAOS_DEF_ERROR_CODE(0, 0x0532) // internal
|
||||
#define TSDB_CODE_VND_ALREADY_IS_VOTER TAOS_DEF_ERROR_CODE(0, 0x0533) // internal
|
||||
|
||||
// tsdb
|
||||
#define TSDB_CODE_TDB_INVALID_TABLE_ID TAOS_DEF_ERROR_CODE(0, 0x0600)
|
||||
|
@ -534,20 +539,20 @@ int32_t* taosGetErrno();
|
|||
// #define TSDB_CODE_SYN_INVALID_CHECKSUM TAOS_DEF_ERROR_CODE(0, 0x0908) // 2.x
|
||||
// #define TSDB_CODE_SYN_INVALID_MSGLEN TAOS_DEF_ERROR_CODE(0, 0x0909) // 2.x
|
||||
// #define TSDB_CODE_SYN_INVALID_MSGTYPE TAOS_DEF_ERROR_CODE(0, 0x090A) // 2.x
|
||||
#define TSDB_CODE_SYN_IS_LEADER TAOS_DEF_ERROR_CODE(0, 0x090B)
|
||||
// #define TSDB_CODE_SYN_IS_LEADER TAOS_DEF_ERROR_CODE(0, 0x090B) // unused
|
||||
#define TSDB_CODE_SYN_NOT_LEADER TAOS_DEF_ERROR_CODE(0, 0x090C)
|
||||
#define TSDB_CODE_SYN_ONE_REPLICA TAOS_DEF_ERROR_CODE(0, 0x090D)
|
||||
#define TSDB_CODE_SYN_NOT_IN_NEW_CONFIG TAOS_DEF_ERROR_CODE(0, 0x090E)
|
||||
#define TSDB_CODE_SYN_NEW_CONFIG_ERROR TAOS_DEF_ERROR_CODE(0, 0x090F) // internal
|
||||
#define TSDB_CODE_SYN_RECONFIG_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0910)
|
||||
// #define TSDB_CODE_SYN_ONE_REPLICA TAOS_DEF_ERROR_CODE(0, 0x090D) // unused
|
||||
// #define TSDB_CODE_SYN_NOT_IN_NEW_CONFIG TAOS_DEF_ERROR_CODE(0, 0x090E) // unused
|
||||
#define TSDB_CODE_SYN_NEW_CONFIG_ERROR TAOS_DEF_ERROR_CODE(0, 0x090F) // internal
|
||||
// #define TSDB_CODE_SYN_RECONFIG_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0910) // unused
|
||||
#define TSDB_CODE_SYN_PROPOSE_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0911)
|
||||
#define TSDB_CODE_SYN_STANDBY_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0912)
|
||||
#define TSDB_CODE_SYN_BATCH_ERROR TAOS_DEF_ERROR_CODE(0, 0x0913)
|
||||
// #define TSDB_CODE_SYN_STANDBY_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0912) // unused
|
||||
// #define TSDB_CODE_SYN_BATCH_ERROR TAOS_DEF_ERROR_CODE(0, 0x0913) // unused
|
||||
#define TSDB_CODE_SYN_RESTORING TAOS_DEF_ERROR_CODE(0, 0x0914)
|
||||
#define TSDB_CODE_SYN_INVALID_SNAPSHOT_MSG TAOS_DEF_ERROR_CODE(0, 0x0915) // internal
|
||||
#define TSDB_CODE_SYN_INVALID_SNAPSHOT_MSG TAOS_DEF_ERROR_CODE(0, 0x0915) // internal
|
||||
#define TSDB_CODE_SYN_BUFFER_FULL TAOS_DEF_ERROR_CODE(0, 0x0916)
|
||||
#define TSDB_CODE_SYN_WRITE_STALL TAOS_DEF_ERROR_CODE(0, 0x0917)
|
||||
#define TSDB_CODE_SYN_NEGO_WIN_EXCEEDED TAOS_DEF_ERROR_CODE(0, 0X0918)
|
||||
#define TSDB_CODE_SYN_NEGOTIATION_WIN_FULL TAOS_DEF_ERROR_CODE(0, 0x0918)
|
||||
#define TSDB_CODE_SYN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x09FF)
|
||||
|
||||
// tq
|
||||
|
@ -568,7 +573,7 @@ int32_t* taosGetErrno();
|
|||
// wal
|
||||
// #define TSDB_CODE_WAL_APP_ERROR TAOS_DEF_ERROR_CODE(0, 0x1000) // 2.x
|
||||
#define TSDB_CODE_WAL_FILE_CORRUPTED TAOS_DEF_ERROR_CODE(0, 0x1001)
|
||||
#define TSDB_CODE_WAL_SIZE_LIMIT TAOS_DEF_ERROR_CODE(0, 0x1002)
|
||||
// #define TSDB_CODE_WAL_SIZE_LIMIT TAOS_DEF_ERROR_CODE(0, 0x1002) // unused
|
||||
#define TSDB_CODE_WAL_INVALID_VER TAOS_DEF_ERROR_CODE(0, 0x1003)
|
||||
// #define TSDB_CODE_WAL_OUT_OF_MEMORY TAOS_DEF_ERROR_CODE(0, 0x1004) // 2.x
|
||||
#define TSDB_CODE_WAL_LOG_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x1005)
|
||||
|
@ -712,15 +717,13 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_UDF_STOPPING TAOS_DEF_ERROR_CODE(0, 0x2901)
|
||||
#define TSDB_CODE_UDF_PIPE_READ_ERR TAOS_DEF_ERROR_CODE(0, 0x2902)
|
||||
#define TSDB_CODE_UDF_PIPE_CONNECT_ERR TAOS_DEF_ERROR_CODE(0, 0x2903)
|
||||
#define TSDB_CODE_UDF_PIPE_NO_PIPE TAOS_DEF_ERROR_CODE(0, 0x2904)
|
||||
#define TSDB_CODE_UDF_PIPE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x2904)
|
||||
#define TSDB_CODE_UDF_LOAD_UDF_FAILURE TAOS_DEF_ERROR_CODE(0, 0x2905)
|
||||
#define TSDB_CODE_UDF_INVALID_STATE TAOS_DEF_ERROR_CODE(0, 0x2906)
|
||||
#define TSDB_CODE_UDF_INVALID_INPUT TAOS_DEF_ERROR_CODE(0, 0x2907)
|
||||
#define TSDB_CODE_UDF_NO_FUNC_HANDLE TAOS_DEF_ERROR_CODE(0, 0x2908)
|
||||
#define TSDB_CODE_UDF_INVALID_BUFSIZE TAOS_DEF_ERROR_CODE(0, 0x2909)
|
||||
#define TSDB_CODE_UDF_INVALID_OUTPUT_TYPE TAOS_DEF_ERROR_CODE(0, 0x290A)
|
||||
#define TSDB_CODE_UDF_SCRIPT_NOT_SUPPORTED TAOS_DEF_ERROR_CODE(0, 0x290B)
|
||||
#define TSDB_CODE_UDF_FUNC_EXEC_FAILURE TAOS_DEF_ERROR_CODE(0, 0x290C)
|
||||
#define TSDB_CODE_UDF_INVALID_INPUT TAOS_DEF_ERROR_CODE(0, 0x2906)
|
||||
#define TSDB_CODE_UDF_INVALID_BUFSIZE TAOS_DEF_ERROR_CODE(0, 0x2907)
|
||||
#define TSDB_CODE_UDF_INVALID_OUTPUT_TYPE TAOS_DEF_ERROR_CODE(0, 0x2908)
|
||||
#define TSDB_CODE_UDF_SCRIPT_NOT_SUPPORTED TAOS_DEF_ERROR_CODE(0, 0x2909)
|
||||
#define TSDB_CODE_UDF_FUNC_EXEC_FAILURE TAOS_DEF_ERROR_CODE(0, 0x290A)
|
||||
|
||||
// sml
|
||||
#define TSDB_CODE_SML_INVALID_PROTOCOL_TYPE TAOS_DEF_ERROR_CODE(0, 0x3000)
|
||||
|
|
|
@ -83,6 +83,12 @@ void taosPrintLongString(const char *flags, ELogLevel level, int32_t dflag, cons
|
|||
#endif
|
||||
;
|
||||
|
||||
void taosPrintSlowLog(const char *format, ...)
|
||||
#ifdef __GNUC__
|
||||
__attribute__((format(printf, 1, 2)))
|
||||
#endif
|
||||
;
|
||||
|
||||
bool taosAssertDebug(bool condition, const char *file, int32_t line, const char *format, ...);
|
||||
bool taosAssertRelease(bool condition);
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ typedef struct {
|
|||
// statistics
|
||||
int32_t reportCnt;
|
||||
int32_t connKeyCnt;
|
||||
int32_t passKeyCnt; // with passVer call back
|
||||
int64_t reportBytes; // not implemented
|
||||
int64_t startTime;
|
||||
// ctl
|
||||
|
@ -125,6 +126,12 @@ typedef struct SAppInfo {
|
|||
TdThreadMutex mutex;
|
||||
} SAppInfo;
|
||||
|
||||
typedef struct {
|
||||
int32_t ver;
|
||||
void* param;
|
||||
__taos_notify_fn_t fp;
|
||||
} SPassInfo;
|
||||
|
||||
typedef struct STscObj {
|
||||
char user[TSDB_USER_LEN];
|
||||
char pass[TSDB_PASSWORD_LEN];
|
||||
|
@ -140,6 +147,7 @@ typedef struct STscObj {
|
|||
int32_t numOfReqs; // number of sqlObj bound to this connection
|
||||
SAppInstInfo* pAppInfo;
|
||||
SHashObj* pRequests;
|
||||
SPassInfo passInfo;
|
||||
} STscObj;
|
||||
|
||||
typedef struct STscDbg {
|
||||
|
@ -353,7 +361,7 @@ void stopAllRequests(SHashObj* pRequests);
|
|||
|
||||
// conn level
|
||||
int hbRegisterConn(SAppHbMgr* pAppHbMgr, int64_t tscRefId, int64_t clusterId, int8_t connType);
|
||||
void hbDeregisterConn(SAppHbMgr* pAppHbMgr, SClientHbKey connKey);
|
||||
void hbDeregisterConn(SAppHbMgr* pAppHbMgr, SClientHbKey connKey, void* param);
|
||||
|
||||
typedef struct SSqlCallbackWrapper {
|
||||
SParseContext* pParseCtx;
|
||||
|
|
|
@ -42,7 +42,7 @@ SAppInfo appInfo;
|
|||
int64_t lastClusterId = 0;
|
||||
int32_t clientReqRefPool = -1;
|
||||
int32_t clientConnRefPool = -1;
|
||||
int32_t clientStop = 0;
|
||||
int32_t clientStop = -1;
|
||||
|
||||
int32_t timestampDeltaLimit = 900; // s
|
||||
|
||||
|
@ -69,7 +69,6 @@ static int32_t registerRequest(SRequestObj *pRequest, STscObj *pTscObj) {
|
|||
}
|
||||
|
||||
static void deregisterRequest(SRequestObj *pRequest) {
|
||||
const static int64_t SLOW_QUERY_INTERVAL = 3000000L; // todo configurable
|
||||
if (pRequest == NULL) {
|
||||
tscError("pRequest == NULL");
|
||||
return;
|
||||
|
@ -80,6 +79,7 @@ static void deregisterRequest(SRequestObj *pRequest) {
|
|||
|
||||
int32_t currentInst = atomic_sub_fetch_64((int64_t *)&pActivity->currentRequests, 1);
|
||||
int32_t num = atomic_sub_fetch_32(&pTscObj->numOfReqs, 1);
|
||||
int32_t reqType = SLOW_LOG_TYPE_OTHERS;
|
||||
|
||||
int64_t duration = taosGetTimestampUs() - pRequest->metric.start;
|
||||
tscDebug("0x%" PRIx64 " free Request from connObj: 0x%" PRIx64 ", reqId:0x%" PRIx64
|
||||
|
@ -95,6 +95,7 @@ static void deregisterRequest(SRequestObj *pRequest) {
|
|||
duration, pRequest->metric.parseCostUs, pRequest->metric.ctgCostUs, pRequest->metric.analyseCostUs,
|
||||
pRequest->metric.planCostUs, pRequest->metric.execCostUs);
|
||||
atomic_add_fetch_64((int64_t *)&pActivity->insertElapsedTime, duration);
|
||||
reqType = SLOW_LOG_TYPE_INSERT;
|
||||
} else if (QUERY_NODE_SELECT_STMT == pRequest->stmtType) {
|
||||
tscDebug("query duration %" PRId64 "us: parseCost:%" PRId64 "us, ctgCost:%" PRId64 "us, analyseCost:%" PRId64
|
||||
"us, planCost:%" PRId64 "us, exec:%" PRId64 "us",
|
||||
|
@ -102,12 +103,16 @@ static void deregisterRequest(SRequestObj *pRequest) {
|
|||
pRequest->metric.planCostUs, pRequest->metric.execCostUs);
|
||||
|
||||
atomic_add_fetch_64((int64_t *)&pActivity->queryElapsedTime, duration);
|
||||
reqType = SLOW_LOG_TYPE_QUERY;
|
||||
}
|
||||
}
|
||||
|
||||
if (duration >= SLOW_QUERY_INTERVAL) {
|
||||
if (duration >= (tsSlowLogThreshold * 1000000UL)) {
|
||||
atomic_add_fetch_64((int64_t *)&pActivity->numOfSlowQueries, 1);
|
||||
tscWarnL("slow query: %s, duration:%" PRId64, pRequest->sqlstr, duration);
|
||||
if (tsSlowLogScope & reqType) {
|
||||
taosPrintSlowLog("PID:%d, Conn:%u, QID:0x%" PRIx64 ", Start:%" PRId64 ", Duration:%" PRId64 "us, SQL:%s",
|
||||
taosGetPId(), pTscObj->connId, pRequest->requestId, pRequest->metric.start, duration, pRequest->sqlstr);
|
||||
}
|
||||
}
|
||||
|
||||
releaseTscObj(pTscObj->id);
|
||||
|
@ -239,7 +244,7 @@ void destroyTscObj(void *pObj) {
|
|||
tscTrace("begin to destroy tscObj %" PRIx64 " p:%p", tscId, pTscObj);
|
||||
|
||||
SClientHbKey connKey = {.tscRid = pTscObj->id, .connType = pTscObj->connType};
|
||||
hbDeregisterConn(pTscObj->pAppInfo->pAppHbMgr, connKey);
|
||||
hbDeregisterConn(pTscObj->pAppInfo->pAppHbMgr, connKey, pTscObj->passInfo.fp);
|
||||
|
||||
destroyAllRequests(pTscObj->pRequests);
|
||||
taosHashCleanup(pTscObj->pRequests);
|
||||
|
@ -427,8 +432,12 @@ static void *tscCrashReportThreadFp(void *param) {
|
|||
}
|
||||
#endif
|
||||
|
||||
if (-1 != atomic_val_compare_exchange_32(&clientStop, -1, 0)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (clientStop) break;
|
||||
if (clientStop > 0) break;
|
||||
if (loopTimes++ < reportPeriodNum) {
|
||||
taosMsleep(sleepTime);
|
||||
continue;
|
||||
|
@ -466,7 +475,7 @@ static void *tscCrashReportThreadFp(void *param) {
|
|||
loopTimes = 0;
|
||||
}
|
||||
|
||||
clientStop = -1;
|
||||
clientStop = -2;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,15 @@
|
|||
#include "scheduler.h"
|
||||
#include "trpc.h"
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
int64_t clusterId;
|
||||
int32_t passKeyCnt;
|
||||
};
|
||||
};
|
||||
} SHbParam;
|
||||
|
||||
static SClientHbMgr clientHbMgr = {0};
|
||||
|
||||
static int32_t hbCreateThread();
|
||||
|
@ -49,6 +58,52 @@ static int32_t hbProcessUserAuthInfoRsp(void *value, int32_t valueLen, struct SC
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t hbProcessUserPassInfoRsp(void *value, int32_t valueLen, SClientHbKey *connKey, SAppHbMgr *pAppHbMgr) {
|
||||
int32_t code = 0;
|
||||
int32_t numOfBatchs = 0;
|
||||
SUserPassBatchRsp batchRsp = {0};
|
||||
if (tDeserializeSUserPassBatchRsp(value, valueLen, &batchRsp) != 0) {
|
||||
code = TSDB_CODE_INVALID_MSG;
|
||||
return code;
|
||||
}
|
||||
|
||||
numOfBatchs = taosArrayGetSize(batchRsp.pArray);
|
||||
|
||||
SClientHbReq *pReq = NULL;
|
||||
while ((pReq = taosHashIterate(pAppHbMgr->activeInfo, pReq))) {
|
||||
STscObj *pTscObj = (STscObj *)acquireTscObj(pReq->connKey.tscRid);
|
||||
if (!pTscObj) {
|
||||
continue;
|
||||
}
|
||||
SPassInfo *passInfo = &pTscObj->passInfo;
|
||||
if (!passInfo->fp) {
|
||||
releaseTscObj(pReq->connKey.tscRid);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < numOfBatchs; ++i) {
|
||||
SGetUserPassRsp *rsp = taosArrayGet(batchRsp.pArray, i);
|
||||
if (0 == strncmp(rsp->user, pTscObj->user, TSDB_USER_LEN)) {
|
||||
int32_t oldVer = atomic_load_32(&passInfo->ver);
|
||||
if (oldVer < rsp->version) {
|
||||
atomic_store_32(&passInfo->ver, rsp->version);
|
||||
if (passInfo->fp) {
|
||||
(*passInfo->fp)(passInfo->param, &passInfo->ver, TAOS_NOTIFY_PASSVER);
|
||||
}
|
||||
tscDebug("update passVer of user %s from %d to %d, tscRid:%" PRIi64, rsp->user, oldVer,
|
||||
atomic_load_32(&passInfo->ver), pTscObj->id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
releaseTscObj(pReq->connKey.tscRid);
|
||||
}
|
||||
|
||||
taosArrayDestroy(batchRsp.pArray);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t hbGenerateVgInfoFromRsp(SDBVgInfo **pInfo, SUseDbRsp *rsp) {
|
||||
int32_t code = 0;
|
||||
SDBVgInfo *vgInfo = taosMemoryCalloc(1, sizeof(SDBVgInfo));
|
||||
|
@ -291,6 +346,15 @@ static int32_t hbQueryHbRspHandle(SAppHbMgr *pAppHbMgr, SClientHbRsp *pRsp) {
|
|||
hbProcessStbInfoRsp(kv->value, kv->valueLen, pCatalog);
|
||||
break;
|
||||
}
|
||||
case HEARTBEAT_KEY_USER_PASSINFO: {
|
||||
if (kv->valueLen <= 0 || NULL == kv->value) {
|
||||
tscError("invalid hb user pass info, len:%d, value:%p", kv->valueLen, kv->value);
|
||||
break;
|
||||
}
|
||||
|
||||
hbProcessUserPassInfoRsp(kv->value, kv->valueLen, &pRsp->connKey, pAppHbMgr);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
tscError("invalid hb key type:%d", kv->key);
|
||||
break;
|
||||
|
@ -472,6 +536,49 @@ int32_t hbGetQueryBasicInfo(SClientHbKey *connKey, SClientHbReq *req) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t hbGetUserBasicInfo(SClientHbKey *connKey, SClientHbReq *req) {
|
||||
STscObj *pTscObj = (STscObj *)acquireTscObj(connKey->tscRid);
|
||||
if (!pTscObj) {
|
||||
tscWarn("tscObj rid %" PRIx64 " not exist", connKey->tscRid);
|
||||
return TSDB_CODE_APP_ERROR;
|
||||
}
|
||||
|
||||
int32_t code = 0;
|
||||
SUserPassVersion *user = taosMemoryMalloc(sizeof(SUserPassVersion));
|
||||
if (!user) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _return;
|
||||
}
|
||||
strncpy(user->user, pTscObj->user, TSDB_USER_LEN);
|
||||
user->version = htonl(pTscObj->passInfo.ver);
|
||||
|
||||
SKv kv = {
|
||||
.key = HEARTBEAT_KEY_USER_PASSINFO,
|
||||
.valueLen = sizeof(SUserPassVersion),
|
||||
.value = user,
|
||||
};
|
||||
|
||||
tscDebug("hb got user basic info, valueLen:%d, user:%s, passVer:%d, tscRid:%" PRIi64, kv.valueLen, user->user,
|
||||
pTscObj->passInfo.ver, connKey->tscRid);
|
||||
|
||||
if (!req->info) {
|
||||
req->info = taosHashInit(64, hbKeyHashFunc, 1, HASH_ENTRY_LOCK);
|
||||
}
|
||||
|
||||
if (taosHashPut(req->info, &kv.key, sizeof(kv.key), &kv, sizeof(kv)) < 0) {
|
||||
code = terrno ? terrno : TSDB_CODE_APP_ERROR;
|
||||
goto _return;
|
||||
}
|
||||
|
||||
_return:
|
||||
releaseTscObj(connKey->tscRid);
|
||||
if (code) {
|
||||
tscError("hb got user basic info failed since %s", terrstr(code));
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t hbGetExpiredUserInfo(SClientHbKey *connKey, struct SCatalog *pCatalog, SClientHbReq *req) {
|
||||
SUserAuthVersion *users = NULL;
|
||||
uint32_t userNum = 0;
|
||||
|
@ -607,19 +714,23 @@ int32_t hbGetAppInfo(int64_t clusterId, SClientHbReq *req) {
|
|||
}
|
||||
|
||||
int32_t hbQueryHbReqHandle(SClientHbKey *connKey, void *param, SClientHbReq *req) {
|
||||
int64_t *clusterId = (int64_t *)param;
|
||||
SHbParam *hbParam = (SHbParam *)param;
|
||||
struct SCatalog *pCatalog = NULL;
|
||||
|
||||
int32_t code = catalogGetHandle(*clusterId, &pCatalog);
|
||||
int32_t code = catalogGetHandle(hbParam->clusterId, &pCatalog);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tscWarn("catalogGetHandle failed, clusterId:%" PRIx64 ", error:%s", *clusterId, tstrerror(code));
|
||||
tscWarn("catalogGetHandle failed, clusterId:%" PRIx64 ", error:%s", hbParam->clusterId, tstrerror(code));
|
||||
return code;
|
||||
}
|
||||
|
||||
hbGetAppInfo(*clusterId, req);
|
||||
hbGetAppInfo(hbParam->clusterId, req);
|
||||
|
||||
hbGetQueryBasicInfo(connKey, req);
|
||||
|
||||
if (hbParam->passKeyCnt > 0) {
|
||||
hbGetUserBasicInfo(connKey, req);
|
||||
}
|
||||
|
||||
code = hbGetExpiredUserInfo(connKey, pCatalog, req);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
return code;
|
||||
|
@ -673,7 +784,26 @@ SClientHbBatchReq *hbGatherAllInfo(SAppHbMgr *pAppHbMgr) {
|
|||
|
||||
while (pIter != NULL) {
|
||||
pOneReq = taosArrayPush(pBatchReq->reqs, pOneReq);
|
||||
code = (*clientHbMgr.reqHandle[pOneReq->connKey.connType])(&pOneReq->connKey, &pOneReq->clusterId, pOneReq);
|
||||
SHbParam param;
|
||||
switch (pOneReq->connKey.connType) {
|
||||
case CONN_TYPE__QUERY: {
|
||||
param.clusterId = pOneReq->clusterId;
|
||||
param.passKeyCnt = atomic_load_32(&pAppHbMgr->passKeyCnt);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (clientHbMgr.reqHandle[pOneReq->connKey.connType]) {
|
||||
code = (*clientHbMgr.reqHandle[pOneReq->connKey.connType])(&pOneReq->connKey, ¶m, pOneReq);
|
||||
if (code) {
|
||||
tscWarn("hbGatherAllInfo failed since %s, tscRid:%" PRIi64 ", connType:%" PRIi8, tstrerror(code),
|
||||
pOneReq->connKey.tscRid, pOneReq->connKey.connType);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
#if 0
|
||||
if (code) {
|
||||
pIter = taosHashIterate(pAppHbMgr->activeInfo, pIter);
|
||||
pOneReq = pIter;
|
||||
|
@ -682,6 +812,7 @@ SClientHbBatchReq *hbGatherAllInfo(SAppHbMgr *pAppHbMgr) {
|
|||
|
||||
pIter = taosHashIterate(pAppHbMgr->activeInfo, pIter);
|
||||
pOneReq = pIter;
|
||||
#endif
|
||||
}
|
||||
releaseTscObj(rid);
|
||||
|
||||
|
@ -1023,7 +1154,7 @@ int hbRegisterConn(SAppHbMgr *pAppHbMgr, int64_t tscRefId, int64_t clusterId, in
|
|||
}
|
||||
}
|
||||
|
||||
void hbDeregisterConn(SAppHbMgr *pAppHbMgr, SClientHbKey connKey) {
|
||||
void hbDeregisterConn(SAppHbMgr *pAppHbMgr, SClientHbKey connKey, void *param) {
|
||||
SClientHbReq *pReq = taosHashAcquire(pAppHbMgr->activeInfo, &connKey, sizeof(SClientHbKey));
|
||||
if (pReq) {
|
||||
tFreeClientHbReq(pReq);
|
||||
|
@ -1036,4 +1167,7 @@ void hbDeregisterConn(SAppHbMgr *pAppHbMgr, SClientHbKey connKey) {
|
|||
}
|
||||
|
||||
atomic_sub_fetch_32(&pAppHbMgr->connKeyCnt, 1);
|
||||
if (param) {
|
||||
atomic_sub_fetch_32(&pAppHbMgr->passKeyCnt, 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1248,6 +1248,11 @@ STscObj* taosConnectImpl(const char* user, const char* auth, const char* db, __t
|
|||
return NULL;
|
||||
}
|
||||
|
||||
pRequest->sqlstr = taosStrdup("taos_connect");
|
||||
if (pRequest->sqlstr) {
|
||||
pRequest->sqlLen = strlen(pRequest->sqlstr);
|
||||
}
|
||||
|
||||
SMsgSendInfo* body = buildConnectMsg(pRequest);
|
||||
|
||||
int64_t transporterId = 0;
|
||||
|
@ -1257,7 +1262,7 @@ STscObj* taosConnectImpl(const char* user, const char* auth, const char* db, __t
|
|||
if (pRequest->code != TSDB_CODE_SUCCESS) {
|
||||
const char* errorMsg =
|
||||
(pRequest->code == TSDB_CODE_RPC_FQDN_ERROR) ? taos_errstr(pRequest) : tstrerror(pRequest->code);
|
||||
fprintf(stderr, "failed to connect to server, reason: %s\n\n", errorMsg);
|
||||
tscError("failed to connect to server, reason: %s", errorMsg);
|
||||
|
||||
terrno = pRequest->code;
|
||||
destroyRequest(pRequest);
|
||||
|
|
|
@ -119,6 +119,39 @@ TAOS *taos_connect(const char *ip, const char *user, const char *pass, const cha
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int taos_set_notify_cb(TAOS *taos, __taos_notify_fn_t fp, void *param, int type) {
|
||||
if (taos == NULL) {
|
||||
terrno = TSDB_CODE_INVALID_PARA;
|
||||
return terrno;
|
||||
}
|
||||
|
||||
STscObj *pObj = acquireTscObj(*(int64_t *)taos);
|
||||
if (NULL == pObj) {
|
||||
terrno = TSDB_CODE_TSC_DISCONNECTED;
|
||||
tscError("invalid parameter for %s", __func__);
|
||||
return terrno;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case TAOS_NOTIFY_PASSVER: {
|
||||
pObj->passInfo.fp = fp;
|
||||
pObj->passInfo.param = param;
|
||||
if (fp) {
|
||||
atomic_add_fetch_32(&pObj->pAppInfo->pAppHbMgr->passKeyCnt, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
terrno = TSDB_CODE_INVALID_PARA;
|
||||
releaseTscObj(*(int64_t *)taos);
|
||||
return terrno;
|
||||
}
|
||||
}
|
||||
|
||||
releaseTscObj(*(int64_t *)taos);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void taos_close_internal(void *taos) {
|
||||
if (taos == NULL) {
|
||||
return;
|
||||
|
|
|
@ -130,6 +130,7 @@ int32_t processConnectRsp(void* param, SDataBuf* pMsg, int32_t code) {
|
|||
lastClusterId = connectRsp.clusterId;
|
||||
|
||||
pTscObj->connType = connectRsp.connType;
|
||||
pTscObj->passInfo.ver = connectRsp.passVer;
|
||||
|
||||
hbRegisterConn(pTscObj->pAppInfo->pAppHbMgr, pTscObj->id, connectRsp.clusterId, connectRsp.connType);
|
||||
|
||||
|
|
|
@ -1511,7 +1511,7 @@ static int32_t tmqWriteRawDataImpl(TAOS* taos, void* data, int32_t dataLen) {
|
|||
rspObj.resType = RES_TYPE__TMQ;
|
||||
|
||||
tDecoderInit(&decoder, data, dataLen);
|
||||
code = tDecodeSMqDataRsp(&decoder, &rspObj.rsp);
|
||||
code = tDecodeMqDataRsp(&decoder, &rspObj.rsp);
|
||||
if (code != 0) {
|
||||
uError("WriteRaw:decode smqDataRsp error");
|
||||
code = TSDB_CODE_INVALID_MSG;
|
||||
|
@ -1615,7 +1615,7 @@ static int32_t tmqWriteRawDataImpl(TAOS* taos, void* data, int32_t dataLen) {
|
|||
code = pRequest->code;
|
||||
|
||||
end:
|
||||
tDeleteSMqDataRsp(&rspObj.rsp);
|
||||
tDeleteMqDataRsp(&rspObj.rsp);
|
||||
tDecoderClear(&decoder);
|
||||
qDestroyQuery(pQuery);
|
||||
destroyRequest(pRequest);
|
||||
|
@ -1858,7 +1858,7 @@ int32_t tmq_get_raw(TAOS_RES* res, tmq_raw_data* raw) {
|
|||
|
||||
int32_t len = 0;
|
||||
int32_t code = 0;
|
||||
tEncodeSize(tEncodeSMqDataRsp, &rspObj->rsp, len, code);
|
||||
tEncodeSize(tEncodeMqDataRsp, &rspObj->rsp, len, code);
|
||||
if (code < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -1866,7 +1866,7 @@ int32_t tmq_get_raw(TAOS_RES* res, tmq_raw_data* raw) {
|
|||
void* buf = taosMemoryCalloc(1, len);
|
||||
SEncoder encoder = {0};
|
||||
tEncoderInit(&encoder, buf, len);
|
||||
tEncodeSMqDataRsp(&encoder, &rspObj->rsp);
|
||||
tEncodeMqDataRsp(&encoder, &rspObj->rsp);
|
||||
tEncoderClear(&encoder);
|
||||
|
||||
raw->raw = buf;
|
||||
|
|
|
@ -660,6 +660,7 @@ static int32_t smlSendMetaMsg(SSmlHandle *info, SName *pName, SArray *pColumns,
|
|||
SMCreateStbReq pReq = {0};
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
SCmdMsgInfo pCmdMsg = {0};
|
||||
char *pSql = NULL;
|
||||
|
||||
// put front for free
|
||||
pReq.numOfColumns = taosArrayGetSize(pColumns);
|
||||
|
@ -667,7 +668,27 @@ static int32_t smlSendMetaMsg(SSmlHandle *info, SName *pName, SArray *pColumns,
|
|||
pReq.numOfTags = taosArrayGetSize(pTags);
|
||||
pReq.pTags = pTags;
|
||||
|
||||
code = buildRequest(info->taos->id, "", 0, NULL, false, &pRequest, 0);
|
||||
if (action == SCHEMA_ACTION_CREATE_STABLE) {
|
||||
pReq.colVer = 1;
|
||||
pReq.tagVer = 1;
|
||||
pReq.suid = 0;
|
||||
pReq.source = TD_REQ_FROM_APP;
|
||||
pSql = "sml_create_stable";
|
||||
} else if (action == SCHEMA_ACTION_ADD_TAG || action == SCHEMA_ACTION_CHANGE_TAG_SIZE) {
|
||||
pReq.colVer = pTableMeta->sversion;
|
||||
pReq.tagVer = pTableMeta->tversion + 1;
|
||||
pReq.suid = pTableMeta->uid;
|
||||
pReq.source = TD_REQ_FROM_TAOX;
|
||||
pSql = (action == SCHEMA_ACTION_ADD_TAG) ? "sml_add_tag" : "sml_modify_tag_size";
|
||||
} else if (action == SCHEMA_ACTION_ADD_COLUMN || action == SCHEMA_ACTION_CHANGE_COLUMN_SIZE) {
|
||||
pReq.colVer = pTableMeta->sversion + 1;
|
||||
pReq.tagVer = pTableMeta->tversion;
|
||||
pReq.suid = pTableMeta->uid;
|
||||
pReq.source = TD_REQ_FROM_TAOX;
|
||||
pSql = (action == SCHEMA_ACTION_ADD_COLUMN) ? "sml_add_column" : "sml_modify_column_size";
|
||||
}
|
||||
|
||||
code = buildRequest(info->taos->id, pSql, strlen(pSql), NULL, false, &pRequest, 0);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto end;
|
||||
}
|
||||
|
@ -678,23 +699,6 @@ static int32_t smlSendMetaMsg(SSmlHandle *info, SName *pName, SArray *pColumns,
|
|||
goto end;
|
||||
}
|
||||
|
||||
if (action == SCHEMA_ACTION_CREATE_STABLE) {
|
||||
pReq.colVer = 1;
|
||||
pReq.tagVer = 1;
|
||||
pReq.suid = 0;
|
||||
pReq.source = TD_REQ_FROM_APP;
|
||||
} else if (action == SCHEMA_ACTION_ADD_TAG || action == SCHEMA_ACTION_CHANGE_TAG_SIZE) {
|
||||
pReq.colVer = pTableMeta->sversion;
|
||||
pReq.tagVer = pTableMeta->tversion + 1;
|
||||
pReq.suid = pTableMeta->uid;
|
||||
pReq.source = TD_REQ_FROM_TAOX;
|
||||
} else if (action == SCHEMA_ACTION_ADD_COLUMN || action == SCHEMA_ACTION_CHANGE_COLUMN_SIZE) {
|
||||
pReq.colVer = pTableMeta->sversion + 1;
|
||||
pReq.tagVer = pTableMeta->tversion;
|
||||
pReq.suid = pTableMeta->uid;
|
||||
pReq.source = TD_REQ_FROM_TAOX;
|
||||
}
|
||||
|
||||
if (pReq.numOfTags == 0) {
|
||||
pReq.numOfTags = 1;
|
||||
SField field = {0};
|
||||
|
@ -1514,6 +1518,44 @@ static int smlProcess(SSmlHandle *info, char *lines[], char *rawLine, char *rawL
|
|||
return code;
|
||||
}
|
||||
|
||||
void smlSetReqSQL(SRequestObj *request, char *lines[], char *rawLine, char *rawLineEnd) {
|
||||
if (tsSlowLogScope & SLOW_LOG_TYPE_INSERT) {
|
||||
int32_t len = 0;
|
||||
int32_t rlen = 0;
|
||||
char* p = NULL;
|
||||
|
||||
if (lines && lines[0]) {
|
||||
len = strlen(lines[0]);
|
||||
p = lines[0];
|
||||
} else if (rawLine) {
|
||||
if (rawLineEnd) {
|
||||
len = rawLineEnd - rawLine;
|
||||
} else {
|
||||
len = strlen(rawLine);
|
||||
}
|
||||
p = rawLine;
|
||||
}
|
||||
|
||||
if (NULL == p) {
|
||||
return;
|
||||
}
|
||||
|
||||
rlen = TMIN(len, TSDB_MAX_ALLOWED_SQL_LEN);
|
||||
rlen = TMAX(rlen, 0);
|
||||
|
||||
char *sql = taosMemoryMalloc(rlen + 1);
|
||||
if (NULL == sql) {
|
||||
uError("malloc %d for sml sql failed", rlen + 1);
|
||||
return;
|
||||
}
|
||||
memcpy(sql, p, rlen);
|
||||
sql[rlen] = 0;
|
||||
|
||||
request->sqlstr = sql;
|
||||
request->sqlLen = rlen;
|
||||
}
|
||||
}
|
||||
|
||||
TAOS_RES *taos_schemaless_insert_inner(TAOS *taos, char *lines[], char *rawLine, char *rawLineEnd, int numLines,
|
||||
int protocol, int precision, int32_t ttl, int64_t reqid) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
@ -1546,6 +1588,8 @@ TAOS_RES *taos_schemaless_insert_inner(TAOS *taos, char *lines[], char *rawLine,
|
|||
info->msgBuf.len = ERROR_MSG_BUF_DEFAULT_SIZE;
|
||||
info->lineNum = numLines;
|
||||
|
||||
smlSetReqSQL(request, lines, rawLine, rawLineEnd);
|
||||
|
||||
SSmlMsgBuf msg = {ERROR_MSG_BUF_DEFAULT_SIZE, request->msgBuf};
|
||||
if (request->pDb == NULL) {
|
||||
request->code = TSDB_CODE_PAR_DB_NOT_SPECIFIED;
|
||||
|
|
|
@ -133,16 +133,23 @@ enum {
|
|||
TMQ_DELAYED_TASK__COMMIT,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int64_t pollCnt;
|
||||
int64_t numOfRows;
|
||||
typedef struct SVgOffsetInfo {
|
||||
STqOffsetVal committedOffset;
|
||||
STqOffsetVal currentOffset;
|
||||
int32_t vgId;
|
||||
int32_t vgStatus;
|
||||
int32_t vgSkipCnt;
|
||||
int64_t emptyBlockReceiveTs; // once empty block is received, idle for ignoreCnt then start to poll data
|
||||
SEpSet epSet;
|
||||
int64_t walVerBegin;
|
||||
int64_t walVerEnd;
|
||||
} SVgOffsetInfo;
|
||||
|
||||
typedef struct {
|
||||
int64_t pollCnt;
|
||||
int64_t numOfRows;
|
||||
SVgOffsetInfo offsetInfo;
|
||||
int32_t vgId;
|
||||
int32_t vgStatus;
|
||||
int32_t vgSkipCnt; // here used to mark the slow vgroups
|
||||
bool receiveInfo;
|
||||
int64_t emptyBlockReceiveTs; // once empty block is received, idle for ignoreCnt then start to poll data
|
||||
SEpSet epSet;
|
||||
} SMqClientVg;
|
||||
|
||||
typedef struct {
|
||||
|
@ -190,6 +197,23 @@ typedef struct {
|
|||
uint64_t requestId; // request id for debug purpose
|
||||
} SMqPollCbParam;
|
||||
|
||||
typedef struct SMqVgCommon {
|
||||
tsem_t rsp;
|
||||
int32_t numOfRsp;
|
||||
SArray* pList;
|
||||
TdThreadMutex mutex;
|
||||
int64_t consumerId;
|
||||
char* pTopicName;
|
||||
int32_t code;
|
||||
} SMqVgCommon;
|
||||
|
||||
typedef struct SMqVgWalInfoParam {
|
||||
int32_t vgId;
|
||||
int32_t epoch;
|
||||
int32_t totalReq;
|
||||
SMqVgCommon* pCommon;
|
||||
} SMqVgWalInfoParam;
|
||||
|
||||
typedef struct {
|
||||
int64_t refId;
|
||||
int32_t epoch;
|
||||
|
@ -204,7 +228,7 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
SMqCommitCbParamSet* params;
|
||||
STqOffset* pOffset;
|
||||
SMqVgOffset* pOffset;
|
||||
char topicName[TSDB_TOPIC_FNAME_LEN];
|
||||
int32_t vgId;
|
||||
tmq_t* pTmq;
|
||||
|
@ -219,7 +243,7 @@ static int32_t doAskEp(tmq_t* tmq);
|
|||
static int32_t makeTopicVgroupKey(char* dst, const char* topicName, int32_t vg);
|
||||
static int32_t tmqCommitDone(SMqCommitCbParamSet* pParamSet);
|
||||
static int32_t doSendCommitMsg(tmq_t* tmq, SMqClientVg* pVg, const char* pTopicName, SMqCommitCbParamSet* pParamSet,
|
||||
int32_t index, int32_t totalVgroups);
|
||||
int32_t index, int32_t totalVgroups, int32_t type);
|
||||
static void commitRspCountDown(SMqCommitCbParamSet* pParamSet, int64_t consumerId, const char* pTopic, int32_t vgId);
|
||||
static void asyncAskEp(tmq_t* pTmq, __tmq_askep_fn_t askEpFn, void* param);
|
||||
static void addToQueueCallbackFn(tmq_t* pTmq, int32_t code, SDataBuf* pDataBuf, void* param);
|
||||
|
@ -441,7 +465,7 @@ static int32_t tmqCommitCb(void* param, SDataBuf* pBuf, int32_t code) {
|
|||
// if (code1 != TSDB_CODE_SUCCESS) { // retry failed.
|
||||
// tscError("consumer:0x%" PRIx64 " topic:%s vgId:%d offset:%" PRId64
|
||||
// " retry failed, ignore this commit. code:%s ordinal:%d/%d",
|
||||
// pParam->pTmq->consumerId, pParam->topicName, pVg->vgId, pVg->committedOffset.version,
|
||||
// pParam->pTmq->consumerId, pParam->topicName, pVg->vgId, pVg->offsetInfo.committedOffset.version,
|
||||
// tstrerror(terrno), index + 1, numOfVgroups);
|
||||
// }
|
||||
// }
|
||||
|
@ -467,22 +491,23 @@ static int32_t tmqCommitCb(void* param, SDataBuf* pBuf, int32_t code) {
|
|||
}
|
||||
|
||||
static int32_t doSendCommitMsg(tmq_t* tmq, SMqClientVg* pVg, const char* pTopicName, SMqCommitCbParamSet* pParamSet,
|
||||
int32_t index, int32_t totalVgroups) {
|
||||
STqOffset* pOffset = taosMemoryCalloc(1, sizeof(STqOffset));
|
||||
int32_t index, int32_t totalVgroups, int32_t type) {
|
||||
SMqVgOffset* pOffset = taosMemoryCalloc(1, sizeof(SMqVgOffset));
|
||||
if (pOffset == NULL) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pOffset->val = pVg->currentOffset;
|
||||
pOffset->consumerId = tmq->consumerId;
|
||||
pOffset->offset.val = pVg->offsetInfo.currentOffset;
|
||||
|
||||
int32_t groupLen = strlen(tmq->groupId);
|
||||
memcpy(pOffset->subKey, tmq->groupId, groupLen);
|
||||
pOffset->subKey[groupLen] = TMQ_SEPARATOR;
|
||||
strcpy(pOffset->subKey + groupLen + 1, pTopicName);
|
||||
memcpy(pOffset->offset.subKey, tmq->groupId, groupLen);
|
||||
pOffset->offset.subKey[groupLen] = TMQ_SEPARATOR;
|
||||
strcpy(pOffset->offset.subKey + groupLen + 1, pTopicName);
|
||||
|
||||
int32_t len = 0;
|
||||
int32_t code = 0;
|
||||
tEncodeSize(tEncodeSTqOffset, pOffset, len, code);
|
||||
tEncodeSize(tEncodeMqVgOffset, pOffset, len, code);
|
||||
if (code < 0) {
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
}
|
||||
|
@ -499,7 +524,7 @@ static int32_t doSendCommitMsg(tmq_t* tmq, SMqClientVg* pVg, const char* pTopicN
|
|||
|
||||
SEncoder encoder;
|
||||
tEncoderInit(&encoder, abuf, len);
|
||||
tEncodeSTqOffset(&encoder, pOffset);
|
||||
tEncodeMqVgOffset(&encoder, pOffset);
|
||||
tEncoderClear(&encoder);
|
||||
|
||||
// build param
|
||||
|
@ -533,19 +558,19 @@ static int32_t doSendCommitMsg(tmq_t* tmq, SMqClientVg* pVg, const char* pTopicN
|
|||
pMsgSendInfo->param = pParam;
|
||||
pMsgSendInfo->paramFreeFp = taosMemoryFree;
|
||||
pMsgSendInfo->fp = tmqCommitCb;
|
||||
pMsgSendInfo->msgType = TDMT_VND_TMQ_COMMIT_OFFSET;
|
||||
pMsgSendInfo->msgType = type;
|
||||
|
||||
atomic_add_fetch_32(&pParamSet->waitingRspNum, 1);
|
||||
atomic_add_fetch_32(&pParamSet->totalRspNum, 1);
|
||||
|
||||
SEp* pEp = GET_ACTIVE_EP(&pVg->epSet);
|
||||
char offsetBuf[80] = {0};
|
||||
tFormatOffset(offsetBuf, tListLen(offsetBuf), &pOffset->val);
|
||||
tFormatOffset(offsetBuf, tListLen(offsetBuf), &pOffset->offset.val);
|
||||
|
||||
char commitBuf[80] = {0};
|
||||
tFormatOffset(commitBuf, tListLen(commitBuf), &pVg->committedOffset);
|
||||
tFormatOffset(commitBuf, tListLen(commitBuf), &pVg->offsetInfo.committedOffset);
|
||||
tscDebug("consumer:0x%" PRIx64 " topic:%s on vgId:%d send offset:%s prev:%s, ep:%s:%d, ordinal:%d/%d, req:0x%" PRIx64,
|
||||
tmq->consumerId, pOffset->subKey, pVg->vgId, offsetBuf, commitBuf, pEp->fqdn, pEp->port, index + 1,
|
||||
tmq->consumerId, pOffset->offset.subKey, pVg->vgId, offsetBuf, commitBuf, pEp->fqdn, pEp->port, index + 1,
|
||||
totalVgroups, pMsgSendInfo->requestId);
|
||||
|
||||
int64_t transporterId = 0;
|
||||
|
@ -554,7 +579,22 @@ static int32_t doSendCommitMsg(tmq_t* tmq, SMqClientVg* pVg, const char* pTopicN
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static void asyncCommitOffset(tmq_t* tmq, const TAOS_RES* pRes, tmq_commit_cb* pCommitFp, void* userParam) {
|
||||
static SMqClientTopic* getTopicByName(tmq_t* tmq, const char* pTopicName) {
|
||||
int32_t numOfTopics = taosArrayGetSize(tmq->clientTopics);
|
||||
for (int32_t i = 0; i < numOfTopics; ++i) {
|
||||
SMqClientTopic* pTopic = taosArrayGet(tmq->clientTopics, i);
|
||||
if (strcmp(pTopic->topicName, pTopicName) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return pTopic;
|
||||
}
|
||||
|
||||
tscError("consumer:0x%" PRIx64 ", total:%d, failed to find topic:%s", tmq->consumerId, numOfTopics, pTopicName);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void asyncCommitOffset(tmq_t* tmq, const TAOS_RES* pRes, int32_t type, tmq_commit_cb* pCommitFp, void* userParam) {
|
||||
char* pTopicName = NULL;
|
||||
int32_t vgId = 0;
|
||||
int32_t code = 0;
|
||||
|
@ -596,15 +636,8 @@ static void asyncCommitOffset(tmq_t* tmq, const TAOS_RES* pRes, tmq_commit_cb* p
|
|||
|
||||
tscDebug("consumer:0x%" PRIx64 " do manual commit offset for %s, vgId:%d", tmq->consumerId, pTopicName, vgId);
|
||||
|
||||
int32_t i = 0;
|
||||
for (; i < numOfTopics; i++) {
|
||||
SMqClientTopic* pTopic = taosArrayGet(tmq->clientTopics, i);
|
||||
if (strcmp(pTopic->topicName, pTopicName) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == numOfTopics) {
|
||||
SMqClientTopic* pTopic = getTopicByName(tmq, pTopicName);
|
||||
if (pTopic == NULL) {
|
||||
tscWarn("consumer:0x%" PRIx64 " failed to find the specified topic:%s, total topics:%d", tmq->consumerId,
|
||||
pTopicName, numOfTopics);
|
||||
taosMemoryFree(pParamSet);
|
||||
|
@ -612,8 +645,6 @@ static void asyncCommitOffset(tmq_t* tmq, const TAOS_RES* pRes, tmq_commit_cb* p
|
|||
return;
|
||||
}
|
||||
|
||||
SMqClientTopic* pTopic = taosArrayGet(tmq->clientTopics, i);
|
||||
|
||||
int32_t j = 0;
|
||||
int32_t numOfVgroups = taosArrayGetSize(pTopic->vgs);
|
||||
for (j = 0; j < numOfVgroups; j++) {
|
||||
|
@ -632,8 +663,8 @@ static void asyncCommitOffset(tmq_t* tmq, const TAOS_RES* pRes, tmq_commit_cb* p
|
|||
}
|
||||
|
||||
SMqClientVg* pVg = taosArrayGet(pTopic->vgs, j);
|
||||
if (pVg->currentOffset.type > 0 && !tOffsetEqual(&pVg->currentOffset, &pVg->committedOffset)) {
|
||||
code = doSendCommitMsg(tmq, pVg, pTopic->topicName, pParamSet, j, numOfVgroups);
|
||||
if (pVg->offsetInfo.currentOffset.type > 0 && !tOffsetEqual(&pVg->offsetInfo.currentOffset, &pVg->offsetInfo.committedOffset)) {
|
||||
code = doSendCommitMsg(tmq, pVg, pTopic->topicName, pParamSet, j, numOfVgroups, type);
|
||||
|
||||
// failed to commit, callback user function directly.
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
|
@ -673,20 +704,20 @@ static void asyncCommitAllOffsets(tmq_t* tmq, tmq_commit_cb* pCommitFp, void* us
|
|||
for (int32_t j = 0; j < numOfVgroups; j++) {
|
||||
SMqClientVg* pVg = taosArrayGet(pTopic->vgs, j);
|
||||
|
||||
if (pVg->currentOffset.type > 0 && !tOffsetEqual(&pVg->currentOffset, &pVg->committedOffset)) {
|
||||
int32_t code = doSendCommitMsg(tmq, pVg, pTopic->topicName, pParamSet, j, numOfVgroups);
|
||||
if (pVg->offsetInfo.currentOffset.type > 0 && !tOffsetEqual(&pVg->offsetInfo.currentOffset, &pVg->offsetInfo.committedOffset)) {
|
||||
int32_t code = doSendCommitMsg(tmq, pVg, pTopic->topicName, pParamSet, j, numOfVgroups, TDMT_VND_TMQ_COMMIT_OFFSET);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tscError("consumer:0x%" PRIx64 " topic:%s vgId:%d offset:%" PRId64 " failed, code:%s ordinal:%d/%d",
|
||||
tmq->consumerId, pTopic->topicName, pVg->vgId, pVg->committedOffset.version, tstrerror(terrno),
|
||||
tmq->consumerId, pTopic->topicName, pVg->vgId, pVg->offsetInfo.committedOffset.version, tstrerror(terrno),
|
||||
j + 1, numOfVgroups);
|
||||
continue;
|
||||
}
|
||||
|
||||
// update the offset value.
|
||||
pVg->committedOffset = pVg->currentOffset;
|
||||
pVg->offsetInfo.committedOffset = pVg->offsetInfo.currentOffset;
|
||||
} else {
|
||||
tscDebug("consumer:0x%" PRIx64 " topic:%s vgId:%d, no commit, current:%" PRId64 ", ordinal:%d/%d",
|
||||
tmq->consumerId, pTopic->topicName, pVg->vgId, pVg->currentOffset.version, j + 1, numOfVgroups);
|
||||
tmq->consumerId, pTopic->topicName, pVg->vgId, pVg->offsetInfo.currentOffset.version, j + 1, numOfVgroups);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1088,7 +1119,7 @@ _failed:
|
|||
}
|
||||
|
||||
int32_t tmq_subscribe(tmq_t* tmq, const tmq_list_t* topic_list) {
|
||||
const int32_t MAX_RETRY_COUNT = 120 * 2; // let's wait for 2 mins at most
|
||||
const int32_t MAX_RETRY_COUNT = 120 * 4; // let's wait for 4 mins at most
|
||||
const SArray* container = &topic_list->container;
|
||||
int32_t sz = taosArrayGetSize(container);
|
||||
void* buf = NULL;
|
||||
|
@ -1141,22 +1172,13 @@ int32_t tmq_subscribe(tmq_t* tmq, const tmq_list_t* topic_list) {
|
|||
goto FAIL;
|
||||
}
|
||||
|
||||
SMqSubscribeCbParam param = {
|
||||
.rspErr = 0,
|
||||
.refId = tmq->refId,
|
||||
.epoch = tmq->epoch,
|
||||
};
|
||||
|
||||
SMqSubscribeCbParam param = { .rspErr = 0, .refId = tmq->refId, .epoch = tmq->epoch };
|
||||
if (tsem_init(¶m.rspSem, 0, 0) != 0) {
|
||||
code = TSDB_CODE_TSC_INTERNAL_ERROR;
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
sendInfo->msgInfo = (SDataBuf){
|
||||
.pData = buf,
|
||||
.len = tlen,
|
||||
.handle = NULL,
|
||||
};
|
||||
sendInfo->msgInfo = (SDataBuf){.pData = buf, .len = tlen, .handle = NULL};
|
||||
|
||||
sendInfo->requestId = generateRequestId();
|
||||
sendInfo->requestObjRefId = 0;
|
||||
|
@ -1184,7 +1206,7 @@ int32_t tmq_subscribe(tmq_t* tmq, const tmq_list_t* topic_list) {
|
|||
int32_t retryCnt = 0;
|
||||
while (TSDB_CODE_MND_CONSUMER_NOT_READY == doAskEp(tmq)) {
|
||||
if (retryCnt++ > MAX_RETRY_COUNT) {
|
||||
tscError("consumer:0x%" PRIx64 ", mnd not ready for subscribe, retry:%d in 500ms", tmq->consumerId, retryCnt);
|
||||
tscError("consumer:0x%" PRIx64 ", mnd not ready for subscribe, max retry reached:%d", tmq->consumerId, retryCnt);
|
||||
code = TSDB_CODE_TSC_INTERNAL_ERROR;
|
||||
goto FAIL;
|
||||
}
|
||||
|
@ -1220,7 +1242,7 @@ void tmq_conf_set_auto_commit_cb(tmq_conf_t* conf, tmq_commit_cb* cb, void* para
|
|||
conf->commitCbUserParam = param;
|
||||
}
|
||||
|
||||
int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) {
|
||||
static int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) {
|
||||
SMqPollCbParam* pParam = (SMqPollCbParam*)param;
|
||||
|
||||
int64_t refId = pParam->refId;
|
||||
|
@ -1273,12 +1295,12 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) {
|
|||
}
|
||||
|
||||
int32_t msgEpoch = ((SMqRspHead*)pMsg->pData)->epoch;
|
||||
int32_t tmqEpoch = atomic_load_32(&tmq->epoch);
|
||||
if (msgEpoch < tmqEpoch) {
|
||||
int32_t clientEpoch = atomic_load_32(&tmq->epoch);
|
||||
if (msgEpoch < clientEpoch) {
|
||||
// do not write into queue since updating epoch reset
|
||||
tscWarn("consumer:0x%" PRIx64
|
||||
" msg discard from vgId:%d since from earlier epoch, rsp epoch %d, current epoch %d, reqId:0x%" PRIx64,
|
||||
tmq->consumerId, vgId, msgEpoch, tmqEpoch, requestId);
|
||||
tmq->consumerId, vgId, msgEpoch, clientEpoch, requestId);
|
||||
|
||||
tsem_post(&tmq->rspSem);
|
||||
taosReleaseRef(tmqMgmt.rsetId, refId);
|
||||
|
@ -1288,9 +1310,9 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (msgEpoch != tmqEpoch) {
|
||||
if (msgEpoch != clientEpoch) {
|
||||
tscWarn("consumer:0x%" PRIx64 " mismatch rsp from vgId:%d, epoch %d, current epoch %d, reqId:0x%" PRIx64,
|
||||
tmq->consumerId, vgId, msgEpoch, tmqEpoch, requestId);
|
||||
tmq->consumerId, vgId, msgEpoch, clientEpoch, requestId);
|
||||
}
|
||||
|
||||
// handle meta rsp
|
||||
|
@ -1316,7 +1338,7 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) {
|
|||
if (rspType == TMQ_MSG_TYPE__POLL_RSP) {
|
||||
SDecoder decoder;
|
||||
tDecoderInit(&decoder, POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)), pMsg->len - sizeof(SMqRspHead));
|
||||
tDecodeSMqDataRsp(&decoder, &pRspWrapper->dataRsp);
|
||||
tDecodeMqDataRsp(&decoder, &pRspWrapper->dataRsp);
|
||||
tDecoderClear(&decoder);
|
||||
memcpy(&pRspWrapper->dataRsp, pMsg->pData, sizeof(SMqRspHead));
|
||||
|
||||
|
@ -1327,7 +1349,7 @@ int32_t tmqPollCb(void* param, SDataBuf* pMsg, int32_t code) {
|
|||
} else if (rspType == TMQ_MSG_TYPE__POLL_META_RSP) {
|
||||
SDecoder decoder;
|
||||
tDecoderInit(&decoder, POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)), pMsg->len - sizeof(SMqRspHead));
|
||||
tDecodeSMqMetaRsp(&decoder, &pRspWrapper->metaRsp);
|
||||
tDecodeMqMetaRsp(&decoder, &pRspWrapper->metaRsp);
|
||||
tDecoderClear(&decoder);
|
||||
memcpy(&pRspWrapper->metaRsp, pMsg->pData, sizeof(SMqRspHead));
|
||||
} else if (rspType == TMQ_MSG_TYPE__TAOSX_RSP) {
|
||||
|
@ -1398,7 +1420,6 @@ static void initClientTopicFromRsp(SMqClientTopic* pTopic, SMqSubTopicEp* pTopic
|
|||
|
||||
SMqClientVg clientVg = {
|
||||
.pollCnt = 0,
|
||||
.currentOffset = offsetNew,
|
||||
.vgId = pVgEp->vgId,
|
||||
.epSet = pVgEp->epSet,
|
||||
.vgStatus = TMQ_VG_STATUS__IDLE,
|
||||
|
@ -1407,6 +1428,10 @@ static void initClientTopicFromRsp(SMqClientTopic* pTopic, SMqSubTopicEp* pTopic
|
|||
.numOfRows = numOfRows,
|
||||
};
|
||||
|
||||
clientVg.offsetInfo.currentOffset = offsetNew;
|
||||
clientVg.offsetInfo.committedOffset = offsetNew;
|
||||
clientVg.offsetInfo.walVerBegin = -1;
|
||||
clientVg.offsetInfo.walVerEnd = -1;
|
||||
taosArrayPush(pTopic->vgs, &clientVg);
|
||||
}
|
||||
}
|
||||
|
@ -1456,11 +1481,11 @@ static bool doUpdateLocalEp(tmq_t* tmq, int32_t epoch, const SMqAskEpRsp* pRsp)
|
|||
makeTopicVgroupKey(vgKey, pTopicCur->topicName, pVgCur->vgId);
|
||||
|
||||
char buf[80];
|
||||
tFormatOffset(buf, 80, &pVgCur->currentOffset);
|
||||
tFormatOffset(buf, 80, &pVgCur->offsetInfo.currentOffset);
|
||||
tscDebug("consumer:0x%" PRIx64 ", epoch:%d vgId:%d vgKey:%s, offset:%s", tmq->consumerId, epoch, pVgCur->vgId,
|
||||
vgKey, buf);
|
||||
|
||||
SVgroupSaveInfo info = {.offset = pVgCur->currentOffset, .numOfRows = pVgCur->numOfRows};
|
||||
SVgroupSaveInfo info = {.offset = pVgCur->offsetInfo.currentOffset, .numOfRows = pVgCur->numOfRows};
|
||||
taosHashPut(pVgOffsetHashMap, vgKey, strlen(vgKey), &info, sizeof(SVgroupSaveInfo));
|
||||
}
|
||||
}
|
||||
|
@ -1536,8 +1561,8 @@ int32_t askEpCallbackFn(void* param, SDataBuf* pMsg, int32_t code) {
|
|||
tscDebug("consumer:0x%" PRIx64 ", recv ep, msg epoch %d, current epoch %d, update local ep", tmq->consumerId,
|
||||
head->epoch, epoch);
|
||||
}
|
||||
pParam->pUserFn(tmq, code, pMsg, pParam->pParam);
|
||||
|
||||
pParam->pUserFn(tmq, code, pMsg, pParam->pParam);
|
||||
taosReleaseRef(tmqMgmt.rsetId, pParam->refId);
|
||||
|
||||
taosMemoryFree(pMsg->pEpSet);
|
||||
|
@ -1556,8 +1581,7 @@ void tmqBuildConsumeReqImpl(SMqPollReq* pReq, tmq_t* tmq, int64_t timeout, SMqCl
|
|||
pReq->consumerId = tmq->consumerId;
|
||||
pReq->timeout = timeout;
|
||||
pReq->epoch = tmq->epoch;
|
||||
/*pReq->currentOffset = reqOffset;*/
|
||||
pReq->reqOffset = pVg->currentOffset;
|
||||
pReq->reqOffset = pVg->offsetInfo.currentOffset;
|
||||
pReq->head.vgId = pVg->vgId;
|
||||
pReq->useSnapshot = tmq->useSnapshot;
|
||||
pReq->reqId = generateRequestId();
|
||||
|
@ -1655,7 +1679,7 @@ static int32_t doTmqPollImpl(tmq_t* pTmq, SMqClientTopic* pTopic, SMqClientVg* p
|
|||
|
||||
pParam->refId = pTmq->refId;
|
||||
pParam->epoch = pTmq->epoch;
|
||||
pParam->pVg = pVg; // pVg may be released,fix it
|
||||
pParam->pVg = pVg;
|
||||
pParam->pTopic = pTopic;
|
||||
pParam->vgId = pVg->vgId;
|
||||
pParam->requestId = req.reqId;
|
||||
|
@ -1667,12 +1691,7 @@ static int32_t doTmqPollImpl(tmq_t* pTmq, SMqClientTopic* pTopic, SMqClientVg* p
|
|||
return handleErrorBeforePoll(pVg, pTmq);
|
||||
}
|
||||
|
||||
sendInfo->msgInfo = (SDataBuf){
|
||||
.pData = msg,
|
||||
.len = msgSize,
|
||||
.handle = NULL,
|
||||
};
|
||||
|
||||
sendInfo->msgInfo = (SDataBuf){.pData = msg, .len = msgSize, .handle = NULL};
|
||||
sendInfo->requestId = req.reqId;
|
||||
sendInfo->requestObjRefId = 0;
|
||||
sendInfo->param = pParam;
|
||||
|
@ -1681,7 +1700,7 @@ static int32_t doTmqPollImpl(tmq_t* pTmq, SMqClientTopic* pTopic, SMqClientVg* p
|
|||
|
||||
int64_t transporterId = 0;
|
||||
char offsetFormatBuf[80];
|
||||
tFormatOffset(offsetFormatBuf, tListLen(offsetFormatBuf), &pVg->currentOffset);
|
||||
tFormatOffset(offsetFormatBuf, tListLen(offsetFormatBuf), &pVg->offsetInfo.currentOffset);
|
||||
|
||||
tscDebug("consumer:0x%" PRIx64 " send poll to %s vgId:%d, epoch %d, req:%s, reqId:0x%" PRIx64, pTmq->consumerId,
|
||||
pTopic->topicName, pVg->vgId, pTmq->epoch, offsetFormatBuf, req.reqId);
|
||||
|
@ -1716,13 +1735,6 @@ static int32_t tmqPollImpl(tmq_t* tmq, int64_t timeout) {
|
|||
tscTrace("consumer:0x%" PRIx64 " epoch %d wait poll-rsp, skip vgId:%d skip cnt %d", tmq->consumerId, tmq->epoch,
|
||||
pVg->vgId, vgSkipCnt);
|
||||
continue;
|
||||
#if 0
|
||||
if (skipCnt < 30000) {
|
||||
continue;
|
||||
} else {
|
||||
tscDebug("consumer:0x%" PRIx64 ",skip vgId:%d skip too much reset", tmq->consumerId, pVg->vgId);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
atomic_store_32(&pVg->vgSkipCnt, 0);
|
||||
|
@ -1798,9 +1810,16 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) {
|
|||
}
|
||||
|
||||
// update the local offset value only for the returned values.
|
||||
pVg->currentOffset = pDataRsp->rspOffset;
|
||||
pVg->offsetInfo.currentOffset = pDataRsp->rspOffset;
|
||||
|
||||
// update the status
|
||||
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
||||
|
||||
// update the valid wal version range
|
||||
pVg->offsetInfo.walVerBegin = pDataRsp->head.walsver;
|
||||
pVg->offsetInfo.walVerEnd = pDataRsp->head.walever;
|
||||
pVg->receiveInfo = true;
|
||||
|
||||
char buf[80];
|
||||
tFormatOffset(buf, 80, &pDataRsp->rspOffset);
|
||||
if (pDataRsp->blockNum == 0) {
|
||||
|
@ -1828,6 +1847,7 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) {
|
|||
taosFreeQitem(pollRspWrapper);
|
||||
}
|
||||
} else if (pRspWrapper->tmqRspType == TMQ_MSG_TYPE__POLL_META_RSP) {
|
||||
// todo handle the wal range and epset for each vgroup
|
||||
SMqPollRspWrapper* pollRspWrapper = (SMqPollRspWrapper*)pRspWrapper;
|
||||
int32_t consumerEpoch = atomic_load_32(&tmq->epoch);
|
||||
|
||||
|
@ -1835,7 +1855,7 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) {
|
|||
|
||||
if (pollRspWrapper->metaRsp.head.epoch == consumerEpoch) {
|
||||
SMqClientVg* pVg = pollRspWrapper->vgHandle;
|
||||
pVg->currentOffset = pollRspWrapper->metaRsp.rspOffset;
|
||||
pVg->offsetInfo.currentOffset = pollRspWrapper->metaRsp.rspOffset;
|
||||
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
||||
// build rsp
|
||||
SMqMetaRspObj* pRsp = tmqBuildMetaRspFromWrapper(pollRspWrapper);
|
||||
|
@ -1853,7 +1873,7 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) {
|
|||
|
||||
if (pollRspWrapper->taosxRsp.head.epoch == consumerEpoch) {
|
||||
SMqClientVg* pVg = pollRspWrapper->vgHandle;
|
||||
pVg->currentOffset = pollRspWrapper->taosxRsp.rspOffset;
|
||||
pVg->offsetInfo.currentOffset = pollRspWrapper->taosxRsp.rspOffset;
|
||||
atomic_store_32(&pVg->vgStatus, TMQ_VG_STATUS__IDLE);
|
||||
|
||||
if (pollRspWrapper->taosxRsp.blockNum == 0) {
|
||||
|
@ -1879,7 +1899,7 @@ static void* tmqHandleAllRsp(tmq_t* tmq, int64_t timeout, bool pollIfReset) {
|
|||
tmq->totalRows += numOfRows;
|
||||
|
||||
char buf[80];
|
||||
tFormatOffset(buf, 80, &pVg->currentOffset);
|
||||
tFormatOffset(buf, 80, &pVg->offsetInfo.currentOffset);
|
||||
tscDebug("consumer:0x%" PRIx64 " process taosx poll rsp, vgId:%d, offset:%s, blocks:%d, rows:%" PRId64
|
||||
", vg total:%" PRId64 " total:%" PRId64 " reqId:0x%" PRIx64,
|
||||
tmq->consumerId, pVg->vgId, buf, pollRspWrapper->dataRsp.blockNum, numOfRows, pVg->numOfRows,
|
||||
|
@ -1915,15 +1935,6 @@ TAOS_RES* tmq_consumer_poll(tmq_t* tmq, int64_t timeout) {
|
|||
tscDebug("consumer:0x%" PRIx64 " start to poll at %" PRId64 ", timeout:%" PRId64, tmq->consumerId, startTime,
|
||||
timeout);
|
||||
|
||||
#if 0
|
||||
tmqHandleAllDelayedTask(tmq);
|
||||
tmqPollImpl(tmq, timeout);
|
||||
rspObj = tmqHandleAllRsp(tmq, timeout, false);
|
||||
if (rspObj) {
|
||||
return (TAOS_RES*)rspObj;
|
||||
}
|
||||
#endif
|
||||
|
||||
// in no topic status, delayed task also need to be processed
|
||||
if (atomic_load_8(&tmq->status) == TMQ_CONSUMER_STATUS__INIT) {
|
||||
tscDebug("consumer:0x%" PRIx64 " poll return since consumer is init", tmq->consumerId);
|
||||
|
@ -2119,11 +2130,11 @@ void tmq_commit_async(tmq_t* tmq, const TAOS_RES* pRes, tmq_commit_cb* cb, void*
|
|||
if (pRes == NULL) { // here needs to commit all offsets.
|
||||
asyncCommitAllOffsets(tmq, cb, param);
|
||||
} else { // only commit one offset
|
||||
asyncCommitOffset(tmq, pRes, cb, param);
|
||||
asyncCommitOffset(tmq, pRes, TDMT_VND_TMQ_COMMIT_OFFSET, cb, param);
|
||||
}
|
||||
}
|
||||
|
||||
static void commitCallBackFn(tmq_t *pTmq, int32_t code, void* param) {
|
||||
static void commitCallBackFn(tmq_t *UNUSED_PARAM(tmq), int32_t code, void* param) {
|
||||
SSyncCommitInfo* pInfo = (SSyncCommitInfo*) param;
|
||||
pInfo->code = code;
|
||||
tsem_post(&pInfo->sem);
|
||||
|
@ -2139,7 +2150,7 @@ int32_t tmq_commit_sync(tmq_t* tmq, const TAOS_RES* pRes) {
|
|||
if (pRes == NULL) {
|
||||
asyncCommitAllOffsets(tmq, commitCallBackFn, pInfo);
|
||||
} else {
|
||||
asyncCommitOffset(tmq, pRes, commitCallBackFn, pInfo);
|
||||
asyncCommitOffset(tmq, pRes, TDMT_VND_TMQ_COMMIT_OFFSET, commitCallBackFn, pInfo);
|
||||
}
|
||||
|
||||
tsem_wait(&pInfo->sem);
|
||||
|
@ -2324,3 +2335,271 @@ SReqResultInfo* tmqGetNextResInfo(TAOS_RES* res, bool convertUcs4) {
|
|||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int32_t tmqGetWalInfoCb(void* param, SDataBuf* pMsg, int32_t code) {
|
||||
SMqVgWalInfoParam* pParam = param;
|
||||
SMqVgCommon* pCommon = pParam->pCommon;
|
||||
|
||||
int32_t total = atomic_add_fetch_32(&pCommon->numOfRsp, 1);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tscError("consumer:0x%" PRIx64 " failed to get the wal info from vgId:%d for topic:%s", pCommon->consumerId,
|
||||
pParam->vgId, pCommon->pTopicName);
|
||||
pCommon->code = code;
|
||||
} else {
|
||||
SMqDataRsp rsp;
|
||||
SDecoder decoder;
|
||||
tDecoderInit(&decoder, POINTER_SHIFT(pMsg->pData, sizeof(SMqRspHead)), pMsg->len - sizeof(SMqRspHead));
|
||||
tDecodeMqDataRsp(&decoder, &rsp);
|
||||
tDecoderClear(&decoder);
|
||||
|
||||
SMqRspHead* pHead = pMsg->pData;
|
||||
|
||||
tmq_topic_assignment assignment = {.begin = pHead->walsver,
|
||||
.end = pHead->walever,
|
||||
.currentOffset = rsp.rspOffset.version,
|
||||
.vgId = pParam->vgId};
|
||||
|
||||
taosThreadMutexLock(&pCommon->mutex);
|
||||
taosArrayPush(pCommon->pList, &assignment);
|
||||
taosThreadMutexUnlock(&pCommon->mutex);
|
||||
}
|
||||
|
||||
if (total == pParam->totalReq) {
|
||||
tsem_post(&pCommon->rsp);
|
||||
}
|
||||
|
||||
taosMemoryFree(pParam);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void destroyCommonInfo(SMqVgCommon* pCommon) {
|
||||
taosArrayDestroy(pCommon->pList);
|
||||
tsem_destroy(&pCommon->rsp);
|
||||
taosThreadMutexDestroy(&pCommon->mutex);
|
||||
taosMemoryFree(pCommon->pTopicName);
|
||||
taosMemoryFree(pCommon);
|
||||
}
|
||||
|
||||
int32_t tmq_get_topic_assignment(tmq_t* tmq, const char* pTopicName, tmq_topic_assignment** assignment,
|
||||
int32_t* numOfAssignment) {
|
||||
*numOfAssignment = 0;
|
||||
*assignment = NULL;
|
||||
|
||||
int32_t accId = tmq->pTscObj->acctId;
|
||||
char tname[128] = {0};
|
||||
sprintf(tname, "%d.%s", accId, pTopicName);
|
||||
|
||||
SMqClientTopic* pTopic = getTopicByName(tmq, tname);
|
||||
if (pTopic == NULL) {
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
}
|
||||
|
||||
// in case of snapshot is opened, no valid offset will return
|
||||
*numOfAssignment = taosArrayGetSize(pTopic->vgs);
|
||||
|
||||
*assignment = taosMemoryCalloc(*numOfAssignment, sizeof(tmq_topic_assignment));
|
||||
if (*assignment == NULL) {
|
||||
tscError("consumer:0x%" PRIx64 " failed to malloc buffer, size:%" PRIzu, tmq->consumerId,
|
||||
(*numOfAssignment) * sizeof(tmq_topic_assignment));
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
bool needFetch = false;
|
||||
|
||||
for (int32_t j = 0; j < (*numOfAssignment); ++j) {
|
||||
SMqClientVg* pClientVg = taosArrayGet(pTopic->vgs, j);
|
||||
if (!pClientVg->receiveInfo) {
|
||||
needFetch = true;
|
||||
break;
|
||||
}
|
||||
|
||||
tmq_topic_assignment* pAssignment = &(*assignment)[j];
|
||||
if (pClientVg->offsetInfo.currentOffset.type == TMQ_OFFSET__LOG) {
|
||||
pAssignment->currentOffset = pClientVg->offsetInfo.currentOffset.version;
|
||||
} else {
|
||||
pAssignment->currentOffset = 0;
|
||||
}
|
||||
|
||||
pAssignment->begin = pClientVg->offsetInfo.walVerBegin;
|
||||
pAssignment->end = pClientVg->offsetInfo.walVerEnd;
|
||||
pAssignment->vgId = pClientVg->vgId;
|
||||
}
|
||||
|
||||
if (needFetch) {
|
||||
SMqVgCommon* pCommon = taosMemoryCalloc(1, sizeof(SMqVgCommon));
|
||||
if (pCommon == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return terrno;
|
||||
}
|
||||
|
||||
pCommon->pList= taosArrayInit(4, sizeof(tmq_topic_assignment));
|
||||
tsem_init(&pCommon->rsp, 0, 0);
|
||||
taosThreadMutexInit(&pCommon->mutex, 0);
|
||||
pCommon->pTopicName = taosStrdup(pTopic->topicName);
|
||||
pCommon->consumerId = tmq->consumerId;
|
||||
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
for (int32_t i = 0; i < (*numOfAssignment); ++i) {
|
||||
SMqClientVg* pClientVg = taosArrayGet(pTopic->vgs, i);
|
||||
|
||||
SMqVgWalInfoParam* pParam = taosMemoryMalloc(sizeof(SMqVgWalInfoParam));
|
||||
if (pParam == NULL) {
|
||||
destroyCommonInfo(pCommon);
|
||||
return terrno;
|
||||
}
|
||||
|
||||
pParam->epoch = tmq->epoch;
|
||||
pParam->vgId = pClientVg->vgId;
|
||||
pParam->totalReq = *numOfAssignment;
|
||||
pParam->pCommon = pCommon;
|
||||
|
||||
SMqPollReq req = {0};
|
||||
tmqBuildConsumeReqImpl(&req, tmq, 10, pTopic, pClientVg);
|
||||
|
||||
int32_t msgSize = tSerializeSMqPollReq(NULL, 0, &req);
|
||||
if (msgSize < 0) {
|
||||
taosMemoryFree(pParam);
|
||||
destroyCommonInfo(pCommon);
|
||||
return terrno;
|
||||
}
|
||||
|
||||
char* msg = taosMemoryCalloc(1, msgSize);
|
||||
if (NULL == msg) {
|
||||
taosMemoryFree(pParam);
|
||||
destroyCommonInfo(pCommon);
|
||||
return terrno;
|
||||
}
|
||||
|
||||
if (tSerializeSMqPollReq(msg, msgSize, &req) < 0) {
|
||||
taosMemoryFree(msg);
|
||||
taosMemoryFree(pParam);
|
||||
destroyCommonInfo(pCommon);
|
||||
return terrno;
|
||||
}
|
||||
|
||||
SMsgSendInfo* sendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
|
||||
if (sendInfo == NULL) {
|
||||
taosMemoryFree(pParam);
|
||||
taosMemoryFree(msg);
|
||||
destroyCommonInfo(pCommon);
|
||||
return terrno;
|
||||
}
|
||||
|
||||
sendInfo->msgInfo = (SDataBuf){.pData = msg, .len = msgSize, .handle = NULL};
|
||||
sendInfo->requestId = req.reqId;
|
||||
sendInfo->requestObjRefId = 0;
|
||||
sendInfo->param = pParam;
|
||||
sendInfo->fp = tmqGetWalInfoCb;
|
||||
sendInfo->msgType = TDMT_VND_TMQ_VG_WALINFO;
|
||||
|
||||
int64_t transporterId = 0;
|
||||
char offsetFormatBuf[80];
|
||||
tFormatOffset(offsetFormatBuf, tListLen(offsetFormatBuf), &pClientVg->offsetInfo.currentOffset);
|
||||
|
||||
tscDebug("consumer:0x%" PRIx64 " %s retrieve wal info vgId:%d, epoch %d, req:%s, reqId:0x%" PRIx64,
|
||||
tmq->consumerId, pTopic->topicName, pClientVg->vgId, tmq->epoch, offsetFormatBuf, req.reqId);
|
||||
asyncSendMsgToServer(tmq->pTscObj->pAppInfo->pTransporter, &pClientVg->epSet, &transporterId, sendInfo);
|
||||
}
|
||||
|
||||
tsem_wait(&pCommon->rsp);
|
||||
int32_t code = pCommon->code;
|
||||
|
||||
terrno = code;
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
taosMemoryFree(*assignment);
|
||||
*assignment = NULL;
|
||||
*numOfAssignment = 0;
|
||||
} else {
|
||||
int32_t num = taosArrayGetSize(pCommon->pList);
|
||||
for(int32_t i = 0; i < num; ++i) {
|
||||
(*assignment)[i] = *(tmq_topic_assignment*)taosArrayGet(pCommon->pList, i);
|
||||
}
|
||||
*numOfAssignment = num;
|
||||
}
|
||||
|
||||
destroyCommonInfo(pCommon);
|
||||
return code;
|
||||
} else {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t tmq_offset_seek(tmq_t* tmq, const char* pTopicName, int32_t vgId, int64_t offset) {
|
||||
if (tmq == NULL) {
|
||||
tscError("invalid tmq handle, null");
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
}
|
||||
|
||||
int32_t accId = tmq->pTscObj->acctId;
|
||||
char tname[128] = {0};
|
||||
sprintf(tname, "%d.%s", accId, pTopicName);
|
||||
|
||||
SMqClientTopic* pTopic = getTopicByName(tmq, tname);
|
||||
if (pTopic == NULL) {
|
||||
tscError("consumer:0x%" PRIx64 " invalid topic name:%s", tmq->consumerId, pTopicName);
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
}
|
||||
|
||||
SMqClientVg* pVg = NULL;
|
||||
int32_t numOfVgs = taosArrayGetSize(pTopic->vgs);
|
||||
for (int32_t i = 0; i < numOfVgs; ++i) {
|
||||
SMqClientVg* pClientVg = taosArrayGet(pTopic->vgs, i);
|
||||
if (pClientVg->vgId == vgId) {
|
||||
pVg = pClientVg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pVg == NULL) {
|
||||
tscError("consumer:0x%" PRIx64 " invalid vgroup id:%d", tmq->consumerId, vgId);
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
}
|
||||
|
||||
SVgOffsetInfo* pOffsetInfo = &pVg->offsetInfo;
|
||||
|
||||
int32_t type = pOffsetInfo->currentOffset.type;
|
||||
if (type != TMQ_OFFSET__LOG) {
|
||||
tscError("consumer:0x%" PRIx64 " offset type:%d not wal version, seek not allowed", tmq->consumerId, type);
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
}
|
||||
|
||||
if (offset < pOffsetInfo->walVerBegin || offset > pOffsetInfo->walVerEnd) {
|
||||
tscError("consumer:0x%" PRIx64 " invalid seek params, offset:%" PRId64, tmq->consumerId, offset);
|
||||
return TSDB_CODE_INVALID_PARA;
|
||||
}
|
||||
|
||||
// update the offset, and then commit to vnode
|
||||
if (pOffsetInfo->currentOffset.type == TMQ_OFFSET__LOG) {
|
||||
pOffsetInfo->currentOffset.version = offset;
|
||||
pOffsetInfo->committedOffset.version = INT64_MIN;
|
||||
}
|
||||
|
||||
SMqRspObj rspObj = {.resType = RES_TYPE__TMQ, .vgId = pVg->vgId};
|
||||
tstrncpy(rspObj.topic, tname, tListLen(rspObj.topic));
|
||||
|
||||
tscDebug("consumer:0x%" PRIx64 " seek to %" PRId64 " on vgId:%d", tmq->consumerId, offset, pVg->vgId);
|
||||
|
||||
SSyncCommitInfo* pInfo = taosMemoryMalloc(sizeof(SSyncCommitInfo));
|
||||
if (pInfo == NULL) {
|
||||
tscError("consumer:0x%"PRIx64" failed to prepare seek operation", tmq->consumerId);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
tsem_init(&pInfo->sem, 0, 0);
|
||||
pInfo->code = 0;
|
||||
|
||||
asyncCommitOffset(tmq, &rspObj, TDMT_VND_TMQ_SEEK_TO_OFFSET, commitCallBackFn, pInfo);
|
||||
|
||||
tsem_wait(&pInfo->sem);
|
||||
int32_t code = pInfo->code;
|
||||
|
||||
tsem_destroy(&pInfo->sem);
|
||||
taosMemoryFree(pInfo);
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tscError("consumer:0x%" PRIx64 " failed to send seek to vgId:%d, code:%s", tmq->consumerId, pVg->vgId,
|
||||
tstrerror(code));
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
|
@ -30,6 +30,27 @@
|
|||
#include "taos.h"
|
||||
|
||||
namespace {
|
||||
|
||||
void printSubResults(void* pRes, int32_t* totalRows) {
|
||||
char buf[1024];
|
||||
|
||||
while (1) {
|
||||
TAOS_ROW row = taos_fetch_row(pRes);
|
||||
if (row == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
TAOS_FIELD* fields = taos_fetch_fields(pRes);
|
||||
int32_t numOfFields = taos_field_count(pRes);
|
||||
int32_t precision = taos_result_precision(pRes);
|
||||
taos_print_row(buf, row, fields, numOfFields);
|
||||
*totalRows += 1;
|
||||
printf("precision: %d, row content: %s\n", precision, buf);
|
||||
}
|
||||
|
||||
// taos_free_result(pRes);
|
||||
}
|
||||
|
||||
void showDB(TAOS* pConn) {
|
||||
TAOS_RES* pRes = taos_query(pConn, "show databases");
|
||||
TAOS_ROW pRow = NULL;
|
||||
|
@ -112,7 +133,7 @@ void createNewTable(TAOS* pConn, int32_t index) {
|
|||
}
|
||||
taos_free_result(pRes);
|
||||
|
||||
for (int32_t i = 0; i < 100; i += 20) {
|
||||
for (int32_t i = 0; i < 10000; i += 20) {
|
||||
char sql[1024] = {0};
|
||||
sprintf(sql,
|
||||
"insert into tu%d values(now+%da, %d)(now+%da, %d)(now+%da, %d)(now+%da, %d)"
|
||||
|
@ -803,7 +824,7 @@ TEST(clientCase, projection_query_tables) {
|
|||
}
|
||||
taos_free_result(pRes);
|
||||
|
||||
for (int32_t i = 0; i < 10000; ++i) {
|
||||
for (int32_t i = 0; i < 1; ++i) {
|
||||
printf("create table :%d\n", i);
|
||||
createNewTable(pConn, i);
|
||||
}
|
||||
|
@ -990,7 +1011,7 @@ TEST(clientCase, sub_db_test) {
|
|||
tmq_conf_set(conf, "td.connect.user", "root");
|
||||
tmq_conf_set(conf, "td.connect.pass", "taosdata");
|
||||
tmq_conf_set(conf, "auto.offset.reset", "earliest");
|
||||
tmq_conf_set(conf, "experimental.snapshot.enable", "true");
|
||||
tmq_conf_set(conf, "experimental.snapshot.enable", "false");
|
||||
tmq_conf_set(conf, "msg.with.table.name", "true");
|
||||
tmq_conf_set_auto_commit_cb(conf, tmq_commit_cb_print, NULL);
|
||||
|
||||
|
@ -1000,7 +1021,7 @@ TEST(clientCase, sub_db_test) {
|
|||
// 创建订阅 topics 列表
|
||||
tmq_list_t* topicList = tmq_list_new();
|
||||
tmq_list_append(topicList, "topic_t1");
|
||||
tmq_list_append(topicList, "topic_s2");
|
||||
// tmq_list_append(topicList, "topic_s2");
|
||||
|
||||
// 启动订阅
|
||||
tmq_subscribe(tmq, topicList);
|
||||
|
@ -1059,13 +1080,13 @@ TEST(clientCase, sub_tb_test) {
|
|||
ASSERT_NE(pConn, nullptr);
|
||||
|
||||
tmq_conf_t* conf = tmq_conf_new();
|
||||
tmq_conf_set(conf, "enable.auto.commit", "true");
|
||||
tmq_conf_set(conf, "enable.auto.commit", "false");
|
||||
tmq_conf_set(conf, "auto.commit.interval.ms", "1000");
|
||||
tmq_conf_set(conf, "group.id", "cgrpName45");
|
||||
tmq_conf_set(conf, "group.id", "cgrpName1024");
|
||||
tmq_conf_set(conf, "td.connect.user", "root");
|
||||
tmq_conf_set(conf, "td.connect.pass", "taosdata");
|
||||
tmq_conf_set(conf, "auto.offset.reset", "earliest");
|
||||
tmq_conf_set(conf, "experimental.snapshot.enable", "true");
|
||||
tmq_conf_set(conf, "experimental.snapshot.enable", "false");
|
||||
tmq_conf_set(conf, "msg.with.table.name", "true");
|
||||
tmq_conf_set_auto_commit_cb(conf, tmq_commit_cb_print, NULL);
|
||||
|
||||
|
@ -1074,11 +1095,10 @@ TEST(clientCase, sub_tb_test) {
|
|||
|
||||
// 创建订阅 topics 列表
|
||||
tmq_list_t* topicList = tmq_list_new();
|
||||
tmq_list_append(topicList, "topic_t2");
|
||||
tmq_list_append(topicList, "topic_t1");
|
||||
|
||||
// 启动订阅
|
||||
tmq_subscribe(tmq, topicList);
|
||||
|
||||
tmq_list_destroy(topicList);
|
||||
|
||||
TAOS_FIELD* fields = NULL;
|
||||
|
@ -1090,11 +1110,21 @@ TEST(clientCase, sub_tb_test) {
|
|||
|
||||
int32_t count = 0;
|
||||
|
||||
tmq_topic_assignment* pAssign = NULL;
|
||||
int32_t numOfAssign = 0;
|
||||
|
||||
int32_t code = tmq_get_topic_assignment(tmq, "topic_t1", &pAssign, &numOfAssign);
|
||||
if (code != 0) {
|
||||
printf("error occurs:%s\n", tmq_err2str(code));
|
||||
tmq_consumer_close(tmq);
|
||||
taos_close(pConn);
|
||||
fprintf(stderr, "%d msg consumed, include %d rows\n", msgCnt, totalRows);
|
||||
return;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
TAOS_RES* pRes = tmq_consumer_poll(tmq, timeout);
|
||||
if (pRes) {
|
||||
char buf[1024];
|
||||
|
||||
if (pRes != NULL) {
|
||||
const char* topicName = tmq_get_topic_name(pRes);
|
||||
const char* dbName = tmq_get_db_name(pRes);
|
||||
int32_t vgroupId = tmq_get_vgroup_id(pRes);
|
||||
|
@ -1103,27 +1133,18 @@ TEST(clientCase, sub_tb_test) {
|
|||
printf("db: %s\n", dbName);
|
||||
printf("vgroup id: %d\n", vgroupId);
|
||||
|
||||
while (1) {
|
||||
TAOS_ROW row = taos_fetch_row(pRes);
|
||||
if (row == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
fields = taos_fetch_fields(pRes);
|
||||
numOfFields = taos_field_count(pRes);
|
||||
precision = taos_result_precision(pRes);
|
||||
taos_print_row(buf, row, fields, numOfFields);
|
||||
totalRows += 1;
|
||||
printf("precision: %d, row content: %s\n", precision, buf);
|
||||
}
|
||||
|
||||
taos_free_result(pRes);
|
||||
// if ((++count) > 1) {
|
||||
// break;
|
||||
// }
|
||||
printSubResults(pRes, &totalRows);
|
||||
} else {
|
||||
break;
|
||||
// tmq_offset_seek(tmq, "topic_t1", pAssign[0].vgroupHandle, pAssign[0].begin);
|
||||
// break;
|
||||
}
|
||||
|
||||
tmq_commit_sync(tmq, pRes);
|
||||
if (pRes != NULL) {
|
||||
taos_free_result(pRes);
|
||||
}
|
||||
|
||||
tmq_offset_seek(tmq, "topic_t1", pAssign[0].vgId, pAssign[0].begin);
|
||||
}
|
||||
|
||||
tmq_consumer_close(tmq);
|
||||
|
|
|
@ -500,7 +500,7 @@ int32_t tRowGet(SRow *pRow, STSchema *pTSchema, int32_t iCol, SColVal *pColVal)
|
|||
break;
|
||||
default:
|
||||
ASSERTS(0, "invalid row format");
|
||||
return TSDB_CODE_IVLD_DATA_FMT;
|
||||
return TSDB_CODE_INVALID_DATA_FMT;
|
||||
}
|
||||
|
||||
if (bv == BIT_FLG_NONE) {
|
||||
|
@ -938,7 +938,7 @@ static int32_t tRowTupleUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *
|
|||
break;
|
||||
default:
|
||||
ASSERTS(0, "Invalid row flag");
|
||||
return TSDB_CODE_IVLD_DATA_FMT;
|
||||
return TSDB_CODE_INVALID_DATA_FMT;
|
||||
}
|
||||
|
||||
while (pColData) {
|
||||
|
@ -963,7 +963,7 @@ static int32_t tRowTupleUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *
|
|||
break;
|
||||
default:
|
||||
ASSERTS(0, "Invalid row flag");
|
||||
return TSDB_CODE_IVLD_DATA_FMT;
|
||||
return TSDB_CODE_INVALID_DATA_FMT;
|
||||
}
|
||||
|
||||
if (bv == BIT_FLG_NONE) {
|
||||
|
@ -1054,7 +1054,7 @@ static int32_t tRowKVUpsertColData(SRow *pRow, STSchema *pTSchema, SColData *aCo
|
|||
pData = pv + ((uint32_t *)pKVIdx->idx)[iCol];
|
||||
} else {
|
||||
ASSERTS(0, "Invalid KV row format");
|
||||
return TSDB_CODE_IVLD_DATA_FMT;
|
||||
return TSDB_CODE_INVALID_DATA_FMT;
|
||||
}
|
||||
|
||||
int16_t cid;
|
||||
|
@ -2503,9 +2503,11 @@ _exit:
|
|||
int32_t tColDataAddValueByBind(SColData *pColData, TAOS_MULTI_BIND *pBind) {
|
||||
int32_t code = 0;
|
||||
|
||||
ASSERT(pColData->type == pBind->buffer_type);
|
||||
if (!(pBind->num == 1 && pBind->is_null && *pBind->is_null)) {
|
||||
ASSERT(pColData->type == pBind->buffer_type);
|
||||
}
|
||||
|
||||
if (IS_VAR_DATA_TYPE(pBind->buffer_type)) { // var-length data type
|
||||
if (IS_VAR_DATA_TYPE(pColData->type)) { // var-length data type
|
||||
for (int32_t i = 0; i < pBind->num; ++i) {
|
||||
if (pBind->is_null && pBind->is_null[i]) {
|
||||
code = tColDataAppendValueImpl[pColData->flag][CV_FLAG_NULL](pColData, NULL, 0);
|
||||
|
|
|
@ -117,6 +117,10 @@ int32_t tsRedirectFactor = 2;
|
|||
int32_t tsRedirectMaxPeriod = 1000;
|
||||
int32_t tsMaxRetryWaitTime = 10000;
|
||||
bool tsUseAdapter = false;
|
||||
int32_t tsSlowLogThreshold = 3; // seconds
|
||||
int32_t tsSlowLogScope = SLOW_LOG_TYPE_ALL;
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
@ -345,6 +349,8 @@ static int32_t taosAddClientCfg(SConfig *pCfg) {
|
|||
if (cfgAddBool(pCfg, "useAdapter", tsUseAdapter, true) != 0) return -1;
|
||||
if (cfgAddBool(pCfg, "crashReporting", tsEnableCrashReport, true) != 0) return -1;
|
||||
if (cfgAddInt64(pCfg, "queryMaxConcurrentTables", tsQueryMaxConcurrentTables, INT64_MIN, INT64_MAX, 1) != 0) return -1;
|
||||
if (cfgAddInt32(pCfg, "slowLogThreshold", tsSlowLogThreshold, 0, INT32_MAX, true) != 0) return -1;
|
||||
if (cfgAddString(pCfg, "slowLogScope", "", true) != 0) return -1;
|
||||
|
||||
tsNumOfRpcThreads = tsNumOfCores / 2;
|
||||
tsNumOfRpcThreads = TRANGE(tsNumOfRpcThreads, 2, TSDB_MAX_RPC_THREADS);
|
||||
|
@ -692,6 +698,42 @@ static void taosSetServerLogCfg(SConfig *pCfg) {
|
|||
metaDebugFlag = cfgGetItem(pCfg, "metaDebugFlag")->i32;
|
||||
}
|
||||
|
||||
static int32_t taosSetSlowLogScope(char *pScope) {
|
||||
if (NULL == pScope || 0 == strlen(pScope)) {
|
||||
tsSlowLogScope = SLOW_LOG_TYPE_ALL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (0 == strcasecmp(pScope, "all")) {
|
||||
tsSlowLogScope = SLOW_LOG_TYPE_ALL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (0 == strcasecmp(pScope, "query")) {
|
||||
tsSlowLogScope = SLOW_LOG_TYPE_QUERY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (0 == strcasecmp(pScope, "insert")) {
|
||||
tsSlowLogScope = SLOW_LOG_TYPE_INSERT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (0 == strcasecmp(pScope, "others")) {
|
||||
tsSlowLogScope = SLOW_LOG_TYPE_OTHERS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (0 == strcasecmp(pScope, "none")) {
|
||||
tsSlowLogScope = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uError("Invalid slowLog scope value:%s", pScope);
|
||||
terrno = TSDB_CODE_INVALID_CFG_VALUE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int32_t taosSetClientCfg(SConfig *pCfg) {
|
||||
tstrncpy(tsLocalFqdn, cfgGetItem(pCfg, "fqdn")->str, TSDB_FQDN_LEN);
|
||||
tsServerPort = (uint16_t)cfgGetItem(pCfg, "serverPort")->i32;
|
||||
|
@ -742,6 +784,10 @@ static int32_t taosSetClientCfg(SConfig *pCfg) {
|
|||
tsUseAdapter = cfgGetItem(pCfg, "useAdapter")->bval;
|
||||
tsEnableCrashReport = cfgGetItem(pCfg, "crashReporting")->bval;
|
||||
tsQueryMaxConcurrentTables = cfgGetItem(pCfg, "queryMaxConcurrentTables")->i64;
|
||||
tsSlowLogThreshold = cfgGetItem(pCfg, "slowLogThreshold")->i32;
|
||||
if (taosSetSlowLogScope(cfgGetItem(pCfg, "slowLogScope")->str)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
tsMaxRetryWaitTime = cfgGetItem(pCfg, "maxRetryWaitTime")->i32;
|
||||
|
||||
|
@ -1156,6 +1202,12 @@ int32_t taosSetCfg(SConfig *pCfg, char *name) {
|
|||
sDebugFlag = cfgGetItem(pCfg, "sDebugFlag")->i32;
|
||||
} else if (strcasecmp("smaDebugFlag", name) == 0) {
|
||||
smaDebugFlag = cfgGetItem(pCfg, "smaDebugFlag")->i32;
|
||||
} else if (strcasecmp("slowLogThreshold", name) == 0) {
|
||||
tsSlowLogThreshold = cfgGetItem(pCfg, "slowLogThreshold")->i32;
|
||||
} else if (strcasecmp("slowLogScope", name) == 0) {
|
||||
if (taosSetSlowLogScope(cfgGetItem(pCfg, "slowLogScope")->str)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -2936,6 +2936,59 @@ void tFreeSUserAuthBatchRsp(SUserAuthBatchRsp *pRsp) {
|
|||
taosArrayDestroy(pRsp->pArray);
|
||||
}
|
||||
|
||||
int32_t tSerializeSUserPassBatchRsp(void *buf, int32_t bufLen, SUserPassBatchRsp *pRsp) {
|
||||
SEncoder encoder = {0};
|
||||
tEncoderInit(&encoder, buf, bufLen);
|
||||
|
||||
if (tStartEncode(&encoder) < 0) return -1;
|
||||
|
||||
int32_t numOfBatch = taosArrayGetSize(pRsp->pArray);
|
||||
if (tEncodeI32(&encoder, numOfBatch) < 0) return -1;
|
||||
for (int32_t i = 0; i < numOfBatch; ++i) {
|
||||
SGetUserPassRsp *pUserPassRsp = taosArrayGet(pRsp->pArray, i);
|
||||
if (tEncodeCStr(&encoder, pUserPassRsp->user) < 0) return -1;
|
||||
if (tEncodeI32(&encoder, pUserPassRsp->version) < 0) return -1;
|
||||
}
|
||||
tEndEncode(&encoder);
|
||||
|
||||
int32_t tlen = encoder.pos;
|
||||
tEncoderClear(&encoder);
|
||||
return tlen;
|
||||
}
|
||||
|
||||
int32_t tDeserializeSUserPassBatchRsp(void *buf, int32_t bufLen, SUserPassBatchRsp *pRsp) {
|
||||
SDecoder decoder = {0};
|
||||
tDecoderInit(&decoder, buf, bufLen);
|
||||
|
||||
if (tStartDecode(&decoder) < 0) return -1;
|
||||
|
||||
int32_t numOfBatch = taosArrayGetSize(pRsp->pArray);
|
||||
if (tDecodeI32(&decoder, &numOfBatch) < 0) return -1;
|
||||
|
||||
pRsp->pArray = taosArrayInit(numOfBatch, sizeof(SGetUserPassRsp));
|
||||
if (pRsp->pArray == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < numOfBatch; ++i) {
|
||||
SGetUserPassRsp rsp = {0};
|
||||
if (tDecodeCStrTo(&decoder, rsp.user) < 0) return -1;
|
||||
if (tDecodeI32(&decoder, &rsp.version) < 0) return -1;
|
||||
taosArrayPush(pRsp->pArray, &rsp);
|
||||
}
|
||||
tEndDecode(&decoder);
|
||||
|
||||
tDecoderClear(&decoder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tFreeSUserPassBatchRsp(SUserPassBatchRsp *pRsp) {
|
||||
if(pRsp) {
|
||||
taosArrayDestroy(pRsp->pArray);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t tSerializeSDbCfgReq(void *buf, int32_t bufLen, SDbCfgReq *pReq) {
|
||||
SEncoder encoder = {0};
|
||||
tEncoderInit(&encoder, buf, bufLen);
|
||||
|
@ -3976,6 +4029,7 @@ int32_t tSerializeSConnectRsp(void *buf, int32_t bufLen, SConnectRsp *pRsp) {
|
|||
if (tEncodeI32(&encoder, pRsp->svrTimestamp) < 0) return -1;
|
||||
if (tEncodeCStr(&encoder, pRsp->sVer) < 0) return -1;
|
||||
if (tEncodeCStr(&encoder, pRsp->sDetailVer) < 0) return -1;
|
||||
if (tEncodeI32(&encoder, pRsp->passVer) < 0) return -1;
|
||||
tEndEncode(&encoder);
|
||||
|
||||
int32_t tlen = encoder.pos;
|
||||
|
@ -3999,6 +4053,13 @@ int32_t tDeserializeSConnectRsp(void *buf, int32_t bufLen, SConnectRsp *pRsp) {
|
|||
if (tDecodeI32(&decoder, &pRsp->svrTimestamp) < 0) return -1;
|
||||
if (tDecodeCStrTo(&decoder, pRsp->sVer) < 0) return -1;
|
||||
if (tDecodeCStrTo(&decoder, pRsp->sDetailVer) < 0) return -1;
|
||||
|
||||
if (!tDecodeIsEnd(&decoder)) {
|
||||
if (tDecodeI32(&decoder, &pRsp->passVer) < 0) return -1;
|
||||
} else {
|
||||
pRsp->passVer = 0;
|
||||
}
|
||||
|
||||
tEndDecode(&decoder);
|
||||
|
||||
tDecoderClear(&decoder);
|
||||
|
@ -6951,6 +7012,18 @@ int32_t tDecodeSTqOffset(SDecoder *pDecoder, STqOffset *pOffset) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t tEncodeMqVgOffset(SEncoder* pEncoder, const SMqVgOffset* pOffset) {
|
||||
if (tEncodeSTqOffset(pEncoder, &pOffset->offset) < 0) return -1;
|
||||
if (tEncodeI64(pEncoder, pOffset->consumerId) < 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tDecodeMqVgOffset(SDecoder* pDecoder, SMqVgOffset* pOffset) {
|
||||
if (tDecodeSTqOffset(pDecoder, &pOffset->offset) < 0) return -1;
|
||||
if (tDecodeI64(pDecoder, &pOffset->consumerId) < 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tEncodeSTqCheckInfo(SEncoder *pEncoder, const STqCheckInfo *pInfo) {
|
||||
if (tEncodeCStr(pEncoder, pInfo->topic) < 0) return -1;
|
||||
if (tEncodeI64(pEncoder, pInfo->ntbUid) < 0) return -1;
|
||||
|
@ -7015,21 +7088,21 @@ int32_t tDecodeDeleteRes(SDecoder *pCoder, SDeleteRes *pRes) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t tEncodeSMqMetaRsp(SEncoder *pEncoder, const SMqMetaRsp *pRsp) {
|
||||
int32_t tEncodeMqMetaRsp(SEncoder *pEncoder, const SMqMetaRsp *pRsp) {
|
||||
if (tEncodeSTqOffsetVal(pEncoder, &pRsp->rspOffset) < 0) return -1;
|
||||
if (tEncodeI16(pEncoder, pRsp->resMsgType)) return -1;
|
||||
if (tEncodeBinary(pEncoder, pRsp->metaRsp, pRsp->metaRspLen)) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tDecodeSMqMetaRsp(SDecoder *pDecoder, SMqMetaRsp *pRsp) {
|
||||
int32_t tDecodeMqMetaRsp(SDecoder *pDecoder, SMqMetaRsp *pRsp) {
|
||||
if (tDecodeSTqOffsetVal(pDecoder, &pRsp->rspOffset) < 0) return -1;
|
||||
if (tDecodeI16(pDecoder, &pRsp->resMsgType) < 0) return -1;
|
||||
if (tDecodeBinaryAlloc(pDecoder, &pRsp->metaRsp, (uint64_t *)&pRsp->metaRspLen) < 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tEncodeSMqDataRsp(SEncoder *pEncoder, const SMqDataRsp *pRsp) {
|
||||
int32_t tEncodeMqDataRsp(SEncoder *pEncoder, const SMqDataRsp *pRsp) {
|
||||
if (tEncodeSTqOffsetVal(pEncoder, &pRsp->reqOffset) < 0) return -1;
|
||||
if (tEncodeSTqOffsetVal(pEncoder, &pRsp->rspOffset) < 0) return -1;
|
||||
if (tEncodeI32(pEncoder, pRsp->blockNum) < 0) return -1;
|
||||
|
@ -7054,7 +7127,7 @@ int32_t tEncodeSMqDataRsp(SEncoder *pEncoder, const SMqDataRsp *pRsp) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t tDecodeSMqDataRsp(SDecoder *pDecoder, SMqDataRsp *pRsp) {
|
||||
int32_t tDecodeMqDataRsp(SDecoder *pDecoder, SMqDataRsp *pRsp) {
|
||||
if (tDecodeSTqOffsetVal(pDecoder, &pRsp->reqOffset) < 0) return -1;
|
||||
if (tDecodeSTqOffsetVal(pDecoder, &pRsp->rspOffset) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &pRsp->blockNum) < 0) return -1;
|
||||
|
@ -7099,7 +7172,7 @@ int32_t tDecodeSMqDataRsp(SDecoder *pDecoder, SMqDataRsp *pRsp) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void tDeleteSMqDataRsp(SMqDataRsp *pRsp) {
|
||||
void tDeleteMqDataRsp(SMqDataRsp *pRsp) {
|
||||
pRsp->blockDataLen = taosArrayDestroy(pRsp->blockDataLen);
|
||||
taosArrayDestroyP(pRsp->blockData, (FDelete)taosMemoryFree);
|
||||
pRsp->blockData = NULL;
|
||||
|
@ -7200,8 +7273,7 @@ int32_t tDecodeSTaosxRsp(SDecoder *pDecoder, STaosxRsp *pRsp) {
|
|||
}
|
||||
|
||||
void tDeleteSTaosxRsp(STaosxRsp *pRsp) {
|
||||
taosArrayDestroy(pRsp->blockDataLen);
|
||||
pRsp->blockDataLen = NULL;
|
||||
pRsp->blockDataLen = taosArrayDestroy(pRsp->blockDataLen);
|
||||
taosArrayDestroyP(pRsp->blockData, (FDelete)taosMemoryFree);
|
||||
pRsp->blockData = NULL;
|
||||
taosArrayDestroyP(pRsp->blockSchema, (FDelete)tDeleteSSchemaWrapper);
|
||||
|
@ -7209,8 +7281,7 @@ void tDeleteSTaosxRsp(STaosxRsp *pRsp) {
|
|||
taosArrayDestroyP(pRsp->blockTbName, (FDelete)taosMemoryFree);
|
||||
pRsp->blockTbName = NULL;
|
||||
|
||||
taosArrayDestroy(pRsp->createTableLen);
|
||||
pRsp->createTableLen = NULL;
|
||||
pRsp->createTableLen = taosArrayDestroy(pRsp->createTableLen);
|
||||
taosArrayDestroyP(pRsp->createTableReq, (FDelete)taosMemoryFree);
|
||||
pRsp->createTableReq = NULL;
|
||||
}
|
||||
|
@ -7583,3 +7654,41 @@ void tDestroySSubmitRsp2(SSubmitRsp2 *pRsp, int32_t flag) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t tEncodeMqSubTopicEp(void **buf, const SMqSubTopicEp *pTopicEp) {
|
||||
int32_t tlen = 0;
|
||||
tlen += taosEncodeString(buf, pTopicEp->topic);
|
||||
tlen += taosEncodeString(buf, pTopicEp->db);
|
||||
int32_t sz = taosArrayGetSize(pTopicEp->vgs);
|
||||
tlen += taosEncodeFixedI32(buf, sz);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
SMqSubVgEp *pVgEp = (SMqSubVgEp *)taosArrayGet(pTopicEp->vgs, i);
|
||||
tlen += tEncodeSMqSubVgEp(buf, pVgEp);
|
||||
}
|
||||
tlen += taosEncodeSSchemaWrapper(buf, &pTopicEp->schema);
|
||||
return tlen;
|
||||
}
|
||||
|
||||
void *tDecodeMqSubTopicEp(void *buf, SMqSubTopicEp *pTopicEp) {
|
||||
buf = taosDecodeStringTo(buf, pTopicEp->topic);
|
||||
buf = taosDecodeStringTo(buf, pTopicEp->db);
|
||||
int32_t sz;
|
||||
buf = taosDecodeFixedI32(buf, &sz);
|
||||
pTopicEp->vgs = taosArrayInit(sz, sizeof(SMqSubVgEp));
|
||||
if (pTopicEp->vgs == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
SMqSubVgEp vgEp;
|
||||
buf = tDecodeSMqSubVgEp(buf, &vgEp);
|
||||
taosArrayPush(pTopicEp->vgs, &vgEp);
|
||||
}
|
||||
buf = taosDecodeSSchemaWrapper(buf, &pTopicEp->schema);
|
||||
return buf;
|
||||
}
|
||||
|
||||
void tDeleteMqSubTopicEp(SMqSubTopicEp *pSubTopicEp) {
|
||||
taosMemoryFreeClear(pSubTopicEp->schema.pSchema);
|
||||
pSubTopicEp->schema.nCols = 0;
|
||||
taosArrayDestroy(pSubTopicEp->vgs);
|
||||
}
|
|
@ -159,6 +159,10 @@ static int32_t mmSyncIsCatchUp(SMnodeMgmt *pMgmt) {
|
|||
return mndIsCatchUp(pMgmt->pMnode);
|
||||
}
|
||||
|
||||
static ESyncRole mmSyncGetRole(SMnodeMgmt *pMgmt) {
|
||||
return mndGetRole(pMgmt->pMnode);
|
||||
}
|
||||
|
||||
SMgmtFunc mmGetMgmtFunc() {
|
||||
SMgmtFunc mgmtFunc = {0};
|
||||
mgmtFunc.openFp = mmOpen;
|
||||
|
@ -170,6 +174,7 @@ SMgmtFunc mmGetMgmtFunc() {
|
|||
mgmtFunc.requiredFp = mmRequire;
|
||||
mgmtFunc.getHandlesFp = mmGetMsgHandles;
|
||||
mgmtFunc.isCatchUpFp = (NodeIsCatchUpFp)mmSyncIsCatchUp;
|
||||
mgmtFunc.nodeRoleFp = (NodeRole)mmSyncGetRole;
|
||||
|
||||
return mgmtFunc;
|
||||
}
|
||||
|
|
|
@ -336,13 +336,23 @@ int32_t vmProcessAlterVnodeTypeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) {
|
|||
|
||||
SVnodeObj *pVnode = vmAcquireVnode(pMgmt, req.vgId);
|
||||
if (pVnode == NULL) {
|
||||
dError("vgId:%d, failed to alter hashrange since %s", req.vgId, terrstr());
|
||||
dError("vgId:%d, failed to alter vnode type since %s", req.vgId, terrstr());
|
||||
terrno = TSDB_CODE_VND_NOT_EXIST;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ESyncRole role = vnodeGetRole(pVnode->pImpl);
|
||||
dInfo("vgId:%d, checking node role:%d", req.vgId, role);
|
||||
if(role == TAOS_SYNC_ROLE_VOTER){
|
||||
terrno = TSDB_CODE_VND_ALREADY_IS_VOTER;
|
||||
vmReleaseVnode(pMgmt, pVnode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dInfo("vgId:%d, checking node catch up", req.vgId);
|
||||
if(vnodeIsCatchUp(pVnode->pImpl) != 0){
|
||||
if(vnodeIsCatchUp(pVnode->pImpl) != 1){
|
||||
terrno = TSDB_CODE_VND_NOT_CATCH_UP;
|
||||
vmReleaseVnode(pMgmt, pVnode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -365,6 +375,7 @@ int32_t vmProcessAlterVnodeTypeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) {
|
|||
req.selfIndex >= req.replica || req.learnerSelfIndex >= req.learnerReplica) {
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
dError("vgId:%d, failed to alter replica since invalid msg", vgId);
|
||||
vmReleaseVnode(pMgmt, pVnode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -381,6 +392,7 @@ int32_t vmProcessAlterVnodeTypeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) {
|
|||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
dError("vgId:%d, dnodeId:%d ep:%s:%u not matched with local dnode", vgId, pReplica->id, pReplica->fqdn,
|
||||
pReplica->port);
|
||||
vmReleaseVnode(pMgmt, pVnode);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -680,9 +692,11 @@ SArray *vmGetMsgHandles() {
|
|||
if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_SUBSCRIBE, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_DELETE_SUB, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_COMMIT_OFFSET, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_SEEK_TO_OFFSET, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_ADD_CHECKINFO, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_DEL_CHECKINFO, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_CONSUME, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_TMQ_VG_WALINFO, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_DELETE, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_BATCH_DEL, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_COMMIT, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
|
|
|
@ -214,9 +214,19 @@ static int32_t dmProcessAlterNodeTypeReq(EDndNodeType ntype, SRpcMsg *pMsg) {
|
|||
|
||||
pWrapper = &pDnode->wrappers[ntype];
|
||||
|
||||
if(pWrapper->func.nodeRoleFp != NULL){
|
||||
ESyncRole role = (*pWrapper->func.nodeRoleFp)(pWrapper->pMgmt);
|
||||
dInfo("node:%s, checking node role:%d", pWrapper->name, role);
|
||||
if(role == TAOS_SYNC_ROLE_VOTER){
|
||||
terrno = TSDB_CODE_MNODE_ALREADY_IS_VOTER;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if(pWrapper->func.isCatchUpFp != NULL){
|
||||
dInfo("node:%s, checking node catch up", pWrapper->name);
|
||||
if(!(*pWrapper->func.isCatchUpFp)(pWrapper->pMgmt) == 0){
|
||||
if((*pWrapper->func.isCatchUpFp)(pWrapper->pMgmt) != 1){
|
||||
terrno = TSDB_CODE_MNODE_NOT_CATCH_UP;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,6 +135,7 @@ typedef int32_t (*NodeDropFp)(const SMgmtInputOpt *pInput, SRpcMsg *pMsg);
|
|||
typedef int32_t (*NodeRequireFp)(const SMgmtInputOpt *pInput, bool *required);
|
||||
typedef SArray *(*NodeGetHandlesFp)(); // array of SMgmtHandle
|
||||
typedef bool (*NodeIsCatchUpFp)(void *pMgmt);
|
||||
typedef bool (*NodeRole)(void *pMgmt);
|
||||
|
||||
typedef struct {
|
||||
NodeOpenFp openFp;
|
||||
|
@ -146,6 +147,7 @@ typedef struct {
|
|||
NodeRequireFp requiredFp;
|
||||
NodeGetHandlesFp getHandlesFp;
|
||||
NodeIsCatchUpFp isCatchUpFp;
|
||||
NodeRole nodeRoleFp;
|
||||
} SMgmtFunc;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -280,6 +280,7 @@ typedef struct {
|
|||
int8_t reserve;
|
||||
int32_t acctId;
|
||||
int32_t authVersion;
|
||||
int32_t passVersion;
|
||||
SHashObj* readDbs;
|
||||
SHashObj* writeDbs;
|
||||
SHashObj* topics;
|
||||
|
|
|
@ -35,6 +35,8 @@ SHashObj *mndDupTableHash(SHashObj *pOld);
|
|||
SHashObj *mndDupTopicHash(SHashObj *pOld);
|
||||
int32_t mndValidateUserAuthInfo(SMnode *pMnode, SUserAuthVersion *pUsers, int32_t numOfUses, void **ppRsp,
|
||||
int32_t *pRspLen);
|
||||
int32_t mndValidateUserPassInfo(SMnode *pMnode, SUserPassVersion *pUsers, int32_t numOfUses, void **ppRsp,
|
||||
int32_t *pRspLen);
|
||||
int32_t mndUserRemoveDb(SMnode *pMnode, STrans *pTrans, char *db);
|
||||
int32_t mndUserRemoveTopic(SMnode *pMnode, STrans *pTrans, char *topic);
|
||||
|
||||
|
|
|
@ -556,9 +556,14 @@ static int32_t mndProcessAskEpReq(SRpcMsg *pMsg) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
((SMqRspHead *)buf)->mqMsgType = TMQ_MSG_TYPE__EP_RSP;
|
||||
((SMqRspHead *)buf)->epoch = serverEpoch;
|
||||
((SMqRspHead *)buf)->consumerId = pConsumer->consumerId;
|
||||
SMqRspHead* pHead = buf;
|
||||
|
||||
pHead->mqMsgType = TMQ_MSG_TYPE__EP_RSP;
|
||||
pHead->epoch = serverEpoch;
|
||||
pHead->consumerId = pConsumer->consumerId;
|
||||
pHead->walsver = 0;
|
||||
pHead->walever = 0;
|
||||
|
||||
|
||||
void *abuf = POINTER_SHIFT(buf, sizeof(SMqRspHead));
|
||||
tEncodeSMqAskEpRsp(&abuf, &rsp);
|
||||
|
|
|
@ -421,6 +421,7 @@ void dumpUser(SSdb *pSdb, SJson *json) {
|
|||
tjsonAddStringToObject(item, "updateTime", i642str(pObj->updateTime));
|
||||
tjsonAddStringToObject(item, "superUser", i642str(pObj->superUser));
|
||||
tjsonAddStringToObject(item, "authVersion", i642str(pObj->authVersion));
|
||||
tjsonAddStringToObject(item, "passVersion", i642str(pObj->passVersion));
|
||||
tjsonAddStringToObject(item, "numOfReadDbs", i642str(taosHashGetSize(pObj->readDbs)));
|
||||
tjsonAddStringToObject(item, "numOfWriteDbs", i642str(taosHashGetSize(pObj->writeDbs)));
|
||||
sdbRelease(pSdb, pObj);
|
||||
|
|
|
@ -590,6 +590,11 @@ int32_t mndIsCatchUp(SMnode *pMnode) {
|
|||
return syncIsCatchUp(rid);
|
||||
}
|
||||
|
||||
ESyncRole mndGetRole(SMnode *pMnode){
|
||||
int64_t rid = pMnode->syncMgmt.sync;
|
||||
return syncGetRole(rid);
|
||||
}
|
||||
|
||||
void mndStop(SMnode *pMnode) {
|
||||
mndSetStop(pMnode);
|
||||
mndSyncStop(pMnode);
|
||||
|
|
|
@ -322,7 +322,8 @@ static int32_t mndBuildAlterMnodeTypeRedoAction(STrans *pTrans,
|
|||
.pCont = pReq,
|
||||
.contLen = contLen,
|
||||
.msgType = TDMT_DND_ALTER_MNODE_TYPE,
|
||||
.acceptableCode = TSDB_CODE_MNODE_ALREADY_DEPLOYED,
|
||||
.retryCode = TSDB_CODE_MNODE_NOT_CATCH_UP,
|
||||
.acceptableCode = TSDB_CODE_MNODE_ALREADY_IS_VOTER,
|
||||
};
|
||||
|
||||
if (mndTransAppendRedoAction(pTrans, &action) != 0) {
|
||||
|
|
|
@ -283,6 +283,7 @@ static int32_t mndProcessConnectReq(SRpcMsg *pReq) {
|
|||
connectRsp.connType = connReq.connType;
|
||||
connectRsp.dnodeNum = mndGetDnodeSize(pMnode);
|
||||
connectRsp.svrTimestamp = taosGetTimestampSec();
|
||||
connectRsp.passVer = pUser->passVersion;
|
||||
|
||||
strcpy(connectRsp.sVer, version);
|
||||
snprintf(connectRsp.sDetailVer, sizeof(connectRsp.sDetailVer), "ver:%s\nbuild:%s\ngitinfo:%s", version, buildinfo,
|
||||
|
@ -547,6 +548,16 @@ static int32_t mndProcessQueryHeartBeat(SMnode *pMnode, SRpcMsg *pMsg, SClientHb
|
|||
}
|
||||
break;
|
||||
}
|
||||
case HEARTBEAT_KEY_USER_PASSINFO: {
|
||||
void *rspMsg = NULL;
|
||||
int32_t rspLen = 0;
|
||||
mndValidateUserPassInfo(pMnode, kv->value, kv->valueLen / sizeof(SUserPassVersion), &rspMsg, &rspLen);
|
||||
if (rspMsg && rspLen > 0) {
|
||||
SKv kv1 = {.key = HEARTBEAT_KEY_USER_PASSINFO, .valueLen = rspLen, .value = rspMsg};
|
||||
taosArrayPush(hbRsp.info, &kv1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
mError("invalid kv key:%d", kv->key);
|
||||
hbRsp.status = TSDB_CODE_APP_ERROR;
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "mndTrans.h"
|
||||
#include "tbase64.h"
|
||||
|
||||
#define USER_VER_NUMBER 3
|
||||
#define USER_VER_NUMBER 4
|
||||
#define USER_RESERVE_SIZE 64
|
||||
|
||||
static int32_t mndCreateDefaultUsers(SMnode *pMnode);
|
||||
|
@ -174,6 +174,7 @@ SSdbRaw *mndUserActionEncode(SUserObj *pUser) {
|
|||
SDB_SET_INT8(pRaw, dataPos, pUser->enable, _OVER)
|
||||
SDB_SET_INT8(pRaw, dataPos, pUser->reserve, _OVER)
|
||||
SDB_SET_INT32(pRaw, dataPos, pUser->authVersion, _OVER)
|
||||
SDB_SET_INT32(pRaw, dataPos, pUser->passVersion, _OVER)
|
||||
SDB_SET_INT32(pRaw, dataPos, numOfReadDbs, _OVER)
|
||||
SDB_SET_INT32(pRaw, dataPos, numOfWriteDbs, _OVER)
|
||||
SDB_SET_INT32(pRaw, dataPos, numOfTopics, _OVER)
|
||||
|
@ -263,7 +264,7 @@ static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) {
|
|||
int8_t sver = 0;
|
||||
if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto _OVER;
|
||||
|
||||
if (sver != 1 && sver != 2 && sver != 3) {
|
||||
if (sver < 1 || sver > USER_VER_NUMBER) {
|
||||
terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
@ -285,6 +286,9 @@ static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) {
|
|||
SDB_GET_INT8(pRaw, dataPos, &pUser->enable, _OVER)
|
||||
SDB_GET_INT8(pRaw, dataPos, &pUser->reserve, _OVER)
|
||||
SDB_GET_INT32(pRaw, dataPos, &pUser->authVersion, _OVER)
|
||||
if (sver >= 4) {
|
||||
SDB_GET_INT32(pRaw, dataPos, &pUser->passVersion, _OVER)
|
||||
}
|
||||
|
||||
int32_t numOfReadDbs = 0;
|
||||
int32_t numOfWriteDbs = 0;
|
||||
|
@ -529,6 +533,7 @@ static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew) {
|
|||
taosWLockLatch(&pOld->lock);
|
||||
pOld->updateTime = pNew->updateTime;
|
||||
pOld->authVersion = pNew->authVersion;
|
||||
pOld->passVersion = pNew->passVersion;
|
||||
pOld->sysInfo = pNew->sysInfo;
|
||||
pOld->enable = pNew->enable;
|
||||
memcpy(pOld->pass, pNew->pass, TSDB_PASSWORD_LEN);
|
||||
|
@ -818,10 +823,14 @@ static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
|
|||
|
||||
if (mndUserDupObj(pUser, &newUser) != 0) goto _OVER;
|
||||
|
||||
newUser.passVersion = pUser->passVersion;
|
||||
if (alterReq.alterType == TSDB_ALTER_USER_PASSWD) {
|
||||
char pass[TSDB_PASSWORD_LEN + 1] = {0};
|
||||
taosEncryptPass_c((uint8_t *)alterReq.pass, strlen(alterReq.pass), pass);
|
||||
memcpy(newUser.pass, pass, TSDB_PASSWORD_LEN);
|
||||
if (0 != strncmp(pUser->pass, pass, TSDB_PASSWORD_LEN)) {
|
||||
++newUser.passVersion;
|
||||
}
|
||||
}
|
||||
|
||||
if (alterReq.alterType == TSDB_ALTER_USER_SUPERUSER) {
|
||||
|
@ -1420,6 +1429,69 @@ _OVER:
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t mndValidateUserPassInfo(SMnode *pMnode, SUserPassVersion *pUsers, int32_t numOfUses, void **ppRsp,
|
||||
int32_t *pRspLen) {
|
||||
int32_t code = 0;
|
||||
SUserPassBatchRsp batchRsp = {0};
|
||||
|
||||
for (int32_t i = 0; i < numOfUses; ++i) {
|
||||
SUserObj *pUser = mndAcquireUser(pMnode, pUsers[i].user);
|
||||
if (pUser == NULL) {
|
||||
mError("user:%s, failed to validate user pass since %s", pUsers[i].user, terrstr());
|
||||
continue;
|
||||
}
|
||||
|
||||
pUsers[i].version = ntohl(pUsers[i].version);
|
||||
if (pUser->passVersion <= pUsers[i].version) {
|
||||
mTrace("user:%s, not update since mnd passVer %d <= client passVer %d", pUsers[i].user, pUser->passVersion,
|
||||
pUsers[i].version);
|
||||
mndReleaseUser(pMnode, pUser);
|
||||
continue;
|
||||
}
|
||||
|
||||
SGetUserPassRsp rsp = {0};
|
||||
memcpy(rsp.user, pUser->user, TSDB_USER_LEN);
|
||||
rsp.version = pUser->passVersion;
|
||||
|
||||
if (!batchRsp.pArray && !(batchRsp.pArray = taosArrayInit(numOfUses, sizeof(SGetUserPassRsp)))) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
mndReleaseUser(pMnode, pUser);
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
taosArrayPush(batchRsp.pArray, &rsp);
|
||||
mndReleaseUser(pMnode, pUser);
|
||||
}
|
||||
|
||||
if (taosArrayGetSize(batchRsp.pArray) <= 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
int32_t rspLen = tSerializeSUserPassBatchRsp(NULL, 0, &batchRsp);
|
||||
if (rspLen < 0) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _OVER;
|
||||
}
|
||||
void *pRsp = taosMemoryMalloc(rspLen);
|
||||
if (pRsp == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _OVER;
|
||||
}
|
||||
tSerializeSUserPassBatchRsp(pRsp, rspLen, &batchRsp);
|
||||
|
||||
*ppRsp = pRsp;
|
||||
*pRspLen = rspLen;
|
||||
|
||||
_OVER:
|
||||
if (code) {
|
||||
*ppRsp = NULL;
|
||||
*pRspLen = 0;
|
||||
}
|
||||
|
||||
tFreeSUserPassBatchRsp(&batchRsp);
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t mndUserRemoveDb(SMnode *pMnode, STrans *pTrans, char *db) {
|
||||
int32_t code = 0;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
|
|
|
@ -1263,6 +1263,8 @@ int32_t mndAddAlterVnodeTypeAction(SMnode *pMnode, STrans *pTrans, SDbObj *pDb,
|
|||
action.pCont = pReq;
|
||||
action.contLen = contLen;
|
||||
action.msgType = TDMT_DND_ALTER_VNODE_TYPE;
|
||||
action.acceptableCode = TSDB_CODE_VND_ALREADY_IS_VOTER;
|
||||
action.retryCode = TSDB_CODE_VND_NOT_CATCH_UP;
|
||||
|
||||
if (mndTransAppendRedoAction(pTrans, &action) != 0) {
|
||||
taosMemoryFree(pReq);
|
||||
|
|
|
@ -69,6 +69,7 @@ void vnodeGetInfo(SVnode *pVnode, const char **dbname, int32_t *vgId);
|
|||
int32_t vnodeProcessCreateTSma(SVnode *pVnode, void *pCont, uint32_t contLen);
|
||||
int32_t vnodeGetAllTableList(SVnode *pVnode, uint64_t uid, SArray *list);
|
||||
int32_t vnodeIsCatchUp(SVnode *pVnode);
|
||||
ESyncRole vnodeGetRole(SVnode *pVnode);
|
||||
|
||||
int32_t vnodeGetCtbIdList(SVnode *pVnode, int64_t suid, SArray *list);
|
||||
int32_t vnodeGetCtbIdListByFilter(SVnode *pVnode, int64_t suid, SArray *list, bool (*filter)(void *arg), void *arg);
|
||||
|
|
|
@ -106,6 +106,7 @@ typedef struct {
|
|||
SMqDataRsp* pDataRsp;
|
||||
char subKey[TSDB_SUBSCRIBE_KEY_LEN];
|
||||
SRpcHandleInfo info;
|
||||
STqHandle* pHandle;
|
||||
} STqPushEntry;
|
||||
|
||||
struct STQ {
|
||||
|
@ -145,8 +146,9 @@ int32_t tqFetchLog(STQ* pTq, STqHandle* pHandle, int64_t* fetchOffset, SWalCkHea
|
|||
// tqExec
|
||||
int32_t tqTaosxScanLog(STQ* pTq, STqHandle* pHandle, SPackedData submit, STaosxRsp* pRsp, int32_t* totalRows);
|
||||
int32_t tqAddBlockDataToRsp(const SSDataBlock* pBlock, SMqDataRsp* pRsp, int32_t numOfCols, int8_t precision);
|
||||
int32_t tqSendDataRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqDataRsp* pRsp, int32_t type);
|
||||
int32_t tqPushDataRsp(STQ* pTq, STqPushEntry* pPushEntry);
|
||||
int32_t tqSendDataRsp(STqHandle* pHandle, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqDataRsp* pRsp,
|
||||
int32_t type, int32_t vgId);
|
||||
int32_t tqPushDataRsp(STqPushEntry* pPushEntry, int32_t vgId);
|
||||
|
||||
// tqMeta
|
||||
int32_t tqMetaOpen(STQ* pTq);
|
||||
|
@ -179,15 +181,17 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t ver);
|
|||
int32_t tqStreamTasksScanWal(STQ* pTq);
|
||||
|
||||
// tq util
|
||||
char* createStreamTaskIdStr(int64_t streamId, int32_t taskId);
|
||||
void createStreamTaskOffsetKey(char* dst, uint64_t streamId, uint32_t taskId);
|
||||
int32_t tqAddInputBlockNLaunchTask(SStreamTask* pTask, SStreamQueueItem* pQueueItem, int64_t ver);
|
||||
int32_t launchTaskForWalBlock(SStreamTask* pTask, SFetchRet* pRet, STqOffset* pOffset);
|
||||
int32_t tqExtractDataForMq(STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequest, SRpcMsg* pMsg);
|
||||
int32_t tqDoSendDataRsp(const SRpcHandleInfo* pRpcHandleInfo, const SMqDataRsp* pRsp, int32_t epoch, int64_t consumerId,
|
||||
int32_t type, int64_t sver, int64_t ever);
|
||||
|
||||
int32_t tqInitDataRsp(SMqDataRsp* pRsp, const SMqPollReq* pReq);
|
||||
void doSaveTaskOffset(STqOffsetStore* pOffsetStore, const char* pKey, int64_t ver);
|
||||
void saveOffsetForAllTasks(STQ* pTq, int64_t ver);
|
||||
void initOffsetForAllRestoreTasks(STQ* pTq);
|
||||
int32_t transferToWalReadTask(SStreamMeta* pStreamMeta, SArray* pTaskList);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -206,7 +206,10 @@ int32_t tqProcessDelCheckInfoReq(STQ* pTq, int64_t version, char* msg, int32_t m
|
|||
int32_t tqProcessSubscribeReq(STQ* pTq, int64_t version, char* msg, int32_t msgLen);
|
||||
int32_t tqProcessDeleteSubReq(STQ* pTq, int64_t version, char* msg, int32_t msgLen);
|
||||
int32_t tqProcessOffsetCommitReq(STQ* pTq, int64_t version, char* msg, int32_t msgLen);
|
||||
int32_t tqProcessSeekReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen);
|
||||
int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg);
|
||||
int32_t tqProcessVgWalInfoReq(STQ* pTq, SRpcMsg* pMsg);
|
||||
|
||||
// tq-stream
|
||||
int32_t tqProcessTaskDeployReq(STQ* pTq, int64_t version, char* msg, int32_t msgLen);
|
||||
int32_t tqProcessTaskDropReq(STQ* pTq, int64_t version, char* msg, int32_t msgLen);
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
// 2: wait to be inited or cleaup
|
||||
#define WAL_READ_TASKS_ID (-1)
|
||||
|
||||
static int32_t tqInitialize(STQ* pTq);
|
||||
|
||||
int32_t tqInit() {
|
||||
int8_t old;
|
||||
while (1) {
|
||||
|
@ -74,7 +76,7 @@ static void destroyTqHandle(void* data) {
|
|||
static void tqPushEntryFree(void* data) {
|
||||
STqPushEntry* p = *(void**)data;
|
||||
if (p->pDataRsp->head.mqMsgType == TMQ_MSG_TYPE__POLL_RSP) {
|
||||
tDeleteSMqDataRsp(p->pDataRsp);
|
||||
tDeleteMqDataRsp(p->pDataRsp);
|
||||
} else if (p->pDataRsp->head.mqMsgType == TMQ_MSG_TYPE__TAOSX_RSP) {
|
||||
tDeleteSTaosxRsp((STaosxRsp*)p->pDataRsp);
|
||||
}
|
||||
|
@ -109,25 +111,32 @@ STQ* tqOpen(const char* path, SVnode* pVnode) {
|
|||
pTq->pCheckInfo = taosHashInit(64, MurmurHash3_32, true, HASH_ENTRY_LOCK);
|
||||
taosHashSetFreeFp(pTq->pCheckInfo, (FDelete)tDeleteSTqCheckInfo);
|
||||
|
||||
tqInitialize(pTq);
|
||||
return pTq;
|
||||
}
|
||||
|
||||
int32_t tqInitialize(STQ* pTq) {
|
||||
if (tqMetaOpen(pTq) < 0) {
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
pTq->pOffsetStore = tqOffsetOpen(pTq);
|
||||
if (pTq->pOffsetStore == NULL) {
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
pTq->pStreamMeta = streamMetaOpen(path, pTq, (FTaskExpand*)tqExpandTask, pTq->pVnode->config.vgId);
|
||||
pTq->pStreamMeta = streamMetaOpen(pTq->path, pTq, (FTaskExpand*)tqExpandTask, pTq->pVnode->config.vgId);
|
||||
if (pTq->pStreamMeta == NULL) {
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (streamLoadTasks(pTq->pStreamMeta, walGetCommittedVer(pVnode->pWal)) < 0) {
|
||||
return NULL;
|
||||
// the version is kept in task's meta data
|
||||
// todo check if this version is required or not
|
||||
if (streamLoadTasks(pTq->pStreamMeta, walGetCommittedVer(pTq->pVnode->pWal)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pTq;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tqClose(STQ* pTq) {
|
||||
|
@ -145,71 +154,30 @@ void tqClose(STQ* pTq) {
|
|||
taosMemoryFree(pTq);
|
||||
}
|
||||
|
||||
static int32_t doSendDataRsp(const SRpcHandleInfo* pRpcHandleInfo, const SMqDataRsp* pRsp, int32_t epoch,
|
||||
int64_t consumerId, int32_t type) {
|
||||
int32_t len = 0;
|
||||
int32_t code = 0;
|
||||
|
||||
if (type == TMQ_MSG_TYPE__POLL_RSP) {
|
||||
tEncodeSize(tEncodeSMqDataRsp, pRsp, len, code);
|
||||
} else if (type == TMQ_MSG_TYPE__TAOSX_RSP) {
|
||||
tEncodeSize(tEncodeSTaosxRsp, (STaosxRsp*)pRsp, len, code);
|
||||
}
|
||||
|
||||
if (code < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t tlen = sizeof(SMqRspHead) + len;
|
||||
void* buf = rpcMallocCont(tlen);
|
||||
if (buf == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
((SMqRspHead*)buf)->mqMsgType = type;
|
||||
((SMqRspHead*)buf)->epoch = epoch;
|
||||
((SMqRspHead*)buf)->consumerId = consumerId;
|
||||
|
||||
void* abuf = POINTER_SHIFT(buf, sizeof(SMqRspHead));
|
||||
|
||||
SEncoder encoder = {0};
|
||||
tEncoderInit(&encoder, abuf, len);
|
||||
|
||||
if (type == TMQ_MSG_TYPE__POLL_RSP) {
|
||||
tEncodeSMqDataRsp(&encoder, pRsp);
|
||||
} else if (type == TMQ_MSG_TYPE__TAOSX_RSP) {
|
||||
tEncodeSTaosxRsp(&encoder, (STaosxRsp*)pRsp);
|
||||
}
|
||||
|
||||
tEncoderClear(&encoder);
|
||||
|
||||
SRpcMsg rsp = {
|
||||
.info = *pRpcHandleInfo,
|
||||
.pCont = buf,
|
||||
.contLen = tlen,
|
||||
.code = 0,
|
||||
};
|
||||
|
||||
tmsgSendRsp(&rsp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tqPushDataRsp(STQ* pTq, STqPushEntry* pPushEntry) {
|
||||
int32_t tqPushDataRsp(STqPushEntry* pPushEntry, int32_t vgId) {
|
||||
SMqDataRsp* pRsp = pPushEntry->pDataRsp;
|
||||
SMqRspHead* pHeader = &pPushEntry->pDataRsp->head;
|
||||
doSendDataRsp(&pPushEntry->info, pRsp, pHeader->epoch, pHeader->consumerId, pHeader->mqMsgType);
|
||||
|
||||
int64_t sver = 0, ever = 0;
|
||||
walReaderValidVersionRange(pPushEntry->pHandle->execHandle.pTqReader->pWalReader, &sver, &ever);
|
||||
|
||||
tqDoSendDataRsp(&pPushEntry->info, pRsp, pHeader->epoch, pHeader->consumerId, pHeader->mqMsgType, sver, ever);
|
||||
|
||||
char buf1[80] = {0};
|
||||
char buf2[80] = {0};
|
||||
tFormatOffset(buf1, tListLen(buf1), &pRsp->reqOffset);
|
||||
tFormatOffset(buf2, tListLen(buf2), &pRsp->rspOffset);
|
||||
tqDebug("vgId:%d, from consumer:0x%" PRIx64 " (epoch %d) push rsp, block num: %d, req:%s, rsp:%s",
|
||||
TD_VID(pTq->pVnode), pRsp->head.consumerId, pRsp->head.epoch, pRsp->blockNum, buf1, buf2);
|
||||
vgId, pRsp->head.consumerId, pRsp->head.epoch, pRsp->blockNum, buf1, buf2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tqSendDataRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqDataRsp* pRsp, int32_t type) {
|
||||
doSendDataRsp(&pMsg->info, pRsp, pReq->epoch, pReq->consumerId, type);
|
||||
int32_t tqSendDataRsp(STqHandle* pHandle, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqDataRsp* pRsp,
|
||||
int32_t type, int32_t vgId) {
|
||||
int64_t sver = 0, ever = 0;
|
||||
walReaderValidVersionRange(pHandle->execHandle.pTqReader->pWalReader, &sver, &ever);
|
||||
|
||||
tqDoSendDataRsp(&pMsg->info, pRsp, pReq->epoch, pReq->consumerId, type, sver, ever);
|
||||
|
||||
char buf1[80] = {0};
|
||||
char buf2[80] = {0};
|
||||
|
@ -217,50 +185,54 @@ int32_t tqSendDataRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, con
|
|||
tFormatOffset(buf2, 80, &pRsp->rspOffset);
|
||||
|
||||
tqDebug("vgId:%d consumer:0x%" PRIx64 " (epoch %d) send rsp, block num:%d, req:%s, rsp:%s, reqId:0x%" PRIx64,
|
||||
TD_VID(pTq->pVnode), pReq->consumerId, pReq->epoch, pRsp->blockNum, buf1, buf2, pReq->reqId);
|
||||
vgId, pReq->consumerId, pReq->epoch, pRsp->blockNum, buf1, buf2, pReq->reqId);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tqProcessOffsetCommitReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen) {
|
||||
STqOffset offset = {0};
|
||||
int32_t vgId = TD_VID(pTq->pVnode);
|
||||
SMqVgOffset vgOffset = {0};
|
||||
int32_t vgId = TD_VID(pTq->pVnode);
|
||||
|
||||
SDecoder decoder;
|
||||
tDecoderInit(&decoder, (uint8_t*)msg, msgLen);
|
||||
if (tDecodeSTqOffset(&decoder, &offset) < 0) {
|
||||
if (tDecodeMqVgOffset(&decoder, &vgOffset) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
tDecoderClear(&decoder);
|
||||
|
||||
if (offset.val.type == TMQ_OFFSET__SNAPSHOT_DATA || offset.val.type == TMQ_OFFSET__SNAPSHOT_META) {
|
||||
STqOffset* pOffset = &vgOffset.offset;
|
||||
|
||||
if (pOffset->val.type == TMQ_OFFSET__SNAPSHOT_DATA || pOffset->val.type == TMQ_OFFSET__SNAPSHOT_META) {
|
||||
tqDebug("receive offset commit msg to %s on vgId:%d, offset(type:snapshot) uid:%" PRId64 ", ts:%" PRId64,
|
||||
offset.subKey, vgId, offset.val.uid, offset.val.ts);
|
||||
} else if (offset.val.type == TMQ_OFFSET__LOG) {
|
||||
tqDebug("receive offset commit msg to %s on vgId:%d, offset(type:log) version:%" PRId64, offset.subKey, vgId,
|
||||
offset.val.version);
|
||||
if (offset.val.version + 1 == sversion) {
|
||||
offset.val.version += 1;
|
||||
pOffset->subKey, vgId, pOffset->val.uid, pOffset->val.ts);
|
||||
} else if (pOffset->val.type == TMQ_OFFSET__LOG) {
|
||||
tqDebug("receive offset commit msg to %s on vgId:%d, offset(type:log) version:%" PRId64, pOffset->subKey, vgId,
|
||||
pOffset->val.version);
|
||||
if (pOffset->val.version + 1 == sversion) {
|
||||
pOffset->val.version += 1;
|
||||
}
|
||||
} else {
|
||||
tqError("invalid commit offset type:%d", offset.val.type);
|
||||
tqError("invalid commit offset type:%d", pOffset->val.type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
STqOffset* pSavedOffset = tqOffsetRead(pTq->pOffsetStore, offset.subKey);
|
||||
if (pSavedOffset != NULL && tqOffsetLessOrEqual(&offset, pSavedOffset)) {
|
||||
STqOffset* pSavedOffset = tqOffsetRead(pTq->pOffsetStore, pOffset->subKey);
|
||||
if (pSavedOffset != NULL && tqOffsetLessOrEqual(pOffset, pSavedOffset)) {
|
||||
tqDebug("not update the offset, vgId:%d sub:%s since committed:%" PRId64 " less than/equal to existed:%" PRId64,
|
||||
vgId, pOffset->subKey, pOffset->val.version, pSavedOffset->val.version);
|
||||
return 0; // no need to update the offset value
|
||||
}
|
||||
|
||||
// save the new offset value
|
||||
if (tqOffsetWrite(pTq->pOffsetStore, &offset) < 0) {
|
||||
if (tqOffsetWrite(pTq->pOffsetStore, pOffset) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (offset.val.type == TMQ_OFFSET__LOG) {
|
||||
STqHandle* pHandle = taosHashGet(pTq->pHandle, offset.subKey, strlen(offset.subKey));
|
||||
if (pHandle && (walRefVer(pHandle->pRef, offset.val.version) < 0)) {
|
||||
if (pOffset->val.type == TMQ_OFFSET__LOG) {
|
||||
STqHandle* pHandle = taosHashGet(pTq->pHandle, pOffset->subKey, strlen(pOffset->subKey));
|
||||
if (pHandle && (walRefVer(pHandle->pRef, pOffset->val.version) < 0)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -268,6 +240,78 @@ int32_t tqProcessOffsetCommitReq(STQ* pTq, int64_t sversion, char* msg, int32_t
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t tqProcessSeekReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen) {
|
||||
SMqVgOffset vgOffset = {0};
|
||||
int32_t vgId = TD_VID(pTq->pVnode);
|
||||
|
||||
SDecoder decoder;
|
||||
tDecoderInit(&decoder, (uint8_t*)msg, msgLen);
|
||||
if (tDecodeMqVgOffset(&decoder, &vgOffset) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
tDecoderClear(&decoder);
|
||||
|
||||
STqOffset* pOffset = &vgOffset.offset;
|
||||
if (pOffset->val.type != TMQ_OFFSET__LOG) {
|
||||
tqError("vgId:%d, subKey:%s invalid seek offset type:%d", vgId, pOffset->subKey, pOffset->val.type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
STqHandle* pHandle = taosHashGet(pTq->pHandle, pOffset->subKey, strlen(pOffset->subKey));
|
||||
if (pHandle == NULL) {
|
||||
tqError("tmq seek: consumer:0x%" PRIx64 " vgId:%d subkey %s not found", vgOffset.consumerId, vgId,
|
||||
pOffset->subKey);
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 2. check consumer-vg assignment status
|
||||
taosRLockLatch(&pTq->lock);
|
||||
if (pHandle->consumerId != vgOffset.consumerId) {
|
||||
tqDebug("ERROR tmq seek: consumer:0x%" PRIx64 " vgId:%d, subkey %s, mismatch for saved handle consumer:0x%" PRIx64,
|
||||
vgOffset.consumerId, vgId, pOffset->subKey, pHandle->consumerId);
|
||||
terrno = TSDB_CODE_TMQ_CONSUMER_MISMATCH;
|
||||
taosRUnLockLatch(&pTq->lock);
|
||||
return -1;
|
||||
}
|
||||
taosRUnLockLatch(&pTq->lock);
|
||||
|
||||
//3. check the offset info
|
||||
STqOffset* pSavedOffset = tqOffsetRead(pTq->pOffsetStore, pOffset->subKey);
|
||||
if (pSavedOffset != NULL) {
|
||||
if (pSavedOffset->val.type != TMQ_OFFSET__LOG) {
|
||||
tqError("invalid saved offset type, vgId:%d sub:%s", vgId, pOffset->subKey);
|
||||
return 0; // no need to update the offset value
|
||||
}
|
||||
|
||||
if (pSavedOffset->val.version == pOffset->val.version) {
|
||||
tqDebug("vgId:%d subKey:%s no need to seek to %" PRId64 " prev offset:%" PRId64, vgId, pOffset->subKey,
|
||||
pOffset->val.version, pSavedOffset->val.version);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t sver = 0, ever = 0;
|
||||
walReaderValidVersionRange(pHandle->execHandle.pTqReader->pWalReader, &sver, &ever);
|
||||
if (pOffset->val.version < sver) {
|
||||
pOffset->val.version = sver;
|
||||
} else if (pOffset->val.version > ever) {
|
||||
pOffset->val.version = ever;
|
||||
}
|
||||
|
||||
// save the new offset value
|
||||
tqDebug("vgId:%d sub:%s seek to %" PRId64 " prev offset:%" PRId64, vgId, pOffset->subKey, pOffset->val.version,
|
||||
pSavedOffset->val.version);
|
||||
|
||||
if (tqOffsetWrite(pTq->pOffsetStore, pOffset) < 0) {
|
||||
tqError("failed to save offset, vgId:%d sub:%s seek to %" PRId64, vgId, pOffset->subKey, pOffset->val.version);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tqCheckColModifiable(STQ* pTq, int64_t tbUid, int32_t colId) {
|
||||
void* pIter = NULL;
|
||||
|
||||
|
@ -344,6 +388,81 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg) {
|
|||
return tqExtractDataForMq(pTq, pHandle, &req, pMsg);
|
||||
}
|
||||
|
||||
int32_t tqProcessVgWalInfoReq(STQ* pTq, SRpcMsg* pMsg) {
|
||||
SMqPollReq req = {0};
|
||||
if (tDeserializeSMqPollReq(pMsg->pCont, pMsg->contLen, &req) < 0) {
|
||||
tqError("tDeserializeSMqPollReq %d failed", pMsg->contLen);
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int64_t consumerId = req.consumerId;
|
||||
STqOffsetVal reqOffset = req.reqOffset;
|
||||
int32_t vgId = TD_VID(pTq->pVnode);
|
||||
|
||||
// 1. find handle
|
||||
STqHandle* pHandle = taosHashGet(pTq->pHandle, req.subKey, strlen(req.subKey));
|
||||
if (pHandle == NULL) {
|
||||
tqError("consumer:0x%" PRIx64 " vgId:%d subkey:%s not found", consumerId, vgId, req.subKey);
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 2. check re-balance status
|
||||
taosRLockLatch(&pTq->lock);
|
||||
if (pHandle->consumerId != consumerId) {
|
||||
tqDebug("ERROR consumer:0x%" PRIx64 " vgId:%d, subkey %s, mismatch for saved handle consumer:0x%" PRIx64,
|
||||
consumerId, vgId, req.subKey, pHandle->consumerId);
|
||||
terrno = TSDB_CODE_TMQ_CONSUMER_MISMATCH;
|
||||
taosRUnLockLatch(&pTq->lock);
|
||||
return -1;
|
||||
}
|
||||
taosRUnLockLatch(&pTq->lock);
|
||||
|
||||
int64_t sver = 0, ever = 0;
|
||||
walReaderValidVersionRange(pHandle->execHandle.pTqReader->pWalReader, &sver, &ever);
|
||||
|
||||
SMqDataRsp dataRsp = {0};
|
||||
tqInitDataRsp(&dataRsp, &req);
|
||||
|
||||
STqOffset* pOffset = tqOffsetRead(pTq->pOffsetStore, req.subKey);
|
||||
if (pOffset != NULL) {
|
||||
if (pOffset->val.type != TMQ_OFFSET__LOG) {
|
||||
tqError("consumer:0x%" PRIx64 " vgId:%d subkey:%s use snapshot, no valid wal info", consumerId, vgId, req.subKey);
|
||||
terrno = TSDB_CODE_INVALID_PARA;
|
||||
tDeleteMqDataRsp(&dataRsp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dataRsp.rspOffset.type = TMQ_OFFSET__LOG;
|
||||
dataRsp.rspOffset.version = pOffset->val.version;
|
||||
} else {
|
||||
if (req.useSnapshot == true) {
|
||||
tqError("consumer:0x%" PRIx64 " vgId:%d subkey:%s snapshot not support wal info", consumerId, vgId, req.subKey);
|
||||
terrno = TSDB_CODE_INVALID_PARA;
|
||||
tDeleteMqDataRsp(&dataRsp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dataRsp.rspOffset.type = TMQ_OFFSET__LOG;
|
||||
|
||||
if (reqOffset.type == TMQ_OFFSET__RESET_EARLIEAST) {
|
||||
dataRsp.rspOffset.version = sver;
|
||||
} else if (reqOffset.type == TMQ_OFFSET__RESET_LATEST) {
|
||||
dataRsp.rspOffset.version = ever;
|
||||
} else {
|
||||
tqError("consumer:0x%" PRIx64 " vgId:%d subkey:%s invalid offset type:%d", consumerId, vgId, req.subKey,
|
||||
reqOffset.type);
|
||||
terrno = TSDB_CODE_INVALID_PARA;
|
||||
tDeleteMqDataRsp(&dataRsp);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
tqDoSendDataRsp(&pMsg->info, &dataRsp, req.epoch, req.consumerId, TMQ_MSG_TYPE__WALINFO_RSP, sver, ever);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tqProcessDeleteSubReq(STQ* pTq, int64_t sversion, char* msg, int32_t msgLen) {
|
||||
SMqVDeleteReq* pReq = (SMqVDeleteReq*)msg;
|
||||
|
||||
|
@ -548,12 +667,8 @@ int32_t tqProcessSubscribeReq(STQ* pTq, int64_t sversion, char* msg, int32_t msg
|
|||
}
|
||||
|
||||
int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t ver) {
|
||||
// todo extract method
|
||||
char buf[128] = {0};
|
||||
sprintf(buf, "0x%"PRIx64"-%d", pTask->id.streamId, pTask->id.taskId);
|
||||
|
||||
int32_t vgId = TD_VID(pTq->pVnode);
|
||||
pTask->id.idStr = taosStrdup(buf);
|
||||
pTask->id.idStr = createStreamTaskIdStr(pTask->id.streamId, pTask->id.taskId);
|
||||
pTask->refCnt = 1;
|
||||
pTask->status.schedStatus = TASK_SCHED_STATUS__INACTIVE;
|
||||
pTask->inputQueue = streamQueueOpen();
|
||||
|
@ -633,8 +748,11 @@ int32_t tqExpandTask(STQ* pTq, SStreamTask* pTask, int64_t ver) {
|
|||
}
|
||||
|
||||
streamSetupTrigger(pTask);
|
||||
tqInfo("vgId:%d expand stream task, s-task:%s, ver:%" PRId64 " child id:%d, level:%d", vgId, pTask->id.idStr,
|
||||
tqInfo("vgId:%d expand stream task, s-task:%s, checkpoint ver:%" PRId64 " child id:%d, level:%d", vgId, pTask->id.idStr,
|
||||
pTask->chkInfo.version, pTask->selfChildId, pTask->taskLevel);
|
||||
|
||||
// next valid version will add one
|
||||
pTask->chkInfo.version += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -750,7 +868,7 @@ int32_t tqProcessTaskDeployReq(STQ* pTq, int64_t sversion, char* msg, int32_t ms
|
|||
|
||||
tDecoderClear(&decoder);
|
||||
|
||||
// 2.save task
|
||||
// 2.save task, use the newest commit version as the initial start version of stream task.
|
||||
code = streamMetaAddDeployedTask(pTq->pStreamMeta, sversion, pTask);
|
||||
if (code < 0) {
|
||||
tqError("vgId:%d failed to add s-task:%s, total:%d", TD_VID(pTq->pVnode), pTask->id.idStr,
|
||||
|
@ -1276,6 +1394,13 @@ int32_t tqStartStreamTasks(STQ* pTq) {
|
|||
|
||||
SStreamMeta* pMeta = pTq->pStreamMeta;
|
||||
taosWLockLatch(&pMeta->lock);
|
||||
int32_t numOfTasks = taosHashGetSize(pTq->pStreamMeta->pTasks);
|
||||
if (numOfTasks == 0) {
|
||||
tqInfo("vgId:%d no stream tasks exists", vgId);
|
||||
taosWUnLockLatch(&pTq->pStreamMeta->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pMeta->walScan += 1;
|
||||
|
||||
if (pMeta->walScan > 1) {
|
||||
|
@ -1292,8 +1417,6 @@ int32_t tqStartStreamTasks(STQ* pTq) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
int32_t numOfTasks = taosHashGetSize(pTq->pStreamMeta->pTasks);
|
||||
|
||||
tqInfo("vgId:%d start wal scan stream tasks, tasks:%d", vgId, numOfTasks);
|
||||
initOffsetForAllRestoreTasks(pTq);
|
||||
|
||||
|
|
|
@ -263,7 +263,7 @@ static void doPushDataForEntry(void* pIter, STqExecHandle* pExec, STQ* pTq, int6
|
|||
|
||||
if (pRsp->blockNum > 0) {
|
||||
tqOffsetResetToLog(&pRsp->rspOffset, ver);
|
||||
tqPushDataRsp(pTq, pPushEntry);
|
||||
tqPushDataRsp(pPushEntry, vgId);
|
||||
recordPushedEntry(pCachedKey, pIter);
|
||||
}
|
||||
}
|
||||
|
@ -376,6 +376,7 @@ int32_t tqRegisterPushHandle(STQ* pTq, void* pHandle, const SMqPollReq* pRequest
|
|||
return -1;
|
||||
}
|
||||
|
||||
pPushEntry->pHandle = pHandle;
|
||||
pPushEntry->info = pRpcMsg->info;
|
||||
memcpy(pPushEntry->subKey, pTqHandle->subKey, TSDB_SUBSCRIBE_KEY_LEN);
|
||||
|
||||
|
@ -388,6 +389,7 @@ int32_t tqRegisterPushHandle(STQ* pTq, void* pHandle, const SMqPollReq* pRequest
|
|||
}
|
||||
|
||||
SMqRspHead* pHead = &pPushEntry->pDataRsp->head;
|
||||
|
||||
pHead->consumerId = consumerId;
|
||||
pHead->epoch = pRequest->epoch;
|
||||
pHead->mqMsgType = type;
|
||||
|
@ -411,7 +413,7 @@ int32_t tqUnregisterPushHandle(STQ* pTq, const char* pKey, int32_t keyLen, uint6
|
|||
(*pEntry)->subKey, vgId, taosHashGetSize(pTq->pPushMgr) - 1);
|
||||
|
||||
if (rspConsumer) { // rsp the old consumer with empty block.
|
||||
tqPushDataRsp(pTq, *pEntry);
|
||||
tqPushDataRsp(*pEntry, vgId);
|
||||
}
|
||||
|
||||
taosHashRemove(pTq->pPushMgr, pKey, keyLen);
|
||||
|
|
|
@ -52,33 +52,9 @@ int tqStreamTasksScanWal(STQ* pTq) {
|
|||
|
||||
double el = (taosGetTimestampMs() - st) / 1000.0;
|
||||
tqInfo("vgId:%d scan wal for stream tasks completed, elapsed time:%.2f sec", vgId, el);
|
||||
|
||||
// restore wal scan flag
|
||||
// atomic_store_8(&pTq->pStreamMeta->walScan, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//int32_t transferToNormalTask(SStreamMeta* pStreamMeta, SArray* pTaskList) {
|
||||
// int32_t numOfTask = taosArrayGetSize(pTaskList);
|
||||
// if (numOfTask <= 0) {
|
||||
// return TSDB_CODE_SUCCESS;
|
||||
// }
|
||||
//
|
||||
// // todo: add lock
|
||||
// for (int32_t i = 0; i < numOfTask; ++i) {
|
||||
// SStreamTask* pTask = taosArrayGetP(pTaskList, i);
|
||||
// tqDebug("vgId:%d transfer s-task:%s state restore -> ready, checkpoint:%" PRId64 " checkpoint id:%" PRId64,
|
||||
// pStreamMeta->vgId, pTask->id.idStr, pTask->chkInfo.version, pTask->chkInfo.id);
|
||||
// taosHashRemove(pStreamMeta->pWalReadTasks, &pTask->id.taskId, sizeof(pTask->id.taskId));
|
||||
//
|
||||
// // NOTE: do not change the following order
|
||||
// atomic_store_8(&pTask->status.taskStatus, TASK_STATUS__NORMAL);
|
||||
// taosHashPut(pStreamMeta->pTasks, &pTask->id.taskId, sizeof(pTask->id.taskId), &pTask, POINTER_BYTES);
|
||||
// }
|
||||
//
|
||||
// return TSDB_CODE_SUCCESS;
|
||||
//}
|
||||
|
||||
int32_t streamTaskReplayWal(SStreamMeta* pStreamMeta, STqOffsetStore* pOffsetStore, bool* pScanIdle) {
|
||||
void* pIter = NULL;
|
||||
int32_t vgId = pStreamMeta->vgId;
|
||||
|
@ -99,8 +75,8 @@ int32_t streamTaskReplayWal(SStreamMeta* pStreamMeta, STqOffsetStore* pOffsetSto
|
|||
continue;
|
||||
}
|
||||
|
||||
if (pTask->status.taskStatus == TASK_STATUS__RECOVER_PREPARE ||
|
||||
pTask->status.taskStatus == TASK_STATUS__WAIT_DOWNSTREAM) {
|
||||
int8_t status = pTask->status.taskStatus;
|
||||
if (status == TASK_STATUS__RECOVER_PREPARE || status == TASK_STATUS__WAIT_DOWNSTREAM) {
|
||||
tqDebug("s-task:%s skip push data, not ready for processing, status %d", pTask->id.idStr,
|
||||
pTask->status.taskStatus);
|
||||
continue;
|
||||
|
|
|
@ -17,7 +17,13 @@
|
|||
|
||||
#define IS_OFFSET_RESET_TYPE(_t) ((_t) < 0)
|
||||
|
||||
static int32_t tqSendMetaPollRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqMetaRsp* pRsp);
|
||||
static int32_t tqSendMetaPollRsp(STqHandle* pHandle, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqMetaRsp* pRsp, int32_t vgId);
|
||||
|
||||
char* createStreamTaskIdStr(int64_t streamId, int32_t taskId) {
|
||||
char buf[128] = {0};
|
||||
sprintf(buf, "0x%" PRIx64 "-%d", streamId, taskId);
|
||||
return taosStrdup(buf);
|
||||
}
|
||||
|
||||
// stream_task:stream_id:task_id
|
||||
void createStreamTaskOffsetKey(char* dst, uint64_t streamId, uint32_t taskId) {
|
||||
|
@ -118,7 +124,7 @@ void doSaveTaskOffset(STqOffsetStore* pOffsetStore, const char* pKey, int64_t ve
|
|||
tqOffsetWrite(pOffsetStore, &offset);
|
||||
}
|
||||
|
||||
static int32_t tqInitDataRsp(SMqDataRsp* pRsp, const SMqPollReq* pReq, int8_t subType) {
|
||||
int32_t tqInitDataRsp(SMqDataRsp* pRsp, const SMqPollReq* pReq) {
|
||||
pRsp->reqOffset = pReq->reqOffset;
|
||||
|
||||
pRsp->blockData = taosArrayInit(0, sizeof(void*));
|
||||
|
@ -144,6 +150,21 @@ static int32_t tqInitTaosxRsp(STaosxRsp* pRsp, const SMqPollReq* pReq) {
|
|||
pRsp->blockSchema = taosArrayInit(0, sizeof(void*));
|
||||
|
||||
if (pRsp->blockData == NULL || pRsp->blockDataLen == NULL || pRsp->blockTbName == NULL || pRsp->blockSchema == NULL) {
|
||||
if (pRsp->blockData != NULL) {
|
||||
pRsp->blockData = taosArrayDestroy(pRsp->blockData);
|
||||
}
|
||||
|
||||
if (pRsp->blockDataLen != NULL) {
|
||||
pRsp->blockDataLen = taosArrayDestroy(pRsp->blockDataLen);
|
||||
}
|
||||
|
||||
if (pRsp->blockTbName != NULL) {
|
||||
pRsp->blockTbName = taosArrayDestroy(pRsp->blockTbName);
|
||||
}
|
||||
|
||||
if (pRsp->blockSchema != NULL) {
|
||||
pRsp->blockSchema = taosArrayDestroy(pRsp->blockSchema);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -193,13 +214,13 @@ static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHand
|
|||
} else if (reqOffset.type == TMQ_OFFSET__RESET_LATEST) {
|
||||
if (pHandle->execHandle.subType == TOPIC_SUB_TYPE__COLUMN) {
|
||||
SMqDataRsp dataRsp = {0};
|
||||
tqInitDataRsp(&dataRsp, pRequest, pHandle->execHandle.subType);
|
||||
tqInitDataRsp(&dataRsp, pRequest);
|
||||
|
||||
tqOffsetResetToLog(&dataRsp.rspOffset, walGetLastVer(pTq->pVnode->pWal));
|
||||
tqDebug("tmq poll: consumer:0x%" PRIx64 ", subkey %s, vgId:%d, (latest) offset reset to %" PRId64, consumerId,
|
||||
pHandle->subKey, vgId, dataRsp.rspOffset.version);
|
||||
int32_t code = tqSendDataRsp(pTq, pMsg, pRequest, &dataRsp, TMQ_MSG_TYPE__POLL_RSP);
|
||||
tDeleteSMqDataRsp(&dataRsp);
|
||||
int32_t code = tqSendDataRsp(pHandle, pMsg, pRequest, &dataRsp, TMQ_MSG_TYPE__POLL_RSP, vgId);
|
||||
tDeleteMqDataRsp(&dataRsp);
|
||||
|
||||
*pBlockReturned = true;
|
||||
return code;
|
||||
|
@ -207,7 +228,7 @@ static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHand
|
|||
STaosxRsp taosxRsp = {0};
|
||||
tqInitTaosxRsp(&taosxRsp, pRequest);
|
||||
tqOffsetResetToLog(&taosxRsp.rspOffset, walGetLastVer(pTq->pVnode->pWal));
|
||||
int32_t code = tqSendDataRsp(pTq, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP);
|
||||
int32_t code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP, vgId);
|
||||
tDeleteSTaosxRsp(&taosxRsp);
|
||||
|
||||
*pBlockReturned = true;
|
||||
|
@ -226,47 +247,43 @@ static int32_t extractResetOffsetVal(STqOffsetVal* pOffsetVal, STQ* pTq, STqHand
|
|||
|
||||
static int32_t extractDataAndRspForNormalSubscribe(STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequest,
|
||||
SRpcMsg* pMsg, STqOffsetVal* pOffset) {
|
||||
char buf[80] = {0};
|
||||
uint64_t consumerId = pRequest->consumerId;
|
||||
int32_t vgId = TD_VID(pTq->pVnode);
|
||||
|
||||
SMqDataRsp dataRsp = {0};
|
||||
tqInitDataRsp(&dataRsp, pRequest, pHandle->execHandle.subType);
|
||||
tqInitDataRsp(&dataRsp, pRequest);
|
||||
|
||||
// lock
|
||||
taosWLockLatch(&pTq->lock);
|
||||
|
||||
qSetTaskId(pHandle->execHandle.task, consumerId, pRequest->reqId);
|
||||
|
||||
int code = tqScanData(pTq, pHandle, &dataRsp, pOffset);
|
||||
if(code != 0) {
|
||||
goto end;
|
||||
if (code == 0) {
|
||||
|
||||
// till now, all data has been transferred to consumer, new data needs to push client once arrived.
|
||||
if (dataRsp.blockNum == 0 && dataRsp.reqOffset.type == TMQ_OFFSET__LOG &&
|
||||
dataRsp.reqOffset.version == dataRsp.rspOffset.version && pHandle->consumerId == pRequest->consumerId) {
|
||||
code = tqRegisterPushHandle(pTq, pHandle, pRequest, pMsg, &dataRsp, TMQ_MSG_TYPE__POLL_RSP);
|
||||
taosWUnLockLatch(&pTq->lock);
|
||||
return code;
|
||||
}
|
||||
|
||||
// NOTE: this pHandle->consumerId may have been changed already.
|
||||
code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&dataRsp, TMQ_MSG_TYPE__POLL_RSP, vgId);
|
||||
}
|
||||
|
||||
// till now, all data has been transferred to consumer, new data needs to push client once arrived.
|
||||
if (dataRsp.blockNum == 0 && dataRsp.reqOffset.type == TMQ_OFFSET__LOG &&
|
||||
dataRsp.reqOffset.version == dataRsp.rspOffset.version && pHandle->consumerId == pRequest->consumerId) {
|
||||
code = tqRegisterPushHandle(pTq, pHandle, pRequest, pMsg, &dataRsp, TMQ_MSG_TYPE__POLL_RSP);
|
||||
taosWUnLockLatch(&pTq->lock);
|
||||
return code;
|
||||
}
|
||||
tFormatOffset(buf, 80, &dataRsp.rspOffset);
|
||||
tqDebug("tmq poll: consumer:0x%" PRIx64 ", subkey %s, vgId:%d, rsp block:%d, rsp offset type:%s, reqId:0x%" PRIx64
|
||||
" code:%d",
|
||||
consumerId, pHandle->subKey, vgId, dataRsp.blockNum, buf, pRequest->reqId, code);
|
||||
taosWUnLockLatch(&pTq->lock);
|
||||
tDeleteMqDataRsp(&dataRsp);
|
||||
|
||||
|
||||
code = tqSendDataRsp(pTq, pMsg, pRequest, (SMqDataRsp*)&dataRsp, TMQ_MSG_TYPE__POLL_RSP);
|
||||
|
||||
// NOTE: this pHandle->consumerId may have been changed already.
|
||||
|
||||
end:
|
||||
{
|
||||
char buf[80] = {0};
|
||||
tFormatOffset(buf, 80, &dataRsp.rspOffset);
|
||||
tqDebug("tmq poll: consumer:0x%" PRIx64 ", subkey %s, vgId:%d, rsp block:%d, rsp offset type:%s, reqId:0x%" PRIx64 " code:%d",
|
||||
consumerId, pHandle->subKey, vgId, dataRsp.blockNum, buf, pRequest->reqId, code);
|
||||
taosWUnLockLatch(&pTq->lock);
|
||||
tDeleteSMqDataRsp(&dataRsp);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequest, SRpcMsg* pMsg, STqOffsetVal *offset) {
|
||||
int code = 0;
|
||||
int32_t vgId = TD_VID(pTq->pVnode);
|
||||
|
@ -277,11 +294,12 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
|
|||
|
||||
if (offset->type != TMQ_OFFSET__LOG) {
|
||||
if (tqScanTaosx(pTq, pHandle, &taosxRsp, &metaRsp, offset) < 0) {
|
||||
tDeleteSTaosxRsp(&taosxRsp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (metaRsp.metaRspLen > 0) {
|
||||
code = tqSendMetaPollRsp(pTq, pMsg, pRequest, &metaRsp);
|
||||
code = tqSendMetaPollRsp(pHandle, pMsg, pRequest, &metaRsp, vgId);
|
||||
tqDebug("tmq poll: consumer:0x%" PRIx64 " subkey:%s vgId:%d, send meta offset type:%d,uid:%" PRId64 ",ts:%" PRId64,
|
||||
pRequest->consumerId, pHandle->subKey, vgId, metaRsp.rspOffset.type, metaRsp.rspOffset.uid, metaRsp.rspOffset.ts);
|
||||
taosMemoryFree(metaRsp.metaRsp);
|
||||
|
@ -292,7 +310,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
|
|||
tqDebug("taosx poll: consumer:0x%" PRIx64 " subkey:%s vgId:%d, send data blockNum:%d, offset type:%d,uid:%" PRId64
|
||||
",ts:%" PRId64,pRequest->consumerId, pHandle->subKey, vgId, taosxRsp.blockNum, taosxRsp.rspOffset.type, taosxRsp.rspOffset.uid,taosxRsp.rspOffset.ts);
|
||||
if (taosxRsp.blockNum > 0) {
|
||||
code = tqSendDataRsp(pTq, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP);
|
||||
code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP, vgId);
|
||||
tDeleteSTaosxRsp(&taosxRsp);
|
||||
return code;
|
||||
}else {
|
||||
|
@ -300,7 +318,6 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (offset->type == TMQ_OFFSET__LOG) {
|
||||
int64_t fetchVer = offset->version + 1;
|
||||
pCkHead = taosMemoryMalloc(sizeof(SWalCkHead) + 2048);
|
||||
|
@ -315,13 +332,14 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
|
|||
int32_t savedEpoch = atomic_load_32(&pHandle->epoch);
|
||||
if (savedEpoch > pRequest->epoch) {
|
||||
tqWarn("tmq poll: consumer:0x%" PRIx64 " (epoch %d), subkey:%s vgId:%d offset %" PRId64
|
||||
", found new consumer epoch %d, discard req epoch %d", pRequest->consumerId, pRequest->epoch, pHandle->subKey, vgId, fetchVer, savedEpoch, pRequest->epoch);
|
||||
", found new consumer epoch %d, discard req epoch %d",
|
||||
pRequest->consumerId, pRequest->epoch, pHandle->subKey, vgId, fetchVer, savedEpoch, pRequest->epoch);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tqFetchLog(pTq, pHandle, &fetchVer, &pCkHead, pRequest->reqId) < 0) {
|
||||
tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer);
|
||||
code = tqSendDataRsp(pTq, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP);
|
||||
code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP, vgId);
|
||||
tDeleteSTaosxRsp(&taosxRsp);
|
||||
taosMemoryFreeClear(pCkHead);
|
||||
return code;
|
||||
|
@ -335,7 +353,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
|
|||
if (pHead->msgType != TDMT_VND_SUBMIT) {
|
||||
if(totalRows > 0) {
|
||||
tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer - 1);
|
||||
code = tqSendDataRsp(pTq, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP);
|
||||
code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP, vgId);
|
||||
tDeleteSTaosxRsp(&taosxRsp);
|
||||
taosMemoryFreeClear(pCkHead);
|
||||
return code;
|
||||
|
@ -346,12 +364,13 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
|
|||
metaRsp.resMsgType = pHead->msgType;
|
||||
metaRsp.metaRspLen = pHead->bodyLen;
|
||||
metaRsp.metaRsp = pHead->body;
|
||||
if (tqSendMetaPollRsp(pTq, pMsg, pRequest, &metaRsp) < 0) {
|
||||
if (tqSendMetaPollRsp(pHandle, pMsg, pRequest, &metaRsp, vgId) < 0) {
|
||||
code = -1;
|
||||
taosMemoryFreeClear(pCkHead);
|
||||
tDeleteSTaosxRsp(&taosxRsp);
|
||||
return code;
|
||||
}
|
||||
|
||||
code = 0;
|
||||
taosMemoryFreeClear(pCkHead);
|
||||
tDeleteSTaosxRsp(&taosxRsp);
|
||||
|
@ -375,7 +394,7 @@ static int32_t extractDataAndRspForDbStbSubscribe(STQ* pTq, STqHandle* pHandle,
|
|||
|
||||
if (totalRows >= 4096 || taosxRsp.createTableNum > 0) {
|
||||
tqOffsetResetToLog(&taosxRsp.rspOffset, fetchVer);
|
||||
code = tqSendDataRsp(pTq, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP);
|
||||
code = tqSendDataRsp(pHandle, pMsg, pRequest, (SMqDataRsp*)&taosxRsp, TMQ_MSG_TYPE__TAOSX_RSP, vgId);
|
||||
tDeleteSTaosxRsp(&taosxRsp);
|
||||
taosMemoryFreeClear(pCkHead);
|
||||
return code;
|
||||
|
@ -423,10 +442,19 @@ int32_t tqExtractDataForMq(STQ* pTq, STqHandle* pHandle, const SMqPollReq* pRequ
|
|||
return extractDataAndRspForDbStbSubscribe(pTq, pHandle, pRequest, pMsg, &offset);
|
||||
}
|
||||
|
||||
int32_t tqSendMetaPollRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqMetaRsp* pRsp) {
|
||||
static void initMqRspHead(SMqRspHead* pMsgHead, int32_t type, int32_t epoch, int64_t consumerId, int64_t sver,
|
||||
int64_t ever) {
|
||||
pMsgHead->consumerId = consumerId;
|
||||
pMsgHead->epoch = epoch;
|
||||
pMsgHead->mqMsgType = type;
|
||||
pMsgHead->walsver = sver;
|
||||
pMsgHead->walever = ever;
|
||||
}
|
||||
|
||||
int32_t tqSendMetaPollRsp(STqHandle* pHandle, const SRpcMsg* pMsg, const SMqPollReq* pReq, const SMqMetaRsp* pRsp, int32_t vgId) {
|
||||
int32_t len = 0;
|
||||
int32_t code = 0;
|
||||
tEncodeSize(tEncodeSMqMetaRsp, pRsp, len, code);
|
||||
tEncodeSize(tEncodeMqMetaRsp, pRsp, len, code);
|
||||
if (code < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -436,27 +464,64 @@ int32_t tqSendMetaPollRsp(STQ* pTq, const SRpcMsg* pMsg, const SMqPollReq* pReq,
|
|||
return -1;
|
||||
}
|
||||
|
||||
((SMqRspHead*)buf)->mqMsgType = TMQ_MSG_TYPE__POLL_META_RSP;
|
||||
((SMqRspHead*)buf)->epoch = pReq->epoch;
|
||||
((SMqRspHead*)buf)->consumerId = pReq->consumerId;
|
||||
int64_t sver = 0, ever = 0;
|
||||
walReaderValidVersionRange(pHandle->execHandle.pTqReader->pWalReader, &sver, &ever);
|
||||
initMqRspHead(buf, TMQ_MSG_TYPE__POLL_META_RSP, pReq->epoch, pReq->consumerId, sver, ever);
|
||||
|
||||
void* abuf = POINTER_SHIFT(buf, sizeof(SMqRspHead));
|
||||
|
||||
SEncoder encoder = {0};
|
||||
tEncoderInit(&encoder, abuf, len);
|
||||
tEncodeSMqMetaRsp(&encoder, pRsp);
|
||||
tEncodeMqMetaRsp(&encoder, pRsp);
|
||||
tEncoderClear(&encoder);
|
||||
|
||||
SRpcMsg resp = {
|
||||
.info = pMsg->info,
|
||||
.pCont = buf,
|
||||
.contLen = tlen,
|
||||
.code = 0,
|
||||
};
|
||||
tmsgSendRsp(&resp);
|
||||
SRpcMsg resp = { .info = pMsg->info, .pCont = buf, .contLen = tlen, .code = 0 };
|
||||
|
||||
tqDebug("vgId:%d, from consumer:0x%" PRIx64 " (epoch %d) send rsp, res msg type %d, offset type:%d",
|
||||
TD_VID(pTq->pVnode), pReq->consumerId, pReq->epoch, pRsp->resMsgType, pRsp->rspOffset.type);
|
||||
tmsgSendRsp(&resp);
|
||||
tqDebug("vgId:%d, from consumer:0x%" PRIx64 " (epoch %d) send rsp, res msg type %d, offset type:%d", vgId,
|
||||
pReq->consumerId, pReq->epoch, pRsp->resMsgType, pRsp->rspOffset.type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tqDoSendDataRsp(const SRpcHandleInfo* pRpcHandleInfo, const SMqDataRsp* pRsp, int32_t epoch, int64_t consumerId,
|
||||
int32_t type, int64_t sver, int64_t ever) {
|
||||
int32_t len = 0;
|
||||
int32_t code = 0;
|
||||
|
||||
if (type == TMQ_MSG_TYPE__POLL_RSP || type == TMQ_MSG_TYPE__WALINFO_RSP) {
|
||||
tEncodeSize(tEncodeMqDataRsp, pRsp, len, code);
|
||||
} else if (type == TMQ_MSG_TYPE__TAOSX_RSP) {
|
||||
tEncodeSize(tEncodeSTaosxRsp, (STaosxRsp*)pRsp, len, code);
|
||||
}
|
||||
|
||||
if (code < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t tlen = sizeof(SMqRspHead) + len;
|
||||
void* buf = rpcMallocCont(tlen);
|
||||
if (buf == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SMqRspHead* pHead = (SMqRspHead*)buf;
|
||||
initMqRspHead(pHead, type, epoch, consumerId, sver, ever);
|
||||
|
||||
void* abuf = POINTER_SHIFT(buf, sizeof(SMqRspHead));
|
||||
|
||||
SEncoder encoder = {0};
|
||||
tEncoderInit(&encoder, abuf, len);
|
||||
|
||||
if (type == TMQ_MSG_TYPE__POLL_RSP || type == TMQ_MSG_TYPE__WALINFO_RSP) {
|
||||
tEncodeMqDataRsp(&encoder, pRsp);
|
||||
} else if (type == TMQ_MSG_TYPE__TAOSX_RSP) {
|
||||
tEncodeSTaosxRsp(&encoder, (STaosxRsp*)pRsp);
|
||||
}
|
||||
|
||||
tEncoderClear(&encoder);
|
||||
SRpcMsg rsp = { .info = *pRpcHandleInfo, .pCont = buf, .contLen = tlen, .code = 0 };
|
||||
|
||||
tmsgSendRsp(&rsp);
|
||||
return 0;
|
||||
}
|
|
@ -1881,8 +1881,8 @@ static FORCE_INLINE STSchema* getLatestTableSchema(STsdbReader* pReader, uint64_
|
|||
return pReader->pSchema;
|
||||
}
|
||||
|
||||
pReader->pSchema = metaGetTbTSchema(pReader->pTsdb->pVnode->pMeta, uid, -1, 1);
|
||||
if (pReader->pSchema == NULL) {
|
||||
int32_t code = metaGetTbTSchemaEx(pReader->pTsdb->pVnode->pMeta, pReader->suid, uid, -1, &pReader->pSchema);
|
||||
if (code != TSDB_CODE_SUCCESS || pReader->pSchema == NULL) {
|
||||
tsdbError("failed to get table schema, uid:%" PRIu64 ", it may have been dropped, ver:-1, %s", uid, pReader->idStr);
|
||||
}
|
||||
|
||||
|
@ -1890,9 +1890,15 @@ static FORCE_INLINE STSchema* getLatestTableSchema(STsdbReader* pReader, uint64_
|
|||
}
|
||||
|
||||
static FORCE_INLINE STSchema* doGetSchemaForTSRow(int32_t sversion, STsdbReader* pReader, uint64_t uid) {
|
||||
int32_t code = 0;
|
||||
|
||||
// always set the newest schema version in pReader->pSchema
|
||||
if (pReader->pSchema == NULL) {
|
||||
pReader->pSchema = metaGetTbTSchema(pReader->pTsdb->pVnode->pMeta, uid, -1, 1);
|
||||
code = metaGetTbTSchemaEx(pReader->pTsdb->pVnode->pMeta, pReader->suid, uid, -1, &pReader->pSchema);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
terrno = code;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (pReader->pSchema && sversion == pReader->pSchema->version) {
|
||||
|
@ -1905,7 +1911,7 @@ static FORCE_INLINE STSchema* doGetSchemaForTSRow(int32_t sversion, STsdbReader*
|
|||
}
|
||||
|
||||
STSchema* ptr = NULL;
|
||||
int32_t code = metaGetTbTSchemaEx(pReader->pTsdb->pVnode->pMeta, pReader->suid, uid, sversion, &ptr);
|
||||
code = metaGetTbTSchemaEx(pReader->pTsdb->pVnode->pMeta, pReader->suid, uid, sversion, &ptr);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
terrno = code;
|
||||
return NULL;
|
||||
|
@ -1969,7 +1975,7 @@ static int32_t doMergeBufAndFileRows(STsdbReader* pReader, STableBlockScanInfo*
|
|||
// DESC: mem -----> imem -----> last block -----> file block
|
||||
if (pReader->order == TSDB_ORDER_ASC) {
|
||||
if (minKey == key) {
|
||||
init = true;
|
||||
init = true; // todo check if pReader->pSchema is null or not
|
||||
int32_t code = tsdbRowMergerInit(&merge, NULL, &fRow, pReader->pSchema);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
|
@ -2014,6 +2020,10 @@ static int32_t doMergeBufAndFileRows(STsdbReader* pReader, STableBlockScanInfo*
|
|||
if (minKey == k.ts) {
|
||||
init = true;
|
||||
STSchema* pSchema = doGetSchemaForTSRow(TSDBROW_SVERSION(pRow), pReader, pBlockScanInfo->uid);
|
||||
if (pSchema == NULL) {
|
||||
return terrno;
|
||||
}
|
||||
|
||||
int32_t code = tsdbRowMergerInit(&merge, NULL, pRow, pSchema);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
|
@ -2222,6 +2232,7 @@ static int32_t doMergeMultiLevelRows(STsdbReader* pReader, STableBlockScanInfo*
|
|||
if (pSchema == NULL) {
|
||||
return code;
|
||||
}
|
||||
|
||||
STSchema* piSchema = doGetSchemaForTSRow(TSDBROW_SVERSION(piRow), pReader, pBlockScanInfo->uid);
|
||||
if (piSchema == NULL) {
|
||||
return code;
|
||||
|
@ -3843,11 +3854,8 @@ int32_t doMergeMemTableMultiRows(TSDBROW* pRow, uint64_t uid, SIterInfo* pIter,
|
|||
return terrno;
|
||||
}
|
||||
|
||||
if (pReader->pSchema == NULL) {
|
||||
pReader->pSchema = pTSchema;
|
||||
}
|
||||
|
||||
code = tsdbRowMergerInit(&merge, pReader->pSchema, ¤t, pTSchema);
|
||||
STSchema* ps = (pReader->pSchema != NULL)? pReader->pSchema:pTSchema;
|
||||
code = tsdbRowMergerInit(&merge, ps, ¤t, pTSchema);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
@ -3891,7 +3899,14 @@ int32_t doMergeMemIMemRows(TSDBROW* pRow, TSDBROW* piRow, STableBlockScanInfo* p
|
|||
TSDBKEY k = TSDBROW_KEY(pRow);
|
||||
TSDBKEY ik = TSDBROW_KEY(piRow);
|
||||
STSchema* pSchema = doGetSchemaForTSRow(TSDBROW_SVERSION(pRow), pReader, pBlockScanInfo->uid);
|
||||
if (pSchema == NULL) {
|
||||
return terrno;
|
||||
}
|
||||
|
||||
STSchema* piSchema = doGetSchemaForTSRow(TSDBROW_SVERSION(piRow), pReader, pBlockScanInfo->uid);
|
||||
if (piSchema == NULL) {
|
||||
return terrno;
|
||||
}
|
||||
|
||||
if (ASCENDING_TRAVERSE(pReader->order)) { // ascending order imem --> mem
|
||||
int32_t code = tsdbRowMergerInit(&merge, pSchema, piRow, piSchema);
|
||||
|
@ -4000,10 +4015,11 @@ int32_t doAppendRowFromTSRow(SSDataBlock* pBlock, STsdbReader* pReader, SRow* pT
|
|||
int64_t uid = pScanInfo->uid;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
int32_t numOfCols = (int32_t)taosArrayGetSize(pBlock->pDataBlock);
|
||||
|
||||
SBlockLoadSuppInfo* pSupInfo = &pReader->suppInfo;
|
||||
STSchema* pSchema = doGetSchemaForTSRow(pTSRow->sver, pReader, uid);
|
||||
if (pSchema == NULL) {
|
||||
return terrno;
|
||||
}
|
||||
|
||||
SColVal colVal = {0};
|
||||
int32_t i = 0, j = 0;
|
||||
|
@ -5187,8 +5203,6 @@ int64_t tsdbGetNumOfRowsInMemTable(STsdbReader* pReader) {
|
|||
}
|
||||
|
||||
int32_t tsdbGetTableSchema(SVnode* pVnode, int64_t uid, STSchema** pSchema, int64_t* suid) {
|
||||
int32_t sversion = 1;
|
||||
|
||||
SMetaReader mr = {0};
|
||||
metaReaderInit(&mr, pVnode->pMeta, 0);
|
||||
int32_t code = metaGetTableEntryByUidCache(&mr, uid);
|
||||
|
@ -5200,6 +5214,7 @@ int32_t tsdbGetTableSchema(SVnode* pVnode, int64_t uid, STSchema** pSchema, int6
|
|||
|
||||
*suid = 0;
|
||||
|
||||
// only child table and ordinary table is allowed, super table is not allowed.
|
||||
if (mr.me.type == TSDB_CHILD_TABLE) {
|
||||
tDecoderClear(&mr.coder);
|
||||
*suid = mr.me.ctbEntry.suid;
|
||||
|
@ -5209,9 +5224,7 @@ int32_t tsdbGetTableSchema(SVnode* pVnode, int64_t uid, STSchema** pSchema, int6
|
|||
metaReaderClear(&mr);
|
||||
return terrno;
|
||||
}
|
||||
sversion = mr.me.stbEntry.schemaRow.version;
|
||||
} else if (mr.me.type == TSDB_NORMAL_TABLE) {
|
||||
sversion = mr.me.ntbEntry.schemaRow.version;
|
||||
} else if (mr.me.type == TSDB_NORMAL_TABLE) { // do nothing
|
||||
} else {
|
||||
terrno = TSDB_CODE_INVALID_PARA;
|
||||
metaReaderClear(&mr);
|
||||
|
@ -5219,9 +5232,10 @@ int32_t tsdbGetTableSchema(SVnode* pVnode, int64_t uid, STSchema** pSchema, int6
|
|||
}
|
||||
|
||||
metaReaderClear(&mr);
|
||||
*pSchema = metaGetTbTSchema(pVnode->pMeta, uid, sversion, 1);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
// get the newest table schema version
|
||||
code = metaGetTbTSchemaEx(pVnode->pMeta, *suid, uid, -1, pSchema);
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbTakeReadSnap(STsdbReader* pReader, _query_reseek_func_t reseek, STsdbReadSnap** ppSnap) {
|
||||
|
|
|
@ -60,19 +60,19 @@ int vnodeCheckCfg(const SVnodeCfg *pCfg) {
|
|||
const char* vnodeRoleToStr(ESyncRole role) {
|
||||
switch (role) {
|
||||
case TAOS_SYNC_ROLE_VOTER:
|
||||
return "voter";
|
||||
return "true";
|
||||
case TAOS_SYNC_ROLE_LEARNER:
|
||||
return "learner";
|
||||
return "false";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
const ESyncRole vnodeStrToRole(char* str) {
|
||||
if(strcmp(str, "voter") == 0){
|
||||
if(strcmp(str, "true") == 0){
|
||||
return TAOS_SYNC_ROLE_VOTER;
|
||||
}
|
||||
if(strcmp(str, "learner") == 0){
|
||||
if(strcmp(str, "false") == 0){
|
||||
return TAOS_SYNC_ROLE_LEARNER;
|
||||
}
|
||||
|
||||
|
@ -139,7 +139,6 @@ int vnodeEncodeConfig(const void *pObj, SJson *pJson) {
|
|||
if (tjsonAddIntegerToObject(pJson, "hashSuffix", pCfg->hashSuffix) < 0) return -1;
|
||||
|
||||
if (tjsonAddIntegerToObject(pJson, "syncCfg.replicaNum", pCfg->syncCfg.replicaNum) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "syncCfg.totalReplicaNum", pCfg->syncCfg.totalReplicaNum) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(pJson, "syncCfg.myIndex", pCfg->syncCfg.myIndex) < 0) return -1;
|
||||
|
||||
if (tjsonAddIntegerToObject(pJson, "vndStats.stables", pCfg->vndStats.numOfSTables) < 0) return -1;
|
||||
|
@ -161,7 +160,7 @@ int vnodeEncodeConfig(const void *pObj, SJson *pJson) {
|
|||
if (tjsonAddStringToObject(info, "nodeFqdn", pNode->nodeFqdn) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(info, "nodeId", pNode->nodeId) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(info, "clusterId", pNode->clusterId) < 0) return -1;
|
||||
if (tjsonAddStringToObject(info, "nodeRole", vnodeRoleToStr(pNode->nodeRole)) < 0) return -1;
|
||||
if (tjsonAddStringToObject(info, "isReplica", vnodeRoleToStr(pNode->nodeRole)) < 0) return -1;
|
||||
if (tjsonAddItemToArray(nodeInfo, info) < 0) return -1;
|
||||
vDebug("vgId:%d, encode config, replica:%d ep:%s:%u dnode:%d", pCfg->vgId, i, pNode->nodeFqdn, pNode->nodePort,
|
||||
pNode->nodeId);
|
||||
|
@ -259,8 +258,6 @@ int vnodeDecodeConfig(const SJson *pJson, void *pObj) {
|
|||
|
||||
tjsonGetNumberValue(pJson, "syncCfg.replicaNum", pCfg->syncCfg.replicaNum, code);
|
||||
if (code < 0) return -1;
|
||||
tjsonGetNumberValue(pJson, "syncCfg.totalReplicaNum", pCfg->syncCfg.totalReplicaNum, code);
|
||||
if (code < 0) return -1;
|
||||
tjsonGetNumberValue(pJson, "syncCfg.myIndex", pCfg->syncCfg.myIndex, code);
|
||||
if (code < 0) return -1;
|
||||
|
||||
|
@ -277,10 +274,7 @@ int vnodeDecodeConfig(const SJson *pJson, void *pObj) {
|
|||
|
||||
SJson *nodeInfo = tjsonGetObjectItem(pJson, "syncCfg.nodeInfo");
|
||||
int arraySize = tjsonGetArraySize(nodeInfo);
|
||||
if(pCfg->syncCfg.totalReplicaNum == 0 && pCfg->syncCfg.replicaNum > 0){
|
||||
pCfg->syncCfg.totalReplicaNum = pCfg->syncCfg.replicaNum;
|
||||
}
|
||||
if (arraySize != pCfg->syncCfg.totalReplicaNum) return -1;
|
||||
pCfg->syncCfg.totalReplicaNum = arraySize;
|
||||
|
||||
vDebug("vgId:%d, decode config, replicas:%d totalReplicas:%d selfIndex:%d", pCfg->vgId, pCfg->syncCfg.replicaNum,
|
||||
pCfg->syncCfg.totalReplicaNum, pCfg->syncCfg.myIndex);
|
||||
|
@ -296,7 +290,7 @@ int vnodeDecodeConfig(const SJson *pJson, void *pObj) {
|
|||
tjsonGetNumberValue(info, "clusterId", pNode->clusterId, code);
|
||||
if (code < 0) return -1;
|
||||
char role[10] = {0};
|
||||
code = tjsonGetStringValue(info, "nodeRole", role);
|
||||
code = tjsonGetStringValue(info, "isReplica", role);
|
||||
if (code < 0) return -1;
|
||||
if(strlen(role) != 0){
|
||||
pNode->nodeRole = vnodeStrToRole(role);
|
||||
|
|
|
@ -431,6 +431,10 @@ int32_t vnodeIsCatchUp(SVnode *pVnode){
|
|||
return syncIsCatchUp(pVnode->sync);
|
||||
}
|
||||
|
||||
ESyncRole vnodeGetRole(SVnode *pVnode){
|
||||
return syncGetRole(pVnode->sync);
|
||||
}
|
||||
|
||||
void vnodeStop(SVnode *pVnode) {}
|
||||
|
||||
int64_t vnodeGetSyncHandle(SVnode *pVnode) { return pVnode->sync; }
|
||||
|
|
|
@ -389,6 +389,11 @@ int32_t vnodeProcessWriteMsg(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRp
|
|||
goto _err;
|
||||
}
|
||||
break;
|
||||
case TDMT_VND_TMQ_SEEK_TO_OFFSET:
|
||||
if (tqProcessSeekReq(pVnode->pTq, version, pReq, pMsg->contLen - sizeof(SMsgHead)) < 0) {
|
||||
goto _err;
|
||||
}
|
||||
break;
|
||||
case TDMT_VND_TMQ_ADD_CHECKINFO:
|
||||
if (tqProcessAddCheckInfoReq(pVnode->pTq, version, pReq, len) < 0) {
|
||||
goto _err;
|
||||
|
@ -539,6 +544,8 @@ int32_t vnodeProcessFetchMsg(SVnode *pVnode, SRpcMsg *pMsg, SQueueInfo *pInfo) {
|
|||
return vnodeGetBatchMeta(pVnode, pMsg);
|
||||
case TDMT_VND_TMQ_CONSUME:
|
||||
return tqProcessPollReq(pVnode->pTq, pMsg);
|
||||
case TDMT_VND_TMQ_VG_WALINFO:
|
||||
return tqProcessVgWalInfoReq(pVnode->pTq, pMsg);
|
||||
case TDMT_STREAM_TASK_RUN:
|
||||
return tqProcessTaskRunReq(pVnode->pTq, pMsg);
|
||||
case TDMT_STREAM_TASK_DISPATCH:
|
||||
|
|
|
@ -547,7 +547,7 @@ static void vnodeRestoreFinish(const SSyncFSM *pFsm, const SyncIndex commitIdx)
|
|||
walApplyVer(pVnode->pWal, commitIdx);
|
||||
|
||||
pVnode->restored = true;
|
||||
vInfo("vgId:%d, sync restore finished", pVnode->config.vgId);
|
||||
vInfo("vgId:%d, sync restore finished, start to restore stream tasks by replay wal", pVnode->config.vgId);
|
||||
|
||||
// start to restore all stream tasks
|
||||
tqStartStreamTasks(pVnode->pTq);
|
||||
|
|
|
@ -108,6 +108,7 @@ uint64_t tableListGetSize(const STableListInfo* pTableList);
|
|||
uint64_t tableListGetSuid(const STableListInfo* pTableList);
|
||||
STableKeyInfo* tableListGetInfo(const STableListInfo* pTableList, int32_t index);
|
||||
int32_t tableListFind(const STableListInfo* pTableList, uint64_t uid, int32_t startIndex);
|
||||
void tableListGetSourceTableInfo(const STableListInfo* pTableList, uint64_t* psuid, uint64_t* uid, int32_t* type);
|
||||
|
||||
size_t getResultRowSize(struct SqlFunctionCtx* pCtx, int32_t numOfOutput);
|
||||
void initResultRowInfo(SResultRowInfo* pResultRowInfo);
|
||||
|
|
|
@ -366,6 +366,7 @@ typedef struct STagScanInfo {
|
|||
int32_t curPos;
|
||||
SReadHandle readHandle;
|
||||
STableListInfo* pTableListInfo;
|
||||
SLimitNode* pSlimit;
|
||||
} STagScanInfo;
|
||||
|
||||
typedef enum EStreamScanMode {
|
||||
|
@ -427,7 +428,6 @@ typedef struct STimeWindowAggSupp {
|
|||
} STimeWindowAggSupp;
|
||||
|
||||
typedef struct SStreamScanInfo {
|
||||
uint64_t tableUid; // queried super table uid
|
||||
SExprInfo* pPseudoExpr;
|
||||
int32_t numOfPseudoExpr;
|
||||
SExprSupp tbnameCalSup;
|
||||
|
|
|
@ -240,6 +240,7 @@ int32_t createDataDeleter(SDataSinkManager* pManager, const SDataSinkNode* pData
|
|||
|
||||
SDataDeleterHandle* deleter = taosMemoryCalloc(1, sizeof(SDataDeleterHandle));
|
||||
if (NULL == deleter) {
|
||||
taosMemoryFree(pParam);
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _end;
|
||||
}
|
||||
|
|
|
@ -408,6 +408,7 @@ int32_t createDataInserter(SDataSinkManager* pManager, const SDataSinkNode* pDat
|
|||
void* pParam) {
|
||||
SDataInserterHandle* inserter = taosMemoryCalloc(1, sizeof(SDataInserterHandle));
|
||||
if (NULL == inserter) {
|
||||
taosMemoryFree(pParam);
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
|
|
@ -27,15 +27,21 @@
|
|||
#include "executorimpl.h"
|
||||
#include "tcompression.h"
|
||||
|
||||
typedef struct STableListIdInfo {
|
||||
uint64_t suid;
|
||||
uint64_t uid;
|
||||
int32_t tableType;
|
||||
} STableListIdInfo;
|
||||
|
||||
// If the numOfOutputGroups is 1, the data blocks that belongs to different groups will be provided randomly
|
||||
// The numOfOutputGroups is specified by physical plan. and will not be affect by numOfGroups
|
||||
struct STableListInfo {
|
||||
bool oneTableForEachGroup;
|
||||
int32_t numOfOuputGroups; // the data block will be generated one by one
|
||||
int32_t* groupOffset; // keep the offset value for each group in the tableList
|
||||
SArray* pTableList;
|
||||
SHashObj* map; // speedup acquire the tableQueryInfo by table uid
|
||||
uint64_t suid;
|
||||
bool oneTableForEachGroup;
|
||||
int32_t numOfOuputGroups; // the data block will be generated one by one
|
||||
int32_t* groupOffset; // keep the offset value for each group in the tableList
|
||||
SArray* pTableList;
|
||||
SHashObj* map; // speedup acquire the tableQueryInfo by table uid
|
||||
STableListIdInfo idInfo; // this maybe the super table or ordinary table
|
||||
};
|
||||
|
||||
typedef struct tagFilterAssist {
|
||||
|
@ -470,7 +476,7 @@ int32_t getColInfoResultForGroupby(void* metaHandle, SNodeList* group, STableLis
|
|||
}
|
||||
|
||||
// int64_t stt = taosGetTimestampUs();
|
||||
code = metaGetTableTags(metaHandle, pTableListInfo->suid, pUidTagList);
|
||||
code = metaGetTableTags(metaHandle, pTableListInfo->idInfo.suid, pUidTagList);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto end;
|
||||
}
|
||||
|
@ -953,7 +959,7 @@ static int32_t doFilterByTagCond(STableListInfo* pListInfo, SArray* pUidList, SN
|
|||
|
||||
FilterCondType condType = checkTagCond(pTagCond);
|
||||
|
||||
int32_t filter = optimizeTbnameInCond(metaHandle, pListInfo->suid, pUidTagList, pTagCond);
|
||||
int32_t filter = optimizeTbnameInCond(metaHandle, pListInfo->idInfo.suid, pUidTagList, pTagCond);
|
||||
if (filter == 0) { // tbname in filter is activated, do nothing and return
|
||||
taosArrayClear(pUidList);
|
||||
|
||||
|
@ -966,12 +972,12 @@ static int32_t doFilterByTagCond(STableListInfo* pListInfo, SArray* pUidList, SN
|
|||
terrno = 0;
|
||||
} else {
|
||||
if ((condType == FILTER_NO_LOGIC || condType == FILTER_AND) && status != SFLT_NOT_INDEX) {
|
||||
code = metaGetTableTagsByUids(metaHandle, pListInfo->suid, pUidTagList);
|
||||
code = metaGetTableTagsByUids(metaHandle, pListInfo->idInfo.suid, pUidTagList);
|
||||
} else {
|
||||
code = metaGetTableTags(metaHandle, pListInfo->suid, pUidTagList);
|
||||
code = metaGetTableTags(metaHandle, pListInfo->idInfo.suid, pUidTagList);
|
||||
}
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("failed to get table tags from meta, reason:%s, suid:%" PRIu64, tstrerror(code), pListInfo->suid);
|
||||
qError("failed to get table tags from meta, reason:%s, suid:%" PRIu64, tstrerror(code), pListInfo->idInfo.suid);
|
||||
terrno = code;
|
||||
goto end;
|
||||
}
|
||||
|
@ -1025,15 +1031,17 @@ int32_t getTableList(void* metaHandle, void* pVnode, SScanPhysiNode* pScanNode,
|
|||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
size_t numOfTables = 0;
|
||||
|
||||
pListInfo->suid = pScanNode->suid;
|
||||
pListInfo->idInfo.suid = pScanNode->suid;
|
||||
pListInfo->idInfo.tableType = pScanNode->tableType;
|
||||
|
||||
SArray* pUidList = taosArrayInit(8, sizeof(uint64_t));
|
||||
|
||||
SIdxFltStatus status = SFLT_NOT_INDEX;
|
||||
if (pScanNode->tableType != TSDB_SUPER_TABLE) {
|
||||
pListInfo->idInfo.uid = pScanNode->uid;
|
||||
if (metaIsTableExist(metaHandle, pScanNode->uid)) {
|
||||
taosArrayPush(pUidList, &pScanNode->uid);
|
||||
}
|
||||
|
||||
code = doFilterByTagCond(pListInfo, pUidList, pTagCond, metaHandle, status);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _end;
|
||||
|
@ -1794,7 +1802,9 @@ uint64_t tableListGetSize(const STableListInfo* pTableList) {
|
|||
return taosArrayGetSize(pTableList->pTableList);
|
||||
}
|
||||
|
||||
uint64_t tableListGetSuid(const STableListInfo* pTableList) { return pTableList->suid; }
|
||||
uint64_t tableListGetSuid(const STableListInfo* pTableList) {
|
||||
return pTableList->idInfo.suid;
|
||||
}
|
||||
|
||||
STableKeyInfo* tableListGetInfo(const STableListInfo* pTableList, int32_t index) {
|
||||
if (taosArrayGetSize(pTableList->pTableList) == 0) {
|
||||
|
@ -1819,6 +1829,12 @@ int32_t tableListFind(const STableListInfo* pTableList, uint64_t uid, int32_t st
|
|||
return -1;
|
||||
}
|
||||
|
||||
void tableListGetSourceTableInfo(const STableListInfo* pTableList, uint64_t* psuid, uint64_t* uid, int32_t* type) {
|
||||
*psuid = pTableList->idInfo.suid;
|
||||
*uid = pTableList->idInfo.uid;
|
||||
*type = pTableList->idInfo.tableType;
|
||||
}
|
||||
|
||||
uint64_t getTableGroupId(const STableListInfo* pTableList, uint64_t tableUid) {
|
||||
int32_t* slot = taosHashGet(pTableList->map, &tableUid, sizeof(tableUid));
|
||||
ASSERT(pTableList->map != NULL && slot != NULL);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
*/
|
||||
|
||||
#include "executor.h"
|
||||
#include <vnode.h>
|
||||
#include "executorimpl.h"
|
||||
#include "planner.h"
|
||||
#include "tdatablock.h"
|
||||
|
@ -327,6 +328,13 @@ static SArray* filterUnqualifiedTables(const SStreamScanInfo* pScanInfo, const S
|
|||
return qa;
|
||||
}
|
||||
|
||||
STableScanInfo* pTableScanInfo = pScanInfo->pTableScanOp->info;
|
||||
|
||||
uint64_t suid = 0;
|
||||
uint64_t uid = 0;
|
||||
int32_t type = 0;
|
||||
tableListGetSourceTableInfo(pTableScanInfo->base.pTableListInfo, &suid, &uid, &type);
|
||||
|
||||
// let's discard the tables those are not created according to the queried super table.
|
||||
SMetaReader mr = {0};
|
||||
metaReaderInit(&mr, pScanInfo->readHandle.meta, 0);
|
||||
|
@ -341,9 +349,21 @@ static SArray* filterUnqualifiedTables(const SStreamScanInfo* pScanInfo, const S
|
|||
|
||||
tDecoderClear(&mr.coder);
|
||||
|
||||
// TODO handle ntb case
|
||||
if (mr.me.type != TSDB_CHILD_TABLE || mr.me.ctbEntry.suid != pScanInfo->tableUid) {
|
||||
if (mr.me.type == TSDB_SUPER_TABLE) {
|
||||
continue;
|
||||
} else {
|
||||
if (type == TSDB_SUPER_TABLE) {
|
||||
// this new created child table does not belong to the scanned super table.
|
||||
if (mr.me.type != TSDB_CHILD_TABLE || mr.me.ctbEntry.suid != suid) {
|
||||
continue;
|
||||
}
|
||||
} else { // ordinary table
|
||||
// In case that the scanned target table is an ordinary table. When replay the WAL during restore the vnode, we
|
||||
// should check all newly created ordinary table to make sure that this table isn't the destination table.
|
||||
if (mr.me.uid != uid) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pScanInfo->pTagCond != NULL) {
|
||||
|
@ -382,7 +402,7 @@ int32_t qUpdateTableListForStreamScanner(qTaskInfo_t tinfo, const SArray* tableI
|
|||
SStreamScanInfo* pScanInfo = pInfo->info;
|
||||
|
||||
if (isAdd) { // add new table id
|
||||
SArray* qa = filterUnqualifiedTables(pScanInfo, tableIdList, GET_TASKID(pTaskInfo));
|
||||
SArray* qa = filterUnqualifiedTables(pScanInfo, tableIdList, id);
|
||||
int32_t numOfQualifiedTables = taosArrayGetSize(qa);
|
||||
qDebug("%d qualified child tables added into stream scanner, %s", numOfQualifiedTables, id);
|
||||
code = tqReaderAddTbUidList(pScanInfo->tqReader, qa);
|
||||
|
@ -497,10 +517,8 @@ int32_t qCreateExecTask(SReadHandle* readHandle, int32_t vgId, uint64_t taskId,
|
|||
goto _error;
|
||||
}
|
||||
|
||||
// pSinkParam has been freed during create sinker.
|
||||
code = dsCreateDataSinker(pSubplan->pDataSink, handle, pSinkParam, (*pTask)->id.str);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
taosMemoryFreeClear(pSinkParam);
|
||||
}
|
||||
}
|
||||
|
||||
qDebug("subplan task create completed, TID:0x%" PRIx64 " QID:0x%" PRIx64, taskId, pSubplan->id.queryId);
|
||||
|
|
|
@ -871,9 +871,9 @@ SOperatorInfo* createPartitionOperatorInfo(SOperatorInfo* downstream, SPartition
|
|||
getBufferPgSize(pInfo->binfo.pRes->info.rowSize, &defaultPgsz, &defaultBufsz);
|
||||
|
||||
if (!osTempSpaceAvailable()) {
|
||||
terrno = TSDB_CODE_NO_AVAIL_DISK;
|
||||
terrno = TSDB_CODE_NO_DISKSPACE;
|
||||
pTaskInfo->code = terrno;
|
||||
qError("Create partition operator info failed since %s", terrstr(terrno));
|
||||
qError("Create partition operator info failed since %s, tempDir:%s", terrstr(), tsTempDir);
|
||||
goto _error;
|
||||
}
|
||||
|
||||
|
|
|
@ -690,7 +690,7 @@ static SSDataBlock* doTableScanImpl(SOperatorInfo* pOperator) {
|
|||
}
|
||||
|
||||
uint32_t status = 0;
|
||||
int32_t code = loadDataBlock(pOperator, &pTableScanInfo->base, pBlock, &status);
|
||||
code = loadDataBlock(pOperator, &pTableScanInfo->base, pBlock, &status);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
T_LONG_JMP(pTaskInfo->env, code);
|
||||
}
|
||||
|
@ -2441,7 +2441,6 @@ SOperatorInfo* createStreamScanOperatorInfo(SReadHandle* pHandle, STableScanPhys
|
|||
}
|
||||
|
||||
pInfo->readHandle = *pHandle;
|
||||
pInfo->tableUid = pScanPhyNode->uid;
|
||||
pTaskInfo->streamInfo.snapshotVer = pHandle->version;
|
||||
pInfo->pCreateTbRes = buildCreateTableBlock(&pInfo->tbnameCalSup, &pInfo->tagCalSup);
|
||||
blockDataEnsureCapacity(pInfo->pCreateTbRes, 8);
|
||||
|
@ -2513,6 +2512,51 @@ _error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void doTagScanOneTable(SOperatorInfo* pOperator, const SSDataBlock* pRes, int32_t count, SMetaReader* mr) {
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
STagScanInfo* pInfo = pOperator->info;
|
||||
SExprInfo* pExprInfo = &pOperator->exprSupp.pExprInfo[0];
|
||||
|
||||
STableKeyInfo* item = tableListGetInfo(pInfo->pTableListInfo, pInfo->curPos);
|
||||
int32_t code = metaGetTableEntryByUid(mr, item->uid);
|
||||
tDecoderClear(&(*mr).coder);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("failed to get table meta, uid:0x%" PRIx64 ", code:%s, %s", item->uid, tstrerror(terrno),
|
||||
GET_TASKID(pTaskInfo));
|
||||
metaReaderClear(mr);
|
||||
T_LONG_JMP(pTaskInfo->env, terrno);
|
||||
}
|
||||
|
||||
char str[512];
|
||||
for (int32_t j = 0; j < pOperator->exprSupp.numOfExprs; ++j) {
|
||||
SColumnInfoData* pDst = taosArrayGet(pRes->pDataBlock, pExprInfo[j].base.resSchema.slotId);
|
||||
|
||||
// refactor later
|
||||
if (fmIsScanPseudoColumnFunc(pExprInfo[j].pExpr->_function.functionId)) {
|
||||
STR_TO_VARSTR(str, (*mr).me.name);
|
||||
colDataSetVal(pDst, (count), str, false);
|
||||
} else { // it is a tag value
|
||||
STagVal val = {0};
|
||||
val.cid = pExprInfo[j].base.pParam[0].pCol->colId;
|
||||
const char* p = metaGetTableTagVal((*mr).me.ctbEntry.pTags, pDst->info.type, &val);
|
||||
|
||||
char* data = NULL;
|
||||
if (pDst->info.type != TSDB_DATA_TYPE_JSON && p != NULL) {
|
||||
data = tTagValToData((const STagVal*)p, false);
|
||||
} else {
|
||||
data = (char*)p;
|
||||
}
|
||||
colDataSetVal(pDst, (count), data,
|
||||
(data == NULL) || (pDst->info.type == TSDB_DATA_TYPE_JSON && tTagIsJsonNull(data)));
|
||||
|
||||
if (pDst->info.type != TSDB_DATA_TYPE_JSON && p != NULL && IS_VAR_DATA_TYPE(((const STagVal*)p)->type) &&
|
||||
data != NULL) {
|
||||
taosMemoryFree(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static SSDataBlock* doTagScan(SOperatorInfo* pOperator) {
|
||||
if (pOperator->status == OP_EXEC_DONE) {
|
||||
return NULL;
|
||||
|
@ -2537,48 +2581,22 @@ static SSDataBlock* doTagScan(SOperatorInfo* pOperator) {
|
|||
metaReaderInit(&mr, pInfo->readHandle.meta, 0);
|
||||
|
||||
while (pInfo->curPos < size && count < pOperator->resultInfo.capacity) {
|
||||
STableKeyInfo* item = tableListGetInfo(pInfo->pTableListInfo, pInfo->curPos);
|
||||
int32_t code = metaGetTableEntryByUid(&mr, item->uid);
|
||||
tDecoderClear(&mr.coder);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("failed to get table meta, uid:0x%" PRIx64 ", code:%s, %s", item->uid, tstrerror(terrno),
|
||||
GET_TASKID(pTaskInfo));
|
||||
metaReaderClear(&mr);
|
||||
T_LONG_JMP(pTaskInfo->env, terrno);
|
||||
}
|
||||
|
||||
for (int32_t j = 0; j < pOperator->exprSupp.numOfExprs; ++j) {
|
||||
SColumnInfoData* pDst = taosArrayGet(pRes->pDataBlock, pExprInfo[j].base.resSchema.slotId);
|
||||
|
||||
// refactor later
|
||||
if (fmIsScanPseudoColumnFunc(pExprInfo[j].pExpr->_function.functionId)) {
|
||||
STR_TO_VARSTR(str, mr.me.name);
|
||||
colDataSetVal(pDst, count, str, false);
|
||||
} else { // it is a tag value
|
||||
STagVal val = {0};
|
||||
val.cid = pExprInfo[j].base.pParam[0].pCol->colId;
|
||||
const char* p = metaGetTableTagVal(mr.me.ctbEntry.pTags, pDst->info.type, &val);
|
||||
|
||||
char* data = NULL;
|
||||
if (pDst->info.type != TSDB_DATA_TYPE_JSON && p != NULL) {
|
||||
data = tTagValToData((const STagVal*)p, false);
|
||||
} else {
|
||||
data = (char*)p;
|
||||
}
|
||||
colDataSetVal(pDst, count, data,
|
||||
(data == NULL) || (pDst->info.type == TSDB_DATA_TYPE_JSON && tTagIsJsonNull(data)));
|
||||
|
||||
if (pDst->info.type != TSDB_DATA_TYPE_JSON && p != NULL && IS_VAR_DATA_TYPE(((const STagVal*)p)->type) &&
|
||||
data != NULL) {
|
||||
taosMemoryFree(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
count += 1;
|
||||
doTagScanOneTable(pOperator, pRes, count, &mr);
|
||||
++count;
|
||||
if (++pInfo->curPos >= size) {
|
||||
setOperatorCompleted(pOperator);
|
||||
}
|
||||
// each table with tbname is a group, hence its own block, but only group when slimit exists for performance reason.
|
||||
if (pInfo->pSlimit != NULL) {
|
||||
if (pInfo->curPos < pInfo->pSlimit->offset) {
|
||||
continue;
|
||||
}
|
||||
pInfo->pRes->info.id.groupId = calcGroupId(mr.me.name, strlen(mr.me.name));
|
||||
if (pInfo->curPos >= (pInfo->pSlimit->offset + pInfo->pSlimit->limit) - 1) {
|
||||
setOperatorCompleted(pOperator);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
metaReaderClear(&mr);
|
||||
|
@ -2629,6 +2647,7 @@ SOperatorInfo* createTagScanOperatorInfo(SReadHandle* pReadHandle, STagScanPhysi
|
|||
pInfo->pRes = createDataBlockFromDescNode(pDescNode);
|
||||
pInfo->readHandle = *pReadHandle;
|
||||
pInfo->curPos = 0;
|
||||
pInfo->pSlimit = (SLimitNode*)pPhyNode->node.pSlimit; //TODO: slimit now only indicate group
|
||||
|
||||
setOperatorInfo(pOperator, "TagScanOperator", QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN, false, OP_NOT_OPENED, pInfo,
|
||||
pTaskInfo);
|
||||
|
|
|
@ -2911,8 +2911,8 @@ int32_t initStreamAggSupporter(SStreamAggSupporter* pSup, SqlFunctionCtx* pCtx,
|
|||
bufSize = pageSize * 4;
|
||||
}
|
||||
if (!osTempSpaceAvailable()) {
|
||||
terrno = TSDB_CODE_NO_AVAIL_DISK;
|
||||
qError("Init stream agg supporter failed since %s", terrstr(terrno));
|
||||
terrno = TSDB_CODE_NO_DISKSPACE;
|
||||
qError("Init stream agg supporter failed since %s, tempDir:%s", terrstr(), tsTempDir);
|
||||
return terrno;
|
||||
}
|
||||
int32_t code = createDiskbasedBuf(&pSup->pResultBuf, pageSize, bufSize, "function", tsTempDir);
|
||||
|
|
|
@ -248,8 +248,8 @@ SLHashObj* tHashInit(int32_t inMemPages, int32_t pageSize, _hash_fn_t fn, int32_
|
|||
}
|
||||
|
||||
if (!osTempSpaceAvailable()) {
|
||||
terrno = TSDB_CODE_NO_AVAIL_DISK;
|
||||
printf("tHash Init failed since %s", terrstr(terrno));
|
||||
terrno = TSDB_CODE_NO_DISKSPACE;
|
||||
printf("tHash Init failed since %s, tempDir:%s", terrstr(), tsTempDir);
|
||||
taosMemoryFree(pHashObj);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -195,8 +195,8 @@ static int32_t doAddToBuf(SSDataBlock* pDataBlock, SSortHandle* pHandle) {
|
|||
|
||||
if (pHandle->pBuf == NULL) {
|
||||
if (!osTempSpaceAvailable()) {
|
||||
terrno = TSDB_CODE_NO_AVAIL_DISK;
|
||||
qError("Add to buf failed since %s", terrstr(terrno));
|
||||
terrno = TSDB_CODE_NO_DISKSPACE;
|
||||
qError("Add to buf failed since %s, tempDir:%s", terrstr(), tsTempDir);
|
||||
return terrno;
|
||||
}
|
||||
|
||||
|
@ -261,9 +261,8 @@ static int32_t sortComparInit(SMsortComparParam* pParam, SArray* pSources, int32
|
|||
// multi-pass internal merge sort is required
|
||||
if (pHandle->pBuf == NULL) {
|
||||
if (!osTempSpaceAvailable()) {
|
||||
code = TSDB_CODE_NO_AVAIL_DISK;
|
||||
terrno = code;
|
||||
qError("Sort compare init failed since %s, %s", tstrerror(code), pHandle->idStr);
|
||||
code = terrno = TSDB_CODE_NO_DISKSPACE;
|
||||
qError("Sort compare init failed since %s, tempDir:%s, idStr:%s", terrstr(), tsTempDir, pHandle->idStr);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
|
@ -855,7 +855,9 @@ int32_t setSelectivityValue(SqlFunctionCtx* pCtx, SSDataBlock* pBlock, const STu
|
|||
int32_t numOfCols = pCtx->subsidiaries.num;
|
||||
const char* p = loadTupleData(pCtx, pTuplePos);
|
||||
if (p == NULL) {
|
||||
terrno = TSDB_CODE_NO_AVAIL_DISK;
|
||||
terrno = TSDB_CODE_NOT_FOUND;
|
||||
qError("Load tuple data failed since %s, groupId:%" PRIu64 ", ts:%" PRId64, terrstr(),
|
||||
pTuplePos->streamTupleKey.groupId, pTuplePos->streamTupleKey.ts);
|
||||
return terrno;
|
||||
}
|
||||
|
||||
|
@ -5098,7 +5100,9 @@ int32_t modeFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
|||
if (maxCount != 0) {
|
||||
const char* pData = loadTupleData(pCtx, &resDataPos);
|
||||
if (pData == NULL) {
|
||||
code = TSDB_CODE_NO_AVAIL_DISK;
|
||||
code = terrno = TSDB_CODE_NOT_FOUND;
|
||||
qError("Load tuple data failed since %s, groupId:%" PRIu64 ", ts:%" PRId64, terrstr(),
|
||||
resDataPos.streamTupleKey.groupId, resDataPos.streamTupleKey.ts);
|
||||
modeFunctionCleanup(pInfo);
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -277,7 +277,7 @@ tMemBucket *tMemBucketCreate(int16_t nElemSize, int16_t dataType, double minval,
|
|||
resetSlotInfo(pBucket);
|
||||
|
||||
if (!osTempSpaceAvailable()) {
|
||||
terrno = TSDB_CODE_NO_AVAIL_DISK;
|
||||
terrno = TSDB_CODE_NO_DISKSPACE;
|
||||
// qError("MemBucket create disk based Buf failed since %s", terrstr(terrno));
|
||||
tMemBucketDestroy(pBucket);
|
||||
return NULL;
|
||||
|
|
|
@ -1580,7 +1580,7 @@ int32_t udfcStartUvTask(SClientUvTaskNode *uvTask) {
|
|||
case UV_TASK_REQ_RSP: {
|
||||
uv_pipe_t *pipe = uvTask->pipe;
|
||||
if (pipe == NULL) {
|
||||
code = TSDB_CODE_UDF_PIPE_NO_PIPE;
|
||||
code = TSDB_CODE_UDF_PIPE_NOT_EXIST;
|
||||
} else {
|
||||
uv_write_t *write = taosMemoryMalloc(sizeof(uv_write_t));
|
||||
write->data = pipe->data;
|
||||
|
@ -1598,7 +1598,7 @@ int32_t udfcStartUvTask(SClientUvTaskNode *uvTask) {
|
|||
case UV_TASK_DISCONNECT: {
|
||||
uv_pipe_t *pipe = uvTask->pipe;
|
||||
if (pipe == NULL) {
|
||||
code = TSDB_CODE_UDF_PIPE_NO_PIPE;
|
||||
code = TSDB_CODE_UDF_PIPE_NOT_EXIST;
|
||||
} else {
|
||||
SClientUvConn *conn = pipe->data;
|
||||
QUEUE_INSERT_TAIL(&conn->taskQueue, &uvTask->connTaskQueue);
|
||||
|
@ -1759,9 +1759,6 @@ int32_t udfcRunUdfUvTask(SClientUdfTask *task, int8_t uvTaskType) {
|
|||
}
|
||||
|
||||
int32_t doSetupUdf(char udfName[], UdfcFuncHandle *funcHandle) {
|
||||
if (gUdfcProxy.udfcState != UDFC_STATE_READY) {
|
||||
return TSDB_CODE_UDF_INVALID_STATE;
|
||||
}
|
||||
SClientUdfTask *task = taosMemoryCalloc(1, sizeof(SClientUdfTask));
|
||||
task->errCode = 0;
|
||||
task->session = taosMemoryCalloc(1, sizeof(SUdfcUvSession));
|
||||
|
@ -1804,7 +1801,7 @@ int32_t callUdf(UdfcFuncHandle handle, int8_t callType, SSDataBlock *input, SUdf
|
|||
SUdfcUvSession *session = (SUdfcUvSession *)handle;
|
||||
if (session->udfUvPipe == NULL) {
|
||||
fnError("No pipe to udfd");
|
||||
return TSDB_CODE_UDF_PIPE_NO_PIPE;
|
||||
return TSDB_CODE_UDF_PIPE_NOT_EXIST;
|
||||
}
|
||||
SClientUdfTask *task = taosMemoryCalloc(1, sizeof(SClientUdfTask));
|
||||
task->errCode = 0;
|
||||
|
@ -1928,7 +1925,7 @@ int32_t doTeardownUdf(UdfcFuncHandle handle) {
|
|||
if (session->udfUvPipe == NULL) {
|
||||
fnError("tear down udf. pipe to udfd does not exist. udf name: %s", session->udfName);
|
||||
taosMemoryFree(session);
|
||||
return TSDB_CODE_UDF_PIPE_NO_PIPE;
|
||||
return TSDB_CODE_UDF_PIPE_NOT_EXIST;
|
||||
}
|
||||
|
||||
SClientUdfTask *task = taosMemoryCalloc(1, sizeof(SClientUdfTask));
|
||||
|
|
|
@ -844,7 +844,7 @@ void udfdGetFuncBodyPath(const SUdf *udf, char *path) {
|
|||
|
||||
int32_t udfdSaveFuncBodyToFile(SFuncInfo *pFuncInfo, SUdf *udf) {
|
||||
if (!osDataSpaceAvailable()) {
|
||||
terrno = TSDB_CODE_NO_AVAIL_DISK;
|
||||
terrno = TSDB_CODE_NO_DISKSPACE;
|
||||
fnError("udfd create shared library failed since %s", terrstr(terrno));
|
||||
return terrno;
|
||||
}
|
||||
|
|
|
@ -251,7 +251,7 @@ int32_t qBindStmtColsValue(void* pBlock, TAOS_MULTI_BIND* bind, char* msgBuf, in
|
|||
goto _return;
|
||||
}
|
||||
|
||||
if (bind[c].buffer_type != pColSchema->type) {
|
||||
if ((!(rowNum == 1 && bind[c].is_null && *bind[c].is_null)) && bind[c].buffer_type != pColSchema->type) { // for rowNum ==1 , connector may not set buffer_type
|
||||
code = buildInvalidOperationMsg(&pBuf, "column type mis-match with buffer type");
|
||||
goto _return;
|
||||
}
|
||||
|
|
|
@ -2418,6 +2418,36 @@ static bool tagScanOptShouldBeOptimized(SLogicNode* pNode) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static SLogicNode* tagScanOptFindAncestorWithSlimit(SLogicNode* pTableScanNode) {
|
||||
SLogicNode* pNode = pTableScanNode->pParent;
|
||||
while (NULL != pNode) {
|
||||
if (QUERY_NODE_LOGIC_PLAN_PARTITION == nodeType(pNode) || QUERY_NODE_LOGIC_PLAN_AGG == nodeType(pNode) ||
|
||||
QUERY_NODE_LOGIC_PLAN_WINDOW == nodeType(pNode) || QUERY_NODE_LOGIC_PLAN_SORT == nodeType(pNode)) {
|
||||
return NULL;
|
||||
}
|
||||
if (NULL != pNode->pSlimit) {
|
||||
return pNode;
|
||||
}
|
||||
pNode = pNode->pParent;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void tagScanOptCloneAncestorSlimit(SLogicNode* pTableScanNode) {
|
||||
if (NULL != pTableScanNode->pSlimit) {
|
||||
return;
|
||||
}
|
||||
|
||||
SLogicNode* pNode = tagScanOptFindAncestorWithSlimit(pTableScanNode);
|
||||
if (NULL != pNode) {
|
||||
//TODO: only set the slimit now. push down slimit later
|
||||
pTableScanNode->pSlimit = nodesCloneNode(pNode->pSlimit);
|
||||
((SLimitNode*)pTableScanNode->pSlimit)->limit += ((SLimitNode*)pTableScanNode->pSlimit)->offset;
|
||||
((SLimitNode*)pTableScanNode->pSlimit)->offset = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static int32_t tagScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) {
|
||||
SScanLogicNode* pScanNode = (SScanLogicNode*)optFindPossibleNode(pLogicSubplan->pNode, tagScanOptShouldBeOptimized);
|
||||
if (NULL == pScanNode) {
|
||||
|
@ -2458,6 +2488,7 @@ static int32_t tagScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubp
|
|||
NODES_CLEAR_LIST(pAgg->pChildren);
|
||||
}
|
||||
nodesDestroyNode((SNode*)pAgg);
|
||||
tagScanOptCloneAncestorSlimit((SLogicNode*)pScanNode);
|
||||
pCxt->optimized = true;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "streamInc.h"
|
||||
#include "ttimer.h"
|
||||
|
||||
#define STREAM_TASK_INPUT_QUEUEU_CAPACITY 2000
|
||||
#define STREAM_TASK_INPUT_QUEUEU_CAPACITY 100000
|
||||
|
||||
int32_t streamInit() {
|
||||
int8_t old;
|
||||
|
@ -353,3 +353,7 @@ void* streamQueueNextItem(SStreamQueue* queue) {
|
|||
return streamQueueCurItem(queue);
|
||||
}
|
||||
}
|
||||
|
||||
void streamTaskInputFail(SStreamTask* pTask) {
|
||||
atomic_store_8(&pTask->inputStatus, TASK_INPUT_STATUS__FAILED);
|
||||
}
|
|
@ -230,23 +230,21 @@ int32_t streamDispatchOneCheckReq(SStreamTask* pTask, const SStreamTaskCheckReq*
|
|||
SEncoder encoder;
|
||||
tEncoderInit(&encoder, abuf, tlen);
|
||||
if ((code = tEncodeSStreamTaskCheckReq(&encoder, pReq)) < 0) {
|
||||
goto FAIL;
|
||||
rpcFreeCont(buf);
|
||||
return code;
|
||||
}
|
||||
|
||||
tEncoderClear(&encoder);
|
||||
|
||||
msg.contLen = tlen + sizeof(SMsgHead);
|
||||
msg.pCont = buf;
|
||||
msg.msgType = TDMT_STREAM_TASK_CHECK;
|
||||
|
||||
qDebug("dispatch from s-task:%s to downstream s-task:%"PRIx64":%d node %d: check msg", pTask->id.idStr,
|
||||
pReq->streamId, pReq->downstreamTaskId, nodeId);
|
||||
qDebug("dispatch from s-task:%s to downstream s-task:%" PRIx64 ":%d node %d: check msg", pTask->id.idStr,
|
||||
pReq->streamId, pReq->downstreamTaskId, nodeId);
|
||||
|
||||
tmsgSendReq(pEpSet, &msg);
|
||||
|
||||
return 0;
|
||||
FAIL:
|
||||
if (buf) rpcFreeCont(buf);
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t streamDispatchOneRecoverFinishReq(SStreamTask* pTask, const SStreamRecoverFinishReq* pReq, int32_t vgId,
|
||||
|
|
|
@ -189,7 +189,10 @@ int32_t streamScanExec(SStreamTask* pTask, int32_t batchSz) {
|
|||
qDebug("task %d scan exec dispatch block num %d", pTask->id.taskId, batchCnt);
|
||||
streamDispatch(pTask);
|
||||
}
|
||||
if (finished) break;
|
||||
|
||||
if (finished) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -296,8 +296,7 @@ int32_t streamLoadTasks(SStreamMeta* pMeta, int64_t ver) {
|
|||
tDecodeStreamTask(&decoder, pTask);
|
||||
tDecoderClear(&decoder);
|
||||
|
||||
// todo set correct initial version.
|
||||
if (pMeta->expandFunc(pMeta->ahandle, pTask, 0) < 0) {
|
||||
if (pMeta->expandFunc(pMeta->ahandle, pTask, pTask->chkInfo.version) < 0) {
|
||||
tdbFree(pKey);
|
||||
tdbFree(pVal);
|
||||
tdbTbcClose(pCur);
|
||||
|
|
|
@ -102,8 +102,10 @@ int32_t streamRecheckOneDownstream(SStreamTask* pTask, const SStreamTaskCheckRsp
|
|||
.downstreamNodeId = pRsp->downstreamNodeId,
|
||||
.childId = pRsp->childId,
|
||||
};
|
||||
qDebug("task %d at node %d check downstream task %d at node %d (recheck)", pTask->id.taskId, pTask->nodeId,
|
||||
|
||||
qDebug("s-task:%s at node %d check downstream task %d at node %d (recheck)", pTask->id.idStr, pTask->nodeId,
|
||||
req.downstreamTaskId, req.downstreamNodeId);
|
||||
|
||||
if (pTask->outputType == TASK_OUTPUT__FIXED_DISPATCH) {
|
||||
streamDispatchOneCheckReq(pTask, &req, pRsp->downstreamNodeId, &pTask->fixedEpDispatcher.epSet);
|
||||
} else if (pTask->outputType == TASK_OUTPUT__SHUFFLE_DISPATCH) {
|
||||
|
@ -116,6 +118,7 @@ int32_t streamRecheckOneDownstream(SStreamTask* pTask, const SStreamTaskCheckRsp
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -158,9 +161,10 @@ int32_t streamProcessTaskCheckRsp(SStreamTask* pTask, const SStreamTaskCheckRsp*
|
|||
} else {
|
||||
ASSERT(0);
|
||||
}
|
||||
} else {
|
||||
} else { // not ready, it should wait for at least 100ms and then retry
|
||||
streamRecheckOneDownstream(pTask, pRsp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -75,10 +75,12 @@ bool syncNodeAgreedUpon(SSyncNode* pNode, SyncIndex index) {
|
|||
SSyncIndexMgr* pMatches = pNode->pMatchIndex;
|
||||
ASSERT(pNode->replicaNum == pMatches->replicaNum);
|
||||
|
||||
for (int i = 0; i < pNode->replicaNum; i++) {
|
||||
SyncIndex matchIndex = pMatches->index[i];
|
||||
if (matchIndex >= index) {
|
||||
count++;
|
||||
for (int i = 0; i < pNode->totalReplicaNum; i++) {
|
||||
if(pNode->raftCfg.cfg.nodeInfo[i].nodeRole == TAOS_SYNC_ROLE_VOTER){
|
||||
SyncIndex matchIndex = pMatches->index[i];
|
||||
if (matchIndex >= index) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -463,8 +463,7 @@ bool syncSnapshotRecving(int64_t rid) {
|
|||
int32_t syncNodeLeaderTransfer(SSyncNode* pSyncNode) {
|
||||
if (pSyncNode->peersNum == 0) {
|
||||
sDebug("vgId:%d, only one replica, cannot leader transfer", pSyncNode->vgId);
|
||||
terrno = TSDB_CODE_SYN_ONE_REPLICA;
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ret = 0;
|
||||
|
@ -486,7 +485,6 @@ int32_t syncNodeLeaderTransfer(SSyncNode* pSyncNode) {
|
|||
int32_t syncNodeLeaderTransferTo(SSyncNode* pSyncNode, SNodeInfo newLeader) {
|
||||
if (pSyncNode->replicaNum == 1) {
|
||||
sDebug("vgId:%d, only one replica, cannot leader transfer", pSyncNode->vgId);
|
||||
terrno = TSDB_CODE_SYN_ONE_REPLICA;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -580,25 +578,37 @@ int32_t syncIsCatchUp(int64_t rid) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
while(1){
|
||||
if(pSyncNode->pLogBuf->totalIndex < 0 || pSyncNode->pLogBuf->commitIndex < 0 ||
|
||||
pSyncNode->pLogBuf->totalIndex < pSyncNode->pLogBuf->commitIndex ||
|
||||
pSyncNode->pLogBuf->totalIndex - pSyncNode->pLogBuf->commitIndex > SYNC_LEARNER_CATCHUP){
|
||||
sInfo("vgId:%d, Not catch up, wait one second, totalIndex:%" PRId64 " commitIndex:%" PRId64 " matchIndex:%" PRId64,
|
||||
pSyncNode->vgId, pSyncNode->pLogBuf->totalIndex, pSyncNode->pLogBuf->commitIndex,
|
||||
pSyncNode->pLogBuf->matchIndex);
|
||||
taosSsleep(1);
|
||||
}
|
||||
else{
|
||||
sInfo("vgId:%d, Catch up, totalIndex:%" PRId64 " commitIndex:%" PRId64 " matchIndex:%" PRId64,
|
||||
pSyncNode->vgId, pSyncNode->pLogBuf->totalIndex, pSyncNode->pLogBuf->commitIndex,
|
||||
pSyncNode->pLogBuf->matchIndex);
|
||||
break;
|
||||
}
|
||||
int32_t isCatchUp = 0;
|
||||
if(pSyncNode->pLogBuf->totalIndex < 0 || pSyncNode->pLogBuf->commitIndex < 0 ||
|
||||
pSyncNode->pLogBuf->totalIndex < pSyncNode->pLogBuf->commitIndex ||
|
||||
pSyncNode->pLogBuf->totalIndex - pSyncNode->pLogBuf->commitIndex > SYNC_LEARNER_CATCHUP){
|
||||
sInfo("vgId:%d, Not catch up, wait one second, totalIndex:%" PRId64 " commitIndex:%" PRId64 " matchIndex:%" PRId64,
|
||||
pSyncNode->vgId, pSyncNode->pLogBuf->totalIndex, pSyncNode->pLogBuf->commitIndex,
|
||||
pSyncNode->pLogBuf->matchIndex);
|
||||
isCatchUp = 0;
|
||||
}
|
||||
else{
|
||||
sInfo("vgId:%d, Catch up, totalIndex:%" PRId64 " commitIndex:%" PRId64 " matchIndex:%" PRId64,
|
||||
pSyncNode->vgId, pSyncNode->pLogBuf->totalIndex, pSyncNode->pLogBuf->commitIndex,
|
||||
pSyncNode->pLogBuf->matchIndex);
|
||||
isCatchUp = 1;
|
||||
}
|
||||
|
||||
syncNodeRelease(pSyncNode);
|
||||
return 0;
|
||||
return isCatchUp;
|
||||
}
|
||||
|
||||
ESyncRole syncGetRole(int64_t rid) {
|
||||
SSyncNode* pSyncNode = syncNodeAcquire(rid);
|
||||
if (pSyncNode == NULL) {
|
||||
sError("sync Node Acquire error since %d", errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ESyncRole role = pSyncNode->raftCfg.cfg.nodeInfo[pSyncNode->raftCfg.cfg.myIndex].nodeRole;
|
||||
|
||||
syncNodeRelease(pSyncNode);
|
||||
return role;
|
||||
}
|
||||
|
||||
int32_t syncNodePropose(SSyncNode* pSyncNode, SRpcMsg* pMsg, bool isWeak, int64_t* seq) {
|
||||
|
@ -2144,7 +2154,7 @@ static void syncNodeEqPeerHeartbeatTimer(void* param, void* tmrId) {
|
|||
|
||||
SSyncHbTimerData* pData = syncHbTimerDataAcquire(hbDataRid);
|
||||
if (pData == NULL) {
|
||||
sError("hb timer get pData NULL, rid:%" PRId64 " addr:%" PRId64, hbDataRid, pData->destId.addr);
|
||||
sError("hb timer get pData NULL, %" PRId64, hbDataRid);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2414,18 +2424,19 @@ int32_t syncNodeOnHeartbeat(SSyncNode* ths, const SRpcMsg* pRpcMsg) {
|
|||
(void)syncBuildLocalCmd(&rpcMsgLocalCmd, ths->vgId);
|
||||
|
||||
SyncLocalCmd* pSyncMsg = rpcMsgLocalCmd.pCont;
|
||||
pSyncMsg->cmd = SYNC_LOCAL_CMD_FOLLOWER_CMT;
|
||||
pSyncMsg->cmd =
|
||||
(ths->state == TAOS_SYNC_STATE_LEARNER) ? SYNC_LOCAL_CMD_LEARNER_CMT : SYNC_LOCAL_CMD_FOLLOWER_CMT;
|
||||
pSyncMsg->commitIndex = pMsg->commitIndex;
|
||||
pSyncMsg->currentTerm = pMsg->term;
|
||||
SyncIndex fcIndex = pSyncMsg->commitIndex;
|
||||
|
||||
if (ths->syncEqMsg != NULL && ths->msgcb != NULL) {
|
||||
int32_t code = ths->syncEqMsg(ths->msgcb, &rpcMsgLocalCmd);
|
||||
if (code != 0) {
|
||||
sError("vgId:%d, sync enqueue fc-commit msg error, code:%d", ths->vgId, code);
|
||||
sError("vgId:%d, failed to enqueue commit msg from heartbeat since %s, code:%d", ths->vgId, terrstr(), code);
|
||||
rpcFreeCont(rpcMsgLocalCmd.pCont);
|
||||
} else {
|
||||
sTrace("vgId:%d, sync enqueue fc-commit msg, fc-index:%" PRId64, ths->vgId, fcIndex);
|
||||
sTrace("vgId:%d, enqueue commit msg from heartbeat, commit-index:%" PRId64 ", term:%" PRId64, ths->vgId,
|
||||
pMsg->commitIndex, pMsg->term);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2446,27 +2457,7 @@ int32_t syncNodeOnHeartbeat(SSyncNode* ths, const SRpcMsg* pRpcMsg) {
|
|||
sError("vgId:%d, sync enqueue step-down msg error, code:%d", ths->vgId, code);
|
||||
rpcFreeCont(rpcMsgLocalCmd.pCont);
|
||||
} else {
|
||||
sTrace("vgId:%d, sync enqueue step-down msg, new-term:%" PRId64, ths->vgId, pSyncMsg->currentTerm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pMsg->term >= currentTerm && ths->state == TAOS_SYNC_STATE_LEARNER) {
|
||||
SRpcMsg rpcMsgLocalCmd = {0};
|
||||
(void)syncBuildLocalCmd(&rpcMsgLocalCmd, ths->vgId);
|
||||
|
||||
SyncLocalCmd* pSyncMsg = rpcMsgLocalCmd.pCont;
|
||||
pSyncMsg->cmd = SYNC_LOCAL_CMD_LEARNER_CMT;
|
||||
pSyncMsg->currentTerm = pMsg->term;
|
||||
pSyncMsg->commitIndex = pMsg->commitIndex;
|
||||
|
||||
if (ths->syncEqMsg != NULL && ths->msgcb != NULL) {
|
||||
int32_t code = ths->syncEqMsg(ths->msgcb, &rpcMsgLocalCmd);
|
||||
if (code != 0) {
|
||||
sError("vgId:%d, sync enqueue step-down msg error, code:%d", ths->vgId, code);
|
||||
rpcFreeCont(rpcMsgLocalCmd.pCont);
|
||||
} else {
|
||||
sTrace("vgId:%d, sync enqueue step-down msg, new-term:%" PRId64, ths->vgId, pSyncMsg->currentTerm);
|
||||
sTrace("vgId:%d, sync enqueue step-down msg, new-term:%" PRId64, ths->vgId, pMsg->term);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2521,7 +2512,7 @@ int32_t syncNodeOnLocalCmd(SSyncNode* ths, const SRpcMsg* pRpcMsg) {
|
|||
if (pMsg->cmd == SYNC_LOCAL_CMD_STEP_DOWN) {
|
||||
syncNodeStepDown(ths, pMsg->currentTerm);
|
||||
|
||||
} else if (pMsg->cmd == SYNC_LOCAL_CMD_FOLLOWER_CMT) {
|
||||
} else if (pMsg->cmd == SYNC_LOCAL_CMD_FOLLOWER_CMT || pMsg->cmd == SYNC_LOCAL_CMD_LEARNER_CMT) {
|
||||
if (syncLogBufferIsEmpty(ths->pLogBuf)) {
|
||||
sError("vgId:%d, sync log buffer is empty.", ths->vgId);
|
||||
return 0;
|
||||
|
@ -2534,20 +2525,7 @@ int32_t syncNodeOnLocalCmd(SSyncNode* ths, const SRpcMsg* pRpcMsg) {
|
|||
sError("vgId:%d, failed to commit raft log since %s. commit index:%" PRId64 "", ths->vgId, terrstr(),
|
||||
ths->commitIndex);
|
||||
}
|
||||
} else if (pMsg->cmd == SYNC_LOCAL_CMD_LEARNER_CMT){
|
||||
if (syncLogBufferIsEmpty(ths->pLogBuf)) {
|
||||
sError("vgId:%d, sync log buffer is empty.", ths->vgId);
|
||||
return 0;
|
||||
}
|
||||
raftStoreSetTerm(ths, pMsg->currentTerm);
|
||||
(void)syncNodeUpdateCommitIndex(ths, pMsg->commitIndex);
|
||||
sTrace("vgId:%d, start to commit raft log in heartbeat. commit index:%" PRId64 "", ths->vgId, ths->commitIndex);
|
||||
if (syncLogBufferCommit(ths->pLogBuf, ths, ths->commitIndex) < 0) {
|
||||
sError("vgId:%d, failed to commit raft log since %s. commit index:%" PRId64 "", ths->vgId, terrstr(),
|
||||
ths->commitIndex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
sError("error local cmd");
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ int32_t syncLogBufferAppend(SSyncLogBuffer* pBuf, SSyncNode* pNode, SSyncRaftEnt
|
|||
}
|
||||
|
||||
if (pNode->restoreFinish && index - pBuf->commitIndex >= TSDB_SYNC_NEGOTIATION_WIN) {
|
||||
terrno = TSDB_CODE_SYN_NEGO_WIN_EXCEEDED;
|
||||
terrno = TSDB_CODE_SYN_NEGOTIATION_WIN_FULL;
|
||||
sError("vgId:%d, failed to append since %s, index:%" PRId64 ", commit-index:%" PRId64, pNode->vgId, terrstr(),
|
||||
index, pBuf->commitIndex);
|
||||
goto _err;
|
||||
|
|
|
@ -21,19 +21,19 @@
|
|||
const char* syncRoleToStr(ESyncRole role) {
|
||||
switch (role) {
|
||||
case TAOS_SYNC_ROLE_VOTER:
|
||||
return "voter";
|
||||
return "true";
|
||||
case TAOS_SYNC_ROLE_LEARNER:
|
||||
return "learner";
|
||||
return "false";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
const ESyncRole syncStrToRole(char* str) {
|
||||
if(strcmp(str, "voter") == 0){
|
||||
if(strcmp(str, "true") == 0){
|
||||
return TAOS_SYNC_ROLE_VOTER;
|
||||
}
|
||||
if(strcmp(str, "learner") == 0){
|
||||
if(strcmp(str, "false") == 0){
|
||||
return TAOS_SYNC_ROLE_LEARNER;
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,6 @@ const ESyncRole syncStrToRole(char* str) {
|
|||
|
||||
static int32_t syncEncodeSyncCfg(const void *pObj, SJson *pJson) {
|
||||
SSyncCfg *pCfg = (SSyncCfg *)pObj;
|
||||
if (tjsonAddDoubleToObject(pJson, "totalReplicaNum", pCfg->totalReplicaNum) < 0) return -1;
|
||||
if (tjsonAddDoubleToObject(pJson, "replicaNum", pCfg->replicaNum) < 0) return -1;
|
||||
if (tjsonAddDoubleToObject(pJson, "myIndex", pCfg->myIndex) < 0) return -1;
|
||||
|
||||
|
@ -56,7 +55,7 @@ static int32_t syncEncodeSyncCfg(const void *pObj, SJson *pJson) {
|
|||
if (tjsonAddStringToObject(info, "nodeFqdn", pCfg->nodeInfo[i].nodeFqdn) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(info, "nodeId", pCfg->nodeInfo[i].nodeId) < 0) return -1;
|
||||
if (tjsonAddIntegerToObject(info, "clusterId", pCfg->nodeInfo[i].clusterId) < 0) return -1;
|
||||
if (tjsonAddStringToObject(info, "nodeRole", syncRoleToStr(pCfg->nodeInfo[i].nodeRole)) < 0) return -1;
|
||||
if (tjsonAddStringToObject(info, "isReplica", syncRoleToStr(pCfg->nodeInfo[i].nodeRole)) < 0) return -1;
|
||||
if (tjsonAddItemToArray(nodeInfo, info) < 0) return -1;
|
||||
}
|
||||
|
||||
|
@ -133,7 +132,6 @@ static int32_t syncDecodeSyncCfg(const SJson *pJson, void *pObj) {
|
|||
SSyncCfg *pCfg = (SSyncCfg *)pObj;
|
||||
int32_t code = 0;
|
||||
|
||||
tjsonGetInt32ValueFromDouble(pJson, "totalReplicaNum", pCfg->totalReplicaNum, code);
|
||||
tjsonGetInt32ValueFromDouble(pJson, "replicaNum", pCfg->replicaNum, code);
|
||||
if (code < 0) return -1;
|
||||
tjsonGetInt32ValueFromDouble(pJson, "myIndex", pCfg->myIndex, code);
|
||||
|
@ -153,7 +151,7 @@ static int32_t syncDecodeSyncCfg(const SJson *pJson, void *pObj) {
|
|||
tjsonGetNumberValue(info, "nodeId", pCfg->nodeInfo[i].nodeId, code);
|
||||
tjsonGetNumberValue(info, "clusterId", pCfg->nodeInfo[i].clusterId, code);
|
||||
char role[10] = {0};
|
||||
code = tjsonGetStringValue(info, "nodeRole", role);
|
||||
code = tjsonGetStringValue(info, "isReplica", role);
|
||||
if(code < 0) return -1;
|
||||
if(strlen(role) != 0){
|
||||
pCfg->nodeInfo[i].nodeRole = syncStrToRole(role);
|
||||
|
|
|
@ -102,6 +102,13 @@ int32_t walNextValidMsg(SWalReader *pReader) {
|
|||
|
||||
int64_t walReaderGetCurrentVer(const SWalReader *pReader) { return pReader->curVersion; }
|
||||
|
||||
void walReaderValidVersionRange(SWalReader *pReader, int64_t *sver, int64_t *ever) {
|
||||
*sver = walGetFirstVer(pReader->pWal);
|
||||
int64_t lastVer = walGetLastVer(pReader->pWal);
|
||||
int64_t committedVer = walGetCommittedVer(pReader->pWal);
|
||||
*ever = pReader->cond.scanUncommited ? lastVer : committedVer;
|
||||
}
|
||||
|
||||
static int64_t walReadSeekFilePos(SWalReader *pReader, int64_t fileFirstVer, int64_t ver) {
|
||||
int64_t ret = 0;
|
||||
|
||||
|
|
|
@ -98,7 +98,8 @@ TAOS_DEFINE_ERROR(TSDB_CODE_NO_ENOUGH_DISKSPACE, "No enough disk space"
|
|||
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_APP_IS_STARTING, "Database is starting up")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_APP_IS_STOPPING, "Database is closing down")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_IVLD_DATA_FMT, "Invalid data format")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_DATA_FMT, "Invalid data format")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_CFG_VALUE, "Invalid configuration value")
|
||||
|
||||
//client
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_OPERATION, "Invalid operation")
|
||||
|
@ -413,20 +414,14 @@ TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_TABLE_LIMITED, "Table creation limite
|
|||
|
||||
// sync
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_TIMEOUT, "Sync timeout")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_IS_LEADER, "Sync is leader")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_NOT_LEADER, "Sync leader is unreachable")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_ONE_REPLICA, "Sync one replica")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_NOT_IN_NEW_CONFIG, "Sync not in new config")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_NEW_CONFIG_ERROR, "Sync new config error")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_RECONFIG_NOT_READY, "Sync not ready for reconfig")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_PROPOSE_NOT_READY, "Sync not ready for propose")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_STANDBY_NOT_READY, "Sync not ready for standby")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_BATCH_ERROR, "Sync batch error")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_PROPOSE_NOT_READY, "Sync not ready to propose")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_RESTORING, "Sync leader is restoring")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_INVALID_SNAPSHOT_MSG, "Sync invalid snapshot msg")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_BUFFER_FULL, "Sync buffer is full")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_WRITE_STALL, "Sync write stall")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_NEGO_WIN_EXCEEDED, "Sync negotiation win exceeded")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_NEGOTIATION_WIN_FULL, "Sync negotiation win is full")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_INTERNAL_ERROR, "Sync internal error")
|
||||
|
||||
//tq
|
||||
|
@ -444,8 +439,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TQ_NO_COMMITTED_OFFSET, "TQ no committed offse
|
|||
|
||||
// wal
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_WAL_FILE_CORRUPTED, "WAL file is corrupted")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_WAL_SIZE_LIMIT, "WAL size exceeds limit")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_WAL_INVALID_VER, "WAL use invalid version")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_WAL_INVALID_VER, "WAL invalid version")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_WAL_LOG_NOT_EXIST, "WAL log not exist")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_WAL_CHKSUM_MISMATCH, "WAL checksum mismatch")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_WAL_LOG_INCOMPLETE, "WAL log incomplete")
|
||||
|
@ -581,11 +575,9 @@ TAOS_DEFINE_ERROR(TSDB_CODE_FUNC_DUP_TIMESTAMP, "Duplicate timestamps
|
|||
TAOS_DEFINE_ERROR(TSDB_CODE_UDF_STOPPING, "udf is stopping")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_UDF_PIPE_READ_ERR, "udf pipe read error")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_UDF_PIPE_CONNECT_ERR, "udf pipe connect error")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_UDF_PIPE_NO_PIPE, "udf no pipe")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_UDF_PIPE_NOT_EXIST, "udf pipe not exist")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_UDF_LOAD_UDF_FAILURE, "udf load failure")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_UDF_INVALID_STATE, "udf invalid state")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_UDF_INVALID_INPUT, "udf invalid function input")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_UDF_NO_FUNC_HANDLE, "udf no function handle")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_UDF_INVALID_BUFSIZE, "udf invalid bufsize")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_UDF_INVALID_OUTPUT_TYPE, "udf invalid output type")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_UDF_SCRIPT_NOT_SUPPORTED, "udf program language not supported")
|
||||
|
|
|
@ -24,10 +24,11 @@
|
|||
#define LOG_MAX_LINE_SIZE (10024)
|
||||
#define LOG_MAX_LINE_BUFFER_SIZE (LOG_MAX_LINE_SIZE + 3)
|
||||
#define LOG_MAX_LINE_DUMP_SIZE (1024 * 1024)
|
||||
#define LOG_MAX_LINE_DUMP_BUFFER_SIZE (LOG_MAX_LINE_DUMP_SIZE + 3)
|
||||
#define LOG_MAX_LINE_DUMP_BUFFER_SIZE (LOG_MAX_LINE_DUMP_SIZE + 128)
|
||||
|
||||
#define LOG_FILE_NAME_LEN 300
|
||||
#define LOG_DEFAULT_BUF_SIZE (20 * 1024 * 1024) // 20MB
|
||||
#define LOG_SLOW_BUF_SIZE (10 * 1024 * 1024) // 10MB
|
||||
|
||||
#define LOG_DEFAULT_INTERVAL 25
|
||||
#define LOG_INTERVAL_STEP 5
|
||||
|
@ -51,6 +52,8 @@ typedef struct {
|
|||
int32_t stop;
|
||||
TdThread asyncThread;
|
||||
TdThreadMutex buffMutex;
|
||||
int32_t writeInterval;
|
||||
int32_t lastDuration;
|
||||
} SLogBuff;
|
||||
|
||||
typedef struct {
|
||||
|
@ -62,6 +65,7 @@ typedef struct {
|
|||
pid_t pid;
|
||||
char logName[LOG_FILE_NAME_LEN];
|
||||
SLogBuff *logHandle;
|
||||
SLogBuff *slowHandle;
|
||||
TdThreadMutex logMutex;
|
||||
} SLogObj;
|
||||
|
||||
|
@ -69,7 +73,6 @@ extern SConfig *tsCfg;
|
|||
static int8_t tsLogInited = 0;
|
||||
static SLogObj tsLogObj = {.fileNum = 1};
|
||||
static int64_t tsAsyncLogLostLines = 0;
|
||||
static int32_t tsWriteInterval = LOG_DEFAULT_INTERVAL;
|
||||
static int32_t tsDaylightActive; /* Currently in daylight saving time. */
|
||||
|
||||
bool tsLogEmbedded = 0;
|
||||
|
@ -82,6 +85,7 @@ int64_t tsNumOfErrorLogs = 0;
|
|||
int64_t tsNumOfInfoLogs = 0;
|
||||
int64_t tsNumOfDebugLogs = 0;
|
||||
int64_t tsNumOfTraceLogs = 0;
|
||||
int64_t tsNumOfSlowLogs = 0;
|
||||
|
||||
// log
|
||||
int32_t dDebugFlag = 131;
|
||||
|
@ -136,6 +140,34 @@ static int32_t taosStartLog() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t taosInitSlowLog() {
|
||||
char fullName[PATH_MAX] = {0};
|
||||
char logFileName[64] = {0};
|
||||
#ifdef CUS_PROMPT
|
||||
snprintf(logFileName, 64, "%sSlowLog", CUS_PROMPT);
|
||||
#else
|
||||
snprintf(logFileName, 64, "taosSlowLog");
|
||||
#endif
|
||||
|
||||
if (strlen(tsLogDir) != 0) {
|
||||
snprintf(fullName, PATH_MAX, "%s" TD_DIRSEP "%s", tsLogDir, logFileName);
|
||||
} else {
|
||||
snprintf(fullName, PATH_MAX, "%s", logFileName);
|
||||
}
|
||||
|
||||
tsLogObj.slowHandle = taosLogBuffNew(LOG_SLOW_BUF_SIZE);
|
||||
if (tsLogObj.slowHandle == NULL) return -1;
|
||||
|
||||
taosUmaskFile(0);
|
||||
tsLogObj.slowHandle->pFile = taosOpenFile(fullName, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_APPEND);
|
||||
if (tsLogObj.slowHandle->pFile == NULL) {
|
||||
printf("\nfailed to open slow log file:%s, reason:%s\n", fullName, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t taosInitLog(const char *logName, int32_t maxFiles) {
|
||||
if (atomic_val_compare_exchange_8(&tsLogInited, 0, 1) != 0) return 0;
|
||||
osUpdate();
|
||||
|
@ -151,6 +183,8 @@ int32_t taosInitLog(const char *logName, int32_t maxFiles) {
|
|||
tsLogObj.logHandle = taosLogBuffNew(LOG_DEFAULT_BUF_SIZE);
|
||||
if (tsLogObj.logHandle == NULL) return -1;
|
||||
if (taosOpenLogFile(fullName, tsNumOfLogLines, maxFiles) < 0) return -1;
|
||||
|
||||
if (taosInitSlowLog() < 0) return -1;
|
||||
if (taosStartLog() < 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -159,25 +193,34 @@ static void taosStopLog() {
|
|||
if (tsLogObj.logHandle) {
|
||||
tsLogObj.logHandle->stop = 1;
|
||||
}
|
||||
if (tsLogObj.slowHandle) {
|
||||
tsLogObj.slowHandle->stop = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void taosCloseLog() {
|
||||
taosStopLog();
|
||||
|
||||
if (tsLogObj.logHandle != NULL && taosCheckPthreadValid(tsLogObj.logHandle->asyncThread)) {
|
||||
taosThreadJoin(tsLogObj.logHandle->asyncThread, NULL);
|
||||
taosThreadClear(&tsLogObj.logHandle->asyncThread);
|
||||
}
|
||||
|
||||
if (tsLogObj.slowHandle != NULL) {
|
||||
taosThreadMutexDestroy(&tsLogObj.slowHandle->buffMutex);
|
||||
taosCloseFile(&tsLogObj.slowHandle->pFile);
|
||||
taosMemoryFreeClear(tsLogObj.slowHandle->buffer);
|
||||
taosMemoryFreeClear(tsLogObj.slowHandle);
|
||||
}
|
||||
|
||||
if (tsLogObj.logHandle != NULL) {
|
||||
taosStopLog();
|
||||
if (tsLogObj.logHandle != NULL && taosCheckPthreadValid(tsLogObj.logHandle->asyncThread)) {
|
||||
taosThreadJoin(tsLogObj.logHandle->asyncThread, NULL);
|
||||
taosThreadClear(&tsLogObj.logHandle->asyncThread);
|
||||
}
|
||||
tsLogInited = 0;
|
||||
|
||||
taosThreadMutexDestroy(&tsLogObj.logHandle->buffMutex);
|
||||
taosCloseFile(&tsLogObj.logHandle->pFile);
|
||||
taosMemoryFreeClear(tsLogObj.logHandle->buffer);
|
||||
memset(&tsLogObj.logHandle->buffer, 0, sizeof(tsLogObj.logHandle->buffer));
|
||||
taosThreadMutexDestroy(&tsLogObj.logMutex);
|
||||
taosMemoryFreeClear(tsLogObj.logHandle);
|
||||
memset(&tsLogObj.logHandle, 0, sizeof(tsLogObj.logHandle));
|
||||
tsLogObj.logHandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -513,10 +556,9 @@ void taosPrintLongString(const char *flags, ELogLevel level, int32_t dflag, cons
|
|||
|
||||
va_list argpointer;
|
||||
va_start(argpointer, format);
|
||||
len += vsnprintf(buffer + len, LOG_MAX_LINE_DUMP_BUFFER_SIZE - len, format, argpointer);
|
||||
len += vsnprintf(buffer + len, LOG_MAX_LINE_DUMP_BUFFER_SIZE - 2 - len, format, argpointer);
|
||||
va_end(argpointer);
|
||||
|
||||
if (len > LOG_MAX_LINE_DUMP_SIZE) len = LOG_MAX_LINE_DUMP_SIZE;
|
||||
buffer[len++] = '\n';
|
||||
buffer[len] = 0;
|
||||
|
||||
|
@ -524,6 +566,31 @@ void taosPrintLongString(const char *flags, ELogLevel level, int32_t dflag, cons
|
|||
taosMemoryFree(buffer);
|
||||
}
|
||||
|
||||
void taosPrintSlowLog(const char *format, ...) {
|
||||
if (!osLogSpaceAvailable()) return;
|
||||
|
||||
char *buffer = taosMemoryMalloc(LOG_MAX_LINE_DUMP_BUFFER_SIZE);
|
||||
int32_t len = taosBuildLogHead(buffer, "");
|
||||
|
||||
va_list argpointer;
|
||||
va_start(argpointer, format);
|
||||
len += vsnprintf(buffer + len, LOG_MAX_LINE_DUMP_BUFFER_SIZE - 2 - len, format, argpointer);
|
||||
va_end(argpointer);
|
||||
|
||||
buffer[len++] = '\n';
|
||||
buffer[len] = 0;
|
||||
|
||||
atomic_add_fetch_64(&tsNumOfSlowLogs, 1);
|
||||
|
||||
if (tsAsyncLog) {
|
||||
taosPushLogBuffer(tsLogObj.slowHandle, buffer, len);
|
||||
} else {
|
||||
taosWriteFile(tsLogObj.slowHandle->pFile, buffer, len);
|
||||
}
|
||||
|
||||
taosMemoryFree(buffer);
|
||||
}
|
||||
|
||||
void taosDumpData(unsigned char *msg, int32_t len) {
|
||||
if (!osLogSpaceAvailable()) return;
|
||||
taosUpdateLogNums(DEBUG_DUMP);
|
||||
|
@ -568,6 +635,7 @@ static SLogBuff *taosLogBuffNew(int32_t bufSize) {
|
|||
LOG_BUF_SIZE(pLogBuf) = bufSize;
|
||||
pLogBuf->minBuffSize = bufSize / 10;
|
||||
pLogBuf->stop = 0;
|
||||
pLogBuf->writeInterval = LOG_DEFAULT_INTERVAL;
|
||||
|
||||
if (taosThreadMutexInit(&LOG_BUF_MUTEX(pLogBuf), NULL) < 0) goto _err;
|
||||
// tsem_init(&(pLogBuf->buffNotEmpty), 0, 0);
|
||||
|
@ -651,83 +719,78 @@ static int32_t taosGetLogRemainSize(SLogBuff *pLogBuf, int32_t start, int32_t en
|
|||
}
|
||||
|
||||
static void taosWriteLog(SLogBuff *pLogBuf) {
|
||||
static int32_t lastDuration = 0;
|
||||
int32_t remainChecked = 0;
|
||||
int32_t start, end, pollSize;
|
||||
int32_t start = LOG_BUF_START(pLogBuf);
|
||||
int32_t end = LOG_BUF_END(pLogBuf);
|
||||
|
||||
do {
|
||||
if (remainChecked == 0) {
|
||||
start = LOG_BUF_START(pLogBuf);
|
||||
end = LOG_BUF_END(pLogBuf);
|
||||
if (start == end) {
|
||||
dbgEmptyW++;
|
||||
pLogBuf->writeInterval = LOG_MAX_INTERVAL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (start == end) {
|
||||
dbgEmptyW++;
|
||||
tsWriteInterval = LOG_MAX_INTERVAL;
|
||||
return;
|
||||
}
|
||||
|
||||
pollSize = taosGetLogRemainSize(pLogBuf, start, end);
|
||||
if (pollSize < pLogBuf->minBuffSize) {
|
||||
lastDuration += tsWriteInterval;
|
||||
if (lastDuration < LOG_MAX_WAIT_MSEC) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lastDuration = 0;
|
||||
int32_t pollSize = taosGetLogRemainSize(pLogBuf, start, end);
|
||||
if (pollSize < pLogBuf->minBuffSize) {
|
||||
pLogBuf->lastDuration += pLogBuf->writeInterval;
|
||||
if (pLogBuf->lastDuration < LOG_MAX_WAIT_MSEC) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (start < end) {
|
||||
taosWriteFile(pLogBuf->pFile, LOG_BUF_BUFFER(pLogBuf) + start, pollSize);
|
||||
} else {
|
||||
int32_t tsize = LOG_BUF_SIZE(pLogBuf) - start;
|
||||
taosWriteFile(pLogBuf->pFile, LOG_BUF_BUFFER(pLogBuf) + start, tsize);
|
||||
pLogBuf->lastDuration = 0;
|
||||
|
||||
taosWriteFile(pLogBuf->pFile, LOG_BUF_BUFFER(pLogBuf), end);
|
||||
if (start < end) {
|
||||
taosWriteFile(pLogBuf->pFile, LOG_BUF_BUFFER(pLogBuf) + start, pollSize);
|
||||
} else {
|
||||
int32_t tsize = LOG_BUF_SIZE(pLogBuf) - start;
|
||||
taosWriteFile(pLogBuf->pFile, LOG_BUF_BUFFER(pLogBuf) + start, tsize);
|
||||
|
||||
taosWriteFile(pLogBuf->pFile, LOG_BUF_BUFFER(pLogBuf), end);
|
||||
}
|
||||
|
||||
dbgWN++;
|
||||
dbgWSize += pollSize;
|
||||
|
||||
if (pollSize < pLogBuf->minBuffSize) {
|
||||
dbgSmallWN++;
|
||||
if (pLogBuf->writeInterval < LOG_MAX_INTERVAL) {
|
||||
pLogBuf->writeInterval += LOG_INTERVAL_STEP;
|
||||
}
|
||||
|
||||
dbgWN++;
|
||||
dbgWSize += pollSize;
|
||||
|
||||
if (pollSize < pLogBuf->minBuffSize) {
|
||||
dbgSmallWN++;
|
||||
if (tsWriteInterval < LOG_MAX_INTERVAL) {
|
||||
tsWriteInterval += LOG_INTERVAL_STEP;
|
||||
}
|
||||
} else if (pollSize > LOG_BUF_SIZE(pLogBuf) / 3) {
|
||||
dbgBigWN++;
|
||||
tsWriteInterval = LOG_MIN_INTERVAL;
|
||||
} else if (pollSize > LOG_BUF_SIZE(pLogBuf) / 4) {
|
||||
if (tsWriteInterval > LOG_MIN_INTERVAL) {
|
||||
tsWriteInterval -= LOG_INTERVAL_STEP;
|
||||
}
|
||||
} else if (pollSize > LOG_BUF_SIZE(pLogBuf) / 3) {
|
||||
dbgBigWN++;
|
||||
pLogBuf->writeInterval = LOG_MIN_INTERVAL;
|
||||
} else if (pollSize > LOG_BUF_SIZE(pLogBuf) / 4) {
|
||||
if (pLogBuf->writeInterval > LOG_MIN_INTERVAL) {
|
||||
pLogBuf->writeInterval -= LOG_INTERVAL_STEP;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_BUF_START(pLogBuf) = (LOG_BUF_START(pLogBuf) + pollSize) % LOG_BUF_SIZE(pLogBuf);
|
||||
LOG_BUF_START(pLogBuf) = (LOG_BUF_START(pLogBuf) + pollSize) % LOG_BUF_SIZE(pLogBuf);
|
||||
|
||||
start = LOG_BUF_START(pLogBuf);
|
||||
end = LOG_BUF_END(pLogBuf);
|
||||
start = LOG_BUF_START(pLogBuf);
|
||||
end = LOG_BUF_END(pLogBuf);
|
||||
|
||||
pollSize = taosGetLogRemainSize(pLogBuf, start, end);
|
||||
if (pollSize < pLogBuf->minBuffSize) {
|
||||
break;
|
||||
}
|
||||
pollSize = taosGetLogRemainSize(pLogBuf, start, end);
|
||||
if (pollSize < pLogBuf->minBuffSize) {
|
||||
return;
|
||||
}
|
||||
|
||||
tsWriteInterval = LOG_MIN_INTERVAL;
|
||||
|
||||
remainChecked = 1;
|
||||
} while (1);
|
||||
pLogBuf->writeInterval = 0;
|
||||
}
|
||||
|
||||
static void *taosAsyncOutputLog(void *param) {
|
||||
SLogBuff *pLogBuf = (SLogBuff *)param;
|
||||
SLogBuff *pLogBuf = (SLogBuff *)tsLogObj.logHandle;
|
||||
SLogBuff *pSlowBuf = (SLogBuff *)tsLogObj.slowHandle;
|
||||
|
||||
setThreadName("log");
|
||||
int32_t count = 0;
|
||||
int32_t updateCron = 0;
|
||||
int32_t writeInterval = 0;
|
||||
|
||||
while (1) {
|
||||
count += tsWriteInterval;
|
||||
writeInterval = TMIN(pLogBuf->writeInterval, pSlowBuf->writeInterval);
|
||||
count += writeInterval;
|
||||
updateCron++;
|
||||
taosMsleep(tsWriteInterval);
|
||||
taosMsleep(writeInterval);
|
||||
if (count > 1000) {
|
||||
osUpdate();
|
||||
count = 0;
|
||||
|
@ -735,13 +798,14 @@ static void *taosAsyncOutputLog(void *param) {
|
|||
|
||||
// Polling the buffer
|
||||
taosWriteLog(pLogBuf);
|
||||
taosWriteLog(pSlowBuf);
|
||||
|
||||
if (updateCron >= 3600 * 24 * 40 / 2) {
|
||||
taosUpdateDaylight();
|
||||
updateCron = 0;
|
||||
}
|
||||
|
||||
if (pLogBuf->stop) break;
|
||||
if (pLogBuf->stop || pSlowBuf->stop) break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
|
|
@ -217,8 +217,8 @@ STaosQueue *tAutoQWorkerAllocQueue(SAutoQWorkerPool *pool, void *ahandle, FItem
|
|||
|
||||
int32_t queueNum = taosGetQueueNumber(pool->qset);
|
||||
int32_t curWorkerNum = taosArrayGetSize(pool->workers);
|
||||
int32_t dstWorkerNum = ceil(queueNum * pool->ratio);
|
||||
if (dstWorkerNum < 2) dstWorkerNum = 2;
|
||||
int32_t dstWorkerNum = ceilf(queueNum * pool->ratio);
|
||||
if (dstWorkerNum < 1) dstWorkerNum = 1;
|
||||
|
||||
// spawn a thread to process queue
|
||||
while (curWorkerNum < dstWorkerNum) {
|
||||
|
|
|
@ -887,6 +887,7 @@
|
|||
,,y,script,./test.sh -f tsim/query/emptyTsRange.sim
|
||||
,,y,script,./test.sh -f tsim/query/partitionby.sim
|
||||
,,y,script,./test.sh -f tsim/query/tableCount.sim
|
||||
,,y,script,./test.sh -f tsim/query/tag_scan.sim
|
||||
,,y,script,./test.sh -f tsim/query/nullColSma.sim
|
||||
,,y,script,./test.sh -f tsim/qnode/basic1.sim
|
||||
,,y,script,./test.sh -f tsim/snode/basic1.sim
|
||||
|
|
|
@ -431,7 +431,7 @@ class TDSql:
|
|||
time.sleep(1)
|
||||
continue
|
||||
|
||||
def execute(self, sql,queryTimes=10):
|
||||
def execute(self, sql,queryTimes=30):
|
||||
self.sql = sql
|
||||
i=1
|
||||
while i <= queryTimes:
|
||||
|
|
|
@ -15,8 +15,11 @@ exe:
|
|||
gcc $(CFLAGS) ./stopquery.c -o $(ROOT)stopquery $(LFLAGS)
|
||||
gcc $(CFLAGS) ./dbTableRoute.c -o $(ROOT)dbTableRoute $(LFLAGS)
|
||||
gcc $(CFLAGS) ./insertSameTs.c -o $(ROOT)insertSameTs $(LFLAGS)
|
||||
gcc $(CFLAGS) ./passwdTest.c -o $(ROOT)passwdTest $(LFLAGS)
|
||||
|
||||
clean:
|
||||
rm $(ROOT)batchprepare
|
||||
rm $(ROOT)stopquery
|
||||
rm $(ROOT)dbTableRoute
|
||||
rm $(ROOT)insertSameTs
|
||||
rm $(ROOT)passwdTest
|
||||
|
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
// TAOS standard API example. The same syntax as MySQL, but only a subset
|
||||
// to compile: gcc -o demo demo.c -ltaos
|
||||
|
||||
/**
|
||||
* passwdTest.c
|
||||
* - Run the test case in clear TDengine environment with default root passwd 'taosdata'
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "taos.h" // TAOS header file
|
||||
|
||||
#define nDup 1
|
||||
#define nRoot 10
|
||||
#define nUser 10
|
||||
#define USER_LEN 24
|
||||
|
||||
void Test(TAOS *taos, char *qstr);
|
||||
void createUers(TAOS *taos, const char *host, char *qstr);
|
||||
void passVerTestMulti(const char *host, char *qstr);
|
||||
|
||||
int nPassVerNotified = 0;
|
||||
TAOS *taosu[nRoot] = {0};
|
||||
char users[nUser][USER_LEN] = {0};
|
||||
|
||||
void __taos_notify_cb(void *param, void *ext, int type) {
|
||||
switch (type) {
|
||||
case TAOS_NOTIFY_PASSVER: {
|
||||
++nPassVerNotified;
|
||||
printf("%s:%d type:%d user:%s ver:%d\n", __func__, __LINE__, type, param ? (char *)param : "NULL", *(int *)ext);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
printf("%s:%d unknown type:%d\n", __func__, __LINE__, type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void queryDB(TAOS *taos, char *command) {
|
||||
int i;
|
||||
TAOS_RES *pSql = NULL;
|
||||
int32_t code = -1;
|
||||
|
||||
for (i = 0; i < nDup; ++i) {
|
||||
if (NULL != pSql) {
|
||||
taos_free_result(pSql);
|
||||
pSql = NULL;
|
||||
}
|
||||
|
||||
pSql = taos_query(taos, command);
|
||||
code = taos_errno(pSql);
|
||||
if (0 == code) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (code != 0) {
|
||||
fprintf(stderr, "failed to run: %s, reason: %s\n", command, taos_errstr(pSql));
|
||||
taos_free_result(pSql);
|
||||
taos_close(taos);
|
||||
exit(EXIT_FAILURE);
|
||||
} else {
|
||||
fprintf(stderr, "success to run: %s\n", command);
|
||||
}
|
||||
|
||||
taos_free_result(pSql);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
char qstr[1024];
|
||||
|
||||
// connect to server
|
||||
if (argc < 2) {
|
||||
printf("please input server-ip \n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
TAOS *taos = taos_connect(argv[1], "root", "taosdata", NULL, 0);
|
||||
if (taos == NULL) {
|
||||
printf("failed to connect to server, reason:%s\n", "null taos" /*taos_errstr(taos)*/);
|
||||
exit(1);
|
||||
}
|
||||
createUers(taos, argv[1], qstr);
|
||||
passVerTestMulti(argv[1], qstr);
|
||||
|
||||
taos_close(taos);
|
||||
taos_cleanup();
|
||||
}
|
||||
|
||||
void createUers(TAOS *taos, const char *host, char *qstr) {
|
||||
// users
|
||||
for (int i = 0; i < nUser; ++i) {
|
||||
sprintf(users[i], "user%d", i);
|
||||
sprintf(qstr, "CREATE USER %s PASS 'taosdata'", users[i]);
|
||||
queryDB(taos, qstr);
|
||||
|
||||
taosu[i] = taos_connect(host, users[i], "taosdata", NULL, 0);
|
||||
if (taosu[i] == NULL) {
|
||||
printf("failed to connect to server, user:%s, reason:%s\n", users[i], "null taos" /*taos_errstr(taos)*/);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int code = taos_set_notify_cb(taosu[i], __taos_notify_cb, users[i], TAOS_NOTIFY_PASSVER);
|
||||
|
||||
if (code != 0) {
|
||||
fprintf(stderr, "failed to run: taos_set_notify_cb for user:%s since %d\n", users[i], code);
|
||||
} else {
|
||||
fprintf(stderr, "success to run: taos_set_notify_cb for user:%s\n", users[i]);
|
||||
}
|
||||
|
||||
// alter pass for users
|
||||
sprintf(qstr, "alter user %s pass 'taos'", users[i]);
|
||||
queryDB(taos, qstr);
|
||||
}
|
||||
}
|
||||
|
||||
void passVerTestMulti(const char *host, char *qstr) {
|
||||
// root
|
||||
TAOS *taos[nRoot] = {0};
|
||||
char userName[USER_LEN] = "root";
|
||||
|
||||
for (int i = 0; i < nRoot; ++i) {
|
||||
taos[i] = taos_connect(host, "root", "taosdata", NULL, 0);
|
||||
if (taos[i] == NULL) {
|
||||
printf("failed to connect to server, reason:%s\n", "null taos" /*taos_errstr(taos)*/);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int code = taos_set_notify_cb(taos[i], __taos_notify_cb, userName, TAOS_NOTIFY_PASSVER);
|
||||
|
||||
if (code != 0) {
|
||||
fprintf(stderr, "failed to run: taos_set_notify_cb since %d\n", code);
|
||||
} else {
|
||||
fprintf(stderr, "success to run: taos_set_notify_cb\n");
|
||||
}
|
||||
}
|
||||
|
||||
queryDB(taos[0], "create database if not exists demo1 vgroups 1 minrows 10");
|
||||
queryDB(taos[0], "create database if not exists demo2 vgroups 1 minrows 10");
|
||||
queryDB(taos[0], "create database if not exists demo3 vgroups 1 minrows 10");
|
||||
|
||||
queryDB(taos[0], "create table demo1.stb (ts timestamp, c1 int) tags(t1 int)");
|
||||
queryDB(taos[0], "create table demo2.stb (ts timestamp, c1 int) tags(t1 int)");
|
||||
queryDB(taos[0], "create table demo3.stb (ts timestamp, c1 int) tags(t1 int)");
|
||||
|
||||
strcpy(qstr, "alter user root pass 'taos'");
|
||||
queryDB(taos[0], qstr);
|
||||
|
||||
// calculate the nPassVerNotified for root and users
|
||||
int nConn = nRoot + nUser;
|
||||
|
||||
for (int i = 0; i < 15; ++i) {
|
||||
if (nPassVerNotified >= nConn) break;
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
// close the taos_conn
|
||||
for (int i = 0; i < nRoot; ++i) {
|
||||
taos_close(taos[i]);
|
||||
printf("%s:%d close taos[%d]\n", __func__, __LINE__, i);
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < nUser; ++i) {
|
||||
taos_close(taosu[i]);
|
||||
printf("%s:%d close taosu[%d]\n", __func__, __LINE__, i);
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
if (nPassVerNotified >= nConn) {
|
||||
fprintf(stderr, "succeed to get passVer notification since nNotify %d >= nConn %d\n", nPassVerNotified, nConn);
|
||||
} else {
|
||||
fprintf(stderr, "failed to get passVer notification since nNotify %d < nConn %d\n", nPassVerNotified, nConn);
|
||||
}
|
||||
// sleep(300);
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
system sh/stop_dnodes.sh
|
||||
system sh/deploy.sh -n dnode1 -i 1
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
sql connect
|
||||
sql drop database if exists test
|
||||
sql create database test;
|
||||
sql use test;
|
||||
|
||||
sql create table st(ts timestamp, f int) tags (t int);
|
||||
sql insert into ct1 using st tags(1) values(now, 1);
|
||||
sql insert into ct2 using st tags(2) values(now, 2);
|
||||
sql insert into ct3 using st tags(3) values(now, 3);
|
||||
sql insert into ct4 using st tags(4) values(now, 4);
|
||||
|
||||
sql create table st2(ts timestamp, f int) tags (t int);
|
||||
sql insert into ct21 using st2 tags(1) values(now, 1);
|
||||
sql insert into ct22 using st2 tags(2) values(now, 2);
|
||||
sql insert into ct23 using st2 tags(3) values(now, 3);
|
||||
sql insert into ct24 using st2 tags(4) values(now, 4);
|
||||
|
||||
sql select tbname, 1 from st group by tbname order by tbname;
|
||||
print $rows $data00 $data10 $data20
|
||||
if $rows != 4 then
|
||||
return -1
|
||||
endi
|
||||
if $data00 != @ct1@ then
|
||||
return -1
|
||||
endi
|
||||
if $data10 != @ct2@ then
|
||||
return -1
|
||||
endi
|
||||
sql select tbname, 1 from st group by tbname slimit 0, 1;
|
||||
print $rows
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
sql select tbname, 1 from st group by tbname slimit 2, 2;
|
||||
print $rows $data00 $data10
|
||||
if $rows != 2 then
|
||||
return -1
|
||||
endi
|
||||
sql select tbname, 1 from st group by tbname order by tbname slimit 0, 1;
|
||||
print $rows $data00 $data10 $data20
|
||||
if $rows != 4 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
|
@ -27,7 +27,7 @@ class TDTestCase:
|
|||
def init(self, conn, logSql, replicaVar=1):
|
||||
self.replicaVar = int(replicaVar)
|
||||
tdLog.debug("start to execute %s" % __file__)
|
||||
tdSql.init(conn.cursor())
|
||||
tdSql.init(conn.cursor(), True)
|
||||
self.dbname = 'db_test'
|
||||
self.setsql = TDSetSql()
|
||||
self.stbname = 'stb'
|
||||
|
|
|
@ -1115,6 +1115,7 @@ int32_t shellExecute() {
|
|||
}
|
||||
|
||||
if (shell.conn == NULL) {
|
||||
printf("failed to connect to server, reason: %s\n", taos_errstr(NULL));
|
||||
fflush(stdout);
|
||||
return -1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue