--- mysql-5.0.37/sql/ha_innodb.cc 2007-03-05 19:21:41.000000000 +0000 +++ /tmp/ha_innodb.cc 2007-03-21 07:50:01.000000000 +0000 @@ -6560,9 +6560,10 @@ pointer to the 'lock' field of current handle is stored next to this array */ - enum thr_lock_type lock_type) /* in: lock type to store in + enum thr_lock_type lock_type, /* in: lock type to store in 'lock'; this may also be TL_IGNORE */ + trx_t* trx) { row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; @@ -6570,6 +6571,12 @@ Be careful to ignore TL_IGNORE if we are going to do something with only 'real' locks! */ + /* Note that trx in this function is NOT necessarily prebuilt->trx + because we call update_thd() later, in ::external_lock()! Failure to + understand this caused a serious memory corruption bug in 5.1.11. */ + + trx = check_trx_exists(thd); + if ((lock_type == TL_READ && thd->in_lock_tables) || (lock_type == TL_READ_HIGH_PRIORITY && thd->in_lock_tables) || lock_type == TL_READ_WITH_SHARED_LOCKS || @@ -6594,9 +6601,8 @@ serializable, and also the results from the update could be unexpected if an obsolete consistent read view would be used. */ - if (srv_locks_unsafe_for_binlog && - prebuilt->trx->isolation_level != TRX_ISO_SERIALIZABLE && + trx->isolation_level != TRX_ISO_SERIALIZABLE && (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT) && (thd->lex->sql_command == SQLCOM_INSERT_SELECT || thd->lex->sql_command == SQLCOM_UPDATE ||