Exemple #1
0
   // PD_TRACE_DECLARE_FUNCTION ( SDB__CLSSYNCMAG__WAKE, "_clsSyncManager::_wake" )
   void _clsSyncManager::_wake( CLS_WAKE_PLAN &plan )
   {

      PD_TRACE_ENTRY ( SDB__CLSSYNCMAG__WAKE ) ;
      SDB_ASSERT( plan.size() <= CLS_REPLSET_MAX_NODE_SIZE - 1,
                  "plan size should <= CLS_REPLSET_MAX_NODE_SIZE - 1" ) ;

      _clsSyncSession session ;
      UINT32 sub = 0 ;
      CLS_WAKE_PLAN::reverse_iterator ritr = plan.rbegin();
      while ( ritr != plan.rend() )
      {
         DPS_LSN lsn ;
         lsn.offset = *ritr ;
         _mtxs[sub].get() ;
         _checkList[sub] = lsn.offset ;
         while ( SDB_OK == _syncList[sub].root( session ) )
         {
            if ( 0 < lsn.compareOffset( session.endLsn ) )
            {
               session.eduCB->getEvent().signal ( SDB_OK ) ;
               _syncList[sub].pop( session ) ;
            }
            else
            {
               break ;
            }
         }
         _mtxs[sub].release() ;

         ++ritr ;
         ++sub ;
      }
      PD_TRACE_EXIT ( SDB__CLSSYNCMAG__WAKE ) ;
   }
   // 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__CLSSYNCMAG_ATLEASTONE, "_clsSyncManager::atLeastOne" )
BOOLEAN _clsSyncManager::atLeastOne( const DPS_LSN_OFFSET &offset )
{
    BOOLEAN res = FALSE ;
    PD_TRACE_ENTRY( SDB__CLSSYNCMAG_ATLEASTONE ) ;
    DPS_LSN lsn ;
    lsn.offset = offset ;
    ossScopedRWLock lock( &_info->mtx, SHARED ) ;

    for ( UINT32 i = 0; i < _validSync ; i++ )
    {
        if ( 0 > lsn.compareOffset( _notifyList[i].offset ) )
        {
            res = TRUE ;
            break ;
        }
    }
    PD_TRACE_EXIT( SDB__CLSSYNCMAG_ATLEASTONE ) ;
    return res ;
}
Exemple #6
0
   // PD_TRACE_DECLARE_FUNCTION ( SDB_CLSSYNCWIN, "clsSyncWindow" )
   CLS_SYNC_STATUS clsSyncWindow( const DPS_LSN &remoteLsn,
                                  const DPS_LSN &fileBeginLsn,
                                  const DPS_LSN &memBeginLSn,
                                  const DPS_LSN &endLsn )
   {
      PD_TRACE_ENTRY ( SDB_CLSSYNCWIN ) ;
      CLS_SYNC_STATUS status = CLS_SYNC_STATUS_NONE ;
      INT32 frc = fileBeginLsn.compare( remoteLsn ) ;
      INT32 mrc = memBeginLSn.compare( remoteLsn ) ;
      INT32 erc = endLsn.compare( remoteLsn ) ;


      if ( 0 < frc )
      {
         goto done ;
      }
      if ( frc <= 0 && 0 < mrc )
      {
         status = CLS_SYNC_STATUS_RC ;
         goto done ;
      }
      else if ( mrc <= 0 && 0 < erc )
      {
         status = CLS_SYNC_STATUS_PEER ;
         goto done ;
      }
      else if ( 0 == erc )
      {
         status = CLS_SYNC_STATUS_PEER ;
         goto done ;
      }
      else
      {
         goto done ;
      }
   done:
      PD_TRACE_EXIT ( SDB_CLSSYNCWIN ) ;
      return status ;
   }
Exemple #7
0
   // PD_TRACE_DECLARE_FUNCTION ( SDB__CLSSYNCMAG__COMPLETE, "_clsSyncManager::_complete" )
   void _clsSyncManager::_complete( const MsgRouteID &id,
                                    const DPS_LSN_OFFSET &offset )
   {
      PD_TRACE_ENTRY ( SDB__CLSSYNCMAG__COMPLETE ) ;
      DPS_LSN lsn ;
      lsn.offset = offset ;

      ossScopedRWLock lock( &_info->mtx, SHARED ) ;

      for ( UINT32 i = 0; i < _validSync ; i++ )
      {
         if ( _notifyList[i].id.value == id.value )
         {
            INT32 result = lsn.compareOffset( _notifyList[i].offset ) ;
            if ( 0 == result )
            {
               ++_notifyList[i].sameReqTimes ;
            }
            else
            {
               _notifyList[i].sameReqTimes = 0 ;
            }

            if ( result > 0 )
            {
               _notifyList[i].offset = offset ;
            }
            break ;
         }
      }

      {
         CLS_WAKE_PLAN plan ;
         _createWakePlan( lsn.offset, plan ) ;
         _wake( plan ) ;
      }
      PD_TRACE_EXIT ( SDB__CLSSYNCMAG__COMPLETE ) ;
      return ;
   }
 // 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 ;
 }
Exemple #9
0
 // 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 ;
   }