Mac原生查询导致端口占用持续增加,最终崩溃

【TDengine 使用环境】
生产环境 /测试/ Poc/预生产环境

【TDengine 版本】

3.0.6,3.8.8,3.4.0均有此现象

【操作系统以及版本】

macOS12,macOS15,intel和arm芯片均有此现象

【部署方式】本地部署

【集群节点数】无

【集群副本数】无

【描述业务影响】调用原生连接器的taos_query方法,每次调用端口占用+1,最终导致资源不足程序崩溃,ws方式连接无此现象

【问题复现路径/shan】

用Qt编译C库,代码如下:

#include “taos.h”
#include
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

// #define TSDB_TIME_PRECISION_MILLI 0
// #define TSDB_TIME_PRECISION_MICRO 1
// #define TSDB_TIME_PRECISION_NANO 2
// #define TSDB_TIME_PRECISION_HOURS 3
// #define TSDB_TIME_PRECISION_MINUTES 4
// #define TSDB_TIME_PRECISION_SECONDS 5

// #define CMD_BUFF_SIZE 1024 * 1024
// #define MAX_FIELD_SIZE 10 * 1024

typedef uint16_t VarDataLenT;
#define TSDB_NCHAR_SIZE sizeof(int32_t)
#define VARSTR_HEADER_SIZE sizeof(VarDataLenT)
#define varDataLen(v) ((VarDataLenT *)(v))[0]

TAOS *taos = NULL;

int printRow(char *str, TAOS_ROW row, TAOS_FIELD *fields, int numFields)
{
int len = 0;
char split = ’ ';

for (int i = 0; i < numFields; ++i)
{
    if (i > 0)
    {
        str[len++] = split;
    }

    if (row[i] == NULL)
    {
        len += sprintf(str + len, "%s", "NULL");
        continue;
    }

    switch (fields[i].type)
    {
    case TSDB_DATA_TYPE_TINYINT:
        len += sprintf(str + len, "%d", *((int8_t *)row[i]));
        break;

    case TSDB_DATA_TYPE_UTINYINT:
        len += sprintf(str + len, "%u", *((uint8_t *)row[i]));
        break;

    case TSDB_DATA_TYPE_SMALLINT:
        len += sprintf(str + len, "%d", *((int16_t *)row[i]));
        break;

    case TSDB_DATA_TYPE_USMALLINT:
        len += sprintf(str + len, "%u", *((uint16_t *)row[i]));
        break;

    case TSDB_DATA_TYPE_INT:
        len += sprintf(str + len, "%d", *((int32_t *)row[i]));
        break;

    case TSDB_DATA_TYPE_UINT:
        len += sprintf(str + len, "%u", *((uint32_t *)row[i]));
        break;

    case TSDB_DATA_TYPE_BIGINT:
        len += sprintf(str + len, "%" PRId64, *((int64_t *)row[i]));
        break;

    case TSDB_DATA_TYPE_UBIGINT:
        len += sprintf(str + len, "%" PRIu64, *((uint64_t *)row[i]));
        break;

    case TSDB_DATA_TYPE_FLOAT: {
        float fv = 0;
        // fv = GET_FLOAT_VAL(row[i]);
        len += sprintf(str + len, "%f", fv);
    }
    break;

    case TSDB_DATA_TYPE_DOUBLE: {
        double dv = 0;
        // dv = GET_DOUBLE_VAL(row[i]);
        len += sprintf(str + len, "%lf", dv);
    }
    break;

    case TSDB_DATA_TYPE_BINARY:
    case TSDB_DATA_TYPE_VARBINARY:
    case TSDB_DATA_TYPE_NCHAR:
    case TSDB_DATA_TYPE_GEOMETRY: {
        int32_t charLen = varDataLen((char *)row[i] - VARSTR_HEADER_SIZE);
        memcpy(str + len, row[i], charLen);
        len += charLen;
    }
    break;

    case TSDB_DATA_TYPE_TIMESTAMP:
        len += sprintf(str + len, "%" PRId64, *((int64_t *)row[i]));
        break;

    case TSDB_DATA_TYPE_BOOL:
        len += sprintf(str + len, "%d", *((int8_t *)row[i]));
    default:
        break;
    }
}

return len;

}

void connectDB()
{
const char *host = “localhost”;
const char *user = “root”;
const char *password = “taosdata”;
int code = 0;
if (1)
{
uint16_t port = 6030;
taos = taos_connect(host, user, password, NULL, port);
if (taos == NULL)
{
fprintf(stderr, “Failed to connect to %s:%hu, ErrCode: 0x%x, ErrMessage: %s.\n”, host, port, taos_errno(NULL), taos_errstr(NULL));
taos_cleanup();
return;
}
}
}
void nativaQuery()
{
const char *sql = “show databases;”;
TAOS_RES *result = taos_query(taos, sql);
int code = taos_errno(result);
if (code != 0)
{
fprintf(stderr, “Failed to query data from power.meters, sql: %s, ErrCode: 0x%x, ErrMessage: %s\n.”, sql, code, taos_errstr(result));
taos_close(taos);
return;
}

TAOS_ROW row = NULL;
int rows = 0;
char buffer[1024];
int num_fields = taos_num_fields(result);
char qstr[10240];
TAOS_FIELD *fields = taos_fetch_fields(result);

fprintf(stdout, "query successfully, got %d fields, the sql is: %s.\n", num_fields, sql);

// fetch the records row by row
while ((row = taos_fetch_row(result)))
{
    rows++;
    char temp[1024] = { 0 };
    printRow(temp, row, fields, num_fields);
    fprintf(stdout, "query successfully, result is: %s.\n", temp);
}
fprintf(stdout, "total rows: %d\n", rows);
taos_free_result(result);

}

void precise_sleep_ms(long milliseconds)
{
struct timespec req, rem;

if (milliseconds > 999)
{
    req.tv_sec = milliseconds / 1000;
    req.tv_nsec = (milliseconds % 1000) * 1000000L;
}
else
{
    req.tv_sec = 0;
    req.tv_nsec = milliseconds * 1000000L;
}

nanosleep(&req, &rem);

}

int main(int argc, char *argv)
{
connectDB();
while (true)
{
nativaQuery();
// taosMsleep(1);
precise_sleep_ms(1);
}
}

【遇到的问题:问题现象及影响】

调用原生连接器的taos_query方法,每次调用端口占用+1,ws方式调用不增加

【资源配置】

【报错完整截图】

复现了,解决后,本地看正常了