* cop

* log
This commit is contained in:
Lev Kokotov
2022-02-20 23:33:04 -08:00
committed by GitHub
parent 64574211c6
commit 303fec063b
2 changed files with 37 additions and 60 deletions

View File

@@ -10,6 +10,8 @@ jobs:
# See: https://circleci.com/docs/2.0/configuration-reference/#docker-machine-macos-windows-executor # See: https://circleci.com/docs/2.0/configuration-reference/#docker-machine-macos-windows-executor
docker: docker:
- image: cimg/rust:1.58.1 - image: cimg/rust:1.58.1
environment:
RUST_LOG: info
- image: cimg/postgres:14.0 - image: cimg/postgres:14.0
auth: auth:
username: mydockerhub-user username: mydockerhub-user

View File

@@ -1,59 +1,27 @@
require "active_record" # frozen_string_literal: true
require 'active_record'
# Uncomment these two to see all queries. # Uncomment these two to see all queries.
# ActiveRecord.verbose_query_logs = true # ActiveRecord.verbose_query_logs = true
# ActiveRecord::Base.logger = Logger.new(STDOUT) # ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Base.establish_connection( ActiveRecord::Base.establish_connection(
adapter: "postgresql", adapter: 'postgresql',
host: "127.0.0.1", host: '127.0.0.1',
port: 6432, port: 6432,
username: "sharding_user", username: 'sharding_user',
password: "sharding_user", password: 'sharding_user',
database: "rails_dev", database: 'rails_dev',
prepared_statements: false, # Transaction mode prepared_statements: false, # Transaction mode
advisory_locks: false, # Same advisory_locks: false # Same
) )
class TestTable < ActiveRecord::Base
self.table_name = "test_table"
end
class TestSafeTable < ActiveRecord::Base class TestSafeTable < ActiveRecord::Base
self.table_name = "test_safe_table" self.table_name = 'test_safe_table'
end end
class ShouldNeverHappenException < Exception class ShouldNeverHappenException < RuntimeError
end
# # Create the table.
class CreateTestTable < ActiveRecord::Migration[7.0]
# Disable transasctions or things will fly out of order!
disable_ddl_transaction!
SHARDS = 3
def change
SHARDS.times do |x|
# This will make this migration reversible!
reversible do
connection.execute "SET SHARD TO '#{x.to_i}'"
connection.execute "SET SERVER ROLE TO 'primary'"
end
# Always wrap the entire migration inside a transaction. If that's not possible,
# execute a `SET SHARD` command before every statement and make sure AR doesn't need
# to load database information beforehand (i.e. it's not the first query in the migration).
connection.transaction do
create_table :test_table, if_not_exists: true do |t|
t.string :name
t.string :description
t.timestamps
end
end
end
end
end end
class CreateSafeShardedTable < ActiveRecord::Migration[7.0] class CreateSafeShardedTable < ActiveRecord::Migration[7.0]
@@ -85,44 +53,51 @@ class CreateSafeShardedTable < ActiveRecord::Migration[7.0]
SHARDS.times do |x| SHARDS.times do |x|
connection.execute "SET SHARD TO '#{x.to_i}'" connection.execute "SET SHARD TO '#{x.to_i}'"
connection.execute "SET SERVER ROLE TO 'primary'" connection.execute "SET SERVER ROLE TO 'primary'"
connection.execute "DROP TABLE test_safe_table CASCADE" connection.execute 'DROP TABLE test_safe_table CASCADE'
end end
end end
end end
20.times do SHARDS = 3
begin
CreateTestTable.migrate(:down)
rescue Exception
puts "Tables don't exist yet"
end
2.times do
begin begin
CreateSafeShardedTable.migrate(:down) CreateSafeShardedTable.migrate(:down)
rescue Exception rescue Exception
puts "Tables don't exist yet" puts "Tables don't exist yet"
end end
CreateTestTable.migrate(:up)
CreateSafeShardedTable.migrate(:up) CreateSafeShardedTable.migrate(:up)
3.times do |x| SHARDS.times do |x|
TestSafeTable.connection.execute "SET SHARD TO '#{x.to_i}'" TestSafeTable.connection.execute "SET SHARD TO '#{x.to_i}'"
TestSafeTable.connection.execute "SET SERVER ROLE TO 'primary'" TestSafeTable.connection.execute "SET SERVER ROLE TO 'primary'"
TestSafeTable.connection.execute "TRUNCATE #{TestTable.table_name}" TestSafeTable.connection.execute "TRUNCATE #{TestSafeTable.table_name}"
end end
10.times do |x| # Equivalent to Makara's stick_to_master! except it sticks until it's changed.
TestSafeTable.connection.execute "SET SERVER ROLE TO 'primary'"
200.times do |x|
x += 1 # Postgres ids start at 1 x += 1 # Postgres ids start at 1
TestSafeTable.connection.execute "SET SHARDING KEY TO '#{x.to_i}'" TestSafeTable.connection.execute "SET SHARDING KEY TO '#{x.to_i}'"
TestSafeTable.connection.execute "SET SERVER ROLE TO 'primary'"
TestSafeTable.create(id: x, name: "something_special_#{x.to_i}", description: "It's a surprise!") TestSafeTable.create(id: x, name: "something_special_#{x.to_i}", description: "It's a surprise!")
end end
10.times do |x| TestSafeTable.connection.execute "SET SERVER ROLE TO 'replica'"
100.times do |x|
x += 1 # 0 confuses our sharding function x += 1 # 0 confuses our sharding function
TestSafeTable.connection.execute "SET SHARDING KEY TO '#{x.to_i}'" TestSafeTable.connection.execute "SET SHARDING KEY TO '#{x.to_i}'"
TestSafeTable.connection.execute "SET SERVER ROLE TO 'replica'" TestSafeTable.find_by_id(x).id
end
# Will use the query parser to direct reads to replicas
TestSafeTable.connection.execute "SET SERVER ROLE TO 'auto'"
100.times do |x|
x += 101
TestSafeTable.connection.execute "SET SHARDING KEY TO '#{x.to_i}'"
TestSafeTable.find_by_id(x).id TestSafeTable.find_by_id(x).id
end end
end end
@@ -130,8 +105,8 @@ end
# Test wrong shard # Test wrong shard
TestSafeTable.connection.execute "SET SHARD TO '1'" TestSafeTable.connection.execute "SET SHARD TO '1'"
begin begin
TestSafeTable.create(id: 5, name: "test", description: "test description") TestSafeTable.create(id: 5, name: 'test', description: 'test description')
raise ShouldNeverHappenException("Uh oh") raise ShouldNeverHappenException('Uh oh')
rescue ActiveRecord::StatementInvalid rescue ActiveRecord::StatementInvalid
puts "OK" puts 'OK'
end end