From: Dmitry Lenev Date: September 27 2010 9:46am Subject: bzr commit into mysql-5.5-runtime branch (Dmitry.Lenev:3142) Bug#56405 Bug#56715 List-Archive: http://lists.mysql.com/commits/119154 X-Bug: 56405,56715 Message-Id: <20100927094707.ECFAFE5A6D@mockturtle> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0206628339==" --===============0206628339== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///home/dlenev/src/bzr/mysql-5.5-rt-56715/ based on revid:jon.hauglid@stripped 3142 Dmitry Lenev 2010-09-27 A better fix for bug #56405 "Deadlock in the MDL deadlock detector", which doesn't introduce bug #56715 "Concurrent transactions + FLUSH result in sporadical unwarranted deadlock errors". Deadlock could have occurred when workload containing mix of DML, DDL and FLUSH TABLES statements affecting same set of tables was executed in heavily concurrent environment. This deadlock occurred when several connections tried to perform deadlock detection in metadata locking subsystem. The first connection started traversing wait-for graph, encountered sub-graph representing wait for flush, acquired LOCK_open and dived into sub-graph inspection. When it has encountered sub-graph corresponding to wait for metadata lock and blocked while trying to acquire rd-lock on MDL_lock::m_rwlock protecting this subgraph, since some other thread had wr-lock on it. When this wr-lock was released it could have happened (if there was other pending wr-lock against this rwlock) that rd-lock from the first connection was left unsatisfied but at the same time new rd-lock request from the second connection sneaked in and was satisfied (for this to be possible second rd- request should come exactly after wr-lock is released but before pending wr-lock manages to grab rwlock, which is possible both on Linux and in our own rwlock implementation). If this second connection continued traversing wait-for graph and encountered sub-graph representing wait for flush it tried to acquire LOCK_open and thus deadlock was created. The previous patch tried to workaround this problem by not allowing deadlock detector to lock LOCK_open mutex if some other thread doing deadlock detection already owns it and current search depth is greater than 0. Instead deadlock was reported. As result it has introduced bug #56715. This patch solves this problem in a different way. It introduces a new rw_pr_lock_t implementation to be used by MDL subsystem instead of one based on Linux rwlocks or our own rwlock implementation. This new implementation never allows situation in which rwlock is rd-locked and there is a blocked pending rd-lock. Thus situation which has caused this bug becomes impossible with it. Due to fact that this implementation is optimized for wr-lock/unlock scenario which is most common in MDL subsystem it doesn't introduce noticiable performance regressions in sysbench tests. Moreover it significantly improves situation for POINT_SELECT test when many connections are used. No test case is provided as this bug is very hard to repeat in MTR environment but is repeatable with the help of RQG tests. This patch also doesn't include test for bug #56715 "Concurrent transactions + FLUSH result in sporadical unwarranted deadlock errors" as it takes too much time to be run as part of normal test-suite runs. @ config.h.cmake We no longer need to check for presence of pthread_rwlockattr_setkind_np as we no longer use Linux-specific implementation of rw_pr_lock_t which uses this function. @ configure.cmake We no longer need to check for presence of pthread_rwlockattr_setkind_np as we no longer use Linux-specific implementation of rw_pr_lock_t which uses this function. @ configure.in We no longer need to check for presence of pthread_rwlockattr_setkind_np as we no longer use Linux-specific implementation of rw_pr_lock_t which uses this function. @ include/my_pthread.h Introduced new implementation of rw_pr_lock_t. Since it never allows situation in which rwlock is rd-locked and there is a blocked pending rd-lock it is not affected by bug #56405 "Deadlock in the MDL deadlock detector". This implementation is also optimized for wr-lock/unlock scenario which is most common in MDL subsystem. So it doesn't introduce noticiable performance regressions in sysbench tests (compared to old Linux-specific implementation). Moreover it significantly improves situation for POINT_SELECT test when many connections are used. As part of this change removed try-lock part of API for this type of lock. It is not used in our code and it would be hard to implement correctly within constraints of new implementation. Finally, removed support of preferring readers from my_rw_lock_t implementation as the only user of this feature was old rw_pr_lock_t implementation. @ include/mysql/psi/mysql_thread.h Removed try-lock part of prlock API. It is not used in our code and it would be hard to implement correctly within constraints of new prlock implementation. @ mysys/thr_rwlock.c Introduced new implementation of rw_pr_lock_t. Since it never allows situation in which rwlock is rd-locked and there is a blocked pending rd-lock it is not affected by bug #56405 "Deadlock in the MDL deadlock detector". This implementation is also optimized for wr-lock/unlock scenario which is most common in MDL subsystem. So it doesn't introduce noticiable performance regressions in sysbench tests (compared to old Linux-specific implementation). Moreover it significantly improves situation for POINT_SELECT test when many connections are used. Also removed support of preferring readers from my_rw_lock_t implementation as the only user of this feature was old rw_pr_lock_t implementation. modified: config.h.cmake configure.cmake configure.in include/my_pthread.h include/mysql/psi/mysql_thread.h mysys/thr_rwlock.c === modified file 'config.h.cmake' --- a/config.h.cmake 2010-07-29 09:42:55 +0000 +++ b/config.h.cmake 2010-09-27 09:46:17 +0000 @@ -220,7 +220,6 @@ #cmakedefine HAVE_PTHREAD_KEY_DELETE 1 #cmakedefine HAVE_PTHREAD_KILL 1 #cmakedefine HAVE_PTHREAD_RWLOCK_RDLOCK 1 -#cmakedefine HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP 1 #cmakedefine HAVE_PTHREAD_SETPRIO_NP 1 #cmakedefine HAVE_PTHREAD_SETSCHEDPARAM 1 #cmakedefine HAVE_PTHREAD_SIGMASK 1 === modified file 'configure.cmake' --- a/configure.cmake 2010-07-29 09:42:55 +0000 +++ b/configure.cmake 2010-09-27 09:46:17 +0000 @@ -346,7 +346,6 @@ CHECK_FUNCTION_EXISTS (pthread_condattr_ CHECK_FUNCTION_EXISTS (pthread_init HAVE_PTHREAD_INIT) CHECK_FUNCTION_EXISTS (pthread_key_delete HAVE_PTHREAD_KEY_DELETE) CHECK_FUNCTION_EXISTS (pthread_rwlock_rdlock HAVE_PTHREAD_RWLOCK_RDLOCK) -CHECK_FUNCTION_EXISTS (pthread_rwlockattr_setkind_np HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP) CHECK_FUNCTION_EXISTS (pthread_sigmask HAVE_PTHREAD_SIGMASK) CHECK_FUNCTION_EXISTS (pthread_threadmask HAVE_PTHREAD_THREADMASK) CHECK_FUNCTION_EXISTS (pthread_yield_np HAVE_PTHREAD_YIELD_NP) === modified file 'configure.in' --- a/configure.in 2010-08-25 14:05:33 +0000 +++ b/configure.in 2010-09-27 09:46:17 +0000 @@ -2169,7 +2169,7 @@ AC_CHECK_FUNCS(alarm bfill bmove bsearch mkstemp mlockall perror poll pread pthread_attr_create mmap mmap64 getpagesize \ pthread_attr_getstacksize pthread_attr_setstacksize pthread_condattr_create \ pthread_getsequence_np pthread_key_delete pthread_rwlock_rdlock \ - pthread_rwlockattr_setkind_np pthread_sigmask \ + pthread_sigmask \ readlink realpath rename rint rwlock_init setupterm \ shmget shmat shmdt shmctl sigaction sigemptyset sigaddset \ sighold sigset sigthreadmask port_create sleep thr_yield \ === modified file 'include/my_pthread.h' --- a/include/my_pthread.h 2010-08-10 21:12:01 +0000 +++ b/include/my_pthread.h 2010-09-27 09:46:17 +0000 @@ -594,7 +594,7 @@ int my_pthread_fastmutex_lock(my_pthread /* Use our own version of read/write locks */ #define NEED_MY_RW_LOCK 1 #define rw_lock_t my_rw_lock_t -#define my_rwlock_init(A,B) my_rw_init((A), 0) +#define my_rwlock_init(A,B) my_rw_init((A)) #define rw_rdlock(A) my_rw_rdlock((A)) #define rw_wrlock(A) my_rw_wrlock((A)) #define rw_tryrdlock(A) my_rw_tryrdlock((A)) @@ -606,49 +606,82 @@ int my_pthread_fastmutex_lock(my_pthread #endif /* USE_MUTEX_INSTEAD_OF_RW_LOCKS */ -/* - Portable read-write locks which prefer readers. +/** + Portable implementation of special type of read-write locks. - Required by some algorithms in order to provide correctness. -*/ + These locks have two properties which are unusual for rwlocks: + 1) They "prefer readers" in the sense that they do not allow + situations in which rwlock is rd-locked and there is a + pending rd-lock which is blocked (e.g. due to pending + request for wr-lock). + This is a stronger guarantee than one which is provided for + PTHREAD_RWLOCK_PREFER_READER_NP rwlocks in Linux. + MDL subsystem deadlock detector relies on this property for + its correctness. + 2) They are optimized for uncontended wr-lock/unlock case. + This is scenario in which they are most oftenly used + within MDL subsystem. Optimizing for it gives significant + performance improvements in some of tests involving many + connections. + + Another important requirement imposed on this type of rwlock + by the MDL subsystem is that it should be OK to destroy rwlock + object which is in unlocked state even though some threads might + have not yet fully left unlock operation for it (of course there + is an external guarantee that no thread will try to lock rwlock + which is destroyed). + Putting it another way the unlock operation should not access + rwlock data after changing its state to unlocked. -#if defined(HAVE_PTHREAD_RWLOCK_RDLOCK) && defined(HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP) -/* - On systems which have a way to specify that readers should - be preferred through attribute mechanism (e.g. Linux) we use - system implementation of read/write locks. + TODO/FIXME: We should consider alleviating this requirement as + it blocks us from doing certain performance optimizations. */ -#define rw_pr_lock_t pthread_rwlock_t + +typedef struct st_rw_pr_lock_t { + /** + Lock which protects the structure. + Also held for the duration of wr-lock. + */ + pthread_mutex_t lock; + /** + Condition variable which is used to wake-up + writers waiting for readers to go away. + */ + pthread_cond_t no_active_readers; + /** Number of active readers. */ + uint active_readers; + /** Number of writers waiting for readers to go away. */ + uint writers_waiting_readers; + /** Indicates whether there is an active writer. */ + my_bool active_writer; +#ifdef SAFE_MUTEX + /** Thread holding wr-lock (for debug purposes only). */ + pthread_t writer_thread; +#endif +} rw_pr_lock_t; + extern int rw_pr_init(rw_pr_lock_t *); -#define rw_pr_rdlock(A) pthread_rwlock_rdlock(A) -#define rw_pr_wrlock(A) pthread_rwlock_wrlock(A) -#define rw_pr_tryrdlock(A) pthread_rwlock_tryrdlock(A) -#define rw_pr_trywrlock(A) pthread_rwlock_trywrlock(A) -#define rw_pr_unlock(A) pthread_rwlock_unlock(A) -#define rw_pr_destroy(A) pthread_rwlock_destroy(A) +extern int rw_pr_rdlock(rw_pr_lock_t *); +extern int rw_pr_wrlock(rw_pr_lock_t *); +extern int rw_pr_unlock(rw_pr_lock_t *); +extern int rw_pr_destroy(rw_pr_lock_t *); +#ifdef SAFE_MUTEX +#define rw_pr_lock_assert_write_owner(A) \ + DBUG_ASSERT((A)->active_writer && pthread_equal(pthread_self(), \ + (A)->writer_thread)) +#define rw_pr_lock_assert_not_write_owner(A) \ + DBUG_ASSERT(! (A)->active_writer || ! pthread_equal(pthread_self(), \ + (A)->writer_thread)) +#else #define rw_pr_lock_assert_write_owner(A) #define rw_pr_lock_assert_not_write_owner(A) -#else -/* Otherwise we have to use our own implementation of read/write locks. */ -#define NEED_MY_RW_LOCK 1 -struct st_my_rw_lock_t; -#define rw_pr_lock_t my_rw_lock_t -extern int rw_pr_init(struct st_my_rw_lock_t *); -#define rw_pr_rdlock(A) my_rw_rdlock((A)) -#define rw_pr_wrlock(A) my_rw_wrlock((A)) -#define rw_pr_tryrdlock(A) my_rw_tryrdlock((A)) -#define rw_pr_trywrlock(A) my_rw_trywrlock((A)) -#define rw_pr_unlock(A) my_rw_unlock((A)) -#define rw_pr_destroy(A) my_rw_destroy((A)) -#define rw_pr_lock_assert_write_owner(A) my_rw_lock_assert_write_owner((A)) -#define rw_pr_lock_assert_not_write_owner(A) my_rw_lock_assert_not_write_owner((A)) -#endif /* defined(HAVE_PTHREAD_RWLOCK_RDLOCK) && defined(HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP) */ +#endif /* SAFE_MUTEX */ #ifdef NEED_MY_RW_LOCK /* - On systems which don't support native read/write locks, or don't support - read/write locks which prefer readers we have to use own implementation. + On systems which don't support native read/write locks we have + to use own implementation. */ typedef struct st_my_rw_lock_t { pthread_mutex_t lock; /* lock for structure */ @@ -656,13 +689,12 @@ typedef struct st_my_rw_lock_t { pthread_cond_t writers; /* waiting writers */ int state; /* -1:writer,0:free,>0:readers */ int waiters; /* number of waiting writers */ - my_bool prefer_readers; #ifdef SAFE_MUTEX pthread_t write_thread; #endif } my_rw_lock_t; -extern int my_rw_init(my_rw_lock_t *, my_bool *); +extern int my_rw_init(my_rw_lock_t *); extern int my_rw_destroy(my_rw_lock_t *); extern int my_rw_rdlock(my_rw_lock_t *); extern int my_rw_wrlock(my_rw_lock_t *); === modified file 'include/mysql/psi/mysql_thread.h' --- a/include/mysql/psi/mysql_thread.h 2010-08-10 21:12:01 +0000 +++ b/include/mysql/psi/mysql_thread.h 2010-09-27 09:46:17 +0000 @@ -141,9 +141,7 @@ typedef struct st_mysql_rwlock mysql_rwl @c mysql_prlock_t is a drop-in replacement for @c rw_pr_lock_t. @sa mysql_prlock_init @sa mysql_prlock_rdlock - @sa mysql_prlock_tryrdlock @sa mysql_prlock_wrlock - @sa mysql_prlock_trywrlock @sa mysql_prlock_unlock @sa mysql_prlock_destroy */ @@ -421,20 +419,6 @@ typedef struct st_mysql_cond mysql_cond_ #endif /** - @def mysql_prlock_tryrdlock(RW) - Instrumented rw_pr_tryrdlock. - @c mysql_prlock_tryrdlock is a drop-in replacement - for @c rw_pr_tryrdlock. -*/ -#ifdef HAVE_PSI_INTERFACE - #define mysql_prlock_tryrdlock(RW) \ - inline_mysql_prlock_tryrdlock(RW, __FILE__, __LINE__) -#else - #define mysql_prlock_tryrdlock(RW) \ - inline_mysql_prlock_tryrdlock(RW) -#endif - -/** @def mysql_rwlock_trywrlock(RW) Instrumented rwlock_trywrlock. @c mysql_rwlock_trywrlock is a drop-in replacement @@ -449,20 +433,6 @@ typedef struct st_mysql_cond mysql_cond_ #endif /** - @def mysql_prlock_trywrlock(RW) - Instrumented rw_pr_trywrlock. - @c mysql_prlock_trywrlock is a drop-in replacement - for @c rw_pr_trywrlock. -*/ -#ifdef HAVE_PSI_INTERFACE - #define mysql_prlock_trywrlock(RW) \ - inline_mysql_prlock_trywrlock(RW, __FILE__, __LINE__) -#else - #define mysql_prlock_trywrlock(RW) \ - inline_mysql_prlock_trywrlock(RW) -#endif - -/** @def mysql_rwlock_unlock(RW) Instrumented rwlock_unlock. @c mysql_rwlock_unlock is a drop-in replacement @@ -905,35 +875,6 @@ static inline int inline_mysql_rwlock_tr return result; } -#ifndef DISABLE_MYSQL_PRLOCK_H -static inline int inline_mysql_prlock_tryrdlock( - mysql_prlock_t *that -#ifdef HAVE_PSI_INTERFACE - , const char *src_file, uint src_line -#endif - ) -{ - int result; -#ifdef HAVE_PSI_INTERFACE - struct PSI_rwlock_locker *locker= NULL; - PSI_rwlock_locker_state state; - if (likely(PSI_server && that->m_psi)) - { - locker= PSI_server->get_thread_rwlock_locker(&state, that->m_psi, - PSI_RWLOCK_TRYREADLOCK); - if (likely(locker != NULL)) - PSI_server->start_rwlock_rdwait(locker, src_file, src_line); - } -#endif - result= rw_pr_tryrdlock(&that->m_prlock); -#ifdef HAVE_PSI_INTERFACE - if (likely(locker != NULL)) - PSI_server->end_rwlock_rdwait(locker, result); -#endif - return result; -} -#endif - static inline int inline_mysql_rwlock_trywrlock( mysql_rwlock_t *that #ifdef HAVE_PSI_INTERFACE @@ -961,35 +902,6 @@ static inline int inline_mysql_rwlock_tr return result; } -#ifndef DISABLE_MYSQL_PRLOCK_H -static inline int inline_mysql_prlock_trywrlock( - mysql_prlock_t *that -#ifdef HAVE_PSI_INTERFACE - , const char *src_file, uint src_line -#endif - ) -{ - int result; -#ifdef HAVE_PSI_INTERFACE - struct PSI_rwlock_locker *locker= NULL; - PSI_rwlock_locker_state state; - if (likely(PSI_server && that->m_psi)) - { - locker= PSI_server->get_thread_rwlock_locker(&state, that->m_psi, - PSI_RWLOCK_TRYWRITELOCK); - if (likely(locker != NULL)) - PSI_server->start_rwlock_wrwait(locker, src_file, src_line); - } -#endif - result= rw_pr_trywrlock(&that->m_prlock); -#ifdef HAVE_PSI_INTERFACE - if (likely(locker != NULL)) - PSI_server->end_rwlock_wrwait(locker, result); -#endif - return result; -} -#endif - static inline int inline_mysql_rwlock_unlock( mysql_rwlock_t *that) { === modified file 'mysys/thr_rwlock.c' --- a/mysys/thr_rwlock.c 2010-08-12 13:50:23 +0000 +++ b/mysys/thr_rwlock.c 2010-09-27 09:46:17 +0000 @@ -59,7 +59,7 @@ * Mountain View, California 94043 */ -int my_rw_init(my_rw_lock_t *rwp, my_bool *prefer_readers_attr) +int my_rw_init(my_rw_lock_t *rwp) { pthread_condattr_t cond_attr; @@ -74,8 +74,6 @@ int my_rw_init(my_rw_lock_t *rwp, my_boo #ifdef SAFE_MUTEX rwp->write_thread = 0; #endif - /* If attribute argument is NULL use default value - prefer writers. */ - rwp->prefer_readers= prefer_readers_attr ? *prefer_readers_attr : FALSE; return(0); } @@ -96,8 +94,7 @@ int my_rw_rdlock(my_rw_lock_t *rwp) pthread_mutex_lock(&rwp->lock); /* active or queued writers */ - while (( rwp->state < 0 ) || - (rwp->waiters && ! rwp->prefer_readers)) + while (( rwp->state < 0 ) || rwp->waiters) pthread_cond_wait( &rwp->readers, &rwp->lock); rwp->state++; @@ -109,8 +106,7 @@ int my_rw_tryrdlock(my_rw_lock_t *rwp) { int res; pthread_mutex_lock(&rwp->lock); - if ((rwp->state < 0 ) || - (rwp->waiters && ! rwp->prefer_readers)) + if ((rwp->state < 0 ) || rwp->waiters) res= EBUSY; /* Can't get lock */ else { @@ -192,30 +188,127 @@ int my_rw_unlock(my_rw_lock_t *rwp) return(0); } +#endif /* defined(NEED_MY_RW_LOCK) */ + -int rw_pr_init(struct st_my_rw_lock_t *rwlock) +int rw_pr_init(rw_pr_lock_t *rwlock) { - my_bool prefer_readers_attr= TRUE; - return my_rw_init(rwlock, &prefer_readers_attr); + pthread_mutex_init(&rwlock->lock, NULL); + pthread_cond_init(&rwlock->no_active_readers, NULL); + rwlock->active_readers= 0; + rwlock->writers_waiting_readers= 0; + rwlock->active_writer= FALSE; +#ifdef SAFE_MUTEX + rwlock->writer_thread= 0; +#endif + return 0; } -#else -/* - We are on system which has native read/write locks which support - preferring of readers. -*/ +int rw_pr_destroy(rw_pr_lock_t *rwlock) +{ + pthread_cond_destroy(&rwlock->no_active_readers); + pthread_mutex_destroy(&rwlock->lock); + return 0; +} -int rw_pr_init(rw_pr_lock_t *rwlock) + +int rw_pr_rdlock(rw_pr_lock_t *rwlock) { - pthread_rwlockattr_t rwlock_attr; + pthread_mutex_lock(&rwlock->lock); + /* + The fact that we were able to acquire 'lock' mutex means + that there are no active writers and we can acquire rd-lock. + Increment active readers counter to prevent requests for + wr-lock from succeeding and unlock mutex. + */ + rwlock->active_readers++; + pthread_mutex_unlock(&rwlock->lock); + return 0; +} + + +int rw_pr_wrlock(rw_pr_lock_t *rwlock) +{ + pthread_mutex_lock(&rwlock->lock); + + if (rwlock->active_readers != 0) + { + /* There are active readers. We have to wait until they are gone. */ + rwlock->writers_waiting_readers++; - pthread_rwlockattr_init(&rwlock_attr); - pthread_rwlockattr_setkind_np(&rwlock_attr, PTHREAD_RWLOCK_PREFER_READER_NP); - pthread_rwlock_init(rwlock, NULL); - pthread_rwlockattr_destroy(&rwlock_attr); + while (rwlock->active_readers != 0) + pthread_cond_wait(&rwlock->no_active_readers, &rwlock->lock); + + rwlock->writers_waiting_readers--; + } + + /* + We own 'lock' mutex so there is no active writers. + Also there are no active readers. + This means that we can grant wr-lock. + Not releasing 'lock' mutex until unlock will block + both requests for rd and wr-locks. + Set 'active_writer' flag to simplify unlock. + + Thanks to the fact wr-lock/unlock in the absence of + contention from readers is essentially mutex lock/unlock + with a few simple checks make this rwlock implementation + wr-lock optimized. + */ + rwlock->active_writer= TRUE; +#ifdef SAFE_MUTEX + rwlock->writer_thread= pthread_self(); +#endif return 0; } -#endif /* defined(NEED_MY_RW_LOCK) */ + +int rw_pr_unlock(rw_pr_lock_t *rwlock) +{ + if (rwlock->active_writer) + { + /* We are unlocking wr-lock. */ +#ifdef SAFE_MUTEX + rwlock->writer_thread= 0; +#endif + rwlock->active_writer= FALSE; + if (rwlock->writers_waiting_readers) + { + /* + Avoid expensive cond signal in case when there is no contention + or it is wr-only. + + Note that from view point of performance it would be better to + signal on the condition variable after unlocking mutex (as it + reduces number of contex switches). + + Unfortunately this would mean that such rwlock can't be safely + used by MDL subsystem, which relies on the fact that it is OK + to destroy rwlock once it is in unlocked state. + */ + pthread_cond_signal(&rwlock->no_active_readers); + } + pthread_mutex_unlock(&rwlock->lock); + } + else + { + /* We are unlocking rd-lock. */ + pthread_mutex_lock(&rwlock->lock); + rwlock->active_readers--; + if (rwlock->active_readers == 0 && + rwlock->writers_waiting_readers) + { + /* + If we are last reader and there are waiting + writers wake them up. + */ + pthread_cond_signal(&rwlock->no_active_readers); + } + pthread_mutex_unlock(&rwlock->lock); + } + return 0; +} + + #endif /* defined(THREAD) */ --===============0206628339== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/dmitry.lenev@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: dmitry.lenev@stripped # target_branch: file:///home/dlenev/src/bzr/mysql-5.5-rt-56715/ # testament_sha1: 26d8884fd2fb488f9400f6c1fe8caa014c899bdd # timestamp: 2010-09-27 13:47:07 +0400 # base_revision_id: jon.hauglid@stripped\ # mpy5ty4vmw0k5j19 # # Begin bundle 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 ADg9o+AP6lSoNiV/4u5IpwoSD2A9T6A= --===============0206628339==--