• Konstantin Osipov's avatar
    Backport of: · f477e66e
    Konstantin Osipov authored
    ------------------------------------------------------------
    revno: 2617.23.18
    committer: Davi Arnaut <Davi.Arnaut@Sun.COM>
    branch nick: 4284-6.0
    timestamp: Mon 2009-03-02 18:18:26 -0300
    message:
    Bug#989: If DROP TABLE while there's an active transaction, wrong binlog order
    WL#4284: Transactional DDL locking
    
    This is a prerequisite patch:
    
    These changes are intended to split lock requests from granted
    locks and to allow the memory and lifetime of granted locks to
    be managed within the MDL subsystem. Furthermore, tickets can
    now be shared and therefore are used to satisfy multiple lock
    requests, but only shared locks can be recursive.
    
    The problem is that the MDL subsystem morphs lock requests into
    granted locks locks but does not manage the memory and lifetime
    of lock requests, and hence, does not manage the memory of
    granted locks either. This can be problematic because it puts the
    burden of tracking references on the users of the subsystem and
    it can't be easily done in transactional contexts where the locks
    have to be kept around for the duration of a transaction.
    
    Another issue is that recursive locks (when the context trying to
    acquire a lock already holds a lock on the same object) requires
    that each time the lock is granted, a unique lock request/granted
    lock structure structure must be kept around until the lock is
    released. This can lead to memory leaks in transactional contexts
    as locks taken during the transaction should only be released at
    the end of the transaction. This also leads to unnecessary wake
    ups (broadcasts) in the MDL subsystem if the context still holds
    a equivalent of the lock being released.
    
    These issues are exacerbated due to the fact that WL#4284 low-level
    design says that the implementation should "2) Store metadata locks
    in transaction memory root, rather than statement memory root" but
    this is not possible because a memory root, as implemented in mysys,
    requires all objects allocated from it to be freed all at once.
    
    This patch combines review input and significant code contributions
    from Konstantin Osipov (kostja) and Dmitri Lenev (dlenev).
    
    
    mysql-test/r/mdl_sync.result:
      Add test case result.
    mysql-test/t/mdl_sync.test:
      Add test case for shared lock upgrade case.
    sql/event_db_repository.cc:
      Rename mdl_alloc_lock to mdl_request_alloc.
    sql/ha_ndbcluster_binlog.cc:
      Use new function names to initialize MDL lock requests.
    sql/lock.cc:
      Rename MDL functions.
    sql/log_event.cc:
      The MDL request now holds the table and database name data (MDL_KEY).
    sql/mdl.cc:
      Move the MDL key to the MDL_LOCK structure in order to make the
      object suitable for allocation from a fixed-size allocator. This
      allows the simplification of the lists in the MDL_LOCK object,
      which now are just two, one for granted tickets and other for
      waiting (upgraders) tickets.
      
      Recursive requests for a shared lock on the same object can now
      be granted using the same lock ticket. This schema is only used
      for shared locks because that the only case that matters. This
      is used to avoid waste of resources in case a context (connection)
      already holds a shared lock on a object.
    sql/mdl.h:
      Introduce a metadata lock object key which is used  to uniquely
      identify lock objects.
      
      Separate the structure used to represent pending lock requests
      from the structure used to represent granted metadata locks.
      
      Rename functions used to manipulate locks requests in order to
      have a more consistent function naming schema.
    sql/sp_head.cc:
      Rename mdl_alloc_lock to mdl_request_alloc.
    sql/sql_acl.cc:
      Rename alloc_mdl_locks to alloc_mdl_requests.
    sql/sql_base.cc:
      Various changes to accommodate that lock requests are separated
      from lock tickets (granted locks).
    sql/sql_class.h:
      Last acquired lock before the savepoint was set.
    sql/sql_delete.cc:
      Various changes to accommodate that lock requests are separated
      from lock tickets (granted locks).
    sql/sql_handler.cc:
      Various changes to accommodate that lock requests are separated
      from lock tickets (granted locks).
    sql/sql_insert.cc:
      Rename alloc_mdl_locks to alloc_mdl_requests.
    sql/sql_parse.cc:
      Rename alloc_mdl_locks to alloc_mdl_requests.
    sql/sql_plist.h:
      Typedef for iterator type.
    sql/sql_plugin.cc:
      Rename alloc_mdl_locks to alloc_mdl_requests.
    sql/sql_servers.cc:
      Rename alloc_mdl_locks to alloc_mdl_requests.
    sql/sql_show.cc:
      Various changes to accommodate that lock requests are separated
      from lock tickets (granted locks).
    sql/sql_table.cc:
      Various changes to accommodate that lock requests are separated
      from lock tickets (granted locks).
    sql/sql_trigger.cc:
      Save reference to the lock ticket so it can be downgraded later.
    sql/sql_udf.cc:
      Rename alloc_mdl_locks to alloc_mdl_requests.
    sql/table.cc:
      Rename mdl_alloc_lock to mdl_request_alloc.
    sql/table.h:
      Separate MDL lock requests from lock tickets (granted locks).
    storage/myisammrg/ha_myisammrg.cc:
      Rename alloc_mdl_locks to alloc_mdl_requests.
    f477e66e
sql_plugin.cc 98.2 KB