Uploaded image for project: 'Aurora'
  1. Aurora
  2. AURORA-1912

DbSnapShot may remove enum values

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • None
    • 0.18.0
    • None
    • None

    Description

      The dbnsapshot restore may truncate enum tables and cause referential integrity issues. From the code it restores from the SQL dump by first dropping all tables:

                  try (Connection c = ((DataSource) store.getUnsafeStoreAccess()).getConnection()) {
                    LOG.info("Dropping all tables");
                    try (PreparedStatement drop = c.prepareStatement("DROP ALL OBJECTS")) {
                      drop.executeUpdate();
                    }
      

      However a freshly started leader will have some data in there from preparing the storage:

        @Override
        @Transactional
        protected void startUp() throws IOException {
          Configuration configuration = sessionFactory.getConfiguration();
          String createStatementName = "create_tables";
          configuration.setMapUnderscoreToCamelCase(true);
      
          // The ReuseExecutor will cache jdbc Statements with equivalent SQL, improving performance
          // slightly when redundant queries are made.
          configuration.setDefaultExecutorType(ExecutorType.REUSE);
      
          addMappedStatement(
              configuration,
              createStatementName,
              CharStreams.toString(new InputStreamReader(
                  DbStorage.class.getResourceAsStream("schema.sql"),
                  StandardCharsets.UTF_8)));
      
          try (SqlSession session = sessionFactory.openSession()) {
            session.update(createStatementName);
          }
      
          for (CronCollisionPolicy policy : CronCollisionPolicy.values()) {
            enumValueMapper.addEnumValue("cron_policies", policy.getValue(), policy.name());
          }
      
          for (MaintenanceMode mode : MaintenanceMode.values()) {
            enumValueMapper.addEnumValue("maintenance_modes", mode.getValue(), mode.name());
          }
      
          for (JobUpdateStatus status : JobUpdateStatus.values()) {
            enumValueMapper.addEnumValue("job_update_statuses", status.getValue(), status.name());
          }
      
          for (JobUpdateAction action : JobUpdateAction.values()) {
            enumValueMapper.addEnumValue("job_instance_update_actions", action.getValue(), action.name());
          }
      
          for (ScheduleStatus status : ScheduleStatus.values()) {
            enumValueMapper.addEnumValue("task_states", status.getValue(), status.name());
          }
      
          for (ResourceType resourceType : ResourceType.values()) {
            enumValueMapper.addEnumValue("resource_types", resourceType.getValue(), resourceType.name());
          }
      
          for (Mode mode : Mode.values()) {
            enumValueMapper.addEnumValue("volume_modes", mode.getValue(), mode.name());
          }
      
          createPoolMetrics();
        }
      

      Consider the case where we add a new value to an existing enum. This means restoring from a snapshot will not allow us to have that value in the enum table.

      To fix this we should have a migration for every enum value we add. However to me it seems that the better idea would be to update the enum tables after we restore from a snapshot.

      Attachments

        Activity

          People

            zmanji Zameer Manji
            zmanji Zameer Manji
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: