1919
2020import  java .io .FileNotFoundException ;
2121import  java .io .IOException ;
22+ import  java .util .Arrays ;
2223import  java .util .Collections ;
2324import  java .util .HashSet ;
2425import  java .util .Iterator ;
26+ import  java .util .LinkedList ;
2527import  java .util .List ;
2628import  java .util .Set ;
2729import  org .apache .hadoop .conf .Configuration ;
@@ -182,19 +184,56 @@ private void claimReplicationQueues(ReplicationSourceManager mgr, Set<ServerName
182184    }
183185  }
184186
185-   private  void  writeInfoFile (FileSystem  fs ) throws  IOException  {
187+   private  void  writeInfoFile (FileSystem  fs ,  boolean   isForce ) throws  IOException  {
186188    // Record the info of this run. Currently only record the time we run the job. We will use this 
187189    // timestamp to clean up the data for last sequence ids and hfile refs in replication queue 
188190    // storage. See ReplicationQueueStorage.removeLastSequenceIdsAndHFileRefsBefore. 
189191    ReplicationSyncUpToolInfo  info  =
190192      new  ReplicationSyncUpToolInfo (EnvironmentEdgeManager .currentTime ());
191193    String  json  = JsonMapper .writeObjectAsString (info );
192194    Path  infoDir  = new  Path (CommonFSUtils .getRootDir (getConf ()), INFO_DIR );
193-     try  (FSDataOutputStream  out  = fs .create (new  Path (infoDir , INFO_FILE ), false )) {
195+     try  (FSDataOutputStream  out  = fs .create (new  Path (infoDir , INFO_FILE ), isForce )) {
194196      out .write (Bytes .toBytes (json ));
195197    }
196198  }
197199
200+   private  static  boolean  parseOpts (String  args []) {
201+     LinkedList <String > argv  = new  LinkedList <>();
202+     argv .addAll (Arrays .asList (args ));
203+     String  cmd  = null ;
204+     while  ((cmd  = argv .poll ()) != null ) {
205+       if  (cmd .equals ("-h" ) || cmd .equals ("--h" ) || cmd .equals ("--help" )) {
206+         printUsageAndExit (null , 0 );
207+       }
208+       if  (cmd .equals ("-f" )) {
209+         return  true ;
210+       }
211+       if  (!argv .isEmpty ()) {
212+         printUsageAndExit ("ERROR: Unrecognized option/command: "  + cmd , -1 );
213+       }
214+     }
215+     return  false ;
216+   }
217+ 
218+   private  static  void  printUsageAndExit (final  String  message , final  int  exitCode ) {
219+     printUsage (message );
220+     System .exit (exitCode );
221+   }
222+ 
223+   private  static  void  printUsage (final  String  message ) {
224+     if  (message  != null  && message .length () > 0 ) {
225+       System .err .println (message );
226+     }
227+     System .err .println ("Usage: hbase "  + ReplicationSyncUp .class .getName () + " \\ " );
228+     System .err .println ("  <OPTIONS> [-D<property=value>]*" );
229+     System .err .println ();
230+     System .err .println ("General Options:" );
231+     System .err .println (" -h|--h|--help  Show this help and exit." );
232+     System .err 
233+       .println (" -f Start a new ReplicationSyncUp after the previous ReplicationSyncUp failed. " 
234+         + "See HBASE-27623 for details." );
235+   }
236+ 
198237  @ Override 
199238  public  int  run (String [] args ) throws  Exception  {
200239    Abortable  abortable  = new  Abortable () {
@@ -217,6 +256,7 @@ public boolean isAborted() {
217256        return  abort ;
218257      }
219258    };
259+     boolean  isForce  = parseOpts (args );
220260    Configuration  conf  = getConf ();
221261    try  (ZKWatcher  zkw  = new  ZKWatcher (conf ,
222262      "syncupReplication"  + EnvironmentEdgeManager .currentTime (), abortable , true )) {
@@ -226,7 +266,7 @@ public boolean isAborted() {
226266      Path  logDir  = new  Path (walRootDir , HConstants .HREGION_LOGDIR_NAME );
227267
228268      System .out .println ("Start Replication Server" );
229-       writeInfoFile (fs );
269+       writeInfoFile (fs ,  isForce );
230270      Replication  replication  = new  Replication ();
231271      // use offline table replication queue storage 
232272      getConf ().setClass (ReplicationStorageFactory .REPLICATION_QUEUE_IMPL ,
0 commit comments