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

Reset the column cache after adding default_miq_group_id to tenants #9177

Conversation

carbonin
Copy link
Member

@carbonin carbonin commented Jun 10, 2016

Before this change, rails was not aware of the column if it was added in the same process that it was queried in.

Specifically the column cache here is not reset after the add_column call so for https://github.com/ManageIQ/manageiq/blob/master/db/migrate/20151021174140_assign_tenant_default_group.rb#L5 to work properly, we need to reset the info manually.

For example, the column would be added, but when we tried to set the value in 20151021174140_assign_tenant_default_group.rb we would silently fail or get a backtrace with:

99000000000001 is out of range for ActiveModel::Type::Integer with limit 4

After this change, the column value is set correctly.

https://bugzilla.redhat.com/show_bug.cgi?id=1344112

@carbonin
Copy link
Member Author

@jrafanie please review

def change
add_column :tenants, :default_miq_group_id, :bigint
Tenant.reset_column_information
Copy link
Member

@chessbyte chessbyte Jun 10, 2016

Choose a reason for hiding this comment

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

Does creating the stub class on line 2 of this file negate the need for this reset?

@Fryguy
Copy link
Member

Fryguy commented Jun 10, 2016

@carbonin As discussed, this is really just a hack because of oddities (dare I say, bugs) in ActiveRecord::Migration, but it's good to get us over the hump of not being able to migrate the database.

cc @lpichler

@Fryguy
Copy link
Member

Fryguy commented Jun 10, 2016

@chessbyte Marking this as a blocker, because you can't upgrade in one-shot without it. That is, db:migrate fails, and then you have to manually db:migrate again as a workaround.

@Fryguy Fryguy added the blocker label Jun 10, 2016
Before this change, rails was not aware of the column if it was
added in the same process that it was queried in.

Specifically, the column cache is not reset after the `add_column` call;
so for 20151021174140_assign_tenant_default_group.rb to work properly
we need to reset the info manually via `Tenant.reset_column_information`.

For example, the column would be added, but when we tried to set the
value in 20151021174140_assign_tenant_default_group.rb we would
silently fail or get a backtrace with:

`99000000000001 is out of range for ActiveModel::Type::Integer with limit 4`

After this change, the column value is set correctly.

https://bugzilla.redhat.com/show_bug.cgi?id=1344112
@carbonin carbonin force-pushed the reset_column_cache_after_adding_tenant_default_group branch from 292d00c to 7278454 Compare June 10, 2016 19:22
@jrafanie
Copy link
Member

jrafanie commented Jun 10, 2016

Just so we don't lose it in gitter, I believe AR's add_column, remove_column, change_column, etc., found here for the abstract adapter, should reset the column information after the execute call:

def add_column(table_name, column_name, type, options = {})
  at = create_alter_table table_name
  at.add_column(column_name, type, options)
  ret = execute schema_creation.accept at
  Class.new(ActiveRecod::Base) { self.table_name = table_name }.reset_column_information!
  ret
end

If this makes sense, I can see about trying to open a PR on rails.

@jrafanie
Copy link
Member

From gitter, I believe the problem is that even if we use two different class stubs (with the same table name) in two different migrations, they end up using the same cache key'd by the table name
see here.

@jrafanie
Copy link
Member

@matthewd At your convenience, I'd love your opinion of this HACK. Is that feasible?

@Fryguy
Copy link
Member

Fryguy commented Jun 10, 2016

Merging this for now as it's a decent workaround that fixes upgrades. However, I'd like to see a general fix regardless. @carbonin or @jrafanie can you open an GH issue to track fixing it?

@Fryguy Fryguy merged commit 5ba6862 into ManageIQ:master Jun 10, 2016
@Fryguy Fryguy added this to the Sprint 42 Ending June 20, 2016 milestone Jun 10, 2016
@Fryguy Fryguy self-assigned this Jun 10, 2016
@carbonin carbonin deleted the reset_column_cache_after_adding_tenant_default_group branch June 10, 2016 20:17
@matthewd
Copy link
Contributor

Someone looked at something around here... @chrisarcand maybe?

IIRC, we decided it was Expected Behaviour that you needed to manually reset the column info if you wanted to use the column inside the migration, but that it was expected to happen automatically at the end of the migration.

@chrisarcand
Copy link
Member

Yes, this is an issue along the same vein 😑

@carbonin As you may know, there are many separate caches at the class level of AR models + the adapter cache. My speculation, unproven: Columns are being looked up by model name at at the adapter level in some way we haven't seen and so our way of namespacing within the migration to avoid the caching doesn't work anymore.

I'll look further in to this next week, but as usual this fix is the most appropriate for now 👍

chessbyte pushed a commit that referenced this pull request Jun 11, 2016
…g_tenant_default_group

Reset the column cache after adding default_miq_group_id to tenants
(cherry picked from commit 5ba6862)
@jrafanie
Copy link
Member

Someone looked at something around here... @chrisarcand maybe?

IIRC, we decided it was Expected Behaviour that you needed to manually reset the column info if you wanted to use the column inside the migration, but that it was expected to happen automatically at the end of the migration.

@matthewd @chrisarcand specifically, this is one migration adding a column that a followup migration doesn't know about. Within the same migration, it makes sense to reset the column information after adding/removing/changing a column if you want to use this column. In this PR, it was the former (one migration messing up a subsequent migration) and it's ugly to have this column cache knowledge of prior/subsequent migrations. It doesn't make sense to have to reset column information after you add/remove/change columns "just in case" some other subsequent migration needs to use this column. We'd have to put this all over all of our migrations and would be really disgusting.

My suggestion above was that it seems that only add/remove/change column calls know when we invalidate the table's cached columns, so they should reset this cache. I don't know where else we would know when the table's column cache is invalidated.

@matthewd
Copy link
Contributor

Found the previous discussion: rails/rails#24300

So.. I'm resignedly-okay with needing the explicit reset within a migration (read: I think it could be better, but don't care enough to fight for it), but agree with you that requiring it across migrations seems too onerous. Maybe that "just" means this line should instead be invoked after each individual migration. As I'm thinking it through, that sounds pretty sensible.

@chrisarcand
Copy link
Member

Maybe that "just" means this line should instead be invoked after each individual migration. As I'm thinking it through, that sounds pretty sensible.

@matthewd I don't think that will fix the issue, IIRC 😕 See the code in that issue you mention; the issue we faced (and continue to face) is that there's no single way to clear all model caches at once. .clear_cache! sadly only clears the adapter cache and leaves individual model caches populated.

@swrobel
Copy link

swrobel commented Dec 2, 2019

@chrisarcand did you ever find a command that will clear the cache for all models?

@jrafanie
Copy link
Member

jrafanie commented Dec 2, 2019

@swrobel See: ManageIQ/manageiq-schema#401 ... our migrations are in an engine that wraps all migrations with ActiveRecord::Base.connection.schema_cache.clear!, which does more than just column information. It's our humble opinion that caching of columns/indexes/key information during migrations is something that should not be happening. As seen in the first link, it's not developer friendly at all to expect developers to reset column information whenever they use a migration stub.

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

7 participants