diff --git a/.gitignore b/.gitignore index f77067c7d1..07003bda4c 100644 --- a/.gitignore +++ b/.gitignore @@ -99,6 +99,7 @@ tests/examples/JDBC/JDBCDemo/.classpath tests/examples/JDBC/JDBCDemo/.project tests/examples/JDBC/JDBCDemo/.settings/ source/libs/parser/inc/sql.* +source/os/src/timezone/ tests/script/tmqResult.txt tests/system-test/case_to_run.txt tests/develop-test/case_to_run.txt diff --git a/docs/en/08-operation/14-user.md b/docs/en/08-operation/14-user.md index ab62c98bfa..5aa8b2e211 100644 --- a/docs/en/08-operation/14-user.md +++ b/docs/en/08-operation/14-user.md @@ -22,10 +22,10 @@ The parameters are explained as follows. - sysinfo: Whether the user can view system information. 1 means they can view it, 0 means they cannot. System information includes server configuration information, various node information such as dnode, query node (qnode), etc., as well as storage-related information, etc. The default is to view system information. - createdb: Whether the user can create databases. 1 means they can create databases, 0 means they cannot. The default value is 0. // Supported starting from TDengine Enterprise version 3.3.2.0 -The following SQL can create a user named test with the password 123456 who can view system information. +The following SQL can create a user named test with the password abc123!@# who can view system information. ```sql -create user test pass '123456' sysinfo 1 +create user test pass 'abc123!@#' sysinfo 1 ``` ### Viewing Users diff --git a/docs/en/14-reference/03-taos-sql/25-user.md b/docs/en/14-reference/03-taos-sql/25-user.md index c658ef9621..04313a5da3 100644 --- a/docs/en/14-reference/03-taos-sql/25-user.md +++ b/docs/en/14-reference/03-taos-sql/25-user.md @@ -17,6 +17,8 @@ The password must be between 8 and 16 characters long and include at least three `SYSINFO` indicates whether the user can view system information. `1` means they can view, `0` means they have no permission to view. System information includes service configuration, dnode, vnode, storage, etc. The default value is `1`. +`CREATEDB` indicates whether the user can create databases. `1` means they can create databases, `0` means they have no permission to create databases. The default value is `0`. // Supported starting from TDengine Enterprise version 3.3.2.0 + In the example below, we create a user with the password `abc123!@#` who can view system information. ```sql diff --git a/docs/en/14-reference/09-error-code.md b/docs/en/14-reference/09-error-code.md index b28cf7f7fb..42b41c0b89 100644 --- a/docs/en/14-reference/09-error-code.md +++ b/docs/en/14-reference/09-error-code.md @@ -251,6 +251,7 @@ This document details the server error codes that may be encountered when using | 0x80000529 | Vnode is stopped | Vnode is closed | Report issue | | 0x80000530 | Duplicate write request | Duplicate write request, internal error | Report issue | | 0x80000531 | Vnode query is busy | Query is busy | Report issue | +| 0x80000540 | Vnode already exist but Dbid not match | Internal error | Report issue | ## tsdb diff --git a/docs/zh/14-reference/03-taos-sql/02-database.md b/docs/zh/14-reference/03-taos-sql/02-database.md index c561b7a624..c73ba9d5c3 100644 --- a/docs/zh/14-reference/03-taos-sql/02-database.md +++ b/docs/zh/14-reference/03-taos-sql/02-database.md @@ -64,7 +64,7 @@ database_option: { - DURATION:数据文件存储数据的时间跨度。可以使用加单位的表示形式,如 DURATION 100h、DURATION 10d 等,支持 m(分钟)、h(小时)和 d(天)三个单位。不加时间单位时默认单位为天,如 DURATION 50 表示 50 天。 - MAXROWS:文件块中记录的最大条数,默认为 4096 条。 - MINROWS:文件块中记录的最小条数,默认为 100 条。 -- KEEP:表示数据文件保存的天数,缺省值为 3650,取值范围 [1, 365000],且必须大于或等于3倍的 DURATION 参数值。数据库会自动删除保存时间超过 KEEP 值的数据从而释放存储空间。KEEP 可以使用加单位的表示形式,如 KEEP 100h、KEEP 10d 等,支持 m(分钟)、h(小时)和 d(天)三个单位。也可以不写单位,如 KEEP 50,此时默认单位为天。企业版支持[多级存储](../../operation/planning/#%E5%A4%9A%E7%BA%A7%E5%AD%98%E5%82%A8)功能, 因此, 可以设置多个保存时间(多个以英文逗号分隔,最多 3 个,满足 keep 0 \<= keep 1 \<= keep 2,如 KEEP 100h,100d,3650d); 社区版不支持多级存储功能(即使配置了多个保存时间, 也不会生效, KEEP 会取最大的保存时间)。 +- KEEP:表示数据文件保存的天数,缺省值为 3650,取值范围 [1, 365000],且必须大于或等于 3 倍的 DURATION 参数值。数据库会自动删除保存时间超过 KEEP 值的数据从而释放存储空间。KEEP 可以使用加单位的表示形式,如 KEEP 100h、KEEP 10d 等,支持 m(分钟)、h(小时)和 d(天)三个单位。也可以不写单位,如 KEEP 50,此时默认单位为天。企业版支持[多级存储](../../operation/planning/#%E5%A4%9A%E7%BA%A7%E5%AD%98%E5%82%A8)功能, 因此, 可以设置多个保存时间(多个以英文逗号分隔,最多 3 个,满足 keep 0 \<= keep 1 \<= keep 2,如 KEEP 100h,100d,3650d); 社区版不支持多级存储功能(即使配置了多个保存时间, 也不会生效, KEEP 会取最大的保存时间)。了解更多,请点击 [关于主键时间戳](https://docs.taosdata.com/reference/taos-sql/insert/) - KEEP_TIME_OFFSET:自 3.2.0.0 版本生效。删除或迁移保存时间超过 KEEP 值的数据的延迟执行时间,默认值为 0 (小时)。在数据文件保存时间超过 KEEP 后,删除或迁移操作不会立即执行,而会额外等待本参数指定的时间间隔,以实现与业务高峰期错开的目的。 - STT_TRIGGER:表示落盘文件触发文件合并的个数。开源版本固定为 1,企业版本可设置范围为 1 到 16。对于少表高频写入场景,此参数建议使用默认配置;而对于多表低频写入场景,此参数建议配置较大的值。 - SINGLE_STABLE:表示此数据库中是否只可以创建一个超级表,用于超级表列非常多的情况。 diff --git a/docs/zh/14-reference/03-taos-sql/25-user.md b/docs/zh/14-reference/03-taos-sql/25-user.md index dde6eba0b2..2cb915f5f9 100644 --- a/docs/zh/14-reference/03-taos-sql/25-user.md +++ b/docs/zh/14-reference/03-taos-sql/25-user.md @@ -18,6 +18,8 @@ CREATE USER user_name PASS 'password' [SYSINFO {1|0}] [CREATEDB {1|0}]; `SYSINFO` 表示该用户是否能够查看系统信息。`1` 表示可以查看,`0` 表示无权查看。系统信息包括服务配置、dnode、vnode、存储等信息。缺省值为 `1`。 +`CREATEDB` 表示该用户是否能够创建数据库。`1` 表示可以创建,`0` 表示无权创建。缺省值为 `0`。// 从 TDengine 企业版 3.3.2.0 开始支持 + 在下面的示例中,我们创建一个密码为 `abc123!@#` 且可以查看系统信息的用户。 ```sql diff --git a/docs/zh/14-reference/09-error-code.md b/docs/zh/14-reference/09-error-code.md index 6731a253df..1aee54ec67 100644 --- a/docs/zh/14-reference/09-error-code.md +++ b/docs/zh/14-reference/09-error-code.md @@ -261,6 +261,7 @@ description: TDengine 服务端的错误码列表和详细说明 | 0x80000529 | Vnode is stopped | Vnode 已经关闭 | 上报问题 | | 0x80000530 | Duplicate write request | 重复写入请求,内部错误 | 上报问题 | | 0x80000531 | Vnode query is busy | 查询忙碌 | 上报问题 | +| 0x80000540 | Vnode already exist but Dbid not match | 内部错误 | 上报问题 | ## tsdb diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 16b2fed254..a84b66d02a 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -565,6 +565,7 @@ int32_t taosGetErrSize(); #define TSDB_CODE_VND_ARB_NOT_SYNCED TAOS_DEF_ERROR_CODE(0, 0x0537) // internal #define TSDB_CODE_VND_WRITE_DISABLED TAOS_DEF_ERROR_CODE(0, 0x0538) // internal #define TSDB_CODE_VND_TTL_FLUSH_INCOMPLETION TAOS_DEF_ERROR_CODE(0, 0x0539) // internal +#define TSDB_CODE_VND_ALREADY_EXIST_BUT_NOT_MATCH TAOS_DEF_ERROR_CODE(0, 0x0540) // tsdb #define TSDB_CODE_TDB_INVALID_TABLE_ID TAOS_DEF_ERROR_CODE(0, 0x0600) diff --git a/source/client/test/connectOptionsTest.cpp b/source/client/test/connectOptionsTest.cpp index d44e43417b..95596e9ed3 100644 --- a/source/client/test/connectOptionsTest.cpp +++ b/source/client/test/connectOptionsTest.cpp @@ -299,8 +299,8 @@ TEST(connectionCase, setConnectionOption_Test) { taosMsleep(2 * HEARTBEAT_INTERVAL); //test user APP and user IP - check_sql_result(pConn, "select user_app from performance_schema.perf_connections", "aaaaaaaaaaaaaaaaaaaaaab"); - check_sql_result(pConn, "select user_ip from performance_schema.perf_connections", "192.168.0.2"); + check_sql_result_integer(pConn, "select count(*) from performance_schema.perf_connections where user_app = 'aaaaaaaaaaaaaaaaaaaaaab'", 1); + check_sql_result_integer(pConn, "select count(*) from performance_schema.perf_connections where user_ip = '192.168.0.2'", 1); code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_USER_IP, "192.168.1.2"); ASSERT(code == 0); @@ -313,9 +313,8 @@ TEST(connectionCase, setConnectionOption_Test) { taosMsleep(2 * HEARTBEAT_INTERVAL); - check_sql_result(pConn, "select user_app from performance_schema.perf_connections", "user"); - check_sql_result(pConn, "select user_ip from performance_schema.perf_connections", "192.168.1.2"); - + check_sql_result_integer(pConn, "select count(*) from performance_schema.perf_connections where user_app = 'user'", 1); + check_sql_result_integer(pConn, "select count(*) from performance_schema.perf_connections where user_ip = '192.168.1.2'", 1); // test clear code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_CLEAR, "192.168.0.2"); @@ -944,3 +943,4 @@ TEST(timezoneCase, localtime_performance_Test) { #endif #pragma GCC diagnostic pop + diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c index 78decaf698..8e8d70118b 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c @@ -378,12 +378,11 @@ int32_t vmProcessCreateVnodeReq(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) { snprintf(path, TSDB_FILENAME_LEN, "vnode%svnode%d", TD_DIRSEP, vnodeCfg.vgId); - if (vnodeCreate(path, &vnodeCfg, diskPrimary, pMgmt->pTfs) < 0) { - dError("vgId:%d, failed to create vnode since %s", req.vgId, terrstr()); + if ((code = vnodeCreate(path, &vnodeCfg, diskPrimary, pMgmt->pTfs)) < 0) { + dError("vgId:%d, failed to create vnode since %s", req.vgId, tstrerror(code)); vmReleaseVnode(pMgmt, pVnode); vmCleanPrimaryDisk(pMgmt, req.vgId); (void)tFreeSCreateVnodeReq(&req); - code = terrno != 0 ? terrno : -1; return code; } diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c index 6a61cc3859..537c1f6297 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c @@ -94,7 +94,7 @@ static void vmUnRegisterCreatingState(SVnodeMgmt *pMgmt, int32_t vgId) { dTrace("vgId:%d, remove from creating Hash", vgId); r = taosHashRemove(pMgmt->creatingHash, &vgId, sizeof(int32_t)); if (r != 0) { - dError("vgId:%d, failed to remove vnode from hash", vgId); + dError("vgId:%d, failed to remove vnode from creatingHash", vgId); } (void)taosThreadRwlockUnlock(&pMgmt->lock); diff --git a/source/dnode/vnode/src/meta/metaOpen.c b/source/dnode/vnode/src/meta/metaOpen.c index 9a5bea33e3..5351554631 100644 --- a/source/dnode/vnode/src/meta/metaOpen.c +++ b/source/dnode/vnode/src/meta/metaOpen.c @@ -138,6 +138,7 @@ static int32_t metaOpenImpl(SVnode *pVnode, SMeta **ppMeta, const char *metaDir, int32_t code = 0; int32_t lino; int32_t offset; + int32_t pathLen = 0; char path[TSDB_FILENAME_LEN] = {0}; char indexFullPath[128] = {0}; @@ -150,14 +151,15 @@ static int32_t metaOpenImpl(SVnode *pVnode, SMeta **ppMeta, const char *metaDir, taosRemoveDir(path); } - if ((pMeta = taosMemoryCalloc(1, sizeof(*pMeta) + strlen(path) + 1)) == NULL) { + pathLen = strlen(path) + 1; + if ((pMeta = taosMemoryCalloc(1, sizeof(*pMeta) + pathLen)) == NULL) { TSDB_CHECK_CODE(code = terrno, lino, _exit); } metaInitLock(pMeta); pMeta->path = (char *)&pMeta[1]; - strcpy(pMeta->path, path); + tstrncpy(pMeta->path, path, pathLen); int32_t ret = taosRealPath(pMeta->path, NULL, strlen(path) + 1); pMeta->pVnode = pVnode; diff --git a/source/dnode/vnode/src/meta/metaTable.c b/source/dnode/vnode/src/meta/metaTable.c index bce8bb3e29..c32d4b30b0 100644 --- a/source/dnode/vnode/src/meta/metaTable.c +++ b/source/dnode/vnode/src/meta/metaTable.c @@ -1189,7 +1189,7 @@ int metaCreateTable(SMeta *pMeta, int64_t ver, SVCreateTbReq *pReq, STableMetaRs (*pMetaRsp)->tableType = TSDB_CHILD_TABLE; (*pMetaRsp)->tuid = pReq->uid; (*pMetaRsp)->suid = pReq->ctb.suid; - strcpy((*pMetaRsp)->tbName, pReq->name); + tstrncpy((*pMetaRsp)->tbName, pReq->name, strlen(pReq->name) + 1); } else { ret = metaUpdateMetaRsp(pReq->uid, pReq->name, &pReq->ntb.schemaRow, *pMetaRsp); if (ret < 0) { @@ -1834,7 +1834,8 @@ static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAl pSchema->pSchema[entry.ntbEntry.schemaRow.nCols - 1].type = pAlterTbReq->type; pSchema->pSchema[entry.ntbEntry.schemaRow.nCols - 1].flags = pAlterTbReq->flags; pSchema->pSchema[entry.ntbEntry.schemaRow.nCols - 1].colId = entry.ntbEntry.ncid++; - strcpy(pSchema->pSchema[entry.ntbEntry.schemaRow.nCols - 1].name, pAlterTbReq->colName); + tstrncpy(pSchema->pSchema[entry.ntbEntry.schemaRow.nCols - 1].name, pAlterTbReq->colName, + strlen(pAlterTbReq->colName) + 1); ++pMeta->pVnode->config.vndStats.numOfNTimeSeries; metaTimeSeriesNotifyCheck(pMeta); @@ -1943,7 +1944,7 @@ static int metaAlterTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pAl goto _err; } pSchema->version++; - strcpy(pColumn->name, pAlterTbReq->colNewName); + tstrncpy(pColumn->name, pAlterTbReq->colNewName, strlen(pAlterTbReq->colNewName) + 1); break; } diff --git a/source/dnode/vnode/src/meta/metaTtl.c b/source/dnode/vnode/src/meta/metaTtl.c index 4077e9fa5d..2b67c27234 100644 --- a/source/dnode/vnode/src/meta/metaTtl.c +++ b/source/dnode/vnode/src/meta/metaTtl.c @@ -49,18 +49,20 @@ const char *ttlV1Tbname = "ttlv1.idx"; int32_t ttlMgrOpen(STtlManger **ppTtlMgr, TDB *pEnv, int8_t rollback, const char *logPrefix, int32_t flushThreshold) { int32_t code = TSDB_CODE_SUCCESS; int64_t startNs = taosGetTimestampNs(); + int32_t pathLen = 0; *ppTtlMgr = NULL; STtlManger *pTtlMgr = (STtlManger *)tdbOsCalloc(1, sizeof(*pTtlMgr)); if (pTtlMgr == NULL) TAOS_RETURN(terrno); - char *logBuffer = (char *)tdbOsCalloc(1, strlen(logPrefix) + 1); + pathLen = strlen(logPrefix) + 1; + char *logBuffer = (char *)tdbOsCalloc(1, pathLen); if (logBuffer == NULL) { tdbOsFree(pTtlMgr); TAOS_RETURN(terrno); } - (void)strcpy(logBuffer, logPrefix); + tstrncpy(logBuffer, logPrefix, pathLen); pTtlMgr->logPrefix = logBuffer; pTtlMgr->flushThreshold = flushThreshold; diff --git a/source/dnode/vnode/src/vnd/vnodeOpen.c b/source/dnode/vnode/src/vnd/vnodeOpen.c index e0dd17f93b..b91abe93af 100644 --- a/source/dnode/vnode/src/vnd/vnodeOpen.c +++ b/source/dnode/vnode/src/vnd/vnodeOpen.c @@ -67,8 +67,17 @@ int32_t vnodeCreate(const char *path, SVnodeCfg *pCfg, int32_t diskPrimary, STfs SVnodeInfo oldInfo = {0}; oldInfo.config = vnodeCfgDefault; if (vnodeLoadInfo(dir, &oldInfo) == 0) { - vWarn("vgId:%d, vnode config info already exists at %s.", oldInfo.config.vgId, dir); - return (oldInfo.config.dbId == info.config.dbId) ? 0 : -1; + code = (oldInfo.config.dbId == info.config.dbId) ? 0 : TSDB_CODE_VND_ALREADY_EXIST_BUT_NOT_MATCH; + if (code == 0) { + vWarn("vgId:%d, vnode config info already exists at %s.", oldInfo.config.vgId, dir); + } else { + vError("vgId:%d, vnode config info already exists at %s. oldDbId:%" PRId64 "(%s) at cluster:%" PRId64 + ", newDbId:%" PRId64 "(%s) at cluser:%" PRId64 ", code:%s", + oldInfo.config.vgId, dir, oldInfo.config.dbId, oldInfo.config.dbname, + oldInfo.config.syncCfg.nodeInfo[oldInfo.config.syncCfg.myIndex].clusterId, info.config.dbId, + info.config.dbname, info.config.syncCfg.nodeInfo[info.config.syncCfg.myIndex].clusterId, tstrerror(code)); + } + return code; } vInfo("vgId:%d, save config while create", info.config.vgId); diff --git a/source/libs/parser/src/parInsertStmt.c b/source/libs/parser/src/parInsertStmt.c index 9e6abe1517..b3c89a6b1c 100644 --- a/source/libs/parser/src/parInsertStmt.c +++ b/source/libs/parser/src/parInsertStmt.c @@ -1017,11 +1017,11 @@ int32_t qBuildStmtTagFields(void* pBlock, void* boundTags, int32_t* fieldNum, TA if (NULL == tags) { return TSDB_CODE_APP_ERROR; } - /* + if (pDataBlock->pMeta->tableType != TSDB_SUPER_TABLE && pDataBlock->pMeta->tableType != TSDB_CHILD_TABLE) { return TSDB_CODE_TSC_STMT_API_ERROR; } - */ + SSchema* pSchema = getTableTagSchema(pDataBlock->pMeta); if (tags->numOfBound <= 0) { *fieldNum = 0; diff --git a/source/util/src/terror.c b/source/util/src/terror.c index 88bc3092c9..4c576cfe96 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -443,6 +443,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_VND_ARB_NOT_SYNCED, "Vgroup peer is not sy TAOS_DEFINE_ERROR(TSDB_CODE_VND_WRITE_DISABLED, "Vnode write is disabled for snapshot") TAOS_DEFINE_ERROR(TSDB_CODE_VND_COLUMN_COMPRESS_ALREADY_EXIST,"Same with old param") TAOS_DEFINE_ERROR(TSDB_CODE_VND_TTL_FLUSH_INCOMPLETION, "Failed to flush all ttl modification to tdb") +TAOS_DEFINE_ERROR(TSDB_CODE_VND_ALREADY_EXIST_BUT_NOT_MATCH, "Vnode already exist but Dbid not match") // tsdb diff --git a/tests/script/api/passwdTest.c b/tests/script/api/passwdTest.c index 259d3bec8e..ca8392771e 100644 --- a/tests/script/api/passwdTest.c +++ b/tests/script/api/passwdTest.c @@ -267,7 +267,7 @@ void createUsers(TAOS *taos, const char *host, char *qstr) { } // alter pass for users - sprintf(qstr, "alter user %s pass 'taos'", users[i]); + sprintf(qstr, "alter user %s pass 'taos@123'", users[i]); queryDB(taos, qstr); } } @@ -302,7 +302,7 @@ void passVerTestMulti(const char *host, char *qstr) { queryDB(taos[0], "create table if not exists demo2.stb (ts timestamp, c1 int) tags(t1 int)"); queryDB(taos[0], "create table if not exists demo3.stb (ts timestamp, c1 int) tags(t1 int)"); - strcpy(qstr, "alter user root pass 'taos'"); + strcpy(qstr, "alter user root pass 'taos@123'"); queryDB(taos[0], qstr); // calculate the nPassVerNotified for root and users @@ -345,7 +345,7 @@ void sysInfoTest(TAOS *taosRoot, const char *host, char *qstr) { char userName[USER_LEN] = "user0"; for (int i = 0; i < nRoot; ++i) { - taos[i] = taos_connect(host, "user0", "taos", NULL, 0); + taos[i] = taos_connect(host, "user0", "taos@123", NULL, 0); if (taos[i] == NULL) { fprintf(stderr, "failed to connect to server, reason:%s\n", "null taos" /*taos_errstr(taos)*/); exit(1); @@ -427,7 +427,7 @@ _loop: printf("\n\n%s:%d LOOP %d, nTestUsers:%d\n", __func__, __LINE__, nLoop, nTestUsers); for (int i = 0; i < nTestUsers; ++i) { // sprintf(users[i], "user%d", i); - taosu[i] = taos_connect(host, users[i], "taos", NULL, 0); + taosu[i] = taos_connect(host, users[i], "taos@123", 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); @@ -476,7 +476,7 @@ _loop: nUserDropped = 0; for (int i = 0; i < nTestUsers; ++i) { sprintf(users[i], "user%d", i); - sprintf(qstr, "CREATE USER %s PASS 'taos'", users[i]); + sprintf(qstr, "CREATE USER %s PASS 'taos@123'", users[i]); fprintf(stderr, "%s:%d create user:%s\n", __func__, __LINE__, users[i]); queryDB(taos, qstr); }