[
https://issues.apache.org/jira/browse/IGNITE-29183?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Ignite TC Bot updated IGNITE-29183:
-----------------------------------
External issue ID: IGN-2928
> Inline size recommendation is never logged: operator precedence bug in
> InlineRecommender throttle condition
> -----------------------------------------------------------------------------------------------------------
>
> Key: IGNITE-29183
> URL: https://issues.apache.org/jira/browse/IGNITE-29183
> Project: Ignite
> Issue Type: Bug
> Components: sql
> Affects Versions: 2.8
> Reporter: Zhang Zhenhao
> Priority: Minor
> Time Spent: 10m
> Remaining Estimate: 0h
>
> {\{InlineRecommender.recommend()}} — the component that logs a recommendation
> when indexed columns of a row cannot be fully inlined into an index (or when
> the inline size is too big) — never performs its check with the default
> configuration, due to an operator precedence error in the throttle condition.
> Code
> (\{{modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/inline/InlineRecommender.java}},
> method \{{recommend()}}):
> {code:java}
> long invokeCnt = inlineSizeCalculationCntr.get();
> if (!inlineSizeCalculationCntr.compareAndSet(invokeCnt, invokeCnt + 1))
> return;
> boolean throttle = invokeCnt + 1 % inlineSizeThrottleThreshold != 0;
> if (throttle)
> return;
> {code}
> In Java \{{%}} binds tighter than \{{+}}, so the condition parses as
> \{{invokeCnt + (1 % inlineSizeThrottleThreshold) != 0}} instead of the
> intended \{{(invokeCnt + 1) % inlineSizeThrottleThreshold != 0}}.
> Consequences:
> * With the default \{{IGNITE_THROTTLE_INLINE_SIZE_CALCULATION}} (1000), \{{1
> % 1000 == 1}}, so the condition is \{{invokeCnt + 1 != 0}} — always true,
> because the counter starts at 0 and only grows. \{{throttle}} is therefore
> always true and the method returns before doing any work, on every
> invocation. Neither the "Indexed columns of a row cannot be fully inlined
> ..." warning nor the "Inline size is too big ..." warning (added by
> IGNITE-23120) can ever be logged with default settings.
> * With the system property set to \{{1}}, \{{1 % 1 == 0}}, so the condition
> becomes \{{invokeCnt != 0}}: only the very first invocation per index
> instance passes, all later ones are skipped. This is the only configuration
> in which the recommender produces any output at all, and it effectively
> inspects a single row per index.
> Expected behavior, per the documented meaning of
> \{{IGNITE_THROTTLE_INLINE_SIZE_CALCULATION}} ("throttles inline size
> calculation and logging index inline size recommendation", default 1000): the
> check should run on every Nth invocation.
> Steps to reproduce:
> # Start a node with default settings.
> # Create a query-enabled cache with a variable-length primary key, e.g.
> String.
> # Put a row with a long key (> inline size), then update the same row several
> thousand times.
> # No warning is ever logged.
> # Repeat with \{{-DIGNITE_THROTTLE_INLINE_SIZE_CALCULATION=1}} — the "Indexed
> columns of a row cannot be fully inlined ..." warning appears, exactly once
> per index (first qualifying put).
> Suggested fix:
> {code:java}
> boolean throttle = (invokeCnt + 1) % inlineSizeThrottleThreshold != 0;
> {code}
> The expression was introduced together with the class in August 2019
> (IGNITE-12061, initially in modules/indexing, later moved to core by
> IGNITE-13056), so releases since ~2.8 are affected.
> The recently added \{{InlineRecommenderSelfTest}} (modules/indexing, [PR
> #13715|https://github.com/apache/ignite/pull/13715] for IGNITE-11355) already
> exercises the recommender with the workaround
> (\{{IGNITE_THROTTLE_INLINE_SIZE_CALCULATION=1}}) and can serve as a starting
> point for a regression test of the fixed sampling behavior (e.g. with a
> threshold of 2, every second qualifying put should trigger a check).
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)