NSStagedMigrationManager shortcomings

It seems to me that NSStagedMigrationManager has algorithmic issues. It doesn't perform staged migration, if all its stages are NSLightweightMigrationStage.

You can try it yourself. There is a test project with three model versions V1, V2, V3, V4. Migrating V1->V2 is compatible with lightweight migration, V2->V3, V3->V4 is also compatible, but V1->V3 is not. I have following output:

Migrating V1->V2, error: nil

Migrating V2->V3, error: nil

Migrating V3->V4, error: nil

Migrating V1->V3, no manager, error: Optional("Persistent store migration failed, missing mapping model.")

Migrating V1->V3, lightweight[1, 2, 3], error: Optional("Persistent store migration failed, missing mapping model.")

Migrating V1->V3, lightweight[1]->lightweight[2]->lightweight[3], error: Optional("Persistent store migration failed, missing mapping model.")

Migrating V1->V3, custom[1->2]->lightweight[3], error: nil

Migrating V1->V3, lightweight[1]->custom[2->3], error: nil

Migrating V1->V3, custom[1->2]->custom[2->3], error: nil

Migrating V1->V4, error: Optional("Persistent store migration failed, missing mapping model.")

Migrating V2->V4, error: nil

Migrating V1->V4, custom[1->2]->lightweight[3, 4], error: nil

Migrating V1->V4, lightweight[3, 4]->custom[1->2], error: Optional("A store file cannot be migrated backwards with staged migration.")

Migrating V1->V4, lightweight[1, 2]->lightweight[3, 4], error: Optional("Persistent store migration failed, missing mapping model.")

Migrating V1->V4, lightweight[1]->custom[2->3]->lightweight[4], error: nil

Migrating V1->V4, lightweight[1,4]->custom[2->3], error: nil

Migrating V1->V4, custom[2->3]->lightweight[1,4], error: Optional("Persistent store migration failed, missing mapping model.")

I think that staged migration should satisfy the following rules for two consecutive stages:

  1. Any version of lightweight stage to any version of lightweight stage;
  2. Any version of lightweight stage to current version of custom stage;
  3. Next version of custom stage to any version of lightweight stage;
  4. Next version of custom stage to current version of custom stage.

However, rule 1 doesn't work, because migration manager skips intermediate versions if they are inside lightweight stages, even different ones.

Note that lightweight[3, 4]->custom[1->2] doesn't work, lightweight[1,4]->custom[2->3] works, but custom[2->3]->lightweight[1,4] doesn't work again.

Would like to hear your opinion on that, especially, from Core Data team, if possible.

Thanks!

Answered by DTS Engineer in 863638022

The framework currently has the following logic: If the migration stages are all of the NSLightweightMigrationStage type, the intermediate stages will be skipped.

That explains why your case, where V1->V2 and V2->V3 are lightweight migration-able but V1->V3 is not, is broken, and also explains why having a custom migration stage (NSCustomMigrationStage) makes it work.

I'd still suggest that you file a feedback report to request either changing or documenting the behavior.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

I think the problem here is that you've introduced a new foo attribute with a different type. Even though the old attribute goes away in model 2, I guess it thinks this attribute in model 3 is supposed match up with the one in model 1. You can fix this by giving the new foo a renaming identifier so that it sees these are different.

The thing with foo attribute is done on purpose to make a direct lightweight migration from V1 to V3 impossible. At the same time, it's possible to migrate using the intermediate V2.

The framework currently has the following logic: If the migration stages are all of the NSLightweightMigrationStage type, the intermediate stages will be skipped.

That explains why your case, where V1->V2 and V2->V3 are lightweight migration-able but V1->V3 is not, is broken, and also explains why having a custom migration stage (NSCustomMigrationStage) makes it work.

I'd still suggest that you file a feedback report to request either changing or documenting the behavior.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Thank you! I'll definitely send an improvement suggestion.

NSStagedMigrationManager shortcomings
 
 
Q