-
Olav Sandstaa authored
This problem occurs due to MRR is creating a second handler object. This handler object is a "clone" of the first/initial handler object and the MRR code use this second handler object for executing some of the operations. The second handler object is created in DsMRR_impl::dsmrr_init() (in handler.cc) by "cloning" the initial handler object: if (!(new_h2= h->clone(thd->mem_root)) || new_h2->ha_external_lock(thd, F_RDLCK)) The important thing about the above code is that on this cloned handler object a call to ha_external_lock() is done with a request to use a read lock (F_RDLCK). When this handler object (h2) is used in DsMrr_impl::dsmrr_fill_buffer() for doing the initial search for the first record in the range interval, the index search done by InnoDB will be done without setting any exclusive lock on the search interval. This allows a second transaction to succeed to insert data within the "read interval" of the first transaction. The fix for this problem is to use the same lock type when calling new_h2->ha_external_lock() as was done on the original handler object. To do this we store (in handler::ha_external_lock()) the original lock type in a new member variable in the handler object (m_lock_type) and use this lock type when "cloning" the handler object in DsMRR_impl::dsmrr_init().
Olav Sandstaa authoredThis problem occurs due to MRR is creating a second handler object. This handler object is a "clone" of the first/initial handler object and the MRR code use this second handler object for executing some of the operations. The second handler object is created in DsMRR_impl::dsmrr_init() (in handler.cc) by "cloning" the initial handler object: if (!(new_h2= h->clone(thd->mem_root)) || new_h2->ha_external_lock(thd, F_RDLCK)) The important thing about the above code is that on this cloned handler object a call to ha_external_lock() is done with a request to use a read lock (F_RDLCK). When this handler object (h2) is used in DsMrr_impl::dsmrr_fill_buffer() for doing the initial search for the first record in the range interval, the index search done by InnoDB will be done without setting any exclusive lock on the search interval. This allows a second transaction to succeed to insert data within the "read interval" of the first transaction. The fix for this problem is to use the same lock type when calling new_h2->ha_external_lock() as was done on the original handler object. To do this we store (in handler::ha_external_lock()) the original lock type in a new member variable in the handler object (m_lock_type) and use this lock type when "cloning" the handler object in DsMRR_impl::dsmrr_init().
Loading