[
https://issues.apache.org/jira/browse/CASSANDRA-8505?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15000767#comment-15000767
]
Sam Tunnicliffe commented on CASSANDRA-8505:
--------------------------------------------
I think the various index states can be reduced to a simple ready/not ready
check. What's more unless we intend to change the established behaviour fairly
significantly, once an index moves to a ready state it never moves back to
being not ready. The only times when we modify the status in the system table
are when the index is removed (in which case we have no problem with being able
to query using it) or during a rebuild. In the latter case though, we probably
shouldn't reject queries (and we don't currently), as an index rebuild is
incremental. That is, we don't scrap the existing index tables and rebuild
everything from scratch, just write new index SSTables to supercede the old
ones. So although it's certainly possible to get incorrect results during a
rebuild (because of missing/stale entries), the results only get more correct
as the rebuild progresses. Changing this so that all queries against that index
return errors until all rebuilds complete seems like a step backwards. It seems
more reasonable to reject queries until the initial build has been performed,
as per the example in the description, but this only requires a simple boolean
to track state between instantiating/registering the index and its initial
build task completing (if one is required).
It would be good to have some test coverage of this, although the best I could
come up with is a dtest which inserts many rows, then adds the index and
queries immediately expecting ReadFailureException, which is fairly lame and
fragile.
A couple of points specific to the 3.0 patch:
* The fix for CASSANDRA-10595 has been lost. If an index doesn't register
itself in {{createIndex}}, don't ask it for an initalization task, just set
{{initialBuildTask == null}}.
* {{SIM::reloadIndex}} has changed since the patch was created (due to
CASSANDRA-10604) - I think that no changes to this method are now required. I
did notice though that the current implementation actually makes a redundant
call to {{getMetadataReloadTask}}, so if you could fix that while you're here,
that'd be great.
bq. Secondary index and their build/not build status are node-local. By
consequence it is not possible to know on a coordinator node if the index is
fully build. It can be built on the coordinator but still building on other
nodes
For future reference on this point, we also have CASSANDRA-9967 which has a
very similar intent.
> Invalid results are returned while secondary index are being build
> ------------------------------------------------------------------
>
> Key: CASSANDRA-8505
> URL: https://issues.apache.org/jira/browse/CASSANDRA-8505
> Project: Cassandra
> Issue Type: Bug
> Components: Coordination
> Reporter: Benjamin Lerer
> Assignee: Benjamin Lerer
> Fix For: 2.2.x, 3.0.x
>
>
> If you request an index creation and then execute a query that use the index
> the results returned might be invalid until the index is fully build. This is
> caused by the fact that the table column will be marked as indexed before the
> index is ready.
> The following unit tests can be use to reproduce the problem:
> {code}
> @Test
> public void testIndexCreatedAfterInsert() throws Throwable
> {
> createTable("CREATE TABLE %s (a int, b int, c int, primary key((a,
> b)))");
> execute("INSERT INTO %s (a, b, c) VALUES (0, 0, 0);");
> execute("INSERT INTO %s (a, b, c) VALUES (0, 1, 1);");
> execute("INSERT INTO %s (a, b, c) VALUES (0, 2, 2);");
> execute("INSERT INTO %s (a, b, c) VALUES (1, 0, 3);");
> execute("INSERT INTO %s (a, b, c) VALUES (1, 1, 4);");
>
> createIndex("CREATE INDEX ON %s(b)");
>
> assertRows(execute("SELECT * FROM %s WHERE b = ?;", 1),
> row(0, 1, 1),
> row(1, 1, 4));
> }
>
> @Test
> public void testIndexCreatedBeforeInsert() throws Throwable
> {
> createTable("CREATE TABLE %s (a int, b int, c int, primary key((a,
> b)))");
> createIndex("CREATE INDEX ON %s(b)");
>
> execute("INSERT INTO %s (a, b, c) VALUES (0, 0, 0);");
> execute("INSERT INTO %s (a, b, c) VALUES (0, 1, 1);");
> execute("INSERT INTO %s (a, b, c) VALUES (0, 2, 2);");
> execute("INSERT INTO %s (a, b, c) VALUES (1, 0, 3);");
> execute("INSERT INTO %s (a, b, c) VALUES (1, 1, 4);");
> assertRows(execute("SELECT * FROM %s WHERE b = ?;", 1),
> row(0, 1, 1),
> row(1, 1, 4));
> }
> {code}
> The first test will fail while the second will work.
> In my opinion the first test should reject the request as invalid (as if the
> index was not existing) until the index is fully build.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)