Skip to content
New issue

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

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

Already on GitHub? # to your account

Make view query limits configurable #1804

Merged
merged 1 commit into from
Jan 23, 2019
Merged

Make view query limits configurable #1804

merged 1 commit into from
Jan 23, 2019

Conversation

garrensmith
Copy link
Member

Overview

This allows us to set a maximun allowed number of documents
to be returned for a global or a partitioned query.

Testing recommendations

Set a view limit in the default.ini.

  • A query with a limit larger than the max will error
  • A query with the limit value below the max will run the query. A
  • A query with no limit will use the max limit set.

Related Issues or Pull Requests

Checklist

  • Code is written and works correctly;
  • Changes are covered by tests;
  • Documentation reflects the changes;

Copy link
Member

@davisp davisp left a comment

Choose a reason for hiding this comment

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

Mostly good but there's a few style issues.

Copy link
Member

@davisp davisp left a comment

Choose a reason for hiding this comment

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

Removing the clause checking for infinity is the main thing. Up to you on whether you want to relax the equality check. Otherwise this all looks good.


% set the highest limit possible if a user has not
% specified a limit
Args1 = case Args#mrargs.limit =:= ?MAX_VIEW_LIMIT
Copy link
Member

Choose a reason for hiding this comment

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

Super minor nit but I'd probably use == instead of =:= here. Only because I had to stop and think on whether we needed the stronger =:= for any reason or not.

% set the highest limit possible if a user has not
% specified a limit
Args1 = case Args#mrargs.limit =:= ?MAX_VIEW_LIMIT
andalso MaxLimit =/= infinity of
Copy link
Member

Choose a reason for hiding this comment

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

No need for this clause checking infinity anymore.

Copy link
Member Author

Choose a reason for hiding this comment

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

I changed this line from if Args1#mrargs.limit =:= MaxLimit -> Args1; true -> to
if Args1#mrargs.limit =< MaxLimit -> Args1; true ->

@davisp davisp force-pushed the feature/database-partitions branch 11 times, most recently from 90be3b0 to 6c2785a Compare December 19, 2018 17:51
@davisp davisp force-pushed the feature/database-partitions branch 2 times, most recently from 005b442 to 60bbe3f Compare December 20, 2018 20:48
@davisp davisp force-pushed the feature/database-partitions branch 5 times, most recently from be1fe52 to 31a4a53 Compare January 8, 2019 17:35
@davisp davisp force-pushed the feature/database-partitions branch 7 times, most recently from 04146c3 to 51a482e Compare January 16, 2019 23:21
@davisp davisp force-pushed the feature/database-partitions branch 2 times, most recently from 8cd68be to 91af772 Compare January 18, 2019 18:35
@davisp davisp closed this Jan 18, 2019
@garrensmith garrensmith changed the base branch from feature/database-partitions to master January 21, 2019 08:08
@garrensmith garrensmith reopened this Jan 21, 2019
Copy link
Member

@davisp davisp left a comment

Choose a reason for hiding this comment

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

Everything looks alright but we have to figure out why those tests are failing before this can be merged. Reading through I'm not seeing anything so my best guess is an unrelated test leaves the config in a bad state.

end,

if Args1#mrargs.limit =< MaxLimit -> Args1; true ->
Fmt = "Limit is too large, must not exceed ~p",
Copy link
Member

Choose a reason for hiding this comment

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

Something is wrong here but I'm not immediately seeing why. The view_multi_key_design.js test has failed with this error message on each worker. Perhaps we left a bad config from an unrelated test?

Copy link
Member Author

Choose a reason for hiding this comment

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

I found the issue. It was because of the fix_skip_and_limit function https://github.com/apache/couchdb/blob/master/src/fabric/src/fabric_view.erl#L380

We made the max limit greater than the defined max limit.

Copy link
Member

Choose a reason for hiding this comment

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

I see the issue there but I'm not seeing what changed to account for it.

Copy link
Member

@davisp davisp left a comment

Choose a reason for hiding this comment

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

Looks good overall except for the debug logging.

end,

if Args1#mrargs.limit =< MaxLimit -> Args1; true ->
Fmt = "Limit is too large, must not exceed ~p",
Copy link
Member

Choose a reason for hiding this comment

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

I see the issue there but I'm not seeing what changed to account for it.

Copy link
Member

@davisp davisp left a comment

Choose a reason for hiding this comment

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

Two other minor changes to make.

%{:body => body} = resp

Enum.each(body["all_nodes"], fn node ->
resp = Couch.put("/_node/#{node}/_config/query_server_config/partition_query_limit", body: "\"2000\"")
Copy link
Member

Choose a reason for hiding this comment

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

Re-reading again, and just noticed this. You should use set_config which takes care of removing the config change after the test finishes. There's an example here:

set_config({"couchdb", "max_partition_size", Integer.to_string(@max_size)})

Copy link
Member

Choose a reason for hiding this comment

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

And samesies for partition_view_test

Copy link
Member

@davisp davisp left a comment

Choose a reason for hiding this comment

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

So now that I've figured out how that interaction with fix_skip_and_limit works I realize that this is wrong. The current version appears to work but only because we're not testing with skip values that are large enough to cause a bad response.

The issue here is that we're calling validate_args on each RPC worker, however, due to clustering when a skip is set, each RPC worker has to return skip+limit rows which the coordinator then does the skip discard and then cuts off the response when limit rows. However, due to how this works we very often might be telling RPC workers to return more than the maximum allowed number of rows which gets flagged as an error.

The fix here is I think simple enough. We should just move the apply_limit code to fabric_util:validate_args which is only ever called from the coordinator layer so we don't have to worry about validating a system modified mrargs record.

@davisp
Copy link
Member

davisp commented Jan 22, 2019

Also, to force the bug, the skip would have to be set to Q * $max_rows because the current apply_limit throws away the skip bump to the limit we'd end up returning 0 rows when there was actual data to return.

That is of course an unlikely scenario and goes against the general recommendation to not use a large skip value but it'd still be an incorrect response if someone did get into that situation where maybe $max_rows was set low enough to be not super crazy.

@davisp
Copy link
Member

davisp commented Jan 22, 2019

Turns out fabric_util was too far up. However we can just move it up one call so the RPC workers don't call it again and that fixes the issue.

Copy link
Member

@davisp davisp left a comment

Choose a reason for hiding this comment

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

+1 but be sure and squerge this down into a single commit before merging. I left it unsquerged so you can see the changes I made separate from the rest of the PR.

This allows us to set a maximun allowed number of documents
to be returned for a global or a partitioned view query and
_all_docs query.

Co-authored-by: Paul J. Davis <paul.joseph.davis@gmail.com>
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants