Count queries go to different shards (rails3) #104

Closed
joshtabak opened this Issue Jun 28, 2012 · 6 comments

Comments

Projects
None yet
3 participants
@joshtabak

These two queries are going to different shards:
User.where(:login => "josh")
User.where(:login => "josh").count

I don't have full replication enabled, and the model in question is not replicated (all queries should go to master).

The count query is going to a slave.

My understanding of Arel is limited, but I've stepped through the code and this is what seems to be happening:

The 'quote' methods in lib/octopus/rails3/arel.rb are running, and the call to ActiveRecord::Base.connection changes @current_model to be ActiveRecord::Base. Most queries run through connection_with_octopus a final time with the correct model (in the example, User), but the count query runs in a different order, and @current_model remains as ActiveRecord::Base. As a result, when octopus decides which shard to send the query, the query gets sent to the wrong shard.

It seems to me incorrect that @current_model should be updated while fulfilling a to_sql request. I have a patch (joshtabak/octopus@952ba3b) that calls connection_proxy instead of connection (which prevents the current model from being updated), but I don't understand the surrounding code well enough to know if this is the correct fix.

Thanks for any help.

@thiagopradi

This comment has been minimized.

Show comment Hide comment
@thiagopradi

thiagopradi Jul 6, 2012

Owner

Hi Josh,

Your fix is correct.

Can you send a pull request?

Thanks.

Owner

thiagopradi commented Jul 6, 2012

Hi Josh,

Your fix is correct.

Can you send a pull request?

Thanks.

@thiagopradi

This comment has been minimized.

Show comment Hide comment
@thiagopradi

thiagopradi Jul 6, 2012

Owner

also, bonus for a failing spec =D

Owner

thiagopradi commented Jul 6, 2012

also, bonus for a failing spec =D

@ghost ghost assigned thiagopradi Feb 11, 2013

@sobrinho

This comment has been minimized.

Show comment Hide comment
@sobrinho

sobrinho Feb 11, 2013

Collaborator

@tchandy there is a pull request on #105.

Can you take a look and write a spec? :)

Collaborator

sobrinho commented Feb 11, 2013

@tchandy there is a pull request on #105.

Can you take a look and write a spec? :)

@thiagopradi

This comment has been minimized.

Show comment Hide comment
@thiagopradi

thiagopradi Feb 16, 2013

Owner

Hi @sobrinho,

I tried to reproduce, without success. I think this commit fixed the issue: 821c330

Owner

thiagopradi commented Feb 16, 2013

Hi @sobrinho,

I tried to reproduce, without success. I think this commit fixed the issue: 821c330

@sobrinho

This comment has been minimized.

Show comment Hide comment
@sobrinho

sobrinho Feb 16, 2013

Collaborator

@tchandy I will try to reproduce it again.

Collaborator

sobrinho commented Feb 16, 2013

@tchandy I will try to reproduce it again.

@sobrinho

This comment has been minimized.

Show comment Hide comment
@sobrinho

sobrinho Feb 16, 2013

Collaborator

I'm not sure how to reproduce the issue, it's working even with 821c330 reverted:

Loading development environment (Rails 3.2.6)
irb(main):001:0> Post.all
  Post Load (0.4ms)  SELECT "posts".* FROM "posts" 
=> [#<Post id: 5, title: "GH-104", body: nil, hits: nil, created_at: "2013-02-16 16:24:10", updated_at: "2013-02-16 16:24:10">]
irb(main):002:0> Post.where(:title => 'GH-104')
  Post Load (1.0ms)  SELECT "posts".* FROM "posts" WHERE "posts"."title" = 'GH-104'
=> [#<Post id: 5, title: "GH-104", body: nil, hits: nil, created_at: "2013-02-16 16:24:10", updated_at: "2013-02-16 16:24:10">]
irb(main):003:0> Post.where(:title => 'GH-104').count
   (0.6ms)  SELECT COUNT(*) FROM "posts" WHERE "posts"."title" = 'GH-104'
=> 1
irb(main):004:0> Post.using(:alpha).all
  Post Load (0.3ms)  SELECT "posts".* FROM "posts" 
=> []
irb(main):005:0> Post.using(:alpha).where(:title => 'GH-104')
  Post Load (0.5ms)  SELECT "posts".* FROM "posts" WHERE "posts"."title" = 'GH-104'
=> #<Octopus::ScopeProxy:0x007ffbd53f9e58 @shard=:alpha, @klass=[#<Post id: 5, title: "GH-104", body: nil, hits: nil, created_at: "2013-02-16 16:24:10", updated_at: "2013-02-16 16:24:10">]>
irb(main):006:0> Post.using(:alpha).where(:title => 'GH-104').count
   (1.1ms)  SELECT COUNT(*) FROM "posts" WHERE "posts"."title" = 'GH-104'
=> 0
irb(main):007:0> Post.where(:title => 'GH-104')
  Post Load (0.5ms)  SELECT "posts".* FROM "posts" WHERE "posts"."title" = 'GH-104'
=> [#<Post id: 5, title: "GH-104", body: nil, hits: nil, created_at: "2013-02-16 16:24:10", updated_at: "2013-02-16 16:24:10">]
irb(main):008:0> Post.where(:title => 'GH-104').count
   (0.6ms)  SELECT COUNT(*) FROM "posts" WHERE "posts"."title" = 'GH-104'
=> 1
irb(main):009:0> ^D

There is a problem on Octopus::ScopeProxy#inspect inspecting the @klass from master shard (I guess) although it's not related to this issue.

The behavior is the identical with and without 821c330.

I'm closing until more information to reproduce is given :)

Collaborator

sobrinho commented Feb 16, 2013

I'm not sure how to reproduce the issue, it's working even with 821c330 reverted:

Loading development environment (Rails 3.2.6)
irb(main):001:0> Post.all
  Post Load (0.4ms)  SELECT "posts".* FROM "posts" 
=> [#<Post id: 5, title: "GH-104", body: nil, hits: nil, created_at: "2013-02-16 16:24:10", updated_at: "2013-02-16 16:24:10">]
irb(main):002:0> Post.where(:title => 'GH-104')
  Post Load (1.0ms)  SELECT "posts".* FROM "posts" WHERE "posts"."title" = 'GH-104'
=> [#<Post id: 5, title: "GH-104", body: nil, hits: nil, created_at: "2013-02-16 16:24:10", updated_at: "2013-02-16 16:24:10">]
irb(main):003:0> Post.where(:title => 'GH-104').count
   (0.6ms)  SELECT COUNT(*) FROM "posts" WHERE "posts"."title" = 'GH-104'
=> 1
irb(main):004:0> Post.using(:alpha).all
  Post Load (0.3ms)  SELECT "posts".* FROM "posts" 
=> []
irb(main):005:0> Post.using(:alpha).where(:title => 'GH-104')
  Post Load (0.5ms)  SELECT "posts".* FROM "posts" WHERE "posts"."title" = 'GH-104'
=> #<Octopus::ScopeProxy:0x007ffbd53f9e58 @shard=:alpha, @klass=[#<Post id: 5, title: "GH-104", body: nil, hits: nil, created_at: "2013-02-16 16:24:10", updated_at: "2013-02-16 16:24:10">]>
irb(main):006:0> Post.using(:alpha).where(:title => 'GH-104').count
   (1.1ms)  SELECT COUNT(*) FROM "posts" WHERE "posts"."title" = 'GH-104'
=> 0
irb(main):007:0> Post.where(:title => 'GH-104')
  Post Load (0.5ms)  SELECT "posts".* FROM "posts" WHERE "posts"."title" = 'GH-104'
=> [#<Post id: 5, title: "GH-104", body: nil, hits: nil, created_at: "2013-02-16 16:24:10", updated_at: "2013-02-16 16:24:10">]
irb(main):008:0> Post.where(:title => 'GH-104').count
   (0.6ms)  SELECT COUNT(*) FROM "posts" WHERE "posts"."title" = 'GH-104'
=> 1
irb(main):009:0> ^D

There is a problem on Octopus::ScopeProxy#inspect inspecting the @klass from master shard (I guess) although it's not related to this issue.

The behavior is the identical with and without 821c330.

I'm closing until more information to reproduce is given :)

@sobrinho sobrinho closed this Feb 16, 2013

@sobrinho sobrinho referenced this issue Mar 23, 2013

Closed

Fix for #104 #105

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment