private boolean updateExistingSchemas(String namespace, String compression, List<ChangeSet> changeSets, List<TableDescriptor> currentHtds, List<SchemaChangeLog> executedLogs) {
        logger.info("[{}] Updating hbase schema.", namespace);

        List<String> executedChangeLogIds = executedLogs.stream()
                .map(SchemaChangeLog::getId).collect(Collectors.toList());
        logger.info("[{}] Executed change logs : {}", namespace, executedChangeLogIds);

        ChangeSetManager changeSetManager = new ChangeSetManager(changeSets);

        // Check if the current table schema matches the expected schema specified by the executed schema change logs.
        HbaseSchemaCommandManager initCommandManager = new HbaseSchemaCommandManager(namespace, compression);
        List<ChangeSet> executedChangeSets = changeSetManager.getExecutedChangeSets(executedLogs);
        for (ChangeSet executedChangeSet : executedChangeSets) {
            initCommandManager.applyChangeSet(executedChangeSet);
        }
        if (!hbaseSchemaVerifier.verifySchemas(initCommandManager.getSchemaSnapshot(), currentHtds)) {
            throw new IllegalStateException("Current table schema does not match the schema change log records.");
        }

        List<ChangeSet> changeSetsToApply = changeSetManager.filterExecutedChangeSets(executedLogs);
        if (changeSetsToApply.isEmpty()) {
            logger.info("[{}] Hbase schema already at latest version", namespace);
            return false;
        }
        HbaseSchemaCommandManager updateCommandManager = new HbaseSchemaCommandManager(namespace, compression, currentHtds);
        return applyChangeSets(updateCommandManager, changeSetsToApply, executedLogs);
    }
This implementation uses the executed schema change logs to compare against the specified {@code changeSets} to
check the current schema status, regardless of how the actual schema looks like.
hbase/hbase-schema/src/main/java/com/navercorp/pinpoint/hbase/schema/service/HbaseSchemaServiceImpl.java