From 25ad40756dec85bfa395441f525dff9023ff2251 Mon Sep 17 00:00:00 2001 From: deffpuzzl Date: Mon, 25 Jun 2018 09:09:45 +0800 Subject: [PATCH 1/3] fix M-SQL group by and order by --- include/tstr.h | 1 - src/stvm.c | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/include/tstr.h b/include/tstr.h index f61951f..4e9ca2a 100644 --- a/include/tstr.h +++ b/include/tstr.h @@ -62,7 +62,6 @@ #include #include #include -#define _GNU_SOURCE #include typedef short int sint; diff --git a/src/stvm.c b/src/stvm.c index 35c2026..01f2648 100644 --- a/src/stvm.c +++ b/src/stvm.c @@ -2988,7 +2988,7 @@ long _lSelectSyntax(SATvm *pstSavm, char *pszSQL, char *pszFile, char *pszDem return RC_FAIL; } - if((p = strcasestr(szWhere, "group")) || (p = strcasestr(szWhere, "order"))) + if((p = strcasestr(szWhere, " group ")) || (p = strcasestr(szWhere, " order "))) { strcpy(szAdorn, p); memset(p, 0, sizeof(szWhere) - (p - szWhere)); @@ -3008,7 +3008,7 @@ long _lSelectSyntax(SATvm *pstSavm, char *pszSQL, char *pszFile, char *pszDem } sltrim(szTable); - if((p = strcasestr(szTable, "group")) || (p = strcasestr(szTable, "order"))) + if((p = strcasestr(szTable, " group ")) || (p = strcasestr(szTable, " order "))) { strcpy(szAdorn, p); memset(p, 0, sizeof(szTable) - (p - szTable)); From 6c1d3731b56eaee281eb537ac3cf331b9b9e8e4d Mon Sep 17 00:00:00 2001 From: deffpuzzl Date: Tue, 24 Jul 2018 09:45:28 +0800 Subject: [PATCH 2/3] add multithread demo --- demo/makefile | 5 ++- demo/thread_demo.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++ src/func.c | 6 +++ src/tree.c | 1 + 4 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 demo/thread_demo.c diff --git a/demo/makefile b/demo/makefile index deedf20..85a6ce8 100755 --- a/demo/makefile +++ b/demo/makefile @@ -29,8 +29,9 @@ POPUP=popup PRESSURE=press_demo TVMPUSH=tvmpush ASYPUSH=asypush +THREAD=thread_demo -all: $(CREATE) $(INSERT) $(QUEUE) $(PUSH) $(POP) $(SELECT) $(QUERY) $(DELETE) $(UPDATE) $(COUNT) $(GROUP) $(EXTREME) $(TRUNCATE) $(DROP) $(PRESSURE) $(CLICK) $(POPUP) $(REPLACE) $(TVMPUSH) $(ASYPUSH) $(TVMPOP) $(TVMREPLACE) clean +all: $(CREATE) $(INSERT) $(QUEUE) $(PUSH) $(POP) $(SELECT) $(QUERY) $(DELETE) $(UPDATE) $(COUNT) $(GROUP) $(EXTREME) $(TRUNCATE) $(DROP) $(PRESSURE) $(CLICK) $(POPUP) $(REPLACE) $(TVMPUSH) $(ASYPUSH) $(TVMPOP) $(TVMREPLACE) $(THREAD) clean $(CREATE): create_table.o $(CC) -o $@ $< $(LIBDIR) $(TVMREPLACE): tvmreplace.o @@ -75,6 +76,8 @@ $(POPUP): popup.o $(CC) -o $@ $< $(LIBDIR) $(PRESSURE): press_demo.o $(CC) -o $@ $< $(LIBDIR) +$(THREAD): thread_demo.o + $(CC) -o $@ $< $(LIBDIR) .SUFFIXES: .c .o diff --git a/demo/thread_demo.c b/demo/thread_demo.c new file mode 100644 index 0000000..9ee4ffa --- /dev/null +++ b/demo/thread_demo.c @@ -0,0 +1,93 @@ +#include "tmain.h" + +#define QUEUE_USER_INFO 21 + +typedef struct __QUEUE_USER_INFO +{ + long acct_id; + char user_no[21]; + char user_type[2]; + char user_nm[81]; + char user_addr[161]; + char user_phone[31]; +}dbUser; + +typedef unsigned long long uint64; +extern uint64 get_tick_time(); + +typedef struct _ST_ARG_ +{ + int threadIndex; + uint64 rows; + uint64 start; +}ARG; + +void* vPushUserInfo(void *arg) +{ + int i = 0; + dbUser stUser; + ARG *pArgInfo = (ARG *)arg; + SATvm *pstSavm = (SATvm *)pCloneSATvm(); + + queueinit(pstSavm, stUser, QUEUE_USER_INFO); // 绑定变量 + for(i = 0; i < pArgInfo->rows; i++) + { + stUser.acct_id = pArgInfo->start + i; // 对结构体赋值 + strcpy(stUser.user_no, "20180223"); // 对结构体赋值 + strcpy(stUser.user_type, "1"); // 对结构体赋值 + strcpy(stUser.user_nm, "Savens Liu"); // 对结构体赋值 + strcpy(stUser.user_addr, "China"); // 对结构体赋值 + strcpy(stUser.user_phone, "18672911111"); // 对结构体赋值 + + if(RC_SUCC != lPush(pstSavm)) // 插入记录 + { + fprintf(stderr, "Insert error:(%d)(%s)\n", pstSavm->m_lErrno, + sGetTError(pstSavm->m_lErrno)); + return NULL; + } + } + + vCloneFree(pstSavm); + return NULL; +} + +int main(int argc, char *argv[]) +{ + uint64 uTime = 0; + ARG arg[100]; + pthread_t thread[10]; + int i = 0, j = 0, rows = 0, num; + SATvm *pstSavm = (SATvm *)pGetSATvm(); + + if(1 != argc) + num = strlen(argv[1])>0?atoi(argv[1]):1; + else + num = 1; + + /* 初始化QUEUE_USER_INFO表,每张表都需要初始化一次, 对于表重建后,需要重新初始化一次。*/ + vHoldConnect(pstSavm); + if(RC_SUCC != lAttchTable(pstSavm, QUEUE_USER_INFO)) + { + fprintf(stderr, "attch failed, err:(%d)(%s)\n", pstSavm->m_lErrno, sGetTError(pstSavm->m_lErrno)); + return RC_FAIL; + } + + rows = 4000000 / num; + for(uTime = get_tick_time(); i < num; i++) + { + arg[i].threadIndex = i + 1; + arg[i].start = rows * i; + arg[i].rows = rows; + pthread_create(&thread[i], NULL, vPushUserInfo, (void*)&arg[i]); + } + + for(j = 0; j < num; j++) + pthread_join(thread[j], NULL); + + fprintf(stdout, "cost_time:[%lld]\r\n", get_tick_time() - uTime); + vTvmDisconnect(pstSavm); + + fprintf(stdout, "新增记录成功, completed successfully!!!\n"); + fflush(stderr); + return RC_SUCC; +} diff --git a/src/func.c b/src/func.c index fc55903..fb71517 100644 --- a/src/func.c +++ b/src/func.c @@ -166,6 +166,12 @@ long lRestoreTables(SATvm *pstSavm) snprintf(szPath, sizeof(szPath), "%s/backup", getenv("TVMDBD")); if ((NULL == (dir = opendir(szPath)))) { + if(ENOENT == errno) + { + mkdir(szPath, S_IRWXU | S_IRGRP); + return RC_SUCC; + } + vRedeError(pstSavm->m_lErrno = 127, strerror(errno)); return RC_FAIL; } diff --git a/src/tree.c b/src/tree.c index c0fa570..f3811fb 100644 --- a/src/tree.c +++ b/src/tree.c @@ -569,6 +569,7 @@ long lAttchTable(SATvm *pstSovm, TABLE t) return RC_FAIL; memcpy((RunTime *)pGetRunTime(pstSovm, t), pstRun, sizeof(RunTime)); + vSetQueueAttch(pstRun, 1); return RC_SUCC; } From e8248418ca4f7eba8f4c1f673a4e4217e4ec1b11 Mon Sep 17 00:00:00 2001 From: deffpuzzl Date: Tue, 24 Jul 2018 09:55:01 +0800 Subject: [PATCH 3/3] add multithread demo --- README.MD | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/README.MD b/README.MD index ced56af..3deaa68 100644 --- a/README.MD +++ b/README.MD @@ -18,13 +18,14 @@ STVM(truck of Virtual memory table)是一个开源的使用ANSI C语言编 ***使用须知*** * 表空间大小在创建时已经确定, 一旦创建不能随意修改大小。 * 多机集群无法使用事务。 -* 数据无法持久化(宕机情况), 可以定时利用接口备份。 +* 数据无法持久化(宕机情况)。 * 索引长度限制(默认64字节),修改需编译项目。 * 启动后不能修改表字段,但可以修改字段别名 +* 单机模式下,进程要设置退出接口,避免kill -9将正在操作内存表的进程杀死造成死锁(可用stvm -l table来重置锁) 建议使用场景:***数据库缓存、数据缓存、事件驱动*** -不定时更新 https://my.oschina.net/deffpuzzl/blog/1627626 +不定时更新 https://my.oschina.net/deffpuzzl/blog/1627626 ## 1、编译 **编译项目** @@ -46,20 +47,17 @@ cd src目录 **./make** * **TVMCFG=$(TVMDBD)/.tvm.run** 启动参数 使用方法: -如果不使用多机集群,无需配置域文件,缺省本地启动(该版本对集群支持较弱, 时间有限,稍后更新,请悉知)。 +如果不使用多机集群,无需配置域文件,缺省本地启动。 -启动系统 +启动系统 > stvm -w -停止系统 -> stvm -s +停止系统 +> stvm -s STVM也提供一个类型sqlpuls类型简单工具。 -进入SQL界面, 该工具主要用来运维调试使用,其中showmode显示模式ROW|COLUMN,showsize单次显示记录数,也可用封装该指令的脚本**msql**进入 -> stvm SQL --showmode=row --showsize=8 - -批量执行M-SQL脚本**exsql**,也可直接执行 ->stvm SQL --msql=msql.bat +进入SQL界面, 该工具主要用来运维调试使用 +> stvm SQL 域的维护 > stvm DOM @@ -70,7 +68,7 @@ STVM也提供一个类型sqlpuls类型简单工具。 配置域完成后,可以配置编译到$TVMCFG下 > stvm -c stvm.conf -然后在 **stvm -w** 启动即可 +然后在stvm -w启动即可 建议以单机模式64位下运行,将性能发挥在极致。 @@ -124,10 +122,19 @@ STVM也提供一个类型sqlpuls类型简单工具。 创建队列语法示例: 在M-SQL中执行 create que_user_info.def - **下本版本:** * 1、新增多机资源共享方式。 -* 2、JAVA接口开发 +* 2、基于raft协议计算分布式集群 +* 3、JAVA接口开发 **不定时更新** + + + +--- +#### *常见错误集合* #### +``` +Q、failed to boot TVM, Invalid parameter or sem has disappeared +A:echo "500 X X X" > /proc/sys/kernel/sem +```