~ubuntu-branches/ubuntu/precise/mysql-5.5/precise-201203300109

« back to all changes in this revision

Viewing changes to sql/mdl.cc

  • Committer: Package Import Robot
  • Author(s): Clint Byrum
  • Date: 2012-02-14 23:59:22 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20120214235922-cux5uek1e5l0hje9
Tags: 5.5.20-0ubuntu1
* New upstream release.
* d/mysql-server-5.5.mysql.upstart: Fix stop on to make sure mysql is
  fully stopped before shutdown commences. (LP: #688541) Also simplify
  start on as it is redundant.
* d/control: Depend on upstart version which has apparmor profile load
  script to prevent failure on upgrade from lucid to precise.
  (LP: #907465)
* d/apparmor-profile: need to allow /run since that is the true path
  of /var/run files. (LP: #917542)
* d/control: mysql-server-5.5 has files in it that used to be owned
  by libmysqlclient-dev, so it must break/replace it. (LP: #912487)
* d/rules, d/control: 5.5.20 Fixes segfault on tests with gcc 4.6,
  change compiler back to system default.
* d/rules: Turn off embedded libedit/readline.(Closes: #659566)

Show diffs side-by-side

added added

removed removed

Lines of Context:
91
91
static bool mdl_initialized= 0;
92
92
 
93
93
 
 
94
class MDL_object_lock;
 
95
class MDL_object_lock_cache_adapter;
 
96
 
 
97
 
94
98
/**
95
99
  A collection of all MDL locks. A singleton,
96
100
  there is only one instance of the map in the server.
111
115
  HASH m_locks;
112
116
  /* Protects access to m_locks hash. */
113
117
  mysql_mutex_t m_mutex;
 
118
  /**
 
119
    Cache of (unused) MDL_lock objects available for re-use.
 
120
 
 
121
    On some systems (e.g. Windows XP) constructing/destructing
 
122
    MDL_lock objects can be fairly expensive. We use this cache
 
123
    to avoid these costs in scenarios in which they can have
 
124
    significant negative effect on performance. For example, when
 
125
    there is only one thread constantly executing statements in
 
126
    auto-commit mode and thus constantly causing creation/
 
127
    destruction of MDL_lock objects for the tables it uses.
 
128
 
 
129
    Note that this cache contains only MDL_object_lock objects.
 
130
 
 
131
    Protected by m_mutex mutex.
 
132
  */
 
133
  typedef I_P_List<MDL_object_lock, MDL_object_lock_cache_adapter,
 
134
                   I_P_List_counter>
 
135
          Lock_cache;
 
136
  Lock_cache m_unused_locks_cache;
114
137
  /** Pre-allocated MDL_lock object for GLOBAL namespace. */
115
138
  MDL_lock *m_global_lock;
116
139
  /** Pre-allocated MDL_lock object for COMMIT namespace. */
379
402
  : key(key_arg),
380
403
    m_ref_usage(0),
381
404
    m_ref_release(0),
382
 
    m_is_destroyed(FALSE)
 
405
    m_is_destroyed(FALSE),
 
406
    m_version(0)
383
407
  {
384
408
    mysql_prlock_init(key_MDL_lock_rwlock, &m_rwlock);
385
409
  }
414
438
  uint m_ref_usage;
415
439
  uint m_ref_release;
416
440
  bool m_is_destroyed;
 
441
  /**
 
442
    We use the same idea and an additional version counter to support
 
443
    caching of unused MDL_lock object for further re-use.
 
444
    This counter is incremented while holding both MDL_map::m_mutex and
 
445
    MDL_lock::m_rwlock locks each time when a MDL_lock is moved from
 
446
    the hash to the unused objects list (or destroyed).
 
447
    A thread, which has found a MDL_lock object for the key in the hash
 
448
    and then released the MDL_map::m_mutex before acquiring the
 
449
    MDL_lock::m_rwlock, can determine that this object was moved to the
 
450
    unused objects list (or destroyed) while it held no locks by comparing
 
451
    the version value which it read while holding the MDL_map::m_mutex
 
452
    with the value read after acquiring the MDL_lock::m_rwlock.
 
453
    Note that since it takes several years to overflow this counter such
 
454
    theoretically possible overflows should not have any practical effects.
 
455
  */
 
456
  ulonglong m_version;
417
457
};
418
458
 
419
459
 
462
502
    : MDL_lock(key_arg)
463
503
  { }
464
504
 
 
505
  /**
 
506
    Reset unused MDL_object_lock object to represent the lock context for a
 
507
    different object.
 
508
  */
 
509
  void reset(const MDL_key *new_key)
 
510
  {
 
511
    /* We need to change only object's key. */
 
512
    key.mdl_key_init(new_key);
 
513
    /* m_granted and m_waiting should be already in the empty/initial state. */
 
514
    DBUG_ASSERT(is_empty());
 
515
    /* Object should not be marked as destroyed. */
 
516
    DBUG_ASSERT(! m_is_destroyed);
 
517
    /*
 
518
      Values of the rest of the fields should be preserved between old and
 
519
      new versions of the object. E.g., m_version and m_ref_usage/release
 
520
      should be kept intact to properly handle possible remaining references
 
521
      to the old version of the object.
 
522
    */
 
523
  }
 
524
 
465
525
  virtual const bitmap_t *incompatible_granted_types_bitmap() const
466
526
  {
467
527
    return m_granted_incompatible;
479
539
private:
480
540
  static const bitmap_t m_granted_incompatible[MDL_TYPE_END];
481
541
  static const bitmap_t m_waiting_incompatible[MDL_TYPE_END];
 
542
 
 
543
public:
 
544
  /** Members for linking the object into the list of unused objects. */
 
545
  MDL_object_lock *next_in_cache, **prev_in_cache;
 
546
};
 
547
 
 
548
 
 
549
/**
 
550
  Helper class for linking MDL_object_lock objects into the unused objects list.
 
551
*/
 
552
class MDL_object_lock_cache_adapter :
 
553
      public I_P_List_adapter<MDL_object_lock, &MDL_object_lock::next_in_cache,
 
554
                              &MDL_object_lock::prev_in_cache>
 
555
{
482
556
};
483
557
 
484
558
 
485
559
static MDL_map mdl_locks;
 
560
/**
 
561
  Start-up parameter for the maximum size of the unused MDL_lock objects cache.
 
562
*/
 
563
ulong mdl_locks_cache_size;
 
564
 
486
565
 
487
566
extern "C"
488
567
{
565
644
  my_hash_free(&m_locks);
566
645
  MDL_lock::destroy(m_global_lock);
567
646
  MDL_lock::destroy(m_commit_lock);
 
647
 
 
648
  MDL_object_lock *lock;
 
649
  while ((lock= m_unused_locks_cache.pop_front()))
 
650
    MDL_lock::destroy(lock);
568
651
}
569
652
 
570
653
 
614
697
                                                          mdl_key->ptr(),
615
698
                                                          mdl_key->length())))
616
699
  {
617
 
    lock= MDL_lock::create(mdl_key);
 
700
    MDL_object_lock *unused_lock= NULL;
 
701
 
 
702
    /*
 
703
      No lock object found so we need to create a new one
 
704
      or reuse an existing unused object.
 
705
    */
 
706
    if (mdl_key->mdl_namespace() != MDL_key::SCHEMA &&
 
707
        m_unused_locks_cache.elements())
 
708
    {
 
709
      /*
 
710
        We need a MDL_object_lock type of object and the unused objects
 
711
        cache has some. Get the first object from the cache and set a new
 
712
        key for it.
 
713
      */
 
714
      DBUG_ASSERT(mdl_key->mdl_namespace() != MDL_key::GLOBAL &&
 
715
                  mdl_key->mdl_namespace() != MDL_key::COMMIT);
 
716
 
 
717
      unused_lock= m_unused_locks_cache.pop_front();
 
718
      unused_lock->reset(mdl_key);
 
719
 
 
720
      lock= unused_lock;
 
721
    }
 
722
    else
 
723
    {
 
724
      lock= MDL_lock::create(mdl_key);
 
725
    }
 
726
 
618
727
    if (!lock || my_hash_insert(&m_locks, (uchar*)lock))
619
728
    {
 
729
      if (unused_lock)
 
730
      {
 
731
        /*
 
732
          Note that we can't easily destroy an object from cache here as it
 
733
          still might be referenced by other threads. So we simply put it
 
734
          back into the cache.
 
735
        */
 
736
        m_unused_locks_cache.push_front(unused_lock);
 
737
      }
 
738
      else
 
739
      {
 
740
        MDL_lock::destroy(lock);
 
741
      }
620
742
      mysql_mutex_unlock(&m_mutex);
621
 
      MDL_lock::destroy(lock);
622
743
      return NULL;
623
744
    }
624
745
  }
633
754
/**
634
755
  Release mdl_locks.m_mutex mutex and lock MDL_lock::m_rwlock for lock
635
756
  object from the hash. Handle situation when object was released
636
 
  while the held no mutex.
 
757
  while we held no locks.
637
758
 
638
759
  @retval FALSE - Success.
639
760
  @retval TRUE  - Object was released while we held no mutex, caller
642
763
 
643
764
bool MDL_map::move_from_hash_to_lock_mutex(MDL_lock *lock)
644
765
{
 
766
  ulonglong version;
 
767
 
645
768
  DBUG_ASSERT(! lock->m_is_destroyed);
646
769
  mysql_mutex_assert_owner(&m_mutex);
647
770
 
651
774
    m_is_destroyed is FALSE.
652
775
  */
653
776
  lock->m_ref_usage++;
 
777
  /* Read value of the version counter under protection of m_mutex lock. */
 
778
  version= lock->m_version;
654
779
  mysql_mutex_unlock(&m_mutex);
655
780
 
656
781
  mysql_prlock_wrlock(&lock->m_rwlock);
657
782
  lock->m_ref_release++;
658
 
  if (unlikely(lock->m_is_destroyed))
 
783
 
 
784
  if (unlikely(lock->m_version != version))
659
785
  {
660
786
    /*
661
 
      Object was released while we held no mutex, we need to
662
 
      release it if no others hold references to it, while our own
663
 
      reference count ensured that the object as such haven't got
664
 
      its memory released yet. We can also safely compare
665
 
      m_ref_usage and m_ref_release since the object is no longer
666
 
      present in the hash so no one will be able to find it and
667
 
      increment m_ref_usage anymore.
 
787
      If the current value of version differs from one that was read while
 
788
      we held m_mutex mutex, this MDL_lock object was moved to the unused
 
789
      objects list or destroyed while we held no locks.
 
790
      We should retry our search. But first we should destroy the MDL_lock
 
791
      object if necessary.
668
792
    */
669
 
    uint ref_usage= lock->m_ref_usage;
670
 
    uint ref_release= lock->m_ref_release;
671
 
    mysql_prlock_unlock(&lock->m_rwlock);
672
 
    if (ref_usage == ref_release)
673
 
      MDL_lock::destroy(lock);
 
793
    if (unlikely(lock->m_is_destroyed))
 
794
    {
 
795
      /*
 
796
        Object was released while we held no locks, we need to
 
797
        release it if no others hold references to it, while our own
 
798
        reference count ensured that the object as such haven't got
 
799
        its memory released yet. We can also safely compare
 
800
        m_ref_usage and m_ref_release since the object is no longer
 
801
        present in the hash (or unused objects list) so no one will
 
802
        be able to find it and increment m_ref_usage anymore.
 
803
      */
 
804
      uint ref_usage= lock->m_ref_usage;
 
805
      uint ref_release= lock->m_ref_release;
 
806
      mysql_prlock_unlock(&lock->m_rwlock);
 
807
      if (ref_usage == ref_release)
 
808
        MDL_lock::destroy(lock);
 
809
    }
 
810
    else
 
811
    {
 
812
      /*
 
813
        Object was not destroyed but its version has changed.
 
814
        This means that it was moved to the unused objects list
 
815
        (and even might be already re-used). So now it might
 
816
        correspond to a different key, therefore we should simply
 
817
        retry our search.
 
818
      */
 
819
      mysql_prlock_unlock(&lock->m_rwlock);
 
820
    }
674
821
    return TRUE;
675
822
  }
676
823
  return FALSE;
685
832
 
686
833
void MDL_map::remove(MDL_lock *lock)
687
834
{
688
 
  uint ref_usage, ref_release;
689
 
 
690
835
  if (lock->key.mdl_namespace() == MDL_key::GLOBAL ||
691
836
      lock->key.mdl_namespace() == MDL_key::COMMIT)
692
837
  {
698
843
    return;
699
844
  }
700
845
 
701
 
  /*
702
 
    Destroy the MDL_lock object, but ensure that anyone that is
703
 
    holding a reference to the object is not remaining, if so he
704
 
    has the responsibility to release it.
705
 
 
706
 
    Setting of m_is_destroyed to TRUE while holding _both_
707
 
    mdl_locks.m_mutex and MDL_lock::m_rwlock mutexes transfers the
708
 
    protection of m_ref_usage from mdl_locks.m_mutex to
709
 
    MDL_lock::m_rwlock while removal of object from the hash makes
710
 
    it read-only.  Therefore whoever acquires MDL_lock::m_rwlock next
711
 
    will see most up to date version of m_ref_usage.
712
 
 
713
 
    This means that when m_is_destroyed is TRUE and we hold the
714
 
    MDL_lock::m_rwlock we can safely read the m_ref_usage
715
 
    member.
716
 
  */
717
846
  mysql_mutex_lock(&m_mutex);
718
847
  my_hash_delete(&m_locks, (uchar*) lock);
719
 
  lock->m_is_destroyed= TRUE;
720
 
  ref_usage= lock->m_ref_usage;
721
 
  ref_release= lock->m_ref_release;
722
 
  mysql_prlock_unlock(&lock->m_rwlock);
723
 
  mysql_mutex_unlock(&m_mutex);
724
 
  if (ref_usage == ref_release)
725
 
    MDL_lock::destroy(lock);
 
848
  /*
 
849
    To let threads holding references to the MDL_lock object know that it was
 
850
    moved to the list of unused objects or destroyed, we increment the version
 
851
    counter under protection of both MDL_map::m_mutex and MDL_lock::m_rwlock
 
852
    locks. This allows us to read the version value while having either one
 
853
    of those locks.
 
854
  */
 
855
  lock->m_version++;
 
856
 
 
857
  if ((lock->key.mdl_namespace() != MDL_key::SCHEMA) &&
 
858
      (m_unused_locks_cache.elements() < mdl_locks_cache_size))
 
859
  {
 
860
    /*
 
861
      This is an object of MDL_object_lock type and the cache of unused
 
862
      objects has not reached its maximum size yet. So instead of destroying
 
863
      object we move it to the list of unused objects to allow its later
 
864
      re-use with possibly different key. Any threads holding references to
 
865
      this object (owning MDL_map::m_mutex or MDL_lock::m_rwlock) will notice
 
866
      this thanks to the fact that we have changed the MDL_lock::m_version
 
867
      counter.
 
868
    */
 
869
    DBUG_ASSERT(lock->key.mdl_namespace() != MDL_key::GLOBAL &&
 
870
                lock->key.mdl_namespace() != MDL_key::COMMIT);
 
871
 
 
872
    m_unused_locks_cache.push_front((MDL_object_lock*)lock);
 
873
    mysql_mutex_unlock(&m_mutex);
 
874
    mysql_prlock_unlock(&lock->m_rwlock);
 
875
  }
 
876
  else
 
877
  {
 
878
    /*
 
879
      Destroy the MDL_lock object, but ensure that anyone that is
 
880
      holding a reference to the object is not remaining, if so he
 
881
      has the responsibility to release it.
 
882
 
 
883
      Setting of m_is_destroyed to TRUE while holding _both_
 
884
      mdl_locks.m_mutex and MDL_lock::m_rwlock mutexes transfers the
 
885
      protection of m_ref_usage from mdl_locks.m_mutex to
 
886
      MDL_lock::m_rwlock while removal of the object from the hash
 
887
      (and cache of unused objects) makes it read-only. Therefore
 
888
      whoever acquires MDL_lock::m_rwlock next will see the most up
 
889
      to date version of m_ref_usage.
 
890
 
 
891
      This means that when m_is_destroyed is TRUE and we hold the
 
892
      MDL_lock::m_rwlock we can safely read the m_ref_usage
 
893
      member.
 
894
    */
 
895
    uint ref_usage, ref_release;
 
896
 
 
897
    lock->m_is_destroyed= TRUE;
 
898
    ref_usage= lock->m_ref_usage;
 
899
    ref_release= lock->m_ref_release;
 
900
    mysql_mutex_unlock(&m_mutex);
 
901
    mysql_prlock_unlock(&lock->m_rwlock);
 
902
    if (ref_usage == ref_release)
 
903
      MDL_lock::destroy(lock);
 
904
  }
726
905
}
727
906
 
728
907
 
820
999
  Auxiliary functions needed for creation/destruction of MDL_lock objects.
821
1000
 
822
1001
  @note Also chooses an MDL_lock descendant appropriate for object namespace.
823
 
 
824
 
  @todo This naive implementation should be replaced with one that saves
825
 
        on memory allocation by reusing released objects.
826
1002
*/
827
1003
 
828
1004
inline MDL_lock *MDL_lock::create(const MDL_key *mdl_key)