Pavel Pereslegin created IGNITE-20498:
-----------------------------------------

             Summary: Prevent potential catalog version order violations.
                 Key: IGNITE-20498
                 URL: https://issues.apache.org/jira/browse/IGNITE-20498
             Project: Ignite
          Issue Type: Bug
            Reporter: Pavel Pereslegin


Currently, catalog versions are stored in an ordered structure. The activation 
timestamp is used as a key, which depends on the configuration property 
"schemaSync.delayDuration".

Changes to "delayDuration" parameter in runtime may lead to a violation of the 
order in which catalog versions are stored. That is, the old version may be 
saved with a larger timestamp than the newer one. 

As a result, the manager can return incorrect (older) version of the catalog 
using a timestamp.

reproducer:


{code:java}
public class CatalogDelayDurationChangeTest extends BaseIgniteAbstractTest {
    private static final String NODE_NAME = "node1";
    private static final String TABLE_NAME = "test1";
    private final HybridClock clock = new HybridClockImpl();
    private final AtomicLong delayFromConfig = new AtomicLong();

    @Test
    public void testChangeDelayDuration() {
        CatalogManager catalogMgr = createManager();

        // Prepare schema changes.
        ColumnParams column = 
ColumnParams.builder().name("ID").type(ColumnType.INT32).build();
        CatalogCommand cmd1 = 
BaseCatalogManagerTest.createTableCommand(TABLE_NAME, List.of(column), 
List.of("ID"), null);
        CatalogCommand cmd2 = 
BaseCatalogManagerTest.createTableCommand("test2", List.of(column), 
List.of("ID"), null);

        // Make first schema change with delay = 1000.
        delayFromConfig.set(1_000);
        CompletableFuture<Void> schemaChangeFuture0 = catalogMgr.execute(cmd1);

        // Make second schema change with delay = 100.
        delayFromConfig.set(1);
        CompletableFuture<Void> schemaChangeFuture1 = catalogMgr.execute(cmd2);

        assertThat(schemaChangeFuture0, willCompleteSuccessfully());
        assertThat(schemaChangeFuture1, willCompleteSuccessfully());

        // Make sure that we are getting the latest version of the schema using 
current timestamp.
        int latestVer = catalogMgr.latestCatalogVersion();
        int currentTsVer = 
catalogMgr.activeCatalogVersion(clock.now().longValue());
        assertThat(currentTsVer, equalTo(latestVer));
    }

    private CatalogManager createManager() {
        VaultManager vault = new VaultManager(new InMemoryVaultService());
        MetaStorageManager metastore = 
StandaloneMetaStorageManager.create(vault, new 
SimpleInMemoryKeyValueStorage(NODE_NAME));
        UpdateLog updateLog = spy(new UpdateLogImpl(metastore));
        ClockWaiter clockWaiter = spy(new ClockWaiter(NODE_NAME, clock));
        CatalogManager manager = new CatalogManagerImpl(updateLog, clockWaiter, 
delayFromConfig::get);

        vault.start();
        metastore.start();
        clockWaiter.start();
        manager.start();

        metastore.deployWatches().join();

        return manager;
    }
}
{code}




--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to