Details
-
New Feature
-
Status: Resolved
-
Normal
-
Resolution: Fixed
-
Operability
-
Low Hanging Fruit
-
All
-
None
-
Description
Add a guardrail to limit the number restrictions generated by the cartesian product of the IN restrictions of a SELECT query, for example:
# Guardrail to warn or abort when IN query creates a cartesian product with a # size exceeding threshold, eg. "a in (1,2,...10) and b in (1,2...10)" results in # cartesian product of 100. # The two thresholds default to -1 to disable. in_select_cartesian_product: warn_threshold: -1 abort_threshold: -1
As an example of why this guardrails is proposed, these queries bring a C* instance to its knees even before the query starts executing:
@Test public void testPartitionKeyTerms() throws Throwable { createTable("CREATE TABLE %s (pk1 int, pk2 int, pk3 int, pk4 int, pk5 int, pk6 int, pk7 int, pk8 int, pk9 int, " + "PRIMARY KEY((pk1, pk2, pk3, pk4, pk5, pk6, pk7, pk8, pk9)))"); execute("SELECT * FROM %s WHERE pk1 in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) " + "AND pk2 in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) " + "AND pk3 in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) " + "AND pk4 in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) " + "AND pk5 in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) " + "AND pk6 in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) " + "AND pk7 in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) " + "AND pk8 in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) " + "AND pk9 in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);"); } @Test public void testClusteringKeyTerms() throws Throwable { createTable("CREATE TABLE %s (pk int ,ck1 int, ck2 int, ck3 int, ck4 int, ck5 int, ck6 int, ck7 int, ck8 int, ck9 int, " + "PRIMARY KEY(pk, ck1, ck2, ck3, ck4, ck5, ck6, ck7, ck8, ck9))"); execute("SELECT * FROM %s WHERE pk = 1 " + "AND ck1 in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) " + "AND ck2 in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) " + "AND ck3 in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) " + "AND ck4 in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) " + "AND ck5 in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) " + "AND ck6 in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) " + "AND ck7 in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) " + "AND ck8 in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) " + "AND ck9 in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);"); }
Additional information for newcomers:
- Add the configuration for the new guardrail on cartesian product in the guardrails section of cassandra.yaml.
- Add a getInCartesianProduct method in GuardrailsConfig returning a Threshold.Config object
- Implement that method in GuardrailsOptions, which is the default yaml-based implementation of GuardrailsConfig
- Add a Threshold guardrail named inCartesianProduct in Guardrails, using the previously created config
- Define JMX-friendly getters and setters for the previously created config in GuardrailsMBean
- Implement the JMX-friendly getters and setters in Guardrails
- Now that we have the guardrail ready, it’s time to use it. We should search for a place to invoke the Guardrails#inCartesianProduct guard method. The MultiCBuilder look like good candidates for this.
- Finally, add some tests for the new guardrail. Given that the new guardrail is a Threshold, our new test should probably extend ThresholdTester.
Attachments
Issue Links
- relates to
-
CASSANDRA-17186 Guardrail for number of partition keys on IN queries
- Resolved