Class: Lhm::LockedSwitcher
- Inherits:
-
Object
- Object
- Lhm::LockedSwitcher
- Defined in:
- lib/lhm/locked_switcher.rb
Overview
Switches origin with destination table nonatomically using a locked write. LockedSwitcher adopts the Facebook strategy, with the following caveat:
"Since alter table causes an implicit commit in innodb, innodb locks get
released after the first alter table. So any transaction that sneaks in
after the first alter table and before the second alter table gets
a 'table not found' error. The second alter table is expected to be very
fast though because copytable is not visible to other transactions and so
there is no need to wait."
Instance Attribute Summary collapse
-
#connection ⇒ Object
readonly
Returns the value of attribute connection.
Instance Method Summary collapse
-
#initialize(migration, connection = nil) ⇒ LockedSwitcher
constructor
A new instance of LockedSwitcher.
- #statements ⇒ Object
- #switch ⇒ Object
- #uncommitted(&block) ⇒ Object
- #validate ⇒ Object
Methods included from SqlHelper
#annotation, #idx_name, #idx_spec, #version_string
Methods included from Command
Constructor Details
#initialize(migration, connection = nil) ⇒ LockedSwitcher
Returns a new instance of LockedSwitcher.
25 26 27 28 29 30 |
# File 'lib/lhm/locked_switcher.rb', line 25 def initialize(migration, connection = nil) @migration = migration @connection = connection @origin = migration.origin @destination = migration.destination end |
Instance Attribute Details
#connection ⇒ Object (readonly)
Returns the value of attribute connection.
23 24 25 |
# File 'lib/lhm/locked_switcher.rb', line 23 def connection @connection end |
Instance Method Details
#statements ⇒ Object
32 33 34 |
# File 'lib/lhm/locked_switcher.rb', line 32 def statements uncommitted { switch } end |
#switch ⇒ Object
36 37 38 39 40 41 42 43 44 |
# File 'lib/lhm/locked_switcher.rb', line 36 def switch [ "lock table `#{ @origin.name }` write, `#{ @destination.name }` write", "alter table `#{ @origin.name }` rename `#{ @migration.archive_name }`", "alter table `#{ @destination.name }` rename `#{ @origin.name }`", 'commit', 'unlock tables' ] end |
#uncommitted(&block) ⇒ Object
46 47 48 49 50 51 52 53 |
# File 'lib/lhm/locked_switcher.rb', line 46 def uncommitted(&block) [ 'set @lhm_auto_commit = @@session.autocommit', 'set session autocommit = 0', yield, 'set session autocommit = @lhm_auto_commit' ].flatten end |
#validate ⇒ Object
55 56 57 58 59 60 |
# File 'lib/lhm/locked_switcher.rb', line 55 def validate unless @connection.table_exists?(@origin.name) && @connection.table_exists?(@destination.name) error "`#{ @origin.name }` and `#{ @destination.name }` must exist" end end |