Class: Lhm::LockedSwitcher
- Inherits:
-
Object
- Object
- Lhm::LockedSwitcher
- Defined in:
- lib/lhm/locked_switcher.rb
Overview
Switches origin with destination table with a write lock. Use this as a safe alternative to rename, which can cause slave inconsistencies:
http://bugs.mysql.com/bug.php?id=39675
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, #sql, #table?, #update
Methods included from Command
Constructor Details
#initialize(migration, connection = nil) ⇒ LockedSwitcher
Returns a new instance of LockedSwitcher.
29 30 31 32 33 34 |
# File 'lib/lhm/locked_switcher.rb', line 29 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.
27 28 29 |
# File 'lib/lhm/locked_switcher.rb', line 27 def connection @connection end |
Instance Method Details
#statements ⇒ Object
36 37 38 |
# File 'lib/lhm/locked_switcher.rb', line 36 def statements uncommitted { switch } end |
#switch ⇒ Object
40 41 42 43 44 45 46 47 48 |
# File 'lib/lhm/locked_switcher.rb', line 40 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
50 51 52 53 54 55 56 57 |
# File 'lib/lhm/locked_switcher.rb', line 50 def uncommitted(&block) [ "set @lhm_auto_commit = @@session.autocommit", "set session autocommit = 0", yield, "set session autocommit = @lhm_auto_commit" ].flatten end |
#validate ⇒ Object
59 60 61 62 63 |
# File 'lib/lhm/locked_switcher.rb', line 59 def validate unless table?(@origin.name) && table?(@destination.name) error "`#{ @origin.name }` and `#{ @destination.name }` must exist" end end |