From: Dmitry Lenev Date: September 29 2010 12:09pm Subject: bzr commit into mysql-5.5-runtime branch (Dmitry.Lenev:3148) Bug#56405 Bug#56715 List-Archive: http://lists.mysql.com/commits/119406 X-Bug: 56405,56715 Message-Id: <20100929120926.82CBF1E5452@mockturtle> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============2115902808==" --===============2115902808== 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 3148 Dmitry Lenev 2010-09-29 A better fix for bug #56405 "Deadlock in the MDL deadlock detector" that doesn't introduce bug #56715 "Concurrent transactions + FLUSH result in sporadical unwarranted deadlock errors". Deadlock could have occurred when workload containing a mix of DML, DDL and FLUSH TABLES statements affecting the same set of tables was executed in a heavily concurrent environment. This deadlock occurred when several connections tried to perform deadlock detection in the metadata locking subsystem. The first connection started traversing wait-for graph, encountered a sub-graph representing a wait for flush, acquired LOCK_open and dived into sub-graph inspection. Then it encountered sub-graph corresponding to wait for metadata lock and blocked while trying to acquire a rd-lock on MDL_lock::m_rwlock, since some,other thread had a wr-lock on it. When this wr-lock was released it could have happened (if there was another pending wr-lock against this rwlock) that the rd-lock from the first connection was left unsatisfied but at the same time the new rd-lock request from the second connection sneaked in and was satisfied (for this to be possible the second rd-request should come exactly after the wr-lock is released but before pending the wr-lock manages to grab rwlock, which is possible both on Linux and in our own rwlock implementation). If this second connection continued traversing the wait-for graph and encountered a sub-graph representing a wait for flush it tried to acquire LOCK_open and thus the deadlock was created. The previous patch tried to workaround this problem by not allowing the 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 a 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 an rwlock is rd-locked and there is a blocked pending rd-lock. Thus the situation which has caused this bug becomes impossible with this implementation. Due to fact that this implementation is optimized for wr-lock/unlock scenario which is most common in the MDL subsystem it doesn't introduce noticeable 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 a 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-29 12:09:07 +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-29 12:09:07 +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-29 12:09:07 +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-29 12:09:07 +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-29 12:09:07 +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-29 12:09:07 +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) */ --===============2115902808== 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: 11263c7cbd1e90c0f2a47efe599e9d5a84feb917 # timestamp: 2010-09-29 16:09:26 +0400 # base_revision_id: jon.hauglid@stripped\ # 6i7a2nvhh2vwvtml # # Begin bundle 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 --===============2115902808==--