// PD_TRACE_DECLARE_FUNCTION ( SDB__DPSRPCMGR__GETSTARTLSN, "_dpsReplicaLogMgr::_getStartLsn" ) DPS_LSN _dpsReplicaLogMgr::_getStartLsn () { PD_TRACE_ENTRY ( SDB__DPSRPCMGR__GETSTARTLSN ); UINT32 begin = _begin ; DPS_LSN lsn ; for ( UINT32 count = 0 ; count < _pageNum; count++ ) { lsn = PAGE(begin)->getBeginLSN () ; if ( !lsn.invalid() ) { goto done ; } if ( begin == _work ) { break ; } begin = _incPageID ( begin ) ; } done : PD_TRACE_EXIT ( SDB__DPSRPCMGR__GETSTARTLSN ); return lsn ; }
DPS_LSN _dpsLogFileMgr::getStartLSN ( BOOLEAN mustExist ) { DPS_LSN lsn = LOG_FILE ( _work + 1 )->getFirstLSN ( mustExist ) ; if ( !lsn.invalid() ) return lsn ; else return LOG_FILE ( _begin )->getFirstLSN ( mustExist ) ; }
DPS_LSN _dpsReplicaLogMgr::getStartLsn ( BOOLEAN logBufOnly ) { ossScopedLock lock( &_mtx ) ; DPS_LSN memBeginLsn = _getStartLsn () ; if ( logBufOnly ) return memBeginLsn ; DPS_LSN lsn = _logger.getStartLSN (); if ( lsn.invalid() || lsn.offset > memBeginLsn.offset) { return memBeginLsn ; } return lsn ; }
// PD_TRACE_DECLARE_FUNCTION ( SDB__DPSRPCMGR_GETLSNWIN, "_dpsReplicaLogMgr::getLsnWindow" ) void _dpsReplicaLogMgr::getLsnWindow( DPS_LSN &fileBeginLsn, DPS_LSN &memBeginLsn, DPS_LSN &endLsn ) { PD_TRACE_ENTRY ( SDB__DPSRPCMGR_GETLSNWIN ); ossScopedLock lock( &_mtx ) ; memBeginLsn = _getStartLsn() ; fileBeginLsn = _logger.getStartLSN () ; if ( fileBeginLsn.invalid() || fileBeginLsn.offset > memBeginLsn.offset ) { fileBeginLsn = memBeginLsn ; } endLsn = _currentLsn ; PD_TRACE_EXIT ( SDB__DPSRPCMGR_GETLSNWIN ); return ; }
// PD_TRACE_DECLARE_FUNCTION ( SDB__CLSSYNCMAG_COMPLETE, "_clsSyncManager::complete" ) void _clsSyncManager::complete( const MsgRouteID &id, const DPS_LSN &lsn, UINT32 TID ) { PD_TRACE_ENTRY ( SDB__CLSSYNCMAG_COMPLETE ) ; if ( lsn.invalid() || MSG_INVALID_ROUTEID == id.value ) { PD_LOG( PDDEBUG, "sync: invalid complete." "[nodeid:%d] [lsn:%d, %lld]", id.columns.nodeID, lsn.version, lsn.offset ) ; goto done ; } { _info->mtx.lock_r() ; _MsgRouteID primary = _info->primary ; _info->mtx.release_r() ; if ( primary.value == _info->local.value && MSG_INVALID_ROUTEID != primary.value ) { _complete( id, lsn.offset ) ; } else if ( MSG_INVALID_ROUTEID != primary.value ) { _MsgReplVirSyncReq msg ; msg.next = lsn ; msg.from = id ; msg.header.TID = TID ; _agent->syncSend( primary, &msg ) ; } else { } } done: PD_TRACE_EXIT ( SDB__CLSSYNCMAG_COMPLETE ) ; return ; }
// PD_TRACE_DECLARE_FUNCTION ( SDB__DPSRPCMGR__ALLOCATE, "_dpsReplicaLogMgr::_allocate" ) void _dpsReplicaLogMgr::_allocate( UINT32 len, dpsPageMeta &allocated ) { PD_TRACE_ENTRY ( SDB__DPSRPCMGR__ALLOCATE ); UINT32 needAlloc = len; UINT32 pageNum = 0; SDB_ASSERT( 0 != len, "can not allocate zero length" ) ; SDB_ASSERT ( _totalSize > len, "total memory size must grater than record size" ) ; while ( _idleSize.peek() < needAlloc ) { PD_LOG ( PDWARNING, "No space in log buffer for %d bytes, currently " "left %d bytes", needAlloc, _idleSize.peek() ) ; _allocateEvent.wait ( OSS_ONE_SEC ) ; } allocated.offset = WORK_PAGE->getLength(); allocated.beginSub = _work ; do { pageNum++ ; if ( 1 == pageNum ) { DPS_LSN beginLSN = WORK_PAGE->getBeginLSN () ; if ( ( beginLSN.invalid() ) || ( _lsn.offset - beginLSN.offset > DPS_DEFAULT_PAGE_SIZE ) ) { WORK_PAGE->setBeginLSN ( _lsn ) ; } } else { DPS_LSN invalid ; invalid.version = _lsn.version ; WORK_PAGE->setBeginLSN ( invalid ) ; } UINT32 pageIdle = WORK_PAGE->getLastSize(); INT32 allocLen = pageIdle < needAlloc ? pageIdle : needAlloc; WORK_PAGE->allocate( allocLen ); needAlloc -= allocLen; if ( _begin == _work && _rollFlag ) { _begin = _incPageID ( _begin ) ; } if ( 0 == WORK_PAGE->getLastSize() ) { _work = _incPageID ( _work ) ; if ( !_rollFlag && _begin != _work ) { _rollFlag = TRUE ; } } } while ( needAlloc > 0 ) ; _idleSize.sub( len ) ; allocated.pageNum = pageNum ; allocated.totalLen = len ; PD_TRACE_EXIT ( SDB__DPSRPCMGR__ALLOCATE ); }
// PD_TRACE_DECLARE_FUNCTION ( SDB__DPSRPCMGR__SEARCH, "_dpsReplicaLogMgr::_search" ) INT32 _dpsReplicaLogMgr::_search ( const DPS_LSN &lsn, _dpsMessageBlock *mb, BOOLEAN onlyHeader ) { INT32 rc = SDB_OK ; PD_TRACE_ENTRY ( SDB__DPSRPCMGR__SEARCH ); dpsLogRecordHeader head ; UINT32 offset = 0 ; UINT32 len = 0 ; UINT32 pageSub = 0 ; DPS_LSN beginLSN ; DPS_LSN lastLSN ; BOOLEAN mtxLocked = FALSE ; BOOLEAN pageLocked = FALSE ; pageSub = ( lsn.offset / DPS_DEFAULT_PAGE_SIZE ) % _pageNum ; offset = lsn.offset % DPS_DEFAULT_PAGE_SIZE ; _mtx.get () ; mtxLocked = TRUE ; beginLSN = _getStartLsn() ; if ( beginLSN.invalid() ) { PD_LOG( PDERROR, "begin lsn invalid [offset:%lld] [version:%d]", beginLSN.offset, beginLSN.version ) ; rc = SDB_DPS_LOG_NOT_IN_BUF ; goto error ; } lastLSN = _lsn ; if ( 0 > lsn.compareOffset(beginLSN.offset) ) { PD_LOG( PDDEBUG, "lsn %lld is smaller than membegin %lld", lsn.offset, beginLSN.offset ) ; rc = SDB_DPS_LOG_NOT_IN_BUF ; goto error ; } else if ( 0 <= lsn.compareOffset(lastLSN.offset) ) { rc = SDB_DPS_LSN_OUTOFRANGE ; goto error ; } (&_pages[pageSub])->lock() ; pageLocked = TRUE ; _mtx.release() ; mtxLocked = FALSE ; rc = _parse ( pageSub, offset, sizeof(dpsLogRecordHeader), (CHAR*)&head ) ; if ( rc ) { PD_LOG ( PDERROR, "Failed to parse log record, rc = %d", rc ) ; goto error ; } if ( head._lsn != lsn.offset || head._length < sizeof(dpsLogRecordHeader) ) { PD_LOG ( PDERROR, "Unexpected LSN is read, expects %lld, %d," "actually read %lld, %d", lsn.offset, lsn.version, head._lsn, head._version ) ; rc = SDB_DPS_CORRUPTED_LOG ; goto error ; } if ( onlyHeader ) { len = sizeof( dpsLogRecordHeader ) ; } else { len = head._length ; } if ( mb->idleSize() < len ) { rc = mb->extend ( len - mb->idleSize () ) ; if ( rc ) { PD_LOG ( PDERROR, "Failed to extend mb, rc = %d", rc ) ; goto error ; } } if ( onlyHeader ) { ossMemcpy( mb->writePtr(), (CHAR*)&head, len ) ; } else { rc = _parse ( pageSub, offset, len, mb->writePtr() ) ; } (&_pages[pageSub])->unlock() ; pageLocked = FALSE ; if ( rc ) { PD_LOG ( PDERROR, "Failed to parse entire log, rc = %d", rc ) ; goto error ; } mb->writePtr ( len + mb->length () ) ; done : if ( mtxLocked ) { _mtx.release () ; } if ( pageLocked ) { (&_pages[pageSub])->unlock() ; } PD_TRACE_EXITRC ( SDB__DPSRPCMGR__SEARCH, rc ); return rc ; error : goto done ; }
// PD_TRACE_DECLARE_FUNCTION ( SDB__DPSRPCMGR_MOVE, "_dpsReplicaLogMgr::move" ) INT32 _dpsReplicaLogMgr::move( const DPS_LSN_OFFSET &offset, const DPS_LSN_VER &version ) { INT32 rc = SDB_OK ; PD_TRACE_ENTRY ( SDB__DPSRPCMGR_MOVE ); UINT32 tmpWork = 0 ; DPS_LSN_OFFSET tmpLsnOffset = 0 ; DPS_LSN_OFFSET tmpBeginOffset = 0 ; DPS_LSN tmpCurLsn ; ossScopedLock lock( &_mtx ) ; if ( DPS_INVALID_LSN_OFFSET == offset ) { rc = SDB_DPS_MOVE_FAILED ; PD_LOG( PDERROR, "can not move to a invalid lsn" ) ; goto error ; } while ( !_queSize.compare( 0 ) ) { ossSleep ( 100 ) ; } tmpWork = _work ; tmpCurLsn = _currentLsn ; tmpLsnOffset = _lsn.offset ; tmpBeginOffset = _getStartLsn().offset ; _idleSize.add ( (&_pages[_work])->getLength() ) ; (&_pages[_work])->clear() ; rc = _movePages ( offset, version ) ; if ( SDB_OK != rc ) { goto error ; } if ( offset >= tmpBeginOffset && offset <= tmpLsnOffset && tmpWork == _work && !tmpCurLsn.invalid() ) { goto done ; } rc = _logger.move( offset, version ) ; if ( SDB_OK != rc ) { goto error ; } if ( !_logger.getStartLSN().invalid() && offset < tmpBeginOffset ) { rc = _restore () ; } else //reset file idle size { _dpsLogFile *file = _logger.getWorkLogFile() ; UINT32 fileIdleSize = file->getIdleSize() + (&_pages[_work])->getLength() ; if ( fileIdleSize % DPS_DEFAULT_PAGE_SIZE != 0 ) { PD_LOG( PDERROR, "File[%s] idle size[%u] is not multi-times of " "page size, cur page info[%u, %s]", file->toString().c_str(), fileIdleSize, _work, (&_pages[_work])->toString().c_str() ) ; rc = SDB_SYS ; SDB_ASSERT( FALSE, "Idle size error" ) ; goto error ; } file->idleSize ( fileIdleSize ) ; } done: PD_TRACE_EXITRC ( SDB__DPSRPCMGR_MOVE, rc ); return rc ; error: goto done ; }
// PD_TRACE_DECLARE_FUNCTION ( SDB__DPSRPCMGR__RESTRORE, "_dpsReplicaLogMgr::_restore" ) INT32 _dpsReplicaLogMgr::_restore () { INT32 rc = SDB_OK ; PD_TRACE_ENTRY ( SDB__DPSRPCMGR__RESTRORE ); _dpsLogFile *file = _logger.getWorkLogFile() ; DPS_LSN beginLsn = file->getFirstLSN ( FALSE ) ; UINT32 length = file->getLength() ; _dpsMessageBlock block ( sizeof ( dpsLogRecordHeader ) ) ; _dpsMergeBlock mergeBlock ; dpsLogRecordHeader &head = mergeBlock.record().head(); _restoreFlag = TRUE ; if ( beginLsn.invalid() ) { rc = SDB_DPS_INVALID_LSN ; goto error ; } _movePages( beginLsn.offset, beginLsn.version ) ; while ( beginLsn.offset % file->size() < length ) { rc = _logger.load ( beginLsn, &block ) ; if ( SDB_OK != rc ) { PD_LOG ( PDERROR, "restore dps file load failed[rc:%d]", rc ) ; goto error ; } ossMemcpy( &head, block.offset(0), sizeof(dpsLogRecordHeader) ) ; mergeBlock.setRow( TRUE ); mergeBlock.record().push( DPS_LOG_ROW_ROWDATA, block.length()- sizeof(dpsLogRecordHeader), block.offset(sizeof(dpsLogRecordHeader))) ; rc = merge ( mergeBlock ) ; if ( SDB_OK != rc ) { PD_LOG ( PDERROR, "restore merge failed[rc:%d]", rc ) ; goto error ; } beginLsn.offset += head._length ; mergeBlock.clear() ; block.clear() ; } { UINT32 fileIdleSize = file->getIdleSize() + (&_pages[_work])->getLength() ; if ( fileIdleSize % DPS_DEFAULT_PAGE_SIZE != 0 ) { PD_LOG( PDERROR, "File[%s] idle size[%u] is not multi-times of " "page size, cur page info[%u, %s]", file->toString().c_str(), fileIdleSize, _work, (&_pages[_work])->toString().c_str() ) ; rc = SDB_SYS ; SDB_ASSERT( FALSE, "Idle size error" ) ; goto error ; } file->idleSize ( fileIdleSize ) ; } done: _restoreFlag = FALSE ; PD_TRACE_EXITRC ( SDB__DPSRPCMGR__RESTRORE, rc ); return rc ; error: goto done ; }