Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
58392c19
TDengine
项目概览
taosdata
/
TDengine
大约 2 年 前同步成功
通知
1192
Star
22018
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
58392c19
编写于
9月 25, 2022
作者:
Z
zhihaop
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: refactor tscBatchWrite and tscBatchMerge for better code readability
上级
138bf9b2
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
438 addition
and
175 deletion
+438
-175
packaging/cfg/taos.cfg
packaging/cfg/taos.cfg
+1
-1
src/client/inc/tscBatchMerge.h
src/client/inc/tscBatchMerge.h
+8
-7
src/client/inc/tscBatchWrite.h
src/client/inc/tscBatchWrite.h
+215
-0
src/client/inc/tsclient.h
src/client/inc/tsclient.h
+8
-8
src/client/src/tscAsync.c
src/client/src/tscAsync.c
+3
-3
src/client/src/tscBatchMerge.c
src/client/src/tscBatchMerge.c
+5
-5
src/client/src/tscBatchWrite.c
src/client/src/tscBatchWrite.c
+180
-133
src/client/src/tscSystem.c
src/client/src/tscSystem.c
+17
-17
src/common/src/tglobal.c
src/common/src/tglobal.c
+1
-1
未找到文件。
packaging/cfg/taos.cfg
浏览文件 @
58392c19
...
@@ -317,7 +317,7 @@ keepColumnName 1
...
@@ -317,7 +317,7 @@ keepColumnName 1
# enable thread local batch dispatcher
# enable thread local batch dispatcher
# asyncBatchThreadLocal 1
# asyncBatchThreadLocal 1
# taosc async insertion batch size, maximum
65535
# taosc async insertion batch size, maximum
4096
# asyncBatchSize 256
# asyncBatchSize 256
# taosc async batching timeout in milliseconds, maximum 2048
# taosc async batching timeout in milliseconds, maximum 2048
...
...
src/client/inc/tsc
DataBlock
Merge.h
→
src/client/inc/tsc
Batch
Merge.h
浏览文件 @
58392c19
...
@@ -13,8 +13,8 @@
...
@@ -13,8 +13,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
*/
#ifndef TDENGINE_TSC
DATABLOCK
MERGE_H
#ifndef TDENGINE_TSC
BATCH
MERGE_H
#define TDENGINE_TSC
DATABLOCK
MERGE_H
#define TDENGINE_TSC
BATCH
MERGE_H
#include "hash.h"
#include "hash.h"
#include "taosmsg.h"
#include "taosmsg.h"
...
@@ -260,14 +260,15 @@ SName** buildSTableNameListBuilder(STableNameListBuilder* builder, size_t* numOf
...
@@ -260,14 +260,15 @@ SName** buildSTableNameListBuilder(STableNameListBuilder* builder, size_t* numOf
* Merge the KV-PayLoad SQL objects into single one.
* Merge the KV-PayLoad SQL objects into single one.
* The statements here must be an insertion statement and no schema attached.
* The statements here must be an insertion statement and no schema attached.
*
*
* @param statements the array of statements. a.k.a SArray<SSqlObj*>.
* @param polls the array of SSqlObj*.
* @param result the returned result. result is not null!
* @param nPolls the number of SSqlObj* in the array.
* @return the status code. usually TSDB_CODE_SUCCESS.
* @param result the returned result. result is not null!
* @return the status code.
*/
*/
int32_t
tscMerge
KVPayLoadSqlObj
(
SArray
*
statement
s
,
SSqlObj
*
result
);
int32_t
tscMerge
SSqlObjs
(
SSqlObj
**
polls
,
size_t
nPoll
s
,
SSqlObj
*
result
);
#ifdef __cplusplus
#ifdef __cplusplus
}
}
#endif
#endif
#endif // TDENGINE_TSC
DATABLOCK
MERGE_H
#endif // TDENGINE_TSC
BATCH
MERGE_H
src/client/inc/tscB
ulk
Write.h
→
src/client/inc/tscB
atch
Write.h
浏览文件 @
58392c19
...
@@ -13,78 +13,139 @@
...
@@ -13,78 +13,139 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
*/
#ifndef TDENGINE_TSCB
ULK
WRITE_H
#ifndef TDENGINE_TSCB
ATCH
WRITE_H
#define TDENGINE_TSCB
ULK
WRITE_H
#define TDENGINE_TSCB
ATCH
WRITE_H
#ifdef __cplusplus
#ifdef __cplusplus
extern
"C"
{
extern
"C"
{
#endif
#endif
#include "tarray.h"
#include "tthread.h"
#include "tthread.h"
// forward declaration.
// forward declaration.
typedef
struct
SSqlObj
SSqlObj
;
typedef
struct
SSqlObj
SSqlObj
;
typedef
struct
SDispatcherTimeoutManager
SDispatcherTimeoutManager
;
/**
/**
* SAsyncBulkWriteDispatcher is an async batching dispatcher(for writing), it can buffer insertion statements, batch
* SAsyncBatchWriteDispatcher is an async batching write dispatcher (ABWD). ABWD accepts the recent SQL requests and put
* and merge them into single statement.
* them in a queue waiting to be scheduled. When the number of requests in the queue reaches batch_size, it merges the
* requests in the queue and sends them to the server, thus reducing the network overhead caused by multiple
* communications to the server and directly improving the throughput of small object asynchronous writes.
*/
*/
typedef
struct
SAsyncB
ulk
WriteDispatcher
{
typedef
struct
SAsyncB
atch
WriteDispatcher
{
// the
buffer to store the insertion statements. equivalent to SArray<SSqlObj*>
.
// the
timeout manager
.
S
Array
*
buff
er
;
S
DispatcherTimeoutManager
*
timeoutManag
er
;
// the mutex to protect the dispatcher.
// the mutex to protect the dispatcher.
pthread_mutex_t
bufferMutex
;
pthread_mutex_t
bufferMutex
;
// the mutex to sleep the background thread.
pthread_mutex_t
sleepMutex
;
// the cond to signal to background thread.
pthread_cond_t
timeout
;
// the cond to signal when buffer not full.
// the cond to signal when buffer not full.
pthread_cond_t
notFull
;
pthread_cond_t
notFull
;
// the background thread to manage batching timeout.
pthread_t
background
;
// the maximum number of insertion rows in a batch.
// the maximum number of insertion rows in a batch.
int32_t
batchSize
;
int32_t
batchSize
;
// the batching timeout in milliseconds.
int32_t
timeoutMs
;
// the number of insertion rows in the buffer.
// the number of insertion rows in the buffer.
int32_t
currentSize
;
int32_t
currentSize
;
// the number of items in the buffer.
int32_t
bufferSize
;
// whether the dispatcher is shutdown.
// whether the dispatcher is shutdown.
volatile
bool
shutdown
;
volatile
bool
shutdown
;
}
SAsyncBulkWriteDispatcher
;
// forward declaration.
SSqlObj
*
buffer
[];
typedef
struct
SSqlObj
SSqlObj
;
}
SAsyncBatchWriteDispatcher
;
/**
* The manager of SAsyncBatchWriteDispatcher. Call dispatcherAcquire(...) to get the SAsyncBatchWriteDispatcher
* instance. SDispatcherManager will manage the life cycle of SAsyncBatchWriteDispatcher.
*/
typedef
struct
SDispatcherManager
{
pthread_key_t
key
;
// the maximum number of insertion rows in a batch.
int32_t
batchSize
;
// the batching timeout in milliseconds.
int32_t
timeoutMs
;
// specifies whether the dispatcher is thread local, if the dispatcher is not
// thread local, we will use the global dispatcher below.
bool
isThreadLocal
;
// the global dispatcher, if thread local enabled, global will be set to NULL.
SAsyncBatchWriteDispatcher
*
global
;
}
SDispatcherManager
;
/**
* Control the timeout of the dispatcher queue.
*/
typedef
struct
SDispatcherTimeoutManager
{
// the dispatcher that timeout manager belongs to.
SAsyncBatchWriteDispatcher
*
dispatcher
;
// the background thread.
pthread_t
background
;
// the mutex to sleep the background thread.
pthread_mutex_t
sleepMutex
;
// the cond to signal to background thread.
pthread_cond_t
timeout
;
// the batching timeout in milliseconds.
int32_t
timeoutMs
;
// whether the timeout manager is shutdown.
volatile
bool
shutdown
;
}
SDispatcherTimeoutManager
;
/**
* Create the dispatcher timeout manager.
*/
SDispatcherTimeoutManager
*
createSDispatcherTimeoutManager
(
SAsyncBatchWriteDispatcher
*
dispatcher
,
int32_t
timeoutMs
);
/**
* Destroy the dispatcher timeout manager.
*/
void
destroySDispatcherTimeoutManager
(
SDispatcherTimeoutManager
*
manager
);
/**
* Check if the timeout manager is shutdown.
* @param manager the timeout manager.
* @return whether the timeout manager is shutdown.
*/
bool
isShutdownSDispatcherTimeoutManager
(
SDispatcherTimeoutManager
*
manager
);
/**
* Shutdown the SDispatcherTimeoutManager.
* @param manager the SDispatcherTimeoutManager.
*/
void
shutdownSDispatcherTimeoutManager
(
SDispatcherTimeoutManager
*
manager
);
/**
/**
* Merge the statements into single SSqlObj.
* Merge the statements into single SSqlObj.
*
*
* @param fp the callback of SSqlObj.
* @param fp the callback of SSqlObj.
* @param param the parameters of the callback.
* @param param the parameters of the callback.
* @param statements the sql statements represents in SArray<SSqlObj*>.
* @param polls the array of SSqlObj*.
* @return the merged SSqlObj.
* @param nPolls the number of SSqlObj* in the array.
* @return the merged SSqlObj.
*/
*/
int32_t
dispatcher
StatementMerge
(
SArray
*
statement
s
,
SSqlObj
**
result
);
int32_t
dispatcher
BatchMerge
(
SSqlObj
**
polls
,
size_t
nPoll
s
,
SSqlObj
**
result
);
/**
/**
* Merge the sql statements and execute the merged sql statement.
* Merge the sql statements and execute the merged sql statement.
*
*
* @param statements the array of sql statement. a.k.a SArray<SSqlObj*>.
* @param polls the array of SSqlObj*.
* @param nPolls the number of SSqlObj* in the array.
*/
*/
void
dispatcherExecute
(
S
Array
*
statement
s
);
void
dispatcherExecute
(
S
SqlObj
**
polls
,
size_t
nPoll
s
);
/**
/**
* Create the async b
ulk
write dispatcher.
* Create the async b
atch
write dispatcher.
*
*
* @param batchSize When user submit an insert statement to `taos_query_ra`, the statement will be buffered
* @param batchSize When user submit an insert statement to `taos_query_ra`, the statement will be buffered
* asynchronously in the buffer instead of executing it. If the number of the buffered
* asynchronously in the buffer instead of executing it. If the number of the buffered
...
@@ -92,25 +153,25 @@ void dispatcherExecute(SArray* statements);
...
@@ -92,25 +153,25 @@ void dispatcherExecute(SArray* statements);
* @param timeout The statements will be sent to vnodes no more than timeout milliseconds. But the actual time
* @param timeout The statements will be sent to vnodes no more than timeout milliseconds. But the actual time
* vnodes received the statements depends on the network quality.
* vnodes received the statements depends on the network quality.
*/
*/
SAsyncB
ulkWriteDispatcher
*
createAsyncBulk
WriteDispatcher
(
int32_t
batchSize
,
int32_t
timeoutMs
);
SAsyncB
atchWriteDispatcher
*
createSAsyncBatch
WriteDispatcher
(
int32_t
batchSize
,
int32_t
timeoutMs
);
/**
/**
* Destroy the async auto batch dispatcher.
* Destroy the async auto batch dispatcher.
*/
*/
void
destroy
AsyncDispatcher
(
SAsyncBulk
WriteDispatcher
*
dispatcher
);
void
destroy
SAsyncBatchWriteDispatcher
(
SAsyncBatch
WriteDispatcher
*
dispatcher
);
/**
/**
* Check if the current sql object
supports bulk insertion
.
* Check if the current sql object
can be dispatch by ABWD
.
* 1. auto batch feature on the sql object must be enabled.
* 1. auto batch feature on the sql object must be enabled.
* 2. must be an `insert into ... value ...` statement.
* 2. must be an `insert into ... value ...` statement.
* 3. the payload type must be kv payload.
* 3. the payload type must be kv payload.
* 4. no schema attached.
* 4. no schema attached.
*
*
* @param dispatcher
the async
dispatcher.
* @param dispatcher
the
dispatcher.
* @param pSql the sql object to check.
* @param pSql
the sql object to check.
* @return
returns true if the sql object supports auto batch
.
* @return
returns true if the sql object can be dispatch by ABWD
.
*/
*/
bool
tscSupportBulkInsertion
(
SAsyncBulk
WriteDispatcher
*
dispatcher
,
SSqlObj
*
pSql
);
bool
dispatcherCanDispatch
(
SAsyncBatch
WriteDispatcher
*
dispatcher
,
SSqlObj
*
pSql
);
/**
/**
* Try to offer the SSqlObj* to the dispatcher. If the number of row reach `batchSize`, the function
* Try to offer the SSqlObj* to the dispatcher. If the number of row reach `batchSize`, the function
...
@@ -119,58 +180,36 @@ bool tscSupportBulkInsertion(SAsyncBulkWriteDispatcher* dispatcher, SSqlObj* pSq
...
@@ -119,58 +180,36 @@ bool tscSupportBulkInsertion(SAsyncBulkWriteDispatcher* dispatcher, SSqlObj* pSq
* @param pSql the insert statement to offer.
* @param pSql the insert statement to offer.
* @return if offer success, returns true.
* @return if offer success, returns true.
*/
*/
bool
dispatcherTryDispatch
(
SAsyncBulkWriteDispatcher
*
dispatcher
,
SSqlObj
*
pSql
);
bool
dispatcherTryDispatch
(
SAsyncBatchWriteDispatcher
*
dispatcher
,
SSqlObj
*
pSql
);
/**
* A holder of SAsyncBulkWriteDispatcher. Call dispatcherAcquire(...) to get the SAsyncBulkWriteDispatcher
* instance. This holder will manage the life cycle of SAsyncBulkWriteDispatcher.
*/
typedef
struct
SDispatcherHolder
{
pthread_key_t
key
;
// the maximum number of insertion rows in a batch.
int32_t
batchSize
;
// the batching timeout in milliseconds.
int32_t
timeoutMs
;
// specifies whether the dispatcher is thread local, if the dispatcher is not
// thread local, we will use the global dispatcher below.
bool
isThreadLocal
;
// the global dispatcher, if thread local enabled, global will be set to NULL.
SAsyncBulkWriteDispatcher
*
global
;
}
SDispatcherHolder
;
/**
/**
* Create
a holder of SAsyncBulk
WriteDispatcher.
* Create
the manager of SAsyncBatch
WriteDispatcher.
*
*
* @param batchSize the batchSize of SAsyncB
ulk
WriteDispatcher.
* @param batchSize the batchSize of SAsyncB
atch
WriteDispatcher.
* @param timeoutMs the timeoutMs of SAsyncB
ulk
WriteDispatcher.
* @param timeoutMs the timeoutMs of SAsyncB
atch
WriteDispatcher.
* @param isThreadLocal specifies whether the dispatcher is thread local.
* @param isThreadLocal specifies whether the dispatcher is thread local.
* @return the SAsyncB
ulkWriteDispatcher hold
er.
* @return the SAsyncB
atchWriteDispatcher manag
er.
*/
*/
SDispatcher
Holder
*
createDispatcherHold
er
(
int32_t
batchSize
,
int32_t
timeoutMs
,
bool
isThreadLocal
);
SDispatcher
Manager
*
createDispatcherManag
er
(
int32_t
batchSize
,
int32_t
timeoutMs
,
bool
isThreadLocal
);
/**
/**
* Destroy the
holder of SAsyncBulkWriteDispatch
er.
* Destroy the
SDispatcherManag
er.
* (will destroy all the instances of SAsyncB
ulk
WriteDispatcher in the thread local variable)
* (will destroy all the instances of SAsyncB
atch
WriteDispatcher in the thread local variable)
*
*
* @param
holder the holder of SAsyncBulkWriteDispatch
er.
* @param
manager the SDispatcherManag
er.
*/
*/
void
destroyDispatcher
Holder
(
SDispatcherHolder
*
hold
er
);
void
destroyDispatcher
Manager
(
SDispatcherManager
*
manag
er
);
/**
/**
* Get an instance of SAsyncB
ulk
WriteDispatcher.
* Get an instance of SAsyncB
atch
WriteDispatcher.
*
*
* @param
holder the holder of SAsyncBulkWriteDispatch
er.
* @param
manager the SDispatcherManag
er.
* @return
the SAsyncBulk
WriteDispatcher instance.
* @return
the SAsyncBatch
WriteDispatcher instance.
*/
*/
SAsyncB
ulkWriteDispatcher
*
dispatcherAcquire
(
SDispatcherHolder
*
hold
er
);
SAsyncB
atchWriteDispatcher
*
dispatcherAcquire
(
SDispatcherManager
*
manag
er
);
#ifdef __cplusplus
#ifdef __cplusplus
}
}
#endif
#endif
#endif // TDENGINE_TSCB
ULK
WRITE_H
#endif // TDENGINE_TSCB
ATCH
WRITE_H
src/client/inc/tsclient.h
浏览文件 @
58392c19
...
@@ -511,18 +511,18 @@ int32_t taos_unused_session(TAOS* taos);
...
@@ -511,18 +511,18 @@ int32_t taos_unused_session(TAOS* taos);
void
waitForQueryRsp
(
void
*
param
,
TAOS_RES
*
tres
,
int
code
);
void
waitForQueryRsp
(
void
*
param
,
TAOS_RES
*
tres
,
int
code
);
/**
/**
* Init the
taosc async bulk
write dispatcher.
* Init the
manager of async batch
write dispatcher.
*
*
* @param batchSize
the batchSize of async bulk
write dispatcher.
* @param batchSize
the batchSize of async batch
write dispatcher.
* @param timeoutMs the timeout of batching in milliseconds.
* @param timeoutMs
the timeout of batching in milliseconds.
* @param isThreadLocal specifies whether the dispatcher is thread local.
* @param isThreadLocal specifies whether the dispatcher is thread local.
*/
*/
void
tscInit
AsyncDispatch
er
(
int32_t
batchSize
,
int32_t
timeoutMs
,
bool
isThreadLocal
);
void
tscInit
DispatcherManag
er
(
int32_t
batchSize
,
int32_t
timeoutMs
,
bool
isThreadLocal
);
/**
/**
* Destroy the
async auto batch
dispatcher.
* Destroy the
manager of async batch write
dispatcher.
*/
*/
void
tscDestroy
AsyncDispatch
er
();
void
tscDestroy
DispatcherManag
er
();
void
doAsyncQuery
(
STscObj
*
pObj
,
SSqlObj
*
pSql
,
__async_cb_func_t
fp
,
void
*
param
,
const
char
*
sqlstr
,
size_t
sqlLen
);
void
doAsyncQuery
(
STscObj
*
pObj
,
SSqlObj
*
pSql
,
__async_cb_func_t
fp
,
void
*
param
,
const
char
*
sqlstr
,
size_t
sqlLen
);
...
@@ -553,8 +553,8 @@ extern SHashObj *tscTableMetaMap;
...
@@ -553,8 +553,8 @@ extern SHashObj *tscTableMetaMap;
extern
SCacheObj
*
tscVgroupListBuf
;
extern
SCacheObj
*
tscVgroupListBuf
;
// forward declaration.
// forward declaration.
typedef
struct
SDispatcher
Holder
SDispatcherHold
er
;
typedef
struct
SDispatcher
Manager
SDispatcherManag
er
;
extern
SDispatcher
Holder
*
tscDispatch
er
;
extern
SDispatcher
Manager
*
tscDispatcherManag
er
;
extern
int
tscObjRef
;
extern
int
tscObjRef
;
extern
void
*
tscTmr
;
extern
void
*
tscTmr
;
extern
void
*
tscQhandle
;
extern
void
*
tscQhandle
;
...
...
src/client/src/tscAsync.c
浏览文件 @
58392c19
...
@@ -22,11 +22,11 @@
...
@@ -22,11 +22,11 @@
#include "qTableMeta.h"
#include "qTableMeta.h"
#include "tnote.h"
#include "tnote.h"
#include "trpc.h"
#include "trpc.h"
#include "tscBatchWrite.h"
#include "tscLog.h"
#include "tscLog.h"
#include "tscSubquery.h"
#include "tscSubquery.h"
#include "tscUtil.h"
#include "tscUtil.h"
#include "tsclient.h"
#include "tsclient.h"
#include "tscBulkWrite.h"
static
void
tscAsyncQueryRowsForNextVnode
(
void
*
param
,
TAOS_RES
*
tres
,
int
numOfRows
);
static
void
tscAsyncQueryRowsForNextVnode
(
void
*
param
,
TAOS_RES
*
tres
,
int
numOfRows
);
...
@@ -395,8 +395,8 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para
...
@@ -395,8 +395,8 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para
return
;
return
;
}
}
if
(
tscDispatcher
!=
NULL
)
{
if
(
tscDispatcher
Manager
!=
NULL
)
{
SAsyncB
ulkWriteDispatcher
*
dispatcher
=
dispatcherAcquire
(
tscDispatch
er
);
SAsyncB
atchWriteDispatcher
*
dispatcher
=
dispatcherAcquire
(
tscDispatcherManag
er
);
if
(
dispatcherTryDispatch
(
dispatcher
,
pSql
))
{
if
(
dispatcherTryDispatch
(
dispatcher
,
pSql
))
{
taosReleaseRef
(
tscObjRef
,
pSql
->
self
);
taosReleaseRef
(
tscObjRef
,
pSql
->
self
);
tscDebug
(
"sql obj %p has been buffer in insert buffer"
,
pSql
);
tscDebug
(
"sql obj %p has been buffer in insert buffer"
,
pSql
);
...
...
src/client/src/tsc
DataBlock
Merge.c
→
src/client/src/tsc
Batch
Merge.c
浏览文件 @
58392c19
...
@@ -13,7 +13,7 @@
...
@@ -13,7 +13,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
*/
#include "tsc
DataBlock
Merge.h"
#include "tsc
Batch
Merge.h"
/**
/**
* A util function to compare two SName.
* A util function to compare two SName.
...
@@ -456,9 +456,9 @@ bool insertSTableNameListBuilder(STableNameListBuilder* builder, SName* name) {
...
@@ -456,9 +456,9 @@ bool insertSTableNameListBuilder(STableNameListBuilder* builder, SName* name) {
return
taosArrayPush
(
builder
->
tableNames
,
&
name
);
return
taosArrayPush
(
builder
->
tableNames
,
&
name
);
}
}
int32_t
tscMerge
KVPayLoadSqlObj
(
SArray
*
statement
s
,
SSqlObj
*
result
)
{
int32_t
tscMerge
SSqlObjs
(
SSqlObj
**
polls
,
size_t
nPoll
s
,
SSqlObj
*
result
)
{
// statement array is empty.
// statement array is empty.
if
(
!
statements
||
!
taosArrayGetSize
(
statements
)
)
{
if
(
!
polls
||
!
nPolls
)
{
return
TSDB_CODE_TSC_INVALID_OPERATION
;
return
TSDB_CODE_TSC_INVALID_OPERATION
;
}
}
...
@@ -474,8 +474,8 @@ int32_t tscMergeKVPayLoadSqlObj(SArray* statements, SSqlObj* result) {
...
@@ -474,8 +474,8 @@ int32_t tscMergeKVPayLoadSqlObj(SArray* statements, SSqlObj* result) {
}
}
// append the existing data blocks to builder.
// append the existing data blocks to builder.
for
(
size_t
i
=
0
;
i
<
taosArrayGetSize
(
statements
)
;
++
i
)
{
for
(
size_t
i
=
0
;
i
<
nPolls
;
++
i
)
{
SSqlObj
*
pSql
=
taosArrayGetP
(
statements
,
i
)
;
SSqlObj
*
pSql
=
polls
[
i
]
;
SInsertStatementParam
*
pInsertParam
=
&
pSql
->
cmd
.
insertParam
;
SInsertStatementParam
*
pInsertParam
=
&
pSql
->
cmd
.
insertParam
;
if
(
!
pInsertParam
->
pDataBlocks
)
{
if
(
!
pInsertParam
->
pDataBlocks
)
{
continue
;
continue
;
...
...
src/client/src/tscB
ulk
Write.c
→
src/client/src/tscB
atch
Write.c
浏览文件 @
58392c19
...
@@ -15,11 +15,11 @@
...
@@ -15,11 +15,11 @@
#include "osAtomic.h"
#include "osAtomic.h"
#include "tscDataBlockMerge.h"
#include "tscBatchMerge.h"
#include "tscBulkWrite.h"
#include "tscBatchWrite.h"
#include "tscLog.h"
#include "tscSubquery.h"
#include "tscSubquery.h"
#include "tsclient.h"
#include "tsclient.h"
#include "tscLog.h"
/**
/**
* Represents the callback function and its context.
* Represents the callback function and its context.
...
@@ -27,15 +27,15 @@
...
@@ -27,15 +27,15 @@
typedef
struct
{
typedef
struct
{
__async_cb_func_t
fp
;
__async_cb_func_t
fp
;
void
*
param
;
void
*
param
;
}
Runnable
;
}
SCallbackHandler
;
/**
/**
* The context of `batchResultCallback`.
* The context of `batchResultCallback`.
*/
*/
typedef
struct
{
typedef
struct
{
size_t
count
;
size_t
nHandlers
;
Runnable
runnable
[];
SCallbackHandler
handler
[];
}
BatchCallB
ackContext
;
}
SBatchCallb
ackContext
;
/**
/**
* Get the number of insertion row in the sql statement.
* Get the number of insertion row in the sql statement.
...
@@ -70,8 +70,8 @@ inline static void tscReturnsError(SSqlObj* pSql, int code) {
...
@@ -70,8 +70,8 @@ inline static void tscReturnsError(SSqlObj* pSql, int code) {
* @param code the error code.
* @param code the error code.
*/
*/
static
void
batchResultCallback
(
void
*
param
,
TAOS_RES
*
tres
,
int32_t
code
)
{
static
void
batchResultCallback
(
void
*
param
,
TAOS_RES
*
tres
,
int32_t
code
)
{
BatchCallBackContext
*
context
=
param
;
SBatchCallbackContext
*
context
=
param
;
SSqlObj
*
res
=
tres
;
SSqlObj
*
res
=
tres
;
// handle corner case [context == null].
// handle corner case [context == null].
if
(
context
==
NULL
)
{
if
(
context
==
NULL
)
{
...
@@ -90,32 +90,27 @@ static void batchResultCallback(void* param, TAOS_RES* tres, int32_t code) {
...
@@ -90,32 +90,27 @@ static void batchResultCallback(void* param, TAOS_RES* tres, int32_t code) {
}
}
// handle results.
// handle results.
tscDebug
(
"async batch result callback, number of item: %zu"
,
context
->
count
);
tscDebug
(
"async batch result callback, number of item: %zu"
,
context
->
nHandlers
);
for
(
int
i
=
0
;
i
<
context
->
count
;
++
i
)
{
for
(
int
i
=
0
;
i
<
context
->
nHandlers
;
++
i
)
{
// the result object is shared by many sql objects.
// the result object is shared by many sql objects.
// therefore, we need to increase the ref count.
// therefore, we need to increase the ref count.
taosAcquireRef
(
tscObjRef
,
res
->
self
);
taosAcquireRef
(
tscObjRef
,
res
->
self
);
Runnable
*
runnable
=
&
context
->
runnable
[
i
];
SCallbackHandler
*
handler
=
&
context
->
handler
[
i
];
runnable
->
fp
(
runnable
->
param
,
res
,
res
==
NULL
?
code
:
taos_errno
(
res
)
);
handler
->
fp
(
handler
->
param
,
res
,
code
);
}
}
taosReleaseRef
(
tscObjRef
,
res
->
self
);
taosReleaseRef
(
tscObjRef
,
res
->
self
);
free
(
context
);
free
(
context
);
}
}
int32_t
dispatcher
StatementMerge
(
SArray
*
statement
s
,
SSqlObj
**
result
)
{
int32_t
dispatcher
BatchMerge
(
SSqlObj
**
polls
,
size_t
nPoll
s
,
SSqlObj
**
result
)
{
if
(
statements
==
NULL
)
{
if
(
!
polls
||
!
nPolls
)
{
return
TSDB_CODE_SUCCESS
;
return
TSDB_CODE_SUCCESS
;
}
}
size_t
count
=
taosArrayGetSize
(
statements
);
if
(
count
==
0
)
{
return
TSDB_CODE_SUCCESS
;
}
// create the callback context.
// create the callback context.
BatchCallBackContext
*
context
=
calloc
(
1
,
sizeof
(
BatchCallBackContext
)
+
count
*
sizeof
(
Runnable
));
SBatchCallbackContext
*
context
=
calloc
(
1
,
sizeof
(
SBatchCallbackContext
)
+
nPolls
*
sizeof
(
SCallbackHandler
));
if
(
context
==
NULL
)
{
if
(
context
==
NULL
)
{
return
TSDB_CODE_TSC_OUT_OF_MEMORY
;
return
TSDB_CODE_TSC_OUT_OF_MEMORY
;
}
}
...
@@ -123,17 +118,17 @@ int32_t dispatcherStatementMerge(SArray* statements, SSqlObj** result) {
...
@@ -123,17 +118,17 @@ int32_t dispatcherStatementMerge(SArray* statements, SSqlObj** result) {
tscDebug
(
"create batch call back context: %p"
,
context
);
tscDebug
(
"create batch call back context: %p"
,
context
);
// initialize the callback context.
// initialize the callback context.
context
->
count
=
count
;
context
->
nHandlers
=
nPolls
;
for
(
size_t
i
=
0
;
i
<
count
;
++
i
)
{
for
(
size_t
i
=
0
;
i
<
nPolls
;
++
i
)
{
SSqlObj
*
statement
=
taosArrayGetP
(
statements
,
i
)
;
SSqlObj
*
pSql
=
polls
[
i
]
;
context
->
runnable
[
i
].
fp
=
statement
->
fp
;
context
->
handler
[
i
].
fp
=
pSql
->
fp
;
context
->
runnable
[
i
].
param
=
statement
->
param
;
context
->
handler
[
i
].
param
=
pSql
->
param
;
}
}
// merge the statements into single one.
// merge the statements into single one.
tscDebug
(
"start to merge %zu sql objs"
,
count
);
tscDebug
(
"start to merge %zu sql objs"
,
nPolls
);
SSqlObj
*
pFirst
=
taosArrayGetP
(
statements
,
0
)
;
SSqlObj
*
pFirst
=
polls
[
0
]
;
int32_t
code
=
tscMerge
KVPayLoadSqlObj
(
statement
s
,
pFirst
);
int32_t
code
=
tscMerge
SSqlObjs
(
polls
,
nPoll
s
,
pFirst
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
const
char
*
msg
=
tstrerror
(
code
);
const
char
*
msg
=
tstrerror
(
code
);
tscDebug
(
"failed to merge sql objects: %s"
,
msg
);
tscDebug
(
"failed to merge sql objects: %s"
,
msg
);
...
@@ -147,8 +142,8 @@ int32_t dispatcherStatementMerge(SArray* statements, SSqlObj** result) {
...
@@ -147,8 +142,8 @@ int32_t dispatcherStatementMerge(SArray* statements, SSqlObj** result) {
pFirst
->
fetchFp
=
pFirst
->
fp
;
pFirst
->
fetchFp
=
pFirst
->
fp
;
*
result
=
pFirst
;
*
result
=
pFirst
;
for
(
int
i
=
1
;
i
<
count
;
++
i
)
{
for
(
int
i
=
1
;
i
<
nPolls
;
++
i
)
{
SSqlObj
*
pSql
=
taosArrayGetP
(
statements
,
i
)
;
SSqlObj
*
pSql
=
polls
[
i
]
;
taosReleaseRef
(
tscObjRef
,
pSql
->
self
);
taosReleaseRef
(
tscObjRef
,
pSql
->
self
);
}
}
return
code
;
return
code
;
...
@@ -159,36 +154,43 @@ int32_t dispatcherStatementMerge(SArray* statements, SSqlObj** result) {
...
@@ -159,36 +154,43 @@ int32_t dispatcherStatementMerge(SArray* statements, SSqlObj** result) {
* you need to notify dispatcher->notFull by yourself.
* you need to notify dispatcher->notFull by yourself.
*
*
* @param dispatcher the dispatcher.
* @param dispatcher the dispatcher.
* @return the items in the dispatcher, SArray<SSqlObj*>.
* @param nPolls the number of polled SSqlObj*.
* @return all the SSqlObj* in the buffer.
*/
*/
inline
static
SArray
*
dispatcherPollAll
(
SAsyncBulkWriteDispatcher
*
dispatcher
)
{
inline
static
SSqlObj
**
dispatcherPollAll
(
SAsyncBatchWriteDispatcher
*
dispatcher
,
size_t
*
nPolls
)
{
if
(
!
taosArrayGetSize
(
dispatcher
->
buffer
))
{
if
(
!
dispatcher
->
bufferSize
)
{
*
nPolls
=
0
;
return
NULL
;
return
NULL
;
}
}
S
Array
*
statements
=
taosArrayDup
(
dispatcher
->
buffer
);
S
SqlObj
**
clone
=
malloc
(
sizeof
(
SSqlObj
*
)
*
dispatcher
->
bufferSize
);
if
(
statements
==
NULL
)
{
if
(
clone
==
NULL
)
{
tscError
(
"failed to poll all items: out of memory"
);
tscError
(
"failed to poll all items: out of memory"
);
*
nPolls
=
0
;
return
NULL
;
return
NULL
;
}
}
memcpy
(
clone
,
dispatcher
->
buffer
,
sizeof
(
SSqlObj
*
)
*
dispatcher
->
bufferSize
);
*
nPolls
=
dispatcher
->
bufferSize
;
dispatcher
->
currentSize
=
0
;
dispatcher
->
currentSize
=
0
;
taosArrayClear
(
dispatcher
->
buffer
)
;
dispatcher
->
bufferSize
=
0
;
return
statements
;
return
clone
;
}
}
/**
/**
* Poll all the SSqlObj* in the dispatcher's buffer.
* Poll all the SSqlObj* in the dispatcher's buffer.
*
*
* @param dispatcher the dispatcher.
* @param dispatcher the dispatcher.
* @return the items in the dispatcher, SArray<SSqlObj*>.
* @param nPolls the number of polled SSqlObj*.
* @return all the SSqlObj* in the buffer.
*/
*/
inline
static
SArray
*
dispatcherLockPollAll
(
SAsyncBulkWriteDispatcher
*
dispatcher
)
{
inline
static
SSqlObj
**
dispatcherLockPollAll
(
SAsyncBatchWriteDispatcher
*
dispatcher
,
size_t
*
nPolls
)
{
SSqlObj
**
polls
=
NULL
;
pthread_mutex_lock
(
&
dispatcher
->
bufferMutex
);
pthread_mutex_lock
(
&
dispatcher
->
bufferMutex
);
SArray
*
statements
=
dispatcherPollAll
(
dispatcher
);
polls
=
dispatcherPollAll
(
dispatcher
,
nPolls
);
pthread_cond_broadcast
(
&
dispatcher
->
notFull
);
pthread_cond_broadcast
(
&
dispatcher
->
notFull
);
pthread_mutex_unlock
(
&
dispatcher
->
bufferMutex
);
pthread_mutex_unlock
(
&
dispatcher
->
bufferMutex
);
return
statement
s
;
return
poll
s
;
}
}
/**
/**
...
@@ -198,7 +200,7 @@ inline static SArray* dispatcherLockPollAll(SAsyncBulkWriteDispatcher* dispatche
...
@@ -198,7 +200,7 @@ inline static SArray* dispatcherLockPollAll(SAsyncBulkWriteDispatcher* dispatche
* @param pSql the sql object to offer.
* @param pSql the sql object to offer.
* @return return whether offer success.
* @return return whether offer success.
*/
*/
inline
static
bool
dispatcherTryOffer
(
SAsyncB
ulk
WriteDispatcher
*
dispatcher
,
SSqlObj
*
pSql
)
{
inline
static
bool
dispatcherTryOffer
(
SAsyncB
atch
WriteDispatcher
*
dispatcher
,
SSqlObj
*
pSql
)
{
pthread_mutex_lock
(
&
dispatcher
->
bufferMutex
);
pthread_mutex_lock
(
&
dispatcher
->
bufferMutex
);
// if dispatcher is shutdown, must fail back to normal insertion.
// if dispatcher is shutdown, must fail back to normal insertion.
...
@@ -216,44 +218,51 @@ inline static bool dispatcherTryOffer(SAsyncBulkWriteDispatcher* dispatcher, SSq
...
@@ -216,44 +218,51 @@ inline static bool dispatcherTryOffer(SAsyncBulkWriteDispatcher* dispatcher, SSq
}
}
}
}
taosArrayPush
(
dispatcher
->
buffer
,
pSql
)
;
dispatcher
->
buffer
[
dispatcher
->
bufferSize
++
]
=
pSql
;
dispatcher
->
currentSize
+=
statementGetInsertionRows
(
pSql
);
dispatcher
->
currentSize
+=
statementGetInsertionRows
(
pSql
);
tscDebug
(
"sql obj %p has been write to insert buffer"
,
pSql
);
tscDebug
(
"sql obj %p has been write to insert buffer"
,
pSql
);
// the dispatcher has been shutdown or reach batch size.
if
(
dispatcher
->
currentSize
<
dispatcher
->
batchSize
)
{
if
(
atomic_load_8
(
&
dispatcher
->
shutdown
)
||
dispatcher
->
currentSize
>=
dispatcher
->
batchSize
)
{
pthread_mutex_unlock
(
&
dispatcher
->
bufferMutex
);
SArray
*
statements
=
dispatcherPollAll
(
dispatcher
);
return
true
;
dispatcherExecute
(
statements
);
taosArrayDestroy
(
&
statements
);
pthread_cond_broadcast
(
&
dispatcher
->
notFull
);
}
}
// the dispatcher reaches batch size.
size_t
nPolls
=
0
;
SSqlObj
**
polls
=
dispatcherPollAll
(
dispatcher
,
&
nPolls
);
pthread_cond_broadcast
(
&
dispatcher
->
notFull
);
pthread_mutex_unlock
(
&
dispatcher
->
bufferMutex
);
pthread_mutex_unlock
(
&
dispatcher
->
bufferMutex
);
if
(
polls
)
{
dispatcherExecute
(
polls
,
nPolls
);
free
(
polls
);
}
return
true
;
return
true
;
}
}
void
dispatcherExecute
(
S
Array
*
statement
s
)
{
void
dispatcherExecute
(
S
SqlObj
**
polls
,
size_t
nPoll
s
)
{
int32_t
code
=
TSDB_CODE_SUCCESS
;
int32_t
code
=
TSDB_CODE_SUCCESS
;
// no item in the buffer (items has been taken by other threads).
// no item in the buffer (items has been taken by other threads).
if
(
!
statements
||
!
taosArrayGetSize
(
statements
)
)
{
if
(
!
polls
||
!
nPolls
)
{
return
;
return
;
}
}
// merge the statements into single one.
// merge the statements into single one.
SSqlObj
*
merged
=
NULL
;
SSqlObj
*
merged
=
NULL
;
code
=
dispatcher
StatementMerge
(
statement
s
,
&
merged
);
code
=
dispatcher
BatchMerge
(
polls
,
nPoll
s
,
&
merged
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
goto
_error
;
goto
_error
;
}
}
tscDebug
(
"merging %zu sql objs into %p"
,
taosArrayGetSize
(
statements
)
,
merged
);
tscDebug
(
"merging %zu sql objs into %p"
,
nPolls
,
merged
);
tscHandleMultivnodeInsert
(
merged
);
tscHandleMultivnodeInsert
(
merged
);
return
;
return
;
_error:
_error:
tscError
(
"send async batch sql obj failed, reason: %s"
,
tstrerror
(
code
));
tscError
(
"send async batch sql obj failed, reason: %s"
,
tstrerror
(
code
));
// handling the failures.
// handling the failures.
for
(
size_t
i
=
0
;
i
<
taosArrayGetSize
(
statements
)
;
++
i
)
{
for
(
size_t
i
=
0
;
i
<
nPolls
;
++
i
)
{
SSqlObj
*
item
=
taosArrayGetP
(
statements
,
i
)
;
SSqlObj
*
item
=
polls
[
i
]
;
tscReturnsError
(
item
,
code
);
tscReturnsError
(
item
,
code
);
}
}
}
}
...
@@ -277,77 +286,69 @@ static inline void afterMillis(struct timespec *t, int32_t millis) {
...
@@ -277,77 +286,69 @@ static inline void afterMillis(struct timespec *t, int32_t millis) {
* @param dispatcher the dispatcher thread to sleep.
* @param dispatcher the dispatcher thread to sleep.
* @param timeout the timeout in CLOCK_REALTIME.
* @param timeout the timeout in CLOCK_REALTIME.
*/
*/
inline
static
void
dispatcherSleepUntil
(
SAsyncBulkWriteDispatcher
*
dispatch
er
,
struct
timespec
*
timeout
)
{
inline
static
void
timeoutManagerSleepUntil
(
SDispatcherTimeoutManager
*
manag
er
,
struct
timespec
*
timeout
)
{
pthread_mutex_lock
(
&
dispatch
er
->
sleepMutex
);
pthread_mutex_lock
(
&
manag
er
->
sleepMutex
);
while
(
true
)
{
while
(
true
)
{
// notified by dispatcherShutdown(...).
// notified by dispatcherShutdown(...).
if
(
atomic_load_8
(
&
dispatcher
->
shutdown
))
{
if
(
isShutdownSDispatcherTimeoutManager
(
manager
))
{
break
;
break
;
}
}
if
(
pthread_cond_timedwait
(
&
dispatcher
->
timeout
,
&
dispatch
er
->
sleepMutex
,
timeout
))
{
if
(
pthread_cond_timedwait
(
&
manager
->
timeout
,
&
manag
er
->
sleepMutex
,
timeout
))
{
fflush
(
stdout
);
fflush
(
stdout
);
break
;
break
;
}
}
}
}
pthread_mutex_unlock
(
&
dispatch
er
->
sleepMutex
);
pthread_mutex_unlock
(
&
manag
er
->
sleepMutex
);
}
}
/**
/**
* The thread to manage batching timeout.
* The thread to manage batching timeout.
*/
*/
static
void
*
dispatcherTimeout
Callback
(
void
*
arg
)
{
static
void
*
timeoutManager
Callback
(
void
*
arg
)
{
S
AsyncBulkWriteDispatcher
*
dispatch
er
=
arg
;
S
DispatcherTimeoutManager
*
manag
er
=
arg
;
setThreadName
(
"tscAsyncBackground"
);
setThreadName
(
"tscAsyncBackground"
);
while
(
!
atomic_load_8
(
&
dispatcher
->
shutdown
))
{
while
(
!
isShutdownSDispatcherTimeoutManager
(
manager
))
{
struct
timespec
timeout
;
struct
timespec
timeout
;
clock_gettime
(
CLOCK_REALTIME
,
&
timeout
);
clock_gettime
(
CLOCK_REALTIME
,
&
timeout
);
afterMillis
(
&
timeout
,
dispatcher
->
timeoutMs
);
afterMillis
(
&
timeout
,
manager
->
timeoutMs
);
size_t
nPolls
=
0
;
SSqlObj
**
polls
=
dispatcherLockPollAll
(
manager
->
dispatcher
,
&
nPolls
);
SArray
*
statements
=
dispatcherLockPollAll
(
dispatcher
);
if
(
polls
)
{
dispatcherExecute
(
statements
);
dispatcherExecute
(
polls
,
nPolls
);
taosArrayDestroy
(
&
statements
);
free
(
polls
);
}
// Similar to scheduleAtFixedRate in Java, if the execution time exceed
// Similar to scheduleAtFixedRate in Java, if the execution time exceed
// `timeoutMs` milliseconds, then there will be no sleep.
// `timeoutMs` milliseconds, then there will be no sleep.
dispatcherSleepUntil
(
dispatch
er
,
&
timeout
);
timeoutManagerSleepUntil
(
manag
er
,
&
timeout
);
}
}
return
NULL
;
return
NULL
;
}
}
SAsyncB
ulkWriteDispatcher
*
createAsyncBulk
WriteDispatcher
(
int32_t
batchSize
,
int32_t
timeoutMs
)
{
SAsyncB
atchWriteDispatcher
*
createSAsyncBatch
WriteDispatcher
(
int32_t
batchSize
,
int32_t
timeoutMs
)
{
SAsyncB
ulkWriteDispatcher
*
dispatcher
=
calloc
(
1
,
sizeof
(
SAsyncBulkWriteDispatcher
));
SAsyncB
atchWriteDispatcher
*
dispatcher
=
calloc
(
1
,
sizeof
(
SAsyncBatchWriteDispatcher
)
+
batchSize
*
sizeof
(
SSqlObj
*
));
if
(
!
dispatcher
)
{
if
(
!
dispatcher
)
{
return
NULL
;
return
NULL
;
}
}
dispatcher
->
currentSize
=
0
;
dispatcher
->
currentSize
=
0
;
dispatcher
->
bufferSize
=
0
;
dispatcher
->
batchSize
=
batchSize
;
dispatcher
->
batchSize
=
batchSize
;
dispatcher
->
timeoutMs
=
timeoutMs
;
atomic_store_8
(
&
dispatcher
->
shutdown
,
false
);
atomic_store_8
(
&
dispatcher
->
shutdown
,
false
);
// init the buffer.
dispatcher
->
buffer
=
taosArrayInit
(
batchSize
,
sizeof
(
SSqlObj
*
));
if
(
!
dispatcher
->
buffer
)
{
tfree
(
dispatcher
);
return
NULL
;
}
// init the mutex and the cond.
// init the mutex and the cond.
pthread_mutex_init
(
&
dispatcher
->
bufferMutex
,
NULL
);
pthread_mutex_init
(
&
dispatcher
->
bufferMutex
,
NULL
);
pthread_mutex_init
(
&
dispatcher
->
sleepMutex
,
NULL
);
pthread_cond_init
(
&
dispatcher
->
timeout
,
NULL
);
pthread_cond_init
(
&
dispatcher
->
notFull
,
NULL
);
pthread_cond_init
(
&
dispatcher
->
notFull
,
NULL
);
// init background thread.
// init timeout manager.
if
(
pthread_create
(
&
dispatcher
->
background
,
NULL
,
dispatcherTimeoutCallback
,
dispatcher
))
{
dispatcher
->
timeoutManager
=
createSDispatcherTimeoutManager
(
dispatcher
,
timeoutMs
);
if
(
!
dispatcher
->
timeoutManager
)
{
pthread_mutex_destroy
(
&
dispatcher
->
bufferMutex
);
pthread_mutex_destroy
(
&
dispatcher
->
bufferMutex
);
pthread_mutex_destroy
(
&
dispatcher
->
sleepMutex
);
pthread_cond_destroy
(
&
dispatcher
->
timeout
);
pthread_cond_destroy
(
&
dispatcher
->
notFull
);
pthread_cond_destroy
(
&
dispatcher
->
notFull
);
taosArrayDestroy
(
&
dispatcher
->
buffer
);
free
(
dispatcher
);
tfree
(
dispatcher
);
return
NULL
;
return
NULL
;
}
}
...
@@ -359,18 +360,14 @@ SAsyncBulkWriteDispatcher* createAsyncBulkWriteDispatcher(int32_t batchSize, int
...
@@ -359,18 +360,14 @@ SAsyncBulkWriteDispatcher* createAsyncBulkWriteDispatcher(int32_t batchSize, int
*
*
* @param dispatcher the dispatcher.
* @param dispatcher the dispatcher.
*/
*/
inline
static
void
dispatcherShutdown
(
SAsyncBulkWriteDispatcher
*
dispatcher
)
{
inline
static
void
dispatcherShutdown
(
SAsyncBatchWriteDispatcher
*
dispatcher
)
{
// mark shutdown, signal shutdown to timeout thread.
pthread_mutex_lock
(
&
dispatcher
->
sleepMutex
);
atomic_store_8
(
&
dispatcher
->
shutdown
,
true
);
atomic_store_8
(
&
dispatcher
->
shutdown
,
true
);
pthread_cond_broadcast
(
&
dispatcher
->
timeout
);
if
(
dispatcher
->
timeoutManager
)
{
pthread_mutex_unlock
(
&
dispatcher
->
sleepMutex
);
shutdownSDispatcherTimeoutManager
(
dispatcher
->
timeoutManager
);
}
// make sure the timeout thread exit.
pthread_join
(
dispatcher
->
background
,
NULL
);
}
}
void
destroy
AsyncDispatcher
(
SAsyncBulk
WriteDispatcher
*
dispatcher
)
{
void
destroy
SAsyncBatchWriteDispatcher
(
SAsyncBatch
WriteDispatcher
*
dispatcher
)
{
if
(
dispatcher
==
NULL
)
{
if
(
dispatcher
==
NULL
)
{
return
;
return
;
}
}
...
@@ -379,28 +376,25 @@ void destroyAsyncDispatcher(SAsyncBulkWriteDispatcher* dispatcher) {
...
@@ -379,28 +376,25 @@ void destroyAsyncDispatcher(SAsyncBulkWriteDispatcher* dispatcher) {
// poll and send all the statements in the buffer.
// poll and send all the statements in the buffer.
while
(
true
)
{
while
(
true
)
{
SArray
*
statements
=
dispatcherLockPollAll
(
dispatcher
);
size_t
nPolls
=
0
;
if
(
!
statements
)
{
SSqlObj
**
polls
=
dispatcherLockPollAll
(
dispatcher
,
&
nPolls
);
if
(
!
polls
)
{
break
;
break
;
}
}
dispatcherExecute
(
polls
,
nPolls
);
dispatcherExecute
(
statements
);
free
(
polls
);
taosArrayDestroy
(
&
statements
);
}
}
// destroy the timeout manager.
// destroy the buffer.
destroySDispatcherTimeoutManager
(
dispatcher
->
timeoutManager
);
taosArrayDestroy
(
&
dispatcher
->
buffer
);
// destroy the mutex.
// destroy the mutex.
pthread_mutex_destroy
(
&
dispatcher
->
bufferMutex
);
pthread_mutex_destroy
(
&
dispatcher
->
bufferMutex
);
pthread_mutex_destroy
(
&
dispatcher
->
sleepMutex
);
pthread_cond_destroy
(
&
dispatcher
->
timeout
);
pthread_cond_destroy
(
&
dispatcher
->
notFull
);
pthread_cond_destroy
(
&
dispatcher
->
notFull
);
free
(
dispatcher
);
free
(
dispatcher
);
}
}
bool
tscSupportBulkInsertion
(
SAsyncBulk
WriteDispatcher
*
dispatcher
,
SSqlObj
*
pSql
)
{
bool
dispatcherCanDispatch
(
SAsyncBatch
WriteDispatcher
*
dispatcher
,
SSqlObj
*
pSql
)
{
if
(
pSql
==
NULL
||
!
pSql
->
enableBatch
)
{
if
(
pSql
==
NULL
||
!
pSql
->
enableBatch
)
{
return
false
;
return
false
;
}
}
...
@@ -438,13 +432,13 @@ bool tscSupportBulkInsertion(SAsyncBulkWriteDispatcher* dispatcher, SSqlObj* pSq
...
@@ -438,13 +432,13 @@ bool tscSupportBulkInsertion(SAsyncBulkWriteDispatcher* dispatcher, SSqlObj* pSq
return
true
;
return
true
;
}
}
bool
dispatcherTryDispatch
(
SAsyncB
ulk
WriteDispatcher
*
dispatcher
,
SSqlObj
*
pSql
)
{
bool
dispatcherTryDispatch
(
SAsyncB
atch
WriteDispatcher
*
dispatcher
,
SSqlObj
*
pSql
)
{
if
(
atomic_load_8
(
&
dispatcher
->
shutdown
))
{
if
(
atomic_load_8
(
&
dispatcher
->
shutdown
))
{
return
false
;
return
false
;
}
}
// the sql object doesn't support bulk insertion.
// the sql object doesn't support bulk insertion.
if
(
!
tscSupportBulkInsertion
(
dispatcher
,
pSql
))
{
if
(
!
dispatcherCanDispatch
(
dispatcher
,
pSql
))
{
return
false
;
return
false
;
}
}
...
@@ -453,20 +447,20 @@ bool dispatcherTryDispatch(SAsyncBulkWriteDispatcher* dispatcher, SSqlObj* pSql)
...
@@ -453,20 +447,20 @@ bool dispatcherTryDispatch(SAsyncBulkWriteDispatcher* dispatcher, SSqlObj* pSql)
}
}
/**
/**
* Destroy the SAsyncB
ulkWriteDispatcher create by SDispatcherHold
er.
* Destroy the SAsyncB
atchWriteDispatcher create by SDispatcherManag
er.
* @param arg the thread local SAsyncB
ulk
WriteDispatcher.
* @param arg the thread local SAsyncB
atch
WriteDispatcher.
*/
*/
static
void
destroyDispatcher
(
void
*
arg
)
{
static
void
destroyDispatcher
(
void
*
arg
)
{
SAsyncB
ulk
WriteDispatcher
*
dispatcher
=
arg
;
SAsyncB
atch
WriteDispatcher
*
dispatcher
=
arg
;
if
(
!
dispatcher
)
{
if
(
!
dispatcher
)
{
return
;
return
;
}
}
destroy
Async
Dispatcher
(
dispatcher
);
destroy
SAsyncBatchWrite
Dispatcher
(
dispatcher
);
}
}
SDispatcher
Holder
*
createDispatcherHold
er
(
int32_t
batchSize
,
int32_t
timeoutMs
,
bool
isThreadLocal
)
{
SDispatcher
Manager
*
createDispatcherManag
er
(
int32_t
batchSize
,
int32_t
timeoutMs
,
bool
isThreadLocal
)
{
SDispatcher
Holder
*
dispatcher
=
calloc
(
1
,
sizeof
(
SDispatcherHold
er
));
SDispatcher
Manager
*
dispatcher
=
calloc
(
1
,
sizeof
(
SDispatcherManag
er
));
if
(
!
dispatcher
)
{
if
(
!
dispatcher
)
{
return
NULL
;
return
NULL
;
}
}
...
@@ -481,7 +475,7 @@ SDispatcherHolder* createDispatcherHolder(int32_t batchSize, int32_t timeoutMs,
...
@@ -481,7 +475,7 @@ SDispatcherHolder* createDispatcherHolder(int32_t batchSize, int32_t timeoutMs,
return
NULL
;
return
NULL
;
}
}
}
else
{
}
else
{
dispatcher
->
global
=
create
AsyncBulk
WriteDispatcher
(
batchSize
,
timeoutMs
);
dispatcher
->
global
=
create
SAsyncBatch
WriteDispatcher
(
batchSize
,
timeoutMs
);
if
(
!
dispatcher
->
global
)
{
if
(
!
dispatcher
->
global
)
{
free
(
dispatcher
);
free
(
dispatcher
);
return
NULL
;
return
NULL
;
...
@@ -490,32 +484,85 @@ SDispatcherHolder* createDispatcherHolder(int32_t batchSize, int32_t timeoutMs,
...
@@ -490,32 +484,85 @@ SDispatcherHolder* createDispatcherHolder(int32_t batchSize, int32_t timeoutMs,
return
dispatcher
;
return
dispatcher
;
}
}
SAsyncB
ulkWriteDispatcher
*
dispatcherAcquire
(
SDispatcherHolder
*
hold
er
)
{
SAsyncB
atchWriteDispatcher
*
dispatcherAcquire
(
SDispatcherManager
*
manag
er
)
{
if
(
!
hold
er
->
isThreadLocal
)
{
if
(
!
manag
er
->
isThreadLocal
)
{
return
hold
er
->
global
;
return
manag
er
->
global
;
}
}
SAsyncB
ulkWriteDispatcher
*
value
=
pthread_getspecific
(
hold
er
->
key
);
SAsyncB
atchWriteDispatcher
*
value
=
pthread_getspecific
(
manag
er
->
key
);
if
(
value
)
{
if
(
value
)
{
return
value
;
return
value
;
}
}
value
=
create
AsyncBulkWriteDispatcher
(
holder
->
batchSize
,
hold
er
->
timeoutMs
);
value
=
create
SAsyncBatchWriteDispatcher
(
manager
->
batchSize
,
manag
er
->
timeoutMs
);
if
(
value
)
{
if
(
value
)
{
pthread_setspecific
(
hold
er
->
key
,
value
);
pthread_setspecific
(
manag
er
->
key
,
value
);
return
value
;
return
value
;
}
}
return
NULL
;
return
NULL
;
}
}
void
destroyDispatcher
Holder
(
SDispatcherHolder
*
hold
er
)
{
void
destroyDispatcher
Manager
(
SDispatcherManager
*
manag
er
)
{
if
(
hold
er
)
{
if
(
manag
er
)
{
if
(
hold
er
->
isThreadLocal
)
{
if
(
manag
er
->
isThreadLocal
)
{
pthread_key_delete
(
hold
er
->
key
);
pthread_key_delete
(
manag
er
->
key
);
}
else
{
}
else
{
destroy
AsyncDispatcher
(
hold
er
->
global
);
destroy
SAsyncBatchWriteDispatcher
(
manag
er
->
global
);
}
}
free
(
holder
);
free
(
manager
);
}
}
SDispatcherTimeoutManager
*
createSDispatcherTimeoutManager
(
SAsyncBatchWriteDispatcher
*
dispatcher
,
int32_t
timeoutMs
)
{
SDispatcherTimeoutManager
*
manager
=
calloc
(
1
,
sizeof
(
SDispatcherTimeoutManager
));
if
(
!
manager
)
{
return
NULL
;
}
manager
->
timeoutMs
=
timeoutMs
;
manager
->
dispatcher
=
dispatcher
;
atomic_store_8
(
&
manager
->
shutdown
,
false
);
pthread_mutex_init
(
&
manager
->
sleepMutex
,
NULL
);
pthread_cond_init
(
&
manager
->
timeout
,
NULL
);
// init background thread.
if
(
pthread_create
(
&
manager
->
background
,
NULL
,
timeoutManagerCallback
,
manager
))
{
pthread_mutex_destroy
(
&
manager
->
sleepMutex
);
pthread_cond_destroy
(
&
manager
->
timeout
);
free
(
manager
);
return
NULL
;
}
return
manager
;
}
void
destroySDispatcherTimeoutManager
(
SDispatcherTimeoutManager
*
manager
)
{
if
(
!
manager
)
{
return
;
}
shutdownSDispatcherTimeoutManager
(
manager
);
manager
->
dispatcher
->
timeoutManager
=
NULL
;
pthread_mutex_destroy
(
&
manager
->
sleepMutex
);
pthread_cond_destroy
(
&
manager
->
timeout
);
free
(
manager
);
}
void
shutdownSDispatcherTimeoutManager
(
SDispatcherTimeoutManager
*
manager
)
{
// mark shutdown, signal shutdown to timeout thread.
pthread_mutex_lock
(
&
manager
->
sleepMutex
);
atomic_store_8
(
&
manager
->
shutdown
,
true
);
pthread_cond_broadcast
(
&
manager
->
timeout
);
pthread_mutex_unlock
(
&
manager
->
sleepMutex
);
// make sure the timeout thread exit.
pthread_join
(
manager
->
background
,
NULL
);
}
bool
isShutdownSDispatcherTimeoutManager
(
SDispatcherTimeoutManager
*
manager
)
{
if
(
!
manager
)
{
return
true
;
}
}
return
atomic_load_8
(
&
manager
->
shutdown
);
}
}
src/client/src/tscSystem.c
浏览文件 @
58392c19
...
@@ -14,19 +14,19 @@
...
@@ -14,19 +14,19 @@
*/
*/
#include "os.h"
#include "os.h"
#include "qScript.h"
#include "taosmsg.h"
#include "taosmsg.h"
#include "tconfig.h"
#include "tglobal.h"
#include "tnote.h"
#include "tref.h"
#include "tref.h"
#include "trpc.h"
#include "trpc.h"
#include "tnote.h"
#include "tscBatchWrite.h"
#include "ttimer.h"
#include "tsched.h"
#include "tscLog.h"
#include "tscLog.h"
#include "tsched.h"
#include "tsclient.h"
#include "tsclient.h"
#include "tglobal.h"
#include "ttimer.h"
#include "tconfig.h"
#include "ttimezone.h"
#include "ttimezone.h"
#include "qScript.h"
#include "tscBulkWrite.h"
// global, not configurable
// global, not configurable
#define TSC_VAR_NOT_RELEASE 1
#define TSC_VAR_NOT_RELEASE 1
...
@@ -50,7 +50,7 @@ void *tscRpcCache; // cache to keep rpc obj
...
@@ -50,7 +50,7 @@ void *tscRpcCache; // cache to keep rpc obj
int32_t
tscNumOfThreads
=
1
;
// num of rpc threads
int32_t
tscNumOfThreads
=
1
;
// num of rpc threads
char
tscLogFileName
[]
=
"taoslog"
;
char
tscLogFileName
[]
=
"taoslog"
;
int
tscLogFileNum
=
10
;
int
tscLogFileNum
=
10
;
SDispatcher
Holder
*
tscDispatch
er
=
NULL
;
SDispatcher
Manager
*
tscDispatcherManag
er
=
NULL
;
static
pthread_mutex_t
rpcObjMutex
;
// mutex to protect open the rpc obj concurrently
static
pthread_mutex_t
rpcObjMutex
;
// mutex to protect open the rpc obj concurrently
static
pthread_once_t
tscinit
=
PTHREAD_ONCE_INIT
;
static
pthread_once_t
tscinit
=
PTHREAD_ONCE_INIT
;
...
@@ -59,16 +59,16 @@ static pthread_mutex_t setConfMutex = PTHREAD_MUTEX_INITIALIZER;
...
@@ -59,16 +59,16 @@ static pthread_mutex_t setConfMutex = PTHREAD_MUTEX_INITIALIZER;
// pthread_once can not return result code, so result code is set to a global variable.
// pthread_once can not return result code, so result code is set to a global variable.
static
volatile
int
tscInitRes
=
0
;
static
volatile
int
tscInitRes
=
0
;
void
tscInit
AsyncDispatch
er
(
int32_t
batchSize
,
int32_t
timeoutMs
,
bool
isThreadLocal
)
{
void
tscInit
DispatcherManag
er
(
int32_t
batchSize
,
int32_t
timeoutMs
,
bool
isThreadLocal
)
{
if
(
tsAsyncBatchEnable
)
{
if
(
tsAsyncBatchEnable
)
{
tscDispatcher
=
createDispatcherHold
er
(
batchSize
,
timeoutMs
,
isThreadLocal
);
tscDispatcher
Manager
=
createDispatcherManag
er
(
batchSize
,
timeoutMs
,
isThreadLocal
);
}
}
}
}
void
tscDestroy
AsyncDispatch
er
()
{
void
tscDestroy
DispatcherManag
er
()
{
if
(
tscDispatcher
)
{
if
(
tscDispatcher
Manager
)
{
destroyDispatcher
Holder
(
tscDispatch
er
);
destroyDispatcher
Manager
(
tscDispatcherManag
er
);
tscDispatcher
=
NULL
;
tscDispatcher
Manager
=
NULL
;
}
}
}
}
...
@@ -230,8 +230,8 @@ void taos_init_imp(void) {
...
@@ -230,8 +230,8 @@ void taos_init_imp(void) {
#endif
#endif
tscDebug
(
"starting to initialize client ..."
);
tscDebug
(
"starting to initialize client ..."
);
tscDebug
(
"Local End Point is:%s"
,
tsLocalEp
);
tscDebug
(
"Local End Point is:%s"
,
tsLocalEp
);
tscInit
AsyncDispatch
er
(
tsAsyncBatchSize
,
tsAsyncBatchTimeout
,
tsAsyncBatchThreadLocal
);
tscInit
DispatcherManag
er
(
tsAsyncBatchSize
,
tsAsyncBatchTimeout
,
tsAsyncBatchThreadLocal
);
}
}
taosSetCoreDump
();
taosSetCoreDump
();
...
@@ -297,7 +297,7 @@ void taos_cleanup(void) {
...
@@ -297,7 +297,7 @@ void taos_cleanup(void) {
scriptEnvPoolCleanup
();
scriptEnvPoolCleanup
();
#endif
#endif
if
(
tsAsyncBatchEnable
)
{
if
(
tsAsyncBatchEnable
)
{
tscDestroy
AsyncDispatch
er
();
tscDestroy
DispatcherManag
er
();
}
}
}
}
...
...
src/common/src/tglobal.c
浏览文件 @
58392c19
...
@@ -1885,7 +1885,7 @@ static void doInitGlobalConfig(void) {
...
@@ -1885,7 +1885,7 @@ static void doInitGlobalConfig(void) {
cfg
.
valType
=
TAOS_CFG_VTYPE_INT32
;
cfg
.
valType
=
TAOS_CFG_VTYPE_INT32
;
cfg
.
cfgType
=
TSDB_CFG_CTYPE_B_CONFIG
;
cfg
.
cfgType
=
TSDB_CFG_CTYPE_B_CONFIG
;
cfg
.
minValue
=
1
;
cfg
.
minValue
=
1
;
cfg
.
maxValue
=
65535
;
cfg
.
maxValue
=
4096
;
cfg
.
ptrLength
=
0
;
cfg
.
ptrLength
=
0
;
cfg
.
unitType
=
TAOS_CFG_UTYPE_NONE
;
cfg
.
unitType
=
TAOS_CFG_UTYPE_NONE
;
taosInitConfigOption
(
cfg
);
taosInitConfigOption
(
cfg
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录