Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

colexec: fix hash aggregator when spilling to disk #63372

Merged
merged 3 commits into from
Apr 9, 2021

Conversation

yuzefovich
Copy link
Member

execinfrapb: introduce aliases for agg funcs and use everywhere

This commit introduces nicer aliases for the specification of the
aggregate functions and uses the aliases throughout the code base.

Release note: None

colexec: clean up aggregator test cases

This commit is only a test change. It cleans up the aggregator test
cases in the following ways:

  • removing some of the defaults in favor of explicit setting (easier to
    read each test case in isolation)
  • reordering the fields to have uniform assignment order
  • inserting any_not_null aggregates for the cases when the input is
    ordered (this will be needed by the follow up commit that will enforce
    a particular order on the output). This change simulates how specs are
    created in the production.
  • removing a couple of impossible in production test cases (when some
    columns are unused).

Release note: None

colexec: fix hash aggregator when spilling to disk

In some cases the aggregation is expected to maintain the required
ordering in order to eliminate an explicit sort afterwards. It is always
the case that the required ordering is a prefix of ordered grouping
columns. With the introduction of disk spilling for the vectorized hash
aggregator in 21.1 release the ordering was no longer maintained if the
spilling occurs. In all previous cases (row-by-row processors and
in-memory columnar operator) the ordering was maintained by
construction, but with hashBasedPartitioner the ordering can be
arbitrary.

In order to fix this issue we now do what we did for the external
distinct - we plan an external sort on top of the external hash
aggregator to restore the required ordering. Note that this will only
kick in if the spilling to disk occurred. This required changes to the
AggregatorSpec to propagate the required output ordering.

Fixes: #63159.

Release note (bug fix): In 21.1 alpha and beta releases CockroachDB
could return the output in an incorrect order if the query containing
hash aggregation was executed via the vectorized engine and spilling to
temporary storage was required, in some cases.

@yuzefovich yuzefovich requested a review from a team as a code owner April 9, 2021 05:38
@cockroach-teamcity
Copy link
Member

This change is Reviewable

Copy link
Collaborator

@rytaft rytaft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm: Thanks for fixing so quickly!

Reviewed 16 of 16 files at r1, 3 of 3 files at r2, 11 of 11 files at r3.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @RaduBerinde)

This commit introduces nicer aliases for the specification of the
aggregate functions and uses the aliases throughout the code base.

Release note: None
This commit is only a test change. It cleans up the aggregator test
cases in the following ways:
- removing some of the defaults in favor of explicit setting (easier to
read each test case in isolation)
- reordering the fields to have uniform assignment order
- inserting any_not_null aggregates for the cases when the input is
ordered (this will be needed by the follow up commit that will enforce
a particular order on the output). This change simulates how specs are
created in the production.
- removing a couple of impossible in production test cases (when some
columns are unused).

Release note: None
In some cases the aggregation is expected to maintain the required
ordering in order to eliminate an explicit sort afterwards. It is always
the case that the required ordering is a prefix of ordered grouping
columns. With the introduction of disk spilling for the vectorized hash
aggregator in 21.1 release the ordering was no longer maintained if the
spilling occurs. In all previous cases (row-by-row processors and
in-memory columnar operator) the ordering was maintained by
construction, but with `hashBasedPartitioner` the ordering can be
arbitrary.

In order to fix this issue we now do what we did for the external
distinct - we plan an external sort on top of the external hash
aggregator to restore the required ordering. Note that this will only
kick in if the spilling to disk occurred. This required changes to the
AggregatorSpec to propagate the required output ordering.

Release note (bug fix): In 21.1 alpha and beta releases CockroachDB
could return the output in an incorrect order if the query containing
hash aggregation was executed via the vectorized engine and spilling to
temporary storage was required, in some cases.
@yuzefovich
Copy link
Member Author

Thanks for a quick review!

bors r+

@craig
Copy link
Contributor

craig bot commented Apr 9, 2021

This PR was included in a batch that was canceled, it will be automatically retried

@craig
Copy link
Contributor

craig bot commented Apr 9, 2021

Build succeeded:

@craig craig bot merged commit 71a023f into cockroachdb:master Apr 9, 2021
@yuzefovich yuzefovich deleted the hash-agg-vec branch April 9, 2021 21:00
@RaduBerinde
Copy link
Member

:lgtm: Thanks for the fix!!

@rafiss rafiss added this to the 21.1 milestone Apr 22, 2021
@yuzefovich
Copy link
Member Author

The third commit is responsible for noticeable regression in a micro-benchmark:

Switching to ef1323208db409467^
Switching to ef1323208db409467
name                                                                                old time/op    new time/op    delta
ExternalHashAggregator/MIN/spilled=true/int/groupSize=1/numInputRows=1024-24          11.3ms ± 4%    15.1ms ± 5%   +33.57%  (p=0.000 n=9+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=2/numInputRows=1024-24          11.2ms ± 5%    16.1ms ± 7%   +44.71%  (p=0.000 n=10+9)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=32/numInputRows=1024-24         10.5ms ± 5%    15.4ms ± 9%   +46.23%  (p=0.000 n=9+9)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=128/numInputRows=1024-24        10.7ms ± 2%    14.3ms ± 4%   +33.48%  (p=0.000 n=10+9)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=1024/numInputRows=1024-24       5.91ms ± 2%    9.18ms ± 9%   +55.46%  (p=0.000 n=9+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=1/numInputRows=65536-24         44.2ms ± 2%    66.3ms ± 5%   +49.90%  (p=0.000 n=10+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=2/numInputRows=65536-24         33.9ms ± 2%    46.1ms ± 3%   +36.07%  (p=0.000 n=10+9)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=32/numInputRows=65536-24        22.2ms ± 8%    24.4ms ± 2%    +9.98%  (p=0.000 n=10+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=128/numInputRows=65536-24       21.5ms ± 2%    23.4ms ± 3%    +8.65%  (p=0.000 n=9+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=1024/numInputRows=65536-24      19.5ms ± 5%    21.9ms ± 2%   +12.26%  (p=0.000 n=10+7)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=1/numInputRows=4194304-24        1.80s ± 6%     3.91s ± 2%  +117.00%  (p=0.000 n=9+9)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=2/numInputRows=4194304-24        1.10s ± 1%     2.02s ± 2%   +83.36%  (p=0.000 n=10+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=32/numInputRows=4194304-24       404ms ± 3%     453ms ± 6%   +12.08%  (p=0.000 n=10+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=128/numInputRows=4194304-24      737ms ± 1%     741ms ± 1%    +0.58%  (p=0.004 n=10+9)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=1024/numInputRows=4194304-24     715ms ± 1%     716ms ± 1%      ~     (p=0.247 n=10+10)

name                                                                                old speed      new speed      delta
ExternalHashAggregator/MIN/spilled=true/int/groupSize=1/numInputRows=1024-24         730kB/s ± 1%   543kB/s ± 5%   -25.62%  (p=0.000 n=8+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=2/numInputRows=1024-24         734kB/s ± 5%   507kB/s ± 7%   -30.97%  (p=0.000 n=10+9)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=32/numInputRows=1024-24        779kB/s ± 5%   524kB/s ±18%   -32.72%  (p=0.000 n=9+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=128/numInputRows=1024-24       765kB/s ± 2%   573kB/s ± 5%   -25.05%  (p=0.000 n=10+9)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=1024/numInputRows=1024-24     1.39MB/s ± 2%  0.90MB/s ± 9%   -35.49%  (p=0.000 n=9+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=1/numInputRows=65536-24       11.9MB/s ± 2%   7.9MB/s ± 4%   -33.27%  (p=0.000 n=10+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=2/numInputRows=65536-24       15.5MB/s ± 2%  11.4MB/s ± 3%   -26.50%  (p=0.000 n=10+9)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=32/numInputRows=65536-24      23.7MB/s ± 7%  21.5MB/s ± 2%    -9.22%  (p=0.000 n=10+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=128/numInputRows=65536-24     24.3MB/s ± 2%  22.4MB/s ± 4%    -7.95%  (p=0.000 n=9+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=1024/numInputRows=65536-24    26.9MB/s ± 5%  24.0MB/s ± 2%   -10.97%  (p=0.000 n=10+7)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=1/numInputRows=4194304-24     18.4MB/s ±12%   8.6MB/s ± 2%   -53.34%  (p=0.000 n=10+9)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=2/numInputRows=4194304-24     30.5MB/s ± 1%  16.6MB/s ± 2%   -45.47%  (p=0.000 n=10+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=32/numInputRows=4194304-24    83.0MB/s ± 3%  74.1MB/s ± 6%   -10.70%  (p=0.000 n=10+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=128/numInputRows=4194304-24   45.6MB/s ± 1%  45.3MB/s ± 1%    -0.57%  (p=0.004 n=10+9)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=1024/numInputRows=4194304-24  46.9MB/s ± 1%  46.8MB/s ± 1%      ~     (p=0.239 n=10+10)

name                                                                                old alloc/op   new alloc/op   delta
ExternalHashAggregator/MIN/spilled=true/int/groupSize=1/numInputRows=1024-24           798kB ± 1%     921kB ± 0%   +15.43%  (p=0.000 n=10+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=2/numInputRows=1024-24           665kB ± 1%     752kB ± 1%   +13.13%  (p=0.000 n=10+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=32/numInputRows=1024-24          588kB ± 0%     649kB ± 1%   +10.32%  (p=0.000 n=9+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=128/numInputRows=1024-24         541kB ± 0%     593kB ± 1%    +9.65%  (p=0.000 n=10+9)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=1024/numInputRows=1024-24        560kB ± 1%     611kB ± 0%    +9.06%  (p=0.000 n=10+8)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=1/numInputRows=65536-24         22.8MB ± 0%    26.5MB ± 0%   +16.34%  (p=0.000 n=9+6)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=2/numInputRows=65536-24         12.7MB ± 0%    14.6MB ± 0%   +14.98%  (p=0.000 n=10+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=32/numInputRows=65536-24        3.38MB ± 0%    3.57MB ± 0%    +5.55%  (p=0.000 n=9+9)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=128/numInputRows=65536-24       3.01MB ± 0%    3.10MB ± 0%    +2.86%  (p=0.000 n=10+8)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=1024/numInputRows=65536-24      1.99MB ± 0%    2.05MB ± 0%    +2.97%  (p=0.000 n=9+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=1/numInputRows=4194304-24       1.44GB ± 0%    1.56GB ± 0%    +8.37%  (p=0.000 n=8+8)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=2/numInputRows=4194304-24        725MB ± 0%     836MB ± 0%   +15.39%  (p=0.000 n=10+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=32/numInputRows=4194304-24      67.8MB ± 0%    75.1MB ± 0%   +10.70%  (p=0.000 n=10+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=128/numInputRows=4194304-24     34.5MB ± 0%    36.3MB ± 0%    +5.36%  (p=0.000 n=10+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=1024/numInputRows=4194304-24    14.9MB ± 0%    15.3MB ± 0%    +2.75%  (p=0.000 n=7+10)

name                                                                                old allocs/op  new allocs/op  delta
ExternalHashAggregator/MIN/spilled=true/int/groupSize=1/numInputRows=1024-24           1.41k ± 1%     1.69k ± 2%   +19.73%  (p=0.000 n=10+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=2/numInputRows=1024-24           1.38k ± 2%     1.66k ± 2%   +20.56%  (p=0.000 n=9+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=32/numInputRows=1024-24          1.10k ± 0%     1.38k ± 0%   +25.79%  (p=0.000 n=10+9)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=128/numInputRows=1024-24           950 ± 0%      1228 ± 0%   +29.26%  (p=0.000 n=10+9)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=1024/numInputRows=1024-24          647 ± 0%       922 ± 0%   +42.57%  (p=0.000 n=7+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=1/numInputRows=65536-24          11.5k ± 0%     12.8k ± 0%   +10.92%  (p=0.000 n=10+8)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=2/numInputRows=65536-24          10.8k ± 0%     11.5k ± 0%    +7.18%  (p=0.000 n=9+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=32/numInputRows=65536-24         6.67k ± 0%     6.96k ± 0%    +4.38%  (p=0.000 n=10+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=128/numInputRows=65536-24        5.87k ± 0%     6.15k ± 0%    +4.79%  (p=0.000 n=10+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=1024/numInputRows=65536-24       3.51k ± 0%     3.79k ± 0%    +7.98%  (p=0.000 n=10+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=1/numInputRows=4194304-24         424k ± 0%      601k ± 0%   +41.85%  (p=0.000 n=10+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=2/numInputRows=4194304-24         374k ± 0%      435k ± 0%   +16.09%  (p=0.000 n=10+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=32/numInputRows=4194304-24        323k ± 0%      325k ± 0%    +0.69%  (p=0.000 n=10+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=128/numInputRows=4194304-24       309k ± 0%      310k ± 0%    +0.25%  (p=0.000 n=10+10)
ExternalHashAggregator/MIN/spilled=true/int/groupSize=1024/numInputRows=4194304-24      168k ± 0%      168k ± 0%    +0.20%  (p=0.000 n=10+10)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

colexec: hash aggregator doesn't maintain the partial ordering when spilling to disk
5 participants