Remove uses of the read replica database.

https://danbooru.donmai.us/forum_topics/9127?page=283#forum_post_160508

There was a recent outage that was caused by the read replica
(yukinoshita.donmai.us) being temporarily unavailable. The pg driver in
rails got hardstuck trying to connect to the replica, which brought down
the whole site. The app servers stopped responding and could only be
brought down with SIGKILL. Even try to boot the rails console didn't
work.

We only really used this to calculate tag counts inside Post.fast_count,
which wasn't really beneficial since the read replica is slower than the
main database.
This commit is contained in:
evazion
2019-10-22 12:15:46 -05:00
parent 8541974d19
commit 2c6567b5d2
6 changed files with 8 additions and 44 deletions

View File

@@ -22,7 +22,7 @@ class TagBatchChangeJob < ApplicationJob
def self.estimate_update_count(antecedent, consequent) def self.estimate_update_count(antecedent, consequent)
CurrentUser.without_safe_mode do CurrentUser.without_safe_mode do
PostReadOnly.tag_match(antecedent).count Post.tag_match(antecedent).count
end end
end end

View File

@@ -1,9 +1,8 @@
class PostQueryBuilder class PostQueryBuilder
attr_accessor :query_string, :read_only attr_accessor :query_string
def initialize(query_string, read_only: false) def initialize(query_string)
@query_string = query_string @query_string = query_string
@read_only = read_only
end end
def add_range_relation(arr, field, relation) def add_range_relation(arr, field, relation)
@@ -117,7 +116,7 @@ class PostQueryBuilder
q = Tag.parse_query(query_string) q = Tag.parse_query(query_string)
end end
relation = read_only ? PostReadOnly.all : Post.all relation = Post.all
if q[:tag_count].to_i > Danbooru.config.tag_query_limit if q[:tag_count].to_i > Danbooru.config.tag_query_limit
raise ::Post::SearchError raise ::Post::SearchError

View File

@@ -1129,8 +1129,8 @@ class Post < ApplicationRecord
end end
def fast_count_search(tags, timeout:, raise_on_timeout:) def fast_count_search(tags, timeout:, raise_on_timeout:)
count = PostReadOnly.with_timeout(timeout, nil, tags: tags) do count = Post.with_timeout(timeout, nil, tags: tags) do
PostReadOnly.tag_match(tags).count Post.tag_match(tags).count
end end
if count.nil? if count.nil?
@@ -1645,8 +1645,8 @@ class Post < ApplicationRecord
where("posts.tag_index @@ to_tsquery('danbooru', E?)", tag.to_escaped_for_tsquery) where("posts.tag_index @@ to_tsquery('danbooru', E?)", tag.to_escaped_for_tsquery)
end end
def tag_match(query, read_only: false) def tag_match(query)
PostQueryBuilder.new(query, read_only: read_only).build PostQueryBuilder.new(query).build
end end
end end

View File

@@ -1,13 +0,0 @@
class PostReadOnly < Post
establish_connection (ENV["RO_DATABASE_URL"] || "ro_#{Rails.env}".to_sym)
attr_readonly *column_names
def with_timeout(n, default_value = nil)
connection.execute("SET STATEMENT_TIMEOUT = #{n}") unless Rails.env == "test"
yield
rescue ::ActiveRecord::StatementInvalid => x
return default_value
ensure
connection.execute("SET STATEMENT_TIMEOUT = 0") unless Rails.env == "test"
end
end

View File

@@ -31,7 +31,6 @@ services:
- SESSION_SECRET_KEY - SESSION_SECRET_KEY
- RAILS_ENV - RAILS_ENV
- DATABASE_URL - DATABASE_URL
- RO_DATABASE_URL
- DEBUG - DEBUG
- ARCHIVE_DATABASE_URL - ARCHIVE_DATABASE_URL
- DANBOORU_AWS_SQS_ARCHIVE_URL - DANBOORU_AWS_SQS_ARCHIVE_URL

View File

@@ -24,27 +24,6 @@ production:
timeout: 5000 timeout: 5000
url: <%= ENV['DATABASE_URL'] %> url: <%= ENV['DATABASE_URL'] %>
# read only databases, just point to local copies if you have no need
ro_development:
adapter: postgresql
database: danbooru2
url: <%= ENV['RO_DATABASE_URL'] %>
ro_test:
adapter: postgresql
database: danbooru2_test
url: <%= ENV['RO_DATABASE_URL'] %>
ro_production:
adapter: postgresql
database: danbooru2
url: <%= ENV['RO_DATABASE_URL'] %>
ro_staging:
adapter: postgresql
database: danbooru2
url: <%= ENV['RO_DATABASE_URL'] %>
archive_development: archive_development:
adapter: postgresql adapter: postgresql
database: archive_development database: archive_development