diff -ur lock/lock0lock.cc lock.mod/lock0lock.cc --- lock/lock0lock.cc 2012-05-15 17:24:51.253119242 +0900 +++ lock.mod/lock0lock.cc 2012-05-15 17:57:16.765114388 +0900 @@ -3729,16 +3729,10 @@ ut_ad(ctx->depth > 0); - do { - /* Restore search state. */ - - stack = &lock_stack[--ctx->depth]; - trx_lock = &stack->lock->trx->lock; + stack = &lock_stack[--ctx->depth]; + trx_lock = &stack->lock->trx->lock; - /* Skip sub-trees that have already been searched. */ - } while (ctx->depth > 0 && trx_lock->deadlock_mark > ctx->mark_start); - - return(ctx->depth == 0) ? NULL : stack; + return stack; } /********************************************************************//** @@ -3820,14 +3814,16 @@ /* Select the joining transaction as the victim. */ return(ctx->start->id); - } else if (lock->trx->lock.que_state == TRX_QUE_LOCK_WAIT) { + } else if (lock->trx->lock.que_state == TRX_QUE_LOCK_WAIT && !(lock->trx->lock.wait_lock->trx->lock.deadlock_mark > ctx->mark_start)) { /* Another trx ahead has requested a lock in an incompatible mode, and is itself waiting for a lock. */ /* Save current search state. */ - if (!lock_deadlock_push(ctx, lock, heap_no)) { + const lock_t* lock2 = lock_get_next_lock(ctx, lock, heap_no); + if ( lock2 != NULL && !lock_deadlock_push(ctx, lock2, heap_no)) { + /* Unable to save current search state, stack size not big enough. */ @@ -3838,12 +3834,15 @@ ctx->wait_lock = lock->trx->lock.wait_lock; lock = lock_get_first_lock(ctx, &heap_no); + ctx->wait_lock->trx->lock.deadlock_mark = ++lock_mark_counter; if (lock != NULL) { continue; } } + if (lock == ctx->wait_lock && ctx->depth > 0) lock = NULL; + if (lock != NULL) { lock = lock_get_next_lock(ctx, lock, heap_no); }