//--------------------------------------------------------------------------// // CRUUnAuditRefreshTaskExecutor::ComposeIndexesSql() // //--------------------------------------------------------------------------// void CRUUnAuditRefreshTaskExecutor::ComposeIndexesSql() { const CDDIndexList &indexList = GetRootMV().GetIndexList(); if( NULL == pUnAuditPopIndexdynamicContainer_ ) { pUnAuditPopIndexdynamicContainer_ = new CRUSQLDynamicStatementContainer(numOfIndexes_); } if( NULL == pUnAuditAvailableIndeXdynamicContainer_ ) { pUnAuditAvailableIndeXdynamicContainer_ = new CRUSQLDynamicStatementContainer(numOfIndexes_); } if( NULL == pUnAuditUnavailableIndeXdynamicContainer_ ) { pUnAuditUnavailableIndeXdynamicContainer_ = new CRUSQLDynamicStatementContainer(numOfIndexes_); } DSListPosition pos = indexList.GetHeadPosition(); for (Int32 i=0;NULL != pos;i++) { CDDIndex *pddIndex = indexList.GetNext(pos); CDSString popIdxRqst; GetRootMV().GetPopIndexCatApiRequestText(popIdxRqst, pddIndex); #pragma nowarn(1506) // warning elimination pUnAuditPopIndexdynamicContainer_->SetStatementText(i, popIdxRqst); #pragma warn(1506) // warning elimination CDSString availablepopIdxRqst; GetRootMV().GetUpdateIndexStatusCatApiRequestText(availablepopIdxRqst, TRUE, /*available*/ pddIndex); #pragma nowarn(1506) // warning elimination pUnAuditAvailableIndeXdynamicContainer_->SetStatementText(i, availablepopIdxRqst); #pragma warn(1506) // warning elimination CDSString unavailableIdxRqst; GetRootMV().GetUpdateIndexStatusCatApiRequestText(unavailableIdxRqst, FALSE, /*unavailable*/ pddIndex); #pragma nowarn(1506) // warning elimination pUnAuditUnavailableIndeXdynamicContainer_->SetStatementText(i, unavailableIdxRqst); #pragma warn(1506) // warning elimination } }
void CRURefreshTaskExecutor::UpdateRootMVStatistics(TInt32 currDuration) { CRURefreshTask &task = *GetRefreshTask(); if (FALSE == task.NeedToExecuteInternalRefresh()) { return; } CRUDeltaDefList &deltaDefList = task.GetDeltaDefList(); TInt32 prevDuration, nextDuration; CRUMV &rootMV = GetRootMV(); if (TRUE == IsRecompute()) { prevDuration = rootMV.GetRecomputeDurationEstimate(); nextDuration = EvaluateHeuristic(currDuration, prevDuration); rootMV.SetRecomputeDurationEstimate(nextDuration); return; } switch(deltaDefList.GetCount()) { case 0: { // This cannot happen // (NeedToExecuteInternalRefresh() must have returned FALSE). RUASSERT(FALSE); } case 1: { CRUDeltaDef *pDdef = deltaDefList.GetAt(0); // A special case: update the refresh duration, // and (optionally) the delta size. UpdateSingleDeltaStatistics(pDdef, currDuration); break; } case 2: { prevDuration = rootMV.GetRefreshDurationEstimateWith_2_Deltas(); nextDuration = EvaluateHeuristic(currDuration, prevDuration); rootMV.SetRefreshDurationEstimateWith_2_Deltas(nextDuration); break; } case 3: { prevDuration = rootMV.GetRefreshDurationEstimateWith_3_Deltas(); nextDuration = EvaluateHeuristic(currDuration, prevDuration); rootMV.SetRefreshDurationEstimateWith_3_Deltas(nextDuration); break; } default: { prevDuration = rootMV.GetRefreshDurationEstimateWith_N_Deltas(); nextDuration = EvaluateHeuristic(currDuration, prevDuration); rootMV.SetRefreshDurationEstimateWith_N_Deltas(nextDuration); break; } } }
void CRURefreshTaskExecutor:: UpdateSingleDeltaStatistics(CRUDeltaDef *pDdef, TInt32 currDuration) { CRUMV &rootMV = GetRootMV(); TInt32 prevDuration, nextDuration; prevDuration = rootMV.GetRefreshDurationEstimate(pDdef->tblUid_); nextDuration = EvaluateHeuristic(currDuration, prevDuration); rootMV.SetRefreshDurationEstimate(pDdef->tblUid_, nextDuration); // Appling the delta size computation heuristic // If there are no statistics, 0 is the default for the delta size TInt32 nextDelta = 0; if (NULL != pDdef->pStat_) { // There are statistics, hence the delta size is known TInt32 currDelta = pDdef->pStat_->GetDeltaSize(); TInt32 prevDelta = rootMV.GetDeltaSizeEstimate(pDdef->tblUid_); nextDelta = EvaluateHeuristic(currDelta, prevDelta); } rootMV.SetDeltaSizeEstimate(pDdef->tblUid_, nextDelta); }
void CRUAuditRefreshTaskExecutor::EpilogueHandleOnStatementMV() { CRUMV &mv = GetRootMV(); CRUTblList &tblList = mv.GetTablesUsedByMe(); DSListPosition pos = tblList.GetHeadPosition(); Int32 i=0; while (NULL != pos) { CRUTbl *pTbl = tblList.GetNext(pos); CDMPreparedStatement *pStat = pLockTablesTEDynamicContainer_->GetPreparedStatement(i); // Perform the LOCK TABLE statement on the used table // (the lock overlaps the original RP open, therefore // guaranteeing the lock continuity). ExecuteStatement(*pStat,IDS_RU_IREFRESH_FAILED); // Release the DDL lock AND the read-protected open on the used table. pTbl->ReleaseResources(); } }
TInt64 CRURefreshTaskExecutor::CalculateTimeStamp() { CRUTblList &tblList = GetRootMV().GetTablesUsedByMe(); DSListPosition pos = tblList.GetHeadPosition(); CRUTbl *pTbl = tblList.GetNext(pos); TInt64 minTS = pTbl->GetTimestamp(); while (NULL != pos) { pTbl = tblList.GetNext(pos); TInt64 nextTS = pTbl->GetTimestamp(); minTS = (nextTS < minTS) ? nextTS : minTS; } if (0 == minTS) { // If the timestamp has not been executed until now, // this is time to compute it. // RUASSERT(CDDObject::eRECOMPUTE == GetRootMV().GetRefreshType()); minTS = CRUGlobals::GetCurrentTimestamp(); } return minTS; }
void CRUAuditRefreshTaskExecutor::PurgeData() { #ifdef _DEBUG CDSString msg( "\nPurging the data from materialized view " + GetRootMVName()); if (TRUE == isPopindex_) { msg += " and its secondary indexes"; } msg += "...\n"; CRUGlobals::GetInstance()-> LogDebugMessage(CRUGlobals::DUMP_PURGEDATA,"",msg); #endif GetRootMV().PurgeDataWithIndexes(); TESTPOINT2(CRUGlobals::TESTPOINT103, GetRootMVName()); // now start the remote states and do a recompute SetState(EX_REMOTE_START); }
void CRURefreshTaskExecutor::FinalMetadataUpdate() { CRURefreshTask *pParentTask = GetRefreshTask(); RUASSERT (NULL != pParentTask); TInt32 currDuration = 0; TInt64 ts = CalculateTimeStamp(); if (TRUE == pParentTask->NeedToExecuteInternalRefresh()) { currDuration = GetTimerDuration(); } CRUMV *pPrevMV, *pCurrMV = NULL; CRUMVList &mvList = pParentTask->GetMVList(); DSListPosition pos = mvList.GetHeadPosition(); while (NULL != pos) { pPrevMV = pCurrMV; pCurrMV = mvList.GetNext(pos); // Update the MV's REFRESHED_AT timestamp pCurrMV->SetTimestamp(ts); // publish the refresh event to the PUBLISH table NABoolean isRecomputePublish = (IsRecompute() == TRUE); pCurrMV->PublishMVRefresh(isRecomputePublish); if (CDDObject::eON_STATEMENT != pCurrMV->GetRefreshType()) { if (NULL == pPrevMV) { // This is the Root MV (the first in the list) if (CDDObject::eON_REQUEST == pCurrMV->GetRefreshType()) { // For every table T used by MV, // set MV.EPOCH[T]<--T.CURRENT_EPOCH. UpdateRootMVCurrentEpochVector(); } UpdateRootMVStatistics(currDuration); } else { UpdateNonRootMVStatistics(pCurrMV, pPrevMV, currDuration); } } pCurrMV->SaveMetadata(); } if (CDDObject::eON_STATEMENT != GetRootMV().GetRefreshType()) { IncrementTopMvCurrentEpoch(); } }
//--------------------------------------------------------------------------// // CRURefreshSQLComposer::ComposeControlQueryShapeCut() // //--------------------------------------------------------------------------// // LCOV_EXCL_START :rfi void CRURefreshSQLComposer::ComposeShowExplain() { sql_ = "INSERT INTO "; sql_ += GetRootMV().GetCatName() + "." + GetRootMV().GetSchName() + ".MV_REFRESH_PLANS "; sql_ += "SELECT '"; sql_ += GetRootMV().GetName() +"',"; sql_ += "PLAN_ID,"; sql_ += "SEQ_NUM,"; sql_ += "SUBSTRING(OPERATOR,1,30),"; sql_ += "LEFT_CHILD_SEQ_NUM,"; sql_ += "RIGHT_CHILD_SEQ_NUM,"; sql_ += "SUBSTRING(TNAME,1,60),"; sql_ += "CARDINALITY,"; sql_ += "OPERATOR_COST,"; sql_ += "TOTAL_COST,"; sql_ += "SUBSTRING(DETAIL_COST,1,1024),"; sql_ += "SUBSTRING(DESCRIPTION,1,2024)"; sql_ += " FROM TABLE(EXPLAIN(NULL,'DESCRIPTOR_FOR_SQLSTMT'));"; }
//--------------------------------------------------------------------------// // CRURefreshSQLComposer::ComposeControlQueryShape() // // //--------------------------------------------------------------------------// // LCOV_EXCL_START :rfi void CRURefreshSQLComposer::ComposeControlQueryShape() { RUASSERT(NULL != GetRootMV().GetMVForceOption()); sql_ = "CONTROL QUERY SHAPE "; ComposeQueryShape(); sql_ += ";"; }
void CRURefreshTaskExecutor::UpdateRootMVCurrentEpochVector() { CRUMV &rootMV = GetRootMV(); CRUTblList &tblList = rootMV.GetTablesUsedByMe(); DSListPosition pos = tblList.GetHeadPosition(); while (NULL != pos) { CRUTbl *pTbl = tblList.GetNext(pos); rootMV.SetEpoch(pTbl->GetUID(), pTbl->GetCurrentEpoch()); } }
void CRUAuditRefreshTaskExecutor::PrologueHandleOnStatementMV() { CRUTblList &tblList = GetRootMV().GetTablesUsedByMe(); DSListPosition pos = tblList.GetHeadPosition(); while (NULL != pos) { CRUTbl *pTbl = tblList.GetNext(pos); pTbl->ExecuteReadProtectedOpen(); } }
void CRUAuditRefreshTaskExecutor::Init() { inherited::Init(); RUASSERT(TRUE == HasWork()); if (FALSE == GetRefreshTask()->NeedToExecuteInternalRefresh()) { return; } Lng32 refreshPattern = GetRootMV().GetRefreshPatternMap(); isPurgedata_ = (0 != (refreshPattern & CRUMV::PURGEDATA)); isPopindex_ = (0 != (refreshPattern & CRUMV::POPINDEX)); CRUMV &mv = GetRootMV(); if (mv.GetCommitNRows() != 0 && TRUE == GetRootMV().IsMultiTxnContext()) { RUASSERT(TRUE == GetRefreshTask()->IsRecompute()); // We need to drop multi-txn context table // becuase we are recomputing a multi-txn mv isDeleteMultiTxnContext_ = TRUE; } // We must synchronize between the table and the mv, so we need to // lock the table partitions // Here we copy the partitions file names in order to allow access to // the files in the remote process when DDOL is not built tableLockProtocol_ = new CRUTableLockProtocol(); tableLockProtocol_->Init(mv.GetTablesUsedByMe(), GetRefreshTask()->GetDeltaDefList()); ComposeMySql(); }
void CRURefreshSQLComposer::StartInternalRefresh() { if (NULL == CRUGlobals::GetInstance()->GetOptions(). FindDebugOption(CRUGlobals::DISPLAY_REFRESH,"") ) { sql_ = "INTERNAL REFRESH "; } else { // LCOV_EXCL_START :dpm sql_ = "DISPLAY INTERNAL REFRESH "; // LCOV_EXCL_STOP } sql_ += GetRootMV().GetFullName(); }
void CRUAuditRefreshTaskExecutor::ComposeMySql() { CRUSimpleRefreshSQLComposer myComposer(GetRefreshTask()); CRUMV &rootMV = GetRootMV(); if (TRUE == isDeleteMultiTxnContext_) { myComposer.ComposeDeleteContextLogTable(); auditRefreshTEDynamicContainer_.SetStatementText (DELETE_MULT_TXN_CTX_TBL,myComposer.GetSQL()); } // POPINDEX CatApi request if (TRUE == isPopindex_) { numOfIndexes_ = rootMV.GetIndexList().GetCount(); if (0 < numOfIndexes_) { ComposeIndexesSql(); } } // Compose the LOCK TABLE sql statements for locking all tables // in the on statement MV initialization if (CDDObject::eON_STATEMENT == GetRootMVType()) { CRUTblList &tblList = rootMV.GetTablesUsedByMe(); DSListPosition pos = tblList.GetHeadPosition(); pLockTablesTEDynamicContainer_ = new CRUSQLDynamicStatementContainer((short)tblList.GetCount()); Int32 i=0; while (NULL != pos) { CRUTbl *pTbl = tblList.GetNext(pos); myComposer.ComposeLock(pTbl->GetFullName(), FALSE /*shared*/); pLockTablesTEDynamicContainer_->SetStatementText (i,myComposer.GetSQL()); i++; } } }
//--------------------------------------------------------------------------// // CRURefreshSQLComposer::ComposeQueryShape() // // The IR tree for internal refresh is as follows : // // JOIN // / \ // JOIN UPDATE MV(sub-tree) // / \ // GRBY SCAN // | MV // DELTA CALC // (sub-tree) // // We allow the user to force the join between the MV and the GROUP BY // block and the GROUP BY node above the DELTA CALCULATION sub-tree //--------------------------------------------------------------------------// // LCOV_EXCL_START :rfi void CRURefreshSQLComposer::ComposeQueryShape() { CDSString grbyStr,joinStr; const CRUMVForceOptions& forceOption = *GetRootMV().GetMVForceOption(); switch(forceOption.GetGroupByoption()) { case CRUForceOptions::GB_HASH: grbyStr = " HASH_GROUPBY(CUT) "; break; case CRUForceOptions::GB_SORT: grbyStr = " SORT_GROUPBY(CUT) "; break; case CRUForceOptions::GB_NO_FORCE: grbyStr = " GROUPBY(CUT) "; break; default: RUASSERT(FALSE); } switch(forceOption.GetJoinoption()) { case CRUForceOptions::JOIN_MERGE: joinStr = " MERGE_JOIN( "; break; case CRUForceOptions::JOIN_HASH: joinStr = " HYBRID_HASH_JOIN( "; break; case CRUForceOptions::JOIN_NESTED: joinStr = " NESTED_JOIN( "; break; case CRUForceOptions::JOIN_NO_FORCE: joinStr = " JOIN("; break; default: RUASSERT(FALSE); } sql_ += " JOIN( " + joinStr + grbyStr + ",CUT),CUT)"; }
void CRUUnAuditRefreshTaskExecutor::Init() { inherited::Init(); RUASSERT(TRUE == HasWork()); if (FALSE == GetRefreshTask()->NeedToExecuteInternalRefresh()) { return; } Lng32 refreshPattern = GetRootMV().GetRefreshPatternMap(); isPurgedata_ = (0 != (refreshPattern & CRUMV::PURGEDATA)); isPopindex_ = (0 != (refreshPattern & CRUMV::POPINDEX)); // Compose the INTERNAL REFRESH // + (optionally) the PopIndex CatApi request statements // + (optionally) the LOCK TABLE statements for ON STATEMENT MV ComposeMySql(); }
void CRURefreshTaskExecutor::CheckSingleDeltaRestriction() { CRUMV &rootMV = GetRootMV(); CRUTblList &tblList = rootMV.GetFullySyncTablesUsedByMe(); DSListPosition pos = tblList.GetHeadPosition(); while (NULL != pos) { CRUTbl *pTbl = tblList.GetNext(pos); RUASSERT (TRUE == pTbl->IsFullySynchronized()); if (TRUE == pTbl->IsEmptyDeltaNeeded() && TRUE == rootMV.IsDeltaNonEmpty(*pTbl)) { CRUException errDesc; errDesc.SetError(IDS_RU_INCONSISTENT_JOIN); errDesc.AddArgument(rootMVName_); throw errDesc; } } }
//--------------------------------------------------------------------------// // CRURefreshTaskExecutor::GetDefaultMdamOptForTable() // // If the table has more then two key columns and the range log is not empty // then mdam must be forced on the table unless the user forced otherwise //--------------------------------------------------------------------------// CRUForceOptions::MdamOptions CRURefreshTaskExecutor::GetDefaultMdamOptForTable(CRUTbl &tbl) { Int32 numTableKeyCol = tbl.GetKeyColumnList().GetCount(); if (numTableKeyCol < 2) { return CRUForceOptions::MDAM_NO_FORCE; } if (FALSE == GetRefreshTask()->IsSingleDeltaRefresh()) { return CRUForceOptions::MDAM_NO_FORCE; } const CRUDeltaDef *pDdef = GetRootMV().GetDeltaDefByUid(tbl.GetUID()); if (NULL != pDdef && TRUE == pDdef->isRangeLogNonEmpty_) { return CRUForceOptions::MDAM_ON; } return CRUForceOptions::MDAM_NO_FORCE; }
//--------------------------------------------------------------------------// // CRUAuditRefreshTaskExecutor::ComposeIndexesSql() // //--------------------------------------------------------------------------// void CRUAuditRefreshTaskExecutor::ComposeIndexesSql() { const CDDIndexList &indexList = GetRootMV().GetIndexList(); if( NULL == pAuditPopIndexdynamicContainer_ ) pAuditPopIndexdynamicContainer_ = new CRUSQLDynamicStatementContainer(numOfIndexes_); if( NULL == pAuditAvailableIndeXdynamicContainer_ ) pAuditAvailableIndeXdynamicContainer_ = new CRUSQLDynamicStatementContainer(numOfIndexes_); if( NULL == pAuditUnavailableIndeXdynamicContainer_ ) pAuditUnavailableIndeXdynamicContainer_ = new CRUSQLDynamicStatementContainer(numOfIndexes_); if( NULL == pAuditToggleOnIndexdynamicContainer_ ) pAuditToggleOnIndexdynamicContainer_ = new CRUSQLDynamicStatementContainer(numOfIndexes_); if( NULL == pAuditToggleOffIndexdynamicContainer_ ) pAuditToggleOffIndexdynamicContainer_ = new CRUSQLDynamicStatementContainer(numOfIndexes_); DSListPosition pos = indexList.GetHeadPosition(); for (Int32 i=0;NULL != pos;i++) { CDDIndex *pddIndex = indexList.GetNext(pos); CDSString popIdxRqst; GetRootMV().GetPopIndexCatApiRequestText(popIdxRqst, pddIndex); pAuditPopIndexdynamicContainer_->SetStatementText(i, popIdxRqst); CDSString availablepopIdxRqst; GetRootMV().GetUpdateIndexStatusCatApiRequestText(availablepopIdxRqst, TRUE, /*available*/ pddIndex); pAuditAvailableIndeXdynamicContainer_->SetStatementText(i, availablepopIdxRqst); CDSString unavailableIdxRqst; GetRootMV().GetUpdateIndexStatusCatApiRequestText(unavailableIdxRqst, FALSE, /*unavailable*/ pddIndex); pAuditUnavailableIndeXdynamicContainer_->SetStatementText(i, unavailableIdxRqst); CDSString auditOffIdxRqst; GetRootMV().GetToggleAuditCatApiRequestText(auditOffIdxRqst, FALSE, /* audit OFF */ pddIndex); pAuditToggleOffIndexdynamicContainer_->SetStatementText(i,auditOffIdxRqst); CDSString auditOnIdxRqst; GetRootMV().GetToggleAuditCatApiRequestText(auditOnIdxRqst, TRUE, /* audit ON */ pddIndex); pAuditToggleOnIndexdynamicContainer_->SetStatementText(i,auditOnIdxRqst); } }
CDSString CRURefreshSQLComposer::GetContextLogName() const { return " (RANGE_LOG_TABLE " + GetRootMV().GetFullName() + " ) "; }