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

Add skip_references option to Rbac/MiqReport #17469

Merged
merged 3 commits into from Nov 21, 2018

Conversation

NickLaMuro
Copy link
Member

@NickLaMuro NickLaMuro commented May 23, 2018

This allows for the manual configuration of product reports to include an option to use skip_references to avoid LEFT JOIN bombs from happening when multiple includes are being referenced in Rbac.

This partially fixes the issue reported in https://bugzilla.redhat.com/show_bug.cgi?id=1580569, but will require an update to the manageiq-ui-classic to be fixed fully.

Background

The /ems_infra/:id?display=hosts route would pull up the product/views/Host.yaml from the manageiq-ui-classic report and run the following query:

-- Many rows here in the SELECT are omitted for space
SELECT "hosts"."id" AS t0_r0,
       "hosts"."name" AS t0_r1,
       -- ...
       "hosts"."physical_server_id" AS t0_r36,
       "ext_management_systems"."id" AS t1_r0,
       "ext_management_systems"."name" AS t1_r1,
       -- ...
       "ext_management_systems"."tenant_mapping_enabled" AS t1_r23,
       "compliances"."id" AS t2_r0,
       -- ...
       "compliances"."event_type" AS t2_r6,
       "tags"."id" AS t3_r0,
       "tags"."name" AS t3_r1
FROM "hosts"
LEFT OUTER JOIN "ext_management_systems" ON "ext_management_systems"."id" = "hosts"."ems_id"
LEFT OUTER JOIN "compliances" ON "compliances"."resource_id" = "hosts"."id" AND "compliances"."resource_type" = 'Host'
LEFT OUTER JOIN "taggings" ON "taggings"."taggable_id" = "hosts"."id" AND "taggings"."taggable_type" = 'Host'
LEFT OUTER JOIN "tags" ON "tags"."id" = "taggings"."tag_id"
ORDER BY LOWER("hosts"."name") ASC

With only 20 hosts, but around 14k compliances, the result set returned from above was over 2 million rows with 60+ columns per row. This caused ActiveRecord/pg gems to use Gigs of memory to process the query, and was taking over 25min for the query to be fully processed.

The change makes it so the query is done in a more SQL friendly fashion by executing the includes as individual SQL calls. Means more SQL calls over all, but only a increase of about 4, with drastically less data sent back over the wire (most of it previously was duplicate).

Links

Allows for manually triggering the `skip_references` option in Rbac for
performance reasons.  This can be used in specific situations where
otherwise the autogenerated reference skipping would not be enabled.
Allows setting `skip_references` in report yaml files, but isn't
something that we would commit to the DB.  This is something that is an
optimization that really won't make sense to an end user, so this fix
simply allows reports in the `product/` folder to modified to be better
optimized.  No DB migration necessary.
Includes :skip_references into the options that are passed to
Rbac.search in the MiqReport#paged_view_search method.
@miq-bot
Copy link
Member

miq-bot commented May 23, 2018

Checked commits NickLaMuro/manageiq@87be69d~...46be5a3 with ruby 2.3.3, rubocop 0.52.1, haml-lint 0.20.0, and yamllint 1.10.0
3 files checked, 2 offenses detected

app/models/miq_report/search.rb

lib/rbac/filterer.rb

@JPrause
Copy link
Member

JPrause commented May 24, 2018

@miq-bot add_label blocker

@JPrause
Copy link
Member

JPrause commented May 24, 2018

@NickLaMuro if this can be backported, can you add the labels; gaprindashvili/yes and fine/yes

@NickLaMuro
Copy link
Member Author

@JPrause I am actually going to remove the blocker label since we have a much lower risk fix for the BZ in the UI classic repo: ManageIQ/manageiq-ui-classic#3989

I will update the fine/yes and gaprindashvili/yes labels later when this becomes something we are focusing on later.

@miq-bot remove_label blocker

@miq-bot miq-bot removed the blocker label May 24, 2018
@kbrock
Copy link
Member

kbrock commented Oct 18, 2018

@NickLaMuro do want to merge this to have in our future toolbox?

unless I missed something, it looks innocuous unless we pass the label. I'm thinking hammer/yes but all else no

@NickLaMuro
Copy link
Member Author

@kbrock I realize this is a month later, but I think we can merge this and expect to use it as part of the ivanchuk release. We can hammer backport if a BZ comes up.

But should be completely harmless to merge, and yes, helpful as another thing to use in our bugfix toolbox.

...though, had to remind myself how this worked again and how it was helpful in the first place 😅

@NickLaMuro
Copy link
Member Author

@miq-bot assign @kbrock

@NickLaMuro
Copy link
Member Author

@miq-bot add_label enhancement, hammer/no

Copy link
Member

@kbrock kbrock left a comment

Choose a reason for hiding this comment

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

Looking good. just the one question

Do we need specs for this?

@@ -310,8 +310,9 @@ def is_sti?(klass)
# as done previously.
def skip_references?(scope, options, attrs, exp_sql, exp_includes)
return false if scope.singleton_class.included_modules.include?(ActiveRecord::NullRelation)
options[:extra_cols].blank? &&
(!attrs[:apply_limit_in_sql] && (exp_sql.nil? || exp_includes.nil?))
options[:skip_references] ||
Copy link
Member

Choose a reason for hiding this comment

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

do we want this to be true or false? or were you thinking only true

Suggested change
options[:skip_references] ||
options.key?(:skip_references) ? options[:skip_references] :

Copy link
Member Author

Choose a reason for hiding this comment

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

@kbrock well, to say:

...or were you thinking only true

Is slightly misleading, because you can pass true or false/nil with this currently, just false/nil will just defer to the other logic. But I do get what you are getting at.

I think for now, I would like to keep it as is just to keep the fail safe check, just to make sure that anyone that uses this doesn't remove references when they are actually needed in the where. I guess that could lead to it being confusing, but I guess for the most part, I assume that (as you suggested) the true will be the only value that is used.

I guess this is a round-about way of saying I don't have a real strong feeling on this one, so what do you think?

@kbrock kbrock merged commit 99dca1f into ManageIQ:master Nov 21, 2018
@mfeifer mfeifer added this to the Sprint 100 Ending Dec 3, 2018 milestone Jan 27, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants