25
25
import java .io .UncheckedIOException ;
26
26
import java .util .ArrayList ;
27
27
import java .util .Arrays ;
28
+ import java .util .Collections ;
29
+ import java .util .HashMap ;
28
30
import java .util .List ;
31
+ import java .util .Map ;
29
32
import org .apache .commons .lang3 .mutable .MutableLong ;
30
33
import org .apache .hadoop .conf .Configuration ;
31
34
import org .apache .hadoop .fs .FileStatus ;
45
48
import org .apache .hadoop .hbase .client .TableDescriptor ;
46
49
import org .apache .hadoop .hbase .client .TableDescriptorBuilder ;
47
50
import org .apache .hadoop .hbase .log .HBaseMarkers ;
51
+ import org .apache .hadoop .hbase .master .assignment .AssignProcedure ;
52
+ import org .apache .hadoop .hbase .master .assignment .MoveRegionProcedure ;
53
+ import org .apache .hadoop .hbase .master .assignment .UnassignProcedure ;
54
+ import org .apache .hadoop .hbase .master .procedure .RecoverMetaProcedure ;
55
+ import org .apache .hadoop .hbase .master .procedure .ServerCrashProcedure ;
48
56
import org .apache .hadoop .hbase .procedure2 .Procedure ;
49
57
import org .apache .hadoop .hbase .procedure2 .ProcedureUtil ;
50
58
import org .apache .hadoop .hbase .procedure2 .store .LeaseRecovery ;
65
73
import org .slf4j .LoggerFactory ;
66
74
67
75
import org .apache .hbase .thirdparty .com .google .common .annotations .VisibleForTesting ;
76
+ import org .apache .hbase .thirdparty .com .google .common .collect .ImmutableSet ;
68
77
import org .apache .hbase .thirdparty .com .google .common .math .IntMath ;
69
78
70
79
import org .apache .hadoop .hbase .shaded .protobuf .generated .ProcedureProtos ;
@@ -298,6 +307,46 @@ private HRegion open(Configuration conf, FileSystem fs, Path rootDir) throws IOE
298
307
null );
299
308
}
300
309
310
+ @ SuppressWarnings ("deprecation" )
311
+ private static final ImmutableSet <Class <?>> UNSUPPORTED_PROCEDURES =
312
+ ImmutableSet .of (RecoverMetaProcedure .class , AssignProcedure .class , UnassignProcedure .class ,
313
+ MoveRegionProcedure .class );
314
+
315
+ /**
316
+ * In HBASE-20811, we have introduced a new TRSP to assign/unassign/move regions, and it is
317
+ * incompatible with the old AssignProcedure/UnassignProcedure/MoveRegionProcedure. So we need to
318
+ * make sure that there are none these procedures when upgrading. If there are, the master will
319
+ * quit, you need to go back to the old version to finish these procedures first before upgrading.
320
+ */
321
+ private void checkUnsupportedProcedure (Map <Class <?>, List <Procedure <?>>> procsByType )
322
+ throws HBaseIOException {
323
+ // Confirm that we do not have unfinished assign/unassign related procedures. It is not easy to
324
+ // support both the old assign/unassign procedures and the new TransitRegionStateProcedure as
325
+ // there will be conflict in the code for AM. We should finish all these procedures before
326
+ // upgrading.
327
+ for (Class <?> clazz : UNSUPPORTED_PROCEDURES ) {
328
+ List <Procedure <?>> procs = procsByType .get (clazz );
329
+ if (procs != null ) {
330
+ LOG .error ("Unsupported procedure type {} found, please rollback your master to the old" +
331
+ " version to finish them, and then try to upgrade again." +
332
+ " See https://hbase.apache.org/book.html#upgrade2.2 for more details." +
333
+ " The full procedure list: {}" , clazz , procs );
334
+ throw new HBaseIOException ("Unsupported procedure type " + clazz + " found" );
335
+ }
336
+ }
337
+ // A special check for SCP, as we do not support RecoverMetaProcedure any more so we need to
338
+ // make sure that no one will try to schedule it but SCP does have a state which will schedule
339
+ // it.
340
+ if (procsByType .getOrDefault (ServerCrashProcedure .class , Collections .emptyList ()).stream ()
341
+ .map (p -> (ServerCrashProcedure ) p ).anyMatch (ServerCrashProcedure ::isInRecoverMetaState )) {
342
+ LOG .error ("At least one ServerCrashProcedure is going to schedule a RecoverMetaProcedure," +
343
+ " which is not supported any more. Please rollback your master to the old version to" +
344
+ " finish them, and then try to upgrade again." +
345
+ " See https://hbase.apache.org/book.html#upgrade2.2 for more details." );
346
+ throw new HBaseIOException ("Unsupported procedure state found for ServerCrashProcedure" );
347
+ }
348
+ }
349
+
301
350
@ SuppressWarnings ("deprecation" )
302
351
private void tryMigrate (FileSystem fs ) throws IOException {
303
352
Configuration conf = server .getConfiguration ();
@@ -311,7 +360,8 @@ private void tryMigrate(FileSystem fs) throws IOException {
311
360
store .start (numThreads );
312
361
store .recoverLease ();
313
362
MutableLong maxProcIdSet = new MutableLong (-1 );
314
- MutableLong maxProcIdFromProcs = new MutableLong (-1 );
363
+ List <Procedure <?>> procs = new ArrayList <>();
364
+ Map <Class <?>, List <Procedure <?>>> activeProcsByType = new HashMap <>();
315
365
store .load (new ProcedureLoader () {
316
366
317
367
@ Override
@@ -321,16 +371,13 @@ public void setMaxProcId(long maxProcId) {
321
371
322
372
@ Override
323
373
public void load (ProcedureIterator procIter ) throws IOException {
324
- long procCount = 0 ;
325
374
while (procIter .hasNext ()) {
326
375
Procedure <?> proc = procIter .next ();
327
- update (proc );
328
- procCount ++;
329
- if (proc .getProcId () > maxProcIdFromProcs .longValue ()) {
330
- maxProcIdFromProcs .setValue (proc .getProcId ());
376
+ procs .add (proc );
377
+ if (!proc .isFinished ()) {
378
+ activeProcsByType .computeIfAbsent (proc .getClass (), k -> new ArrayList <>()).add (proc );
331
379
}
332
380
}
333
- LOG .info ("Migrated {} procedures" , procCount );
334
381
}
335
382
336
383
@ Override
@@ -347,6 +394,22 @@ public void handleCorrupted(ProcedureIterator procIter) throws IOException {
347
394
}
348
395
}
349
396
});
397
+
398
+ // check whether there are unsupported procedures, this could happen when we are migrating from
399
+ // 2.1-. We used to do this in HMaster, after loading all the procedures from procedure store,
400
+ // but here we have to do it before migrating, otherwise, if we find some unsupported
401
+ // procedures, the users can not go back to 2.1 to finish them any more, as all the data are now
402
+ // in the new region based procedure store, which is not supported in 2.1-.
403
+ checkUnsupportedProcedure (activeProcsByType );
404
+
405
+ MutableLong maxProcIdFromProcs = new MutableLong (-1 );
406
+ for (Procedure <?> proc : procs ) {
407
+ update (proc );
408
+ if (proc .getProcId () > maxProcIdFromProcs .longValue ()) {
409
+ maxProcIdFromProcs .setValue (proc .getProcId ());
410
+ }
411
+ }
412
+ LOG .info ("Migrated {} existing procedures from the old storage format." , procs .size ());
350
413
LOG .info ("The WALProcedureStore max pid is {}, and the max pid of all loaded procedures is {}" ,
351
414
maxProcIdSet .longValue (), maxProcIdFromProcs .longValue ());
352
415
// Theoretically, the maxProcIdSet should be greater than or equal to maxProcIdFromProcs, but
0 commit comments