Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
慢慢CG
TDengine
提交
0ce56655
T
TDengine
项目概览
慢慢CG
/
TDengine
与 Fork 源项目一致
Fork自
taosdata / TDengine
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
0ce56655
编写于
8月 05, 2020
作者:
H
Haojun Liao
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[td-225] fix bug in hash and queryhandle management.
上级
4222cfcd
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
69 addition
and
78 deletion
+69
-78
src/inc/query.h
src/inc/query.h
+3
-0
src/query/src/qExecutor.c
src/query/src/qExecutor.c
+18
-38
src/util/src/hash.c
src/util/src/hash.c
+13
-5
src/util/src/tcache.c
src/util/src/tcache.c
+7
-2
src/vnode/src/vnodeRead.c
src/vnode/src/vnodeRead.c
+28
-33
未找到文件。
src/inc/query.h
浏览文件 @
0ce56655
...
...
@@ -76,6 +76,9 @@ void* qGetResultRetrieveMsg(qinfo_t qinfo);
*/
int32_t
qKillQuery
(
qinfo_t
qinfo
);
int32_t
qQueryCompleted
(
qinfo_t
qinfo
);
/**
* destroy query info structure
* @param qHandle
...
...
src/query/src/qExecutor.c
浏览文件 @
0ce56655
...
...
@@ -6432,34 +6432,6 @@ int32_t qRetrieveQueryResultInfo(qinfo_t qinfo, bool* buildRes, void* pRspContex
return
code
;
}
bool
qHasMoreResultsToRetrieve
(
qinfo_t
qinfo
)
{
SQInfo
*
pQInfo
=
(
SQInfo
*
)
qinfo
;
if
(
!
isValidQInfo
(
pQInfo
)
||
pQInfo
->
code
!=
TSDB_CODE_SUCCESS
)
{
qDebug
(
"QInfo:%p invalid qhandle or error occurs, abort query, code:%x"
,
pQInfo
,
pQInfo
->
code
);
return
false
;
}
SQuery
*
pQuery
=
pQInfo
->
runtimeEnv
.
pQuery
;
bool
ret
=
false
;
if
(
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_OVER
))
{
ret
=
false
;
}
else
if
(
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_RESBUF_FULL
))
{
ret
=
true
;
}
else
if
(
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_COMPLETED
))
{
ret
=
true
;
}
else
{
assert
(
0
);
}
if
(
ret
)
{
qDebug
(
"QInfo:%p has more results waits for client retrieve"
,
pQInfo
);
}
return
ret
;
}
int32_t
qDumpRetrieveResult
(
qinfo_t
qinfo
,
SRetrieveTableRsp
**
pRsp
,
int32_t
*
contLen
,
bool
*
continueExec
)
{
SQInfo
*
pQInfo
=
(
SQInfo
*
)
qinfo
;
...
...
@@ -6487,11 +6459,11 @@ int32_t qDumpRetrieveResult(qinfo_t qinfo, SRetrieveTableRsp **pRsp, int32_t *co
int32_t
code
=
pQInfo
->
code
;
if
(
code
==
TSDB_CODE_SUCCESS
)
{
(
*
pRsp
)
->
offset
=
htobe64
(
pQuery
->
limit
.
offset
);
(
*
pRsp
)
->
offset
=
htobe64
(
pQuery
->
limit
.
offset
);
(
*
pRsp
)
->
useconds
=
htobe64
(
pRuntimeEnv
->
summary
.
elapsedTime
);
}
else
{
(
*
pRsp
)
->
useconds
=
0
;
(
*
pRsp
)
->
offset
=
0
;
(
*
pRsp
)
->
offset
=
0
;
(
*
pRsp
)
->
useconds
=
htobe64
(
pRuntimeEnv
->
summary
.
elapsedTime
)
;
}
(
*
pRsp
)
->
precision
=
htons
(
pQuery
->
precision
);
...
...
@@ -6503,22 +6475,30 @@ int32_t qDumpRetrieveResult(qinfo_t qinfo, SRetrieveTableRsp **pRsp, int32_t *co
}
pQInfo
->
rspContext
=
NULL
;
pQInfo
->
dataReady
=
QUERY_RESULT_NOT_READY
;
pQInfo
->
dataReady
=
QUERY_RESULT_NOT_READY
;
if
(
IS_QUERY_KILLED
(
pQInfo
)
||
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_OVER
))
{
*
continueExec
=
false
;
(
*
pRsp
)
->
completed
=
1
;
// notify no more result to client
}
if
(
qHasMoreResultsToRetrieve
(
pQInfo
))
{
}
else
{
*
continueExec
=
true
;
}
else
{
// failed to dump result, free qhandle immediately
*
continueExec
=
false
;
qKillQuery
(
pQInfo
);
qDebug
(
"QInfo:%p has more results waits for client retrieve"
,
pQInfo
);
}
return
code
;
}
int32_t
qQueryCompleted
(
qinfo_t
qinfo
)
{
SQInfo
*
pQInfo
=
(
SQInfo
*
)
qinfo
;
if
(
pQInfo
==
NULL
||
!
isValidQInfo
(
pQInfo
))
{
return
TSDB_CODE_QRY_INVALID_QHANDLE
;
}
SQuery
*
pQuery
=
pQInfo
->
runtimeEnv
.
pQuery
;
return
IS_QUERY_KILLED
(
pQInfo
)
||
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_OVER
);
}
int32_t
qKillQuery
(
qinfo_t
qinfo
)
{
SQInfo
*
pQInfo
=
(
SQInfo
*
)
qinfo
;
...
...
src/util/src/hash.c
浏览文件 @
0ce56655
...
...
@@ -353,24 +353,32 @@ int32_t taosHashRemoveWithData(SHashObj *pHashObj, const void *key, size_t keyLe
int32_t
slot
=
HASH_INDEX
(
hashVal
,
pHashObj
->
capacity
);
SHashEntry
*
pe
=
pHashObj
->
hashList
[
slot
];
// no data, return directly
if
(
pe
->
num
==
0
)
{
assert
(
pe
->
next
==
NULL
);
__rd_unlock
(
&
pHashObj
->
lock
,
pHashObj
->
type
);
return
-
1
;
}
if
(
pHashObj
->
type
==
HASH_ENTRY_LOCK
)
{
taosWLockLatch
(
&
pe
->
latch
);
}
if
(
pe
->
num
==
0
)
{
assert
(
pe
->
next
==
NULL
);
}
else
{
assert
(
pe
->
next
!=
NULL
);
}
//
no data, return directly
//
double check after locked
if
(
pe
->
num
==
0
)
{
assert
(
pe
->
next
==
NULL
);
taosWUnLockLatch
(
&
pe
->
latch
);
__rd_unlock
(
&
pHashObj
->
lock
,
pHashObj
->
type
);
return
-
1
;
}
if
(
pHashObj
->
type
==
HASH_ENTRY_LOCK
)
{
taosWLockLatch
(
&
pe
->
latch
);
}
SHashNode
*
pNode
=
pe
->
next
;
SHashNode
*
pRes
=
NULL
;
...
...
src/util/src/tcache.c
浏览文件 @
0ce56655
...
...
@@ -438,8 +438,8 @@ void taosCacheRelease(SCacheObj *pCacheObj, void **data, bool _remove) {
char
*
key
=
pNode
->
key
;
char
*
d
=
pNode
->
data
;
int32_t
ref
=
T_REF_
DEC
(
pNode
);
uDebug
(
"cache:%s, key:%p, %p is released, refcnt:%d"
,
pCacheObj
->
name
,
key
,
d
,
ref
);
int32_t
ref
=
T_REF_
VAL_GET
(
pNode
);
uDebug
(
"cache:%s, key:%p, %p is released, refcnt:%d"
,
pCacheObj
->
name
,
key
,
d
,
ref
-
1
);
/*
* If it is not referenced by other users, remove it immediately. Otherwise move this node to trashcan wait for all users
...
...
@@ -449,6 +449,8 @@ void taosCacheRelease(SCacheObj *pCacheObj, void **data, bool _remove) {
* that tries to do the same thing.
*/
if
(
inTrashCan
)
{
ref
=
T_REF_DEC
(
pNode
);
if
(
ref
==
0
)
{
assert
(
pNode
->
pTNodeHeader
->
pData
==
pNode
);
...
...
@@ -459,7 +461,10 @@ void taosCacheRelease(SCacheObj *pCacheObj, void **data, bool _remove) {
doDestroyTrashcanElem
(
pCacheObj
,
pNode
->
pTNodeHeader
);
}
}
else
{
// NOTE: remove it from hash in the first place, otherwise, the pNode may have been released by other thread
// when reaches here.
int32_t
ret
=
taosHashRemove
(
pCacheObj
->
pHashTable
,
pNode
->
key
,
pNode
->
keySize
);
ref
=
T_REF_DEC
(
pNode
);
// successfully remove from hash table, if failed, this node must have been move to trash already, do nothing.
// note that the remove operation can be executed only once.
...
...
src/vnode/src/vnodeRead.c
浏览文件 @
0ce56655
...
...
@@ -66,7 +66,7 @@ int32_t vnodeProcessRead(void *param, SReadMsg *pReadMsg) {
return
(
*
vnodeProcessReadMsgFp
[
msgType
])(
pVnode
,
pReadMsg
);
}
static
void
vnodePutItemIntoReadQueue
(
SVnodeObj
*
pVnode
,
void
*
qhandle
)
{
static
void
vnodePutItemIntoReadQueue
(
SVnodeObj
*
pVnode
,
void
*
*
qhandle
)
{
SReadMsg
*
pRead
=
(
SReadMsg
*
)
taosAllocateQitem
(
sizeof
(
SReadMsg
));
pRead
->
rpcMsg
.
msgType
=
TSDB_MSG_TYPE_QUERY
;
pRead
->
pCont
=
qhandle
;
...
...
@@ -75,22 +75,22 @@ static void vnodePutItemIntoReadQueue(SVnodeObj *pVnode, void *qhandle) {
atomic_add_fetch_32
(
&
pVnode
->
refCount
,
1
);
vDebug
(
"QInfo:%p add to
query task queue for exec, msg:%p"
,
qhandle
,
pRead
);
vDebug
(
"QInfo:%p add to
vread queue for exec query, msg:%p"
,
*
qhandle
,
pRead
);
taosWriteQitem
(
pVnode
->
rqueue
,
TAOS_QTYPE_QUERY
,
pRead
);
}
static
int32_t
vnodeDumpQueryResult
(
SRspRet
*
pRet
,
void
*
pVnode
,
void
*
handle
,
bool
*
freeHandle
)
{
static
int32_t
vnodeDumpQueryResult
(
SRspRet
*
pRet
,
void
*
pVnode
,
void
*
*
handle
,
bool
*
freeHandle
)
{
bool
continueExec
=
false
;
int32_t
code
=
TSDB_CODE_SUCCESS
;
if
((
code
=
qDumpRetrieveResult
(
handle
,
(
SRetrieveTableRsp
**
)
&
pRet
->
rsp
,
&
pRet
->
len
,
&
continueExec
))
==
TSDB_CODE_SUCCESS
)
{
if
((
code
=
qDumpRetrieveResult
(
*
handle
,
(
SRetrieveTableRsp
**
)
&
pRet
->
rsp
,
&
pRet
->
len
,
&
continueExec
))
==
TSDB_CODE_SUCCESS
)
{
if
(
continueExec
)
{
*
freeHandle
=
false
;
vnodePutItemIntoReadQueue
(
pVnode
,
handle
);
pRet
->
qhandle
=
handle
;
pRet
->
qhandle
=
*
handle
;
}
else
{
*
freeHandle
=
true
;
vDebug
(
"QInfo:%p exec completed, free handle:%d"
,
handle
,
*
freeHandle
);
vDebug
(
"QInfo:%p exec completed, free handle:%d"
,
*
handle
,
*
freeHandle
);
}
}
else
{
pRet
->
rsp
=
(
SRetrieveTableRsp
*
)
rpcMallocCont
(
sizeof
(
SRetrieveTableRsp
));
...
...
@@ -181,50 +181,45 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) {
if
(
handle
!=
NULL
)
{
vDebug
(
"vgId:%d, QInfo:%p, dnode query msg disposed, create qhandle and returns to app"
,
vgId
,
*
handle
);
vnodePutItemIntoReadQueue
(
pVnode
,
*
handle
);
vnodePutItemIntoReadQueue
(
pVnode
,
handle
);
}
}
else
{
assert
(
pCont
!=
NULL
);
void
**
qhandle
=
(
void
**
)
pCont
;
// *handle = /*(void*) */pCont;
handle
=
qAcquireQInfo
(
pVnode
->
qMgmt
,
(
uint64_t
)
pCont
);
if
(
handle
==
NULL
)
{
vWarn
(
"QInfo:%p invalid qhandle in continuing exec query, conn:%p"
,
(
void
*
)
pCont
,
pReadMsg
->
rpcMsg
.
handle
);
code
=
TSDB_CODE_QRY_INVALID_QHANDLE
;
}
else
{
vDebug
(
"vgId:%d, QInfo:%p, dnode continues to exec query"
,
pVnode
->
vgId
,
(
void
*
)
pCont
);
//
handle = qAcquireQInfo(pVnode->qMgmt, (uint64_t) pCont);
//
if (handle == NULL) {
//
vWarn("QInfo:%p invalid qhandle in continuing exec query, conn:%p", (void*) pCont, pReadMsg->rpcMsg.handle);
//
code = TSDB_CODE_QRY_INVALID_QHANDLE;
//
} else {
vDebug
(
"vgId:%d, QInfo:%p, dnode continues to exec query"
,
pVnode
->
vgId
,
*
qhandle
);
bool
freehandle
=
false
;
bool
buildRes
=
qTableQuery
(
*
handle
);
// do execute query
bool
buildRes
=
qTableQuery
(
*
q
handle
);
// do execute query
// build query rsp, the retrieve request has reached here already
if
(
buildRes
)
{
// update the connection info according to the retrieve connection
pReadMsg
->
rpcMsg
.
handle
=
qGetResultRetrieveMsg
(
*
handle
);
pReadMsg
->
rpcMsg
.
handle
=
qGetResultRetrieveMsg
(
*
q
handle
);
assert
(
pReadMsg
->
rpcMsg
.
handle
!=
NULL
);
vDebug
(
"vgId:%d, QInfo:%p, start to build retrieval rsp after query paused, %p"
,
pVnode
->
vgId
,
*
handle
,
vDebug
(
"vgId:%d, QInfo:%p, start to build retrieval rsp after query paused, %p"
,
pVnode
->
vgId
,
*
q
handle
,
pReadMsg
->
rpcMsg
.
handle
);
code
=
vnodeDumpQueryResult
(
&
pReadMsg
->
rspRet
,
pVnode
,
*
handle
,
&
freehandle
);
code
=
vnodeDumpQueryResult
(
&
pReadMsg
->
rspRet
,
pVnode
,
q
handle
,
&
freehandle
);
// todo test the error code case
if
(
code
==
TSDB_CODE_SUCCESS
)
{
code
=
TSDB_CODE_QRY_HAS_RSP
;
}
}
else
{
freehandle
=
qQueryCompleted
(
*
qhandle
);
}
// If retrieval request has not arrived, release the qhandle and decrease the reference count to allow
// the queryMgmt to free it when expired
void
**
dup
=
handle
;
qReleaseQInfo
(
pVnode
->
qMgmt
,
(
void
**
)
&
handle
,
false
);
// NOTE:
// if the qhandle is put into query vread queue and wait to be executed by worker in read queue,
// the reference count of qhandle can not be decreased. Otherwise, qhandle may be released before or in the
// procedure of query execution
if
(
freehandle
)
{
qReleaseQInfo
(
pVnode
->
qMgmt
,
(
void
**
)
&
dup
,
freehandle
);
// NOTE: if the qhandle is not put into vread queue or query is completed, free the qhandle.
if
(
freehandle
||
(
!
buildRes
))
{
qReleaseQInfo
(
pVnode
->
qMgmt
,
(
void
**
)
&
qhandle
,
freehandle
);
}
}
}
return
code
;
...
...
@@ -269,7 +264,7 @@ static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) {
//TODO handle malloc failure
pRet
->
rsp
=
(
SRetrieveTableRsp
*
)
rpcMallocCont
(
sizeof
(
SRetrieveTableRsp
));
memset
(
pRet
->
rsp
,
0
,
sizeof
(
SRetrieveTableRsp
));
qReleaseQInfo
(
pVnode
->
qMgmt
,
(
void
**
)
&
handle
,
freeHandl
e
);
qReleaseQInfo
(
pVnode
->
qMgmt
,
(
void
**
)
&
handle
,
tru
e
);
}
else
{
// result is not ready, return immediately
if
(
!
buildRes
)
{
qReleaseQInfo
(
pVnode
->
qMgmt
,
(
void
**
)
&
handle
,
false
);
...
...
@@ -277,12 +272,12 @@ static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SReadMsg *pReadMsg) {
}
void
**
dup
=
handle
;
code
=
vnodeDumpQueryResult
(
pRet
,
pVnode
,
*
handle
,
&
freeHandle
);
code
=
vnodeDumpQueryResult
(
pRet
,
pVnode
,
handle
,
&
freeHandle
);
qReleaseQInfo
(
pVnode
->
qMgmt
,
(
void
**
)
&
handle
,
false
);
// not added into task queue,
free it
immediate
// not added into task queue,
the query must be completed already, free qhandle
immediate
if
(
freeHandle
)
{
qReleaseQInfo
(
pVnode
->
qMgmt
,
(
void
**
)
&
dup
,
freeHandl
e
);
qReleaseQInfo
(
pVnode
->
qMgmt
,
(
void
**
)
&
dup
,
tru
e
);
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录