enh: add memory pre-check
This commit is contained in:
parent
75d24720e7
commit
30d63415e8
|
@ -42,7 +42,7 @@ typedef enum MemPoolUsageLevel {
|
||||||
typedef void (*decConcSessionNum)(void);
|
typedef void (*decConcSessionNum)(void);
|
||||||
typedef void (*incConcSessionNum)(void);
|
typedef void (*incConcSessionNum)(void);
|
||||||
typedef void (*setConcSessionNum)(int32_t);
|
typedef void (*setConcSessionNum)(int32_t);
|
||||||
typedef bool (*retireCollection)(uint64_t, int64_t);
|
typedef bool (*retireCollection)(uint64_t, int64_t, bool);
|
||||||
|
|
||||||
typedef struct SMemPoolCallBack {
|
typedef struct SMemPoolCallBack {
|
||||||
decConcSessionNum decSessFp;
|
decConcSessionNum decSessFp;
|
||||||
|
@ -79,6 +79,13 @@ int32_t taosMemPoolInitSession(void* poolHandle, void** ppSession, void* pCollec
|
||||||
void taosMemPoolDestroySession(void* poolHandle, void* session);
|
void taosMemPoolDestroySession(void* poolHandle, void* session);
|
||||||
int32_t taosMemPoolCallocCollection(uint64_t collectionId, void** ppCollection);
|
int32_t taosMemPoolCallocCollection(uint64_t collectionId, void** ppCollection);
|
||||||
|
|
||||||
|
#define taosMemPoolFreeClear(ptr) \
|
||||||
|
do { \
|
||||||
|
if (ptr) { \
|
||||||
|
taosMemPoolFree((void *)ptr); \
|
||||||
|
(ptr) = NULL; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
extern threadlocal void* threadPoolHandle;
|
extern threadlocal void* threadPoolHandle;
|
||||||
extern threadlocal void* threadPoolSession;
|
extern threadlocal void* threadPoolSession;
|
||||||
|
|
|
@ -238,17 +238,27 @@ typedef struct SQWQueryInfo {
|
||||||
SHashObj* pSessions;
|
SHashObj* pSessions;
|
||||||
} SQWQueryInfo;
|
} SQWQueryInfo;
|
||||||
|
|
||||||
typedef struct SQWRetireCtx {
|
typedef struct SQWRetireLowCtx {
|
||||||
|
int8_t retireBegin;
|
||||||
|
} SQWRetireLowCtx;
|
||||||
|
|
||||||
|
typedef struct SQWRetireMidCtx {
|
||||||
int8_t retireBegin;
|
int8_t retireBegin;
|
||||||
TdThreadCond retired;
|
TdThreadCond retired;
|
||||||
BoundedQueue* collectionQueue;
|
BoundedQueue* collectionQueue;
|
||||||
|
} SQWRetireMidCtx;
|
||||||
|
|
||||||
|
typedef struct SQWRetireCtx {
|
||||||
|
SQWRetireLowCtx lowCtx;
|
||||||
|
SQWRetireMidCtx midCtx;
|
||||||
} SQWRetireCtx;
|
} SQWRetireCtx;
|
||||||
|
|
||||||
typedef struct SQueryMgmt {
|
typedef struct SQueryMgmt {
|
||||||
SRWLatch taskMgmtLock;
|
SRWLatch taskMgmtLock;
|
||||||
int32_t concTaskLevel;
|
int32_t concTaskLevel;
|
||||||
SHashObj* pQueryInfo;
|
SHashObj* pQueryInfo;
|
||||||
void* memPoolHandle;
|
void* memPoolHandle;
|
||||||
|
SQWRetireCtx retireCtx;
|
||||||
} SQueryMgmt;
|
} SQueryMgmt;
|
||||||
|
|
||||||
#define QW_CTX_NOT_EXISTS_ERR_CODE(mgmt) (atomic_load_8(&(mgmt)->nodeStopped) ? TSDB_CODE_VND_STOPPED : TSDB_CODE_QRY_TASK_CTX_NOT_EXIST)
|
#define QW_CTX_NOT_EXISTS_ERR_CODE(mgmt) (atomic_load_8(&(mgmt)->nodeStopped) ? TSDB_CODE_VND_STOPPED : TSDB_CODE_QRY_TASK_CTX_NOT_EXIST)
|
||||||
|
@ -320,6 +330,18 @@ extern SQueryMgmt gQueryMgmt;
|
||||||
(eId) = *(int32_t *)((char *)(id) + sizeof(qId) + sizeof(tId)); \
|
(eId) = *(int32_t *)((char *)(id) + sizeof(qId) + sizeof(tId)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define QW_SET_TEID(id, tId, eId) \
|
||||||
|
do { \
|
||||||
|
*(uint64_t *)(id) = (tId); \
|
||||||
|
*(uint32_t *)((char *)(id) + sizeof(tId)) = (eId); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define QW_GET_TEID(id, tId, eId) \
|
||||||
|
do { \
|
||||||
|
(tId) = *(uint64_t *)(id); \
|
||||||
|
(eId) = *(uint32_t *)((char *)(id) + sizeof(tId)); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define QW_ERR_RET(c) \
|
#define QW_ERR_RET(c) \
|
||||||
do { \
|
do { \
|
||||||
int32_t _code = (c); \
|
int32_t _code = (c); \
|
||||||
|
|
|
@ -68,7 +68,7 @@ int32_t qwInitQueryInfo(uint64_t qId, SQWQueryInfo* pQuery) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t qwInitSession(uint64_t qId, void** ppSession) {
|
int32_t qwInitSession(QW_FPARAMS_DEF, void** ppSession) {
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
SQWQueryInfo* pQuery = NULL;
|
SQWQueryInfo* pQuery = NULL;
|
||||||
|
|
||||||
|
@ -95,22 +95,32 @@ int32_t qwInitSession(uint64_t qId, void** ppSession) {
|
||||||
pQuery = (SQWQueryInfo*)taosHashGet(gQueryMgmt.pQueryInfo, &qId, sizeof(qId));
|
pQuery = (SQWQueryInfo*)taosHashGet(gQueryMgmt.pQueryInfo, &qId, sizeof(qId));
|
||||||
}
|
}
|
||||||
|
|
||||||
code = taosHashPut(pQuery->pSessions, ppSession, POINTER_BYTES, NULL, 0);
|
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
|
||||||
qError("fail to put session into query session hash, errno:%d", terrno);
|
|
||||||
return terrno;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
QW_ERR_RET(taosMemPoolInitSession(gQueryMgmt.memPoolHandle, ppSession, pQuery->pCollection));
|
QW_ERR_RET(taosMemPoolInitSession(gQueryMgmt.memPoolHandle, ppSession, pQuery->pCollection));
|
||||||
|
|
||||||
|
char id[sizeof(tId) + sizeof(eId)] = {0};
|
||||||
|
QW_SET_TEID(id, tId, eId);
|
||||||
|
|
||||||
|
code = taosHashPut(pQuery->pSessions, id, sizeof(id), ppSession, POINTER_BYTES);
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
qError("fail to put session into query session hash, errno:%d", terrno);
|
||||||
|
return terrno;
|
||||||
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool qwRetireCollection(uint64_t collectionId, int64_t retireSize) {
|
bool qwLowLevelRetire() {
|
||||||
//TODO
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool qwRetireCollection(uint64_t collectionId, int64_t retireSize, bool retireLow) {
|
||||||
|
if (retireLow) {
|
||||||
|
return qwLowLevelRetire();
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -734,7 +734,7 @@ int32_t qwPreprocessQuery(QW_FPARAMS_DEF, SQWMsg *qwMsg) {
|
||||||
ctx->phase = -1;
|
ctx->phase = -1;
|
||||||
|
|
||||||
if (NULL != gQueryMgmt.memPoolHandle) {
|
if (NULL != gQueryMgmt.memPoolHandle) {
|
||||||
QW_ERR_JRET(qwInitSession(qId, &ctx->memPoolSession));
|
QW_ERR_JRET(qwInitSession(QW_IDS(), &ctx->memPoolSession));
|
||||||
}
|
}
|
||||||
|
|
||||||
QW_ERR_JRET(qwAddTaskStatus(QW_FPARAMS(), JOB_TASK_STATUS_INIT));
|
QW_ERR_JRET(qwAddTaskStatus(QW_FPARAMS(), JOB_TASK_STATUS_INIT));
|
||||||
|
|
|
@ -205,7 +205,8 @@ typedef struct SMPSession {
|
||||||
|
|
||||||
int64_t sessionId;
|
int64_t sessionId;
|
||||||
|
|
||||||
SMPCollection* pCollection;
|
void* pCollection;
|
||||||
|
SMPCollection* pMpCollection;
|
||||||
bool needRetire;
|
bool needRetire;
|
||||||
SMPCtrlInfo ctrlInfo;
|
SMPCtrlInfo ctrlInfo;
|
||||||
|
|
||||||
|
|
|
@ -300,10 +300,10 @@ void memPoolUpdateAllocMemSize(SMemPool* pPool, SMPSession* pSession, int64_t si
|
||||||
int64_t allocMemSize = atomic_add_fetch_64(&pSession->allocMemSize, size);
|
int64_t allocMemSize = atomic_add_fetch_64(&pSession->allocMemSize, size);
|
||||||
memPoolUpdateMaxAllocMemSize(&pSession->maxAllocMemSize, allocMemSize);
|
memPoolUpdateMaxAllocMemSize(&pSession->maxAllocMemSize, allocMemSize);
|
||||||
|
|
||||||
allocMemSize = atomic_add_fetch_64(&pSession->pCollection->allocMemSize, size);
|
allocMemSize = atomic_load_64(&pSession->pMpCollection->allocMemSize);
|
||||||
memPoolUpdateMaxAllocMemSize(&pSession->pCollection->maxAllocMemSize, allocMemSize);
|
memPoolUpdateMaxAllocMemSize(&pSession->pMpCollection->maxAllocMemSize, allocMemSize);
|
||||||
|
|
||||||
allocMemSize = atomic_add_fetch_64(&pPool->allocMemSize, size);
|
allocMemSize = atomic_load_64(&pPool->allocMemSize);
|
||||||
memPoolUpdateMaxAllocMemSize(&pPool->maxAllocMemSize, allocMemSize);
|
memPoolUpdateMaxAllocMemSize(&pPool->maxAllocMemSize, allocMemSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,11 +382,42 @@ _return:
|
||||||
|
|
||||||
|
|
||||||
bool memPoolMemQuotaOverflow(SMemPool* pPool, SMPSession* pSession, int64_t size) {
|
bool memPoolMemQuotaOverflow(SMemPool* pPool, SMPSession* pSession, int64_t size) {
|
||||||
if (pPool->cfg.collectionQuota > 0 && (atomic_load_64(&pSession->pCollection->allocMemSize) + size) > atomic_load_64(&pPool->cfg.collectionQuota)) {
|
int64_t allocSize = atomic_add_fetch_64(&pSession->pMpCollection->allocMemSize, size);
|
||||||
|
int64_t quota = atomic_load_64(&pPool->cfg.collectionQuota);
|
||||||
|
if (quota > 0 && allocSize > quota) {
|
||||||
|
uWarn("collection %" PRIx64 " allocSize " PRId64 " is over than quota %" PRId64, pSession->pMpCollection->collectionId, allocSize, quota);
|
||||||
|
atomic_sub_fetch_64(&pSession->pMpCollection->allocMemSize, size);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((atomic_load_64(&pPool->allocMemSize) + size) >= pPool->memRetireThreshold[1]) {
|
|
||||||
return (*pPool->cfg.cb.retireFp)(pSession->pCollection->collectionId, pPool->memRetireUnit);
|
allocSize = atomic_add_fetch_64(&pPool->allocMemSize, size);
|
||||||
|
quota = atomic_load_64(&pPool->memRetireThreshold[2]);
|
||||||
|
if (allocSize >= quota) {
|
||||||
|
uWarn("pool allocSize " PRId64 " reaches the high quota %" PRId64, allocSize, quota);
|
||||||
|
atomic_sub_fetch_64(&pPool->allocMemSize, size);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
quota = atomic_load_64(&pPool->memRetireThreshold[1]);
|
||||||
|
if (allocSize >= quota) {
|
||||||
|
uInfo("pool allocSize " PRId64 " reaches the middle quota %" PRId64, allocSize, quota);
|
||||||
|
bool retire = (*pPool->cfg.cb.retireFp)(pSession->pMpCollection->collectionId, pPool->memRetireUnit, false);
|
||||||
|
if (retire) {
|
||||||
|
uWarn("session retired in middle quota retire choise, sessionAllocSize: %" PRId64, atomic_load_64(&pSession->allocMemSize));
|
||||||
|
atomic_sub_fetch_64(&pPool->allocMemSize, size);
|
||||||
|
}
|
||||||
|
return retire;
|
||||||
|
}
|
||||||
|
|
||||||
|
quota = atomic_load_64(&pPool->memRetireThreshold[0]);
|
||||||
|
if (allocSize >= quota) {
|
||||||
|
uInfo("pool allocSize " PRId64 " reaches the low quota %" PRId64, allocSize, quota);
|
||||||
|
bool retire = (*pPool->cfg.cb.retireFp)(pSession->pMpCollection->collectionId, pPool->memRetireUnit, true);
|
||||||
|
if (retire) {
|
||||||
|
uWarn("session retired in low quota retire choise, sessionAllocSize: %" PRId64, atomic_load_64(&pSession->allocMemSize));
|
||||||
|
atomic_sub_fetch_64(&pPool->allocMemSize, size);
|
||||||
|
}
|
||||||
|
return retire;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -401,6 +432,10 @@ void* memPoolAllocDirect(SMemPool* pPool, SMPSession* pSession, int64_t size, ui
|
||||||
void* res = alignment ? taosMemMallocAlign(alignment, size) : taosMemMalloc(size);
|
void* res = alignment ? taosMemMallocAlign(alignment, size) : taosMemMalloc(size);
|
||||||
if (NULL != res) {
|
if (NULL != res) {
|
||||||
memPoolUpdateAllocMemSize(pPool, pSession, size);
|
memPoolUpdateAllocMemSize(pPool, pSession, size);
|
||||||
|
} else {
|
||||||
|
atomic_sub_fetch_64(&pSession->pMpCollection->allocMemSize, size);
|
||||||
|
atomic_sub_fetch_64(&pPool->allocMemSize, size);
|
||||||
|
uError("malloc %" PRId64 " alighment %d failed", size, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -842,7 +877,7 @@ int32_t taosMemPoolInitSession(void* poolHandle, void** ppSession, void* pCollec
|
||||||
MP_ADD_TO_CHUNK_LIST(pSession->srcChunkHead, pSession->srcChunkTail, pSession->srcChunkNum, pChunk);
|
MP_ADD_TO_CHUNK_LIST(pSession->srcChunkHead, pSession->srcChunkTail, pSession->srcChunkNum, pChunk);
|
||||||
MP_ADD_TO_CHUNK_LIST(pSession->inUseChunkHead, pSession->inUseChunkTail, pSession->inUseChunkNum, pChunk);
|
MP_ADD_TO_CHUNK_LIST(pSession->inUseChunkHead, pSession->inUseChunkTail, pSession->inUseChunkNum, pChunk);
|
||||||
|
|
||||||
pSession->pCollection = (SMPCollection*)pCollection;
|
pSession->pMpCollection = (SMPCollection*)pCollection;
|
||||||
|
|
||||||
_return:
|
_return:
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue