Documentation Home
MySQL Internals Manual

23.18.25 store_lock


Creates and releases table locks.


virtual THR_LOCK_DATA ** store_lock (





thd ;


to ;

enum thr_lock_type

lock_type ;


This is the store_lock method.

The idea with handler::store_lock() is the following:

The statement decided which locks we should need for the table for updates/deletes/inserts we get WRITE locks, for SELECT... we get read locks.

Before adding the lock into the table lock handler mysqld calls store lock with the requested locks. Store lock can modify the lock level, for example, change blocking write lock to non-blocking, ignore the lock (if we don't want to use MySQL table locks at all), or add locks for many tables (like we do when we are using a MERGE handler).

When releasing locks, store_lock() are also called. In this case one usually doesn't have to do anything.

If the argument of store_lock is TL_IGNORE, it means that MySQL requests the handler to store the same lock level as the last time.

Called from by get_lock_data().


  • thd

  • to

  • lock_type

Return Values

There are no return values.


The following example is from the ARCHIVE storage engine:

   Below is an example of how to setup row level locking.
 THR_LOCK_DATA **ha_archive::store_lock(THD *thd,
                                        THR_LOCK_DATA **to,
                                        enum thr_lock_type lock_type)
   if (lock_type == TL_WRITE_DELAYED)
     delayed_insert= TRUE;
     delayed_insert= FALSE;
   if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK)
       Here is where we get into the guts of a row level lock.
       If TL_UNLOCK is set
       If we are not doing a LOCK TABLE or DISCARD/IMPORT
       TABLESPACE, then allow multiple writers
     if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
          lock_type <= TL_WRITE) && !thd->in_lock_tables
         && !thd->tablespace_op)
       lock_type = TL_WRITE_ALLOW_WRITE;
       In queries of type INSERT INTO t1 SELECT ... FROM t2 ...
       MySQL would use the lock TL_READ_NO_INSERT on t2, and that
       would conflict with TL_WRITE_ALLOW_WRITE, blocking all inserts
       to t2. Convert the lock to a normal read lock to allow
       concurrent inserts to t2.
     if (lock_type == TL_READ_NO_INSERT && !thd->in_lock_tables)
       lock_type = TL_READ;
   *to++= &lock;
   return to;

The following is the minimal implementation, for a storage engine that does not need to downgrade locks:

THR_LOCK_DATA **ha_tina::store_lock(THD *thd,
                                    THR_LOCK_DATA **to,
                                    enum thr_lock_type lock_type)
   /* Note that if the lock type is TL_IGNORE we don't update lock.type,
      preserving the previous lock level */
   if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK)
    /* the heart of the store_lock() method and it's main purpose -
      storing the (possibly changed) lock level into the provided
      memory */
     *to++= &lock;
     return to;

See also ha_myisammrg::store_lock() for more complex implementation