about new work
This commit is contained in:
parent
de7a7777a0
commit
b3e06e4ee1
File diff suppressed because it is too large
Load Diff
|
|
@ -2136,7 +2136,7 @@ void ReportIllegalCharExceptionThreshold()
|
|||
/*
|
||||
* 功能:执行分布式导入操作,读取外部数据并填充元组表槽
|
||||
*
|
||||
* 参数:
|
||||
* 参数列表:
|
||||
* node:外部扫描状态
|
||||
*
|
||||
* 返回值:
|
||||
|
|
@ -2251,7 +2251,7 @@ retry:
|
|||
/*
|
||||
* 功能:结束分布式导入操作,释放相关资源
|
||||
*
|
||||
* 参数:
|
||||
* 参数列表:
|
||||
* node:外部扫描状态
|
||||
*
|
||||
* 注意:
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -32,7 +32,14 @@ template bool getNextRoach<true>(CopyState cstate);
|
|||
template bool getNextRoach<false>(CopyState cstate);
|
||||
template void initRoachState<true>(CopyState cstate, const char *filename, List *totalTask);
|
||||
template void initRoachState<false>(CopyState cstate, const char *filename, List *totalTask);
|
||||
|
||||
/*
|
||||
* Function: initRoachRoutine
|
||||
*
|
||||
* Initializes a RoachRoutine by looking up the "roach_handler" function and
|
||||
* checking its return type.
|
||||
*
|
||||
* Returns: A RoachRoutine pointer.
|
||||
*/
|
||||
RoachRoutine *initRoachRoutine()
|
||||
{
|
||||
Datum datum;
|
||||
|
|
@ -50,7 +57,16 @@ RoachRoutine *initRoachRoutine()
|
|||
|
||||
return routine;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: getNextRoach
|
||||
*
|
||||
* Gets the next Roach data to import or export in a COPY operation.
|
||||
*
|
||||
* Parameters:
|
||||
* - cstate: The COPY operation's state.
|
||||
*
|
||||
* Returns: true if successful, false if there's no more data to process.
|
||||
*/
|
||||
template <bool import>
|
||||
bool getNextRoach(CopyState cstate)
|
||||
{
|
||||
|
|
@ -78,7 +94,19 @@ bool getNextRoach(CopyState cstate)
|
|||
cstate->roach_context = roach_context;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: copyGetRoachData
|
||||
*
|
||||
* Reads Roach data for a COPY operation.
|
||||
*
|
||||
* Parameters:
|
||||
* - cstate: The COPY operation's state.
|
||||
* - databuf: The data buffer to read into.
|
||||
* - minread: The minimum number of bytes to read.
|
||||
* - maxread: The maximum number of bytes to read.
|
||||
*
|
||||
* Returns: The number of bytes read.
|
||||
*/
|
||||
int copyGetRoachData(CopyState cstate, void *databuf, int minread, int maxread)
|
||||
{
|
||||
Assert(cstate->roach_routine);
|
||||
|
|
@ -91,7 +119,16 @@ int copyGetRoachData(CopyState cstate, void *databuf, int minread, int maxread)
|
|||
|
||||
return bytesread;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: initRoachState
|
||||
*
|
||||
* Initializes the state for a Roach COPY operation.
|
||||
*
|
||||
* Parameters:
|
||||
* - cstate: The COPY operation's state.
|
||||
* - filename: The Roach file to import/export.
|
||||
* - totalTask: The total tasks to process.
|
||||
*/
|
||||
template <bool import>
|
||||
void initRoachState(CopyState cstate, const char *filename, List *totalTask)
|
||||
{
|
||||
|
|
@ -117,8 +154,8 @@ void initRoachState(CopyState cstate, const char *filename, List *totalTask)
|
|||
char roachPath[PATH_MAX + 1];
|
||||
const char *pos = strstr(filename, ROACH_PREFIX);
|
||||
pos += ROACH_PREFIX_LEN;
|
||||
errno_t ret = snprintf_s(roachPath, sizeof(roachPath), PATH_MAX, "%s/%s", pos,
|
||||
g_instance.attr.attr_common.PGXCNodeName);
|
||||
errno_t ret =
|
||||
snprintf_s(roachPath, sizeof(roachPath), PATH_MAX, "%s/%s", pos, g_instance.attr.attr_common.PGXCNodeName);
|
||||
securec_check_ss(ret, "", "");
|
||||
roachPath[PATH_MAX] = '\0';
|
||||
|
||||
|
|
@ -137,7 +174,14 @@ void initRoachState(CopyState cstate, const char *filename, List *totalTask)
|
|||
(void)getNextRoach<import>(cstate);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: endRoachBulkLoad
|
||||
*
|
||||
* Ends a Roach bulk load operation.
|
||||
*
|
||||
* Parameters:
|
||||
* - cstate: The COPY operation's state.
|
||||
*/
|
||||
void endRoachBulkLoad(CopyState cstate)
|
||||
{
|
||||
if (IS_PGXC_DATANODE) {
|
||||
|
|
@ -149,7 +193,14 @@ void endRoachBulkLoad(CopyState cstate)
|
|||
ereport(ERROR, (errcode_for_file_access(), errmsg("could not close roach %s", cstate->filename)));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: exportRoach
|
||||
*
|
||||
* Exports data to Roach in a COPY operation.
|
||||
*
|
||||
* Parameters:
|
||||
* - cstate: The COPY operation's state.
|
||||
*/
|
||||
void exportRoach(CopyState cstate)
|
||||
{
|
||||
Assert(cstate->copy_dest == COPY_ROACH);
|
||||
|
|
@ -196,7 +247,15 @@ void exportRoach(CopyState cstate)
|
|||
|
||||
resetStringInfo(in);
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: exportRoachFlushOut
|
||||
*
|
||||
* Flushes the data to Roach in a COPY operation.
|
||||
*
|
||||
* Parameters:
|
||||
* - cstate: The COPY operation's state.
|
||||
* - isWholeLineAtEnd: Indicates if the whole line is at the end.
|
||||
*/
|
||||
void exportRoachFlushOut(CopyState cstate, bool isWholeLineAtEnd)
|
||||
{
|
||||
Assert(cstate->roach_routine);
|
||||
|
|
|
|||
|
|
@ -52,40 +52,88 @@ extern void SyncBulkloadStates(CopyState cstate);
|
|||
extern void CleanBulkloadStates(); // all stuffs used for bulkload(end).
|
||||
|
||||
// Try to save importing error if needed
|
||||
/*
|
||||
* 功能:尝试保存导入错误
|
||||
*
|
||||
* 参数列表:
|
||||
* importState:导入执行状态指针,包含导入过程中的相关信息
|
||||
* node:外部扫描状态指针,用于访问外部扫描相关信息
|
||||
*
|
||||
* 返回值:
|
||||
* 如果成功保存导入错误,返回true;否则返回false。
|
||||
*
|
||||
* 注意:
|
||||
* 这个函数用于尝试保存导入错误,它检查错误码是否为数据异常(Data Exception)并且是否可以接受错误。
|
||||
* 如果满足条件,它会保存错误记录,并在必要时清除错误状态。
|
||||
*/
|
||||
bool TrySaveImportError(DistImportExecutionState *importState, ForeignScanState *node)
|
||||
{
|
||||
// 检查当前错误码是否为数据异常(Data Exception)
|
||||
if ((ERRCODE_TO_CATEGORY((unsigned int)geterrcode()) == ERRCODE_DATA_EXCEPTION) && DoAcceptOneError(importState)) {
|
||||
// 如果是数据异常并且DoAcceptOneError返回true,表示可以接受错误
|
||||
|
||||
// 检查错误码是否为字符不在字符集中或者无法翻译的字符
|
||||
if (geterrcode() == ERRCODE_CHARACTER_NOT_IN_REPERTOIRE || geterrcode() == ERRCODE_UNTRANSLATABLE_CHARACTER)
|
||||
t_thrd.bulk_cxt.illegal_character_err_cnt++;
|
||||
|
||||
ListCell *lc = NULL;
|
||||
|
||||
// 遍历错误记录器列表,处理每个错误记录
|
||||
foreach (lc, importState->elogger) {
|
||||
ImportErrorLogger *elogger = (ImportErrorLogger *)lfirst(lc);
|
||||
FormAndSaveImportError(importState, importState->errLogRel, importState->beginTime, elogger);
|
||||
}
|
||||
|
||||
// clear error state
|
||||
//
|
||||
// 清除错误状态
|
||||
FlushErrorStateWithoutDeleteChildrenContext();
|
||||
return true;
|
||||
return true; // 返回true表示成功保存导入错误
|
||||
}
|
||||
return false;
|
||||
return false; // 返回false表示没有保存导入错误
|
||||
}
|
||||
|
||||
/*
|
||||
* 功能:尝试保存导入错误
|
||||
*
|
||||
* 参数列表:
|
||||
* cstate:复制状态指针,包含复制过程中的相关信息
|
||||
*
|
||||
* 返回值:
|
||||
* 如果成功保存导入错误,返回true;否则返回false。
|
||||
*
|
||||
* 注意:
|
||||
* 这个函数用于尝试保存导入错误,它检查错误码是否为数据异常(Data Exception)并且是否可以接受错误。
|
||||
* 如果满足条件,它会保存错误记录,并在必要时清除错误状态。
|
||||
*/
|
||||
bool TrySaveImportError(CopyState cstate)
|
||||
{
|
||||
// 增加错误行数计数器
|
||||
cstate->errorrows++;
|
||||
if ((ERRCODE_TO_CATEGORY((unsigned int)geterrcode()) == ERRCODE_DATA_EXCEPTION) && DoAcceptOneError(cstate)) {
|
||||
FormAndSaveImportError(cstate, cstate->err_table, cstate->copy_beginTime, cstate->logger);
|
||||
// clear error state
|
||||
//
|
||||
FlushErrorStateWithoutDeleteChildrenContext();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查当前错误码是否为数据异常(Data Exception)
|
||||
if ((ERRCODE_TO_CATEGORY((unsigned int)geterrcode()) == ERRCODE_DATA_EXCEPTION) && DoAcceptOneError(cstate)) {
|
||||
// 如果是数据异常并且DoAcceptOneError返回true,表示可以接受错误
|
||||
|
||||
// 调用函数保存导入错误
|
||||
FormAndSaveImportError(cstate, cstate->err_table, cstate->copy_beginTime, cstate->logger);
|
||||
|
||||
// 清除错误状态
|
||||
FlushErrorStateWithoutDeleteChildrenContext();
|
||||
return true; // 返回true表示成功保存导入错误
|
||||
}
|
||||
return false; // 返回false表示没有保存导入错误
|
||||
}
|
||||
/*
|
||||
* 功能:执行向量化外部数据导入
|
||||
*
|
||||
* 参数列表:
|
||||
* node:向量化外部扫描状态指针,包含导入过程中的相关信息
|
||||
*
|
||||
* 返回值:
|
||||
* 返回包含导入数据的向量批次(VectorBatch)。
|
||||
*
|
||||
* 注意:
|
||||
* 这个函数用于执行向量化的外部数据导入操作。它从外部数据源中读取数据并将其填充到VectorBatch中。
|
||||
* 同时,它还处理错误并保存导入错误记录。
|
||||
*/
|
||||
VectorBatch *distExecVecImport(VecForeignScanState *node)
|
||||
{
|
||||
DistImportExecutionState *importState = (DistImportExecutionState *)node->fdw_state;
|
||||
|
|
@ -97,60 +145,45 @@ VectorBatch *distExecVecImport(VecForeignScanState *node)
|
|||
MemoryContext oldMemoryContext;
|
||||
MemoryContext scanMcxt = node->scanMcxt;
|
||||
|
||||
/* Set up callback to identify error line number. */
|
||||
/* 设置错误回调以识别错误行号 */
|
||||
errcontext.callback = BulkloadErrorCallback;
|
||||
errcontext.arg = (void *)importState;
|
||||
errcontext.previous = t_thrd.log_cxt.error_context_stack;
|
||||
t_thrd.log_cxt.error_context_stack = &errcontext;
|
||||
|
||||
/*
|
||||
* The protocol for loading a virtual tuple into a slot is first
|
||||
* ExecClearTuple, then fill the values/isnull arrays, then
|
||||
* ExecStoreVirtualTuple. If we don't find another row in the file, we
|
||||
* just skip the last step, leaving the slot empty as required.
|
||||
*
|
||||
* We can pass ExprContext = NULL because we read all columns from the
|
||||
* file, so no need to evaluate default expressions.
|
||||
*
|
||||
* We can also pass tupleOid = NULL because we don't allow oids for
|
||||
* foreign tables.
|
||||
*/
|
||||
batch->Reset(true);
|
||||
|
||||
if (node->m_done) {
|
||||
/* Remove error callback. */
|
||||
/* 移除错误回调 */
|
||||
t_thrd.log_cxt.error_context_stack = errcontext.previous;
|
||||
return batch;
|
||||
}
|
||||
|
||||
MemoryContextReset(scanMcxt);
|
||||
oldMemoryContext = MemoryContextSwitchTo(scanMcxt);
|
||||
#ifndef ENABLE_LITE_MODE
|
||||
SetObsMemoryContext(((CopyState)importState)->copycontext);
|
||||
#endif
|
||||
|
||||
for (batch->m_rows = 0; batch->m_rows < BatchMaxSize; batch->m_rows++) {
|
||||
retry:
|
||||
retry:
|
||||
PG_TRY();
|
||||
{
|
||||
/*
|
||||
* Synchronize the current bulkload states.
|
||||
*/
|
||||
/* 同步当前批量加载状态 */
|
||||
SyncBulkloadStates((CopyState)importState);
|
||||
|
||||
// 从外部数据源中读取下一行数据
|
||||
found = NextCopyFrom((CopyState)importState, NULL, values, nulls, NULL);
|
||||
}
|
||||
PG_CATCH();
|
||||
{
|
||||
/*
|
||||
* Clean the current bulkload states.
|
||||
*/
|
||||
CleanBulkloadStates();
|
||||
/* 清理当前批量加载状态 */
|
||||
|
||||
// 尝试保存导入错误,如果成功则重试
|
||||
if (TrySaveImportError(importState, node)) {
|
||||
(void)MemoryContextSwitchTo(scanMcxt);
|
||||
MemoryContextReset(scanMcxt);
|
||||
CHECK_FOR_INTERRUPTS();
|
||||
goto retry;
|
||||
} else {
|
||||
/* clean copy state and re throw */
|
||||
/* 清理复制状态并重新抛出异常 */
|
||||
importState->isExceptionShutdown = true;
|
||||
EndDistImport(importState);
|
||||
PG_RE_THROW();
|
||||
|
|
@ -158,13 +191,13 @@ retry:
|
|||
}
|
||||
PG_END_TRY();
|
||||
|
||||
/*
|
||||
* Clean the current bulkload states.
|
||||
*/
|
||||
/* 清理当前批量加载状态 */
|
||||
CleanBulkloadStates();
|
||||
|
||||
if (found) {
|
||||
int rows = batch->m_rows;
|
||||
|
||||
// 将读取的数据填充到VectorBatch中
|
||||
for (int i = 0; i < batch->m_cols; i++) {
|
||||
ScalarVector *vec = &(batch->m_arr[i]);
|
||||
if (nulls[i]) {
|
||||
|
|
@ -187,7 +220,8 @@ retry:
|
|||
}
|
||||
|
||||
(void)MemoryContextSwitchTo(oldMemoryContext);
|
||||
/* Remove error callback. */
|
||||
|
||||
/* 移除错误回调 */
|
||||
t_thrd.log_cxt.error_context_stack = errcontext.previous;
|
||||
|
||||
return batch;
|
||||
|
|
|
|||
Loading…
Reference in New Issue