mirror of
https://github.com/MariaDB/server.git
synced 2026-05-16 20:07:13 +02:00
Merge from mysql-5.1-innodb:
------------------------------------------------------------ revno: 3495 committer: Marko Mäkelä <marko.makela@oracle.com> branch nick: 5.1-innodb timestamp: Wed 2010-06-02 13:37:14 +0300 message: Bug#53674: InnoDB: Error: unlock row could not find a 4 mode lock on the record In semi-consistent read, only unlock freshly locked non-matching records. lock_rec_lock_fast(): Return LOCK_REC_SUCCESS, LOCK_REC_SUCCESS_CREATED, or LOCK_REC_FAIL instead of TRUE/FALSE. enum db_err: Add DB_SUCCESS_LOCKED_REC for indicating a successful operation where a record lock was created. lock_sec_rec_read_check_and_lock(), lock_clust_rec_read_check_and_lock(), lock_rec_enqueue_waiting(), lock_rec_lock_slow(), lock_rec_lock(), row_ins_set_shared_rec_lock(), row_ins_set_exclusive_rec_lock(), sel_set_rec_lock(), row_sel_get_clust_rec_for_mysql(): Return DB_SUCCESS_LOCKED_REC if a new record lock was created. Adjust callers. row_unlock_for_mysql(): Correct the function documentation. row_prebuilt_t::new_rec_locks: Correct the documentation.
This commit is contained in:
parent
8f5d78c28b
commit
a2b9532188
10 changed files with 308 additions and 211 deletions
|
|
@ -1121,9 +1121,9 @@ nonstandard_exit_func:
|
|||
/*********************************************************************//**
|
||||
Sets a shared lock on a record. Used in locking possible duplicate key
|
||||
records and also in checking foreign key constraints.
|
||||
@return DB_SUCCESS or error code */
|
||||
@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */
|
||||
static
|
||||
ulint
|
||||
enum db_err
|
||||
row_ins_set_shared_rec_lock(
|
||||
/*========================*/
|
||||
ulint type, /*!< in: LOCK_ORDINARY, LOCK_GAP, or
|
||||
|
|
@ -1134,7 +1134,7 @@ row_ins_set_shared_rec_lock(
|
|||
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
|
||||
que_thr_t* thr) /*!< in: query thread */
|
||||
{
|
||||
ulint err;
|
||||
enum db_err err;
|
||||
|
||||
ut_ad(rec_offs_validate(rec, index, offsets));
|
||||
|
||||
|
|
@ -1152,9 +1152,9 @@ row_ins_set_shared_rec_lock(
|
|||
/*********************************************************************//**
|
||||
Sets a exclusive lock on a record. Used in locking possible duplicate key
|
||||
records
|
||||
@return DB_SUCCESS or error code */
|
||||
@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */
|
||||
static
|
||||
ulint
|
||||
enum db_err
|
||||
row_ins_set_exclusive_rec_lock(
|
||||
/*===========================*/
|
||||
ulint type, /*!< in: LOCK_ORDINARY, LOCK_GAP, or
|
||||
|
|
@ -1165,7 +1165,7 @@ row_ins_set_exclusive_rec_lock(
|
|||
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
|
||||
que_thr_t* thr) /*!< in: query thread */
|
||||
{
|
||||
ulint err;
|
||||
enum db_err err;
|
||||
|
||||
ut_ad(rec_offs_validate(rec, index, offsets));
|
||||
|
||||
|
|
@ -1205,7 +1205,6 @@ row_ins_check_foreign_constraint(
|
|||
dict_index_t* check_index;
|
||||
ulint n_fields_cmp;
|
||||
btr_pcur_t pcur;
|
||||
ibool moved;
|
||||
int cmp;
|
||||
ulint err;
|
||||
ulint i;
|
||||
|
|
@ -1336,13 +1335,13 @@ run_again:
|
|||
|
||||
/* Scan index records and check if there is a matching record */
|
||||
|
||||
for (;;) {
|
||||
do {
|
||||
const rec_t* rec = btr_pcur_get_rec(&pcur);
|
||||
const buf_block_t* block = btr_pcur_get_block(&pcur);
|
||||
|
||||
if (page_rec_is_infimum(rec)) {
|
||||
|
||||
goto next_rec;
|
||||
continue;
|
||||
}
|
||||
|
||||
offsets = rec_get_offsets(rec, check_index,
|
||||
|
|
@ -1353,12 +1352,13 @@ run_again:
|
|||
err = row_ins_set_shared_rec_lock(LOCK_ORDINARY, block,
|
||||
rec, check_index,
|
||||
offsets, thr);
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
break;
|
||||
switch (err) {
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
case DB_SUCCESS:
|
||||
continue;
|
||||
default:
|
||||
goto end_scan;
|
||||
}
|
||||
|
||||
goto next_rec;
|
||||
}
|
||||
|
||||
cmp = cmp_dtuple_rec(entry, rec, offsets);
|
||||
|
|
@ -1369,9 +1369,12 @@ run_again:
|
|||
err = row_ins_set_shared_rec_lock(
|
||||
LOCK_ORDINARY, block,
|
||||
rec, check_index, offsets, thr);
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
switch (err) {
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
case DB_SUCCESS:
|
||||
break;
|
||||
default:
|
||||
goto end_scan;
|
||||
}
|
||||
} else {
|
||||
/* Found a matching record. Lock only
|
||||
|
|
@ -1382,15 +1385,18 @@ run_again:
|
|||
LOCK_REC_NOT_GAP, block,
|
||||
rec, check_index, offsets, thr);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
switch (err) {
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
case DB_SUCCESS:
|
||||
break;
|
||||
default:
|
||||
goto end_scan;
|
||||
}
|
||||
|
||||
if (check_ref) {
|
||||
err = DB_SUCCESS;
|
||||
|
||||
break;
|
||||
goto end_scan;
|
||||
} else if (foreign->type != 0) {
|
||||
/* There is an ON UPDATE or ON DELETE
|
||||
condition: check them in a separate
|
||||
|
|
@ -1416,7 +1422,7 @@ run_again:
|
|||
err = DB_FOREIGN_DUPLICATE_KEY;
|
||||
}
|
||||
|
||||
break;
|
||||
goto end_scan;
|
||||
}
|
||||
|
||||
/* row_ins_foreign_check_on_constraint
|
||||
|
|
@ -1429,49 +1435,41 @@ run_again:
|
|||
thr, foreign, rec, entry);
|
||||
|
||||
err = DB_ROW_IS_REFERENCED;
|
||||
break;
|
||||
goto end_scan;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ut_a(cmp < 0);
|
||||
|
||||
if (cmp < 0) {
|
||||
err = row_ins_set_shared_rec_lock(
|
||||
LOCK_GAP, block,
|
||||
rec, check_index, offsets, thr);
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
break;
|
||||
switch (err) {
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
case DB_SUCCESS:
|
||||
if (check_ref) {
|
||||
err = DB_NO_REFERENCED_ROW;
|
||||
row_ins_foreign_report_add_err(
|
||||
trx, foreign, rec, entry);
|
||||
} else {
|
||||
err = DB_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (check_ref) {
|
||||
err = DB_NO_REFERENCED_ROW;
|
||||
row_ins_foreign_report_add_err(
|
||||
trx, foreign, rec, entry);
|
||||
} else {
|
||||
err = DB_SUCCESS;
|
||||
}
|
||||
|
||||
break;
|
||||
goto end_scan;
|
||||
}
|
||||
} while (btr_pcur_move_to_next(&pcur, &mtr));
|
||||
|
||||
ut_a(cmp == 0);
|
||||
next_rec:
|
||||
moved = btr_pcur_move_to_next(&pcur, &mtr);
|
||||
|
||||
if (!moved) {
|
||||
if (check_ref) {
|
||||
rec = btr_pcur_get_rec(&pcur);
|
||||
row_ins_foreign_report_add_err(
|
||||
trx, foreign, rec, entry);
|
||||
err = DB_NO_REFERENCED_ROW;
|
||||
} else {
|
||||
err = DB_SUCCESS;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
if (check_ref) {
|
||||
row_ins_foreign_report_add_err(
|
||||
trx, foreign, btr_pcur_get_rec(&pcur), entry);
|
||||
err = DB_NO_REFERENCED_ROW;
|
||||
} else {
|
||||
err = DB_SUCCESS;
|
||||
}
|
||||
|
||||
end_scan:
|
||||
btr_pcur_close(&pcur);
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
|
@ -1719,9 +1717,13 @@ row_ins_scan_sec_index_for_duplicate(
|
|||
rec, index, offsets, thr);
|
||||
}
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
switch (err) {
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
err = DB_SUCCESS;
|
||||
case DB_SUCCESS:
|
||||
break;
|
||||
default:
|
||||
goto end_scan;
|
||||
}
|
||||
|
||||
if (page_rec_is_supremum(rec)) {
|
||||
|
|
@ -1738,17 +1740,15 @@ row_ins_scan_sec_index_for_duplicate(
|
|||
|
||||
thr_get_trx(thr)->error_info = index;
|
||||
|
||||
break;
|
||||
goto end_scan;
|
||||
}
|
||||
} else {
|
||||
ut_a(cmp < 0);
|
||||
goto end_scan;
|
||||
}
|
||||
|
||||
if (cmp < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
ut_a(cmp == 0);
|
||||
} while (btr_pcur_move_to_next(&pcur, &mtr));
|
||||
|
||||
end_scan:
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
|
|
@ -1837,7 +1837,11 @@ row_ins_duplicate_error_in_clust(
|
|||
cursor->index, offsets, thr);
|
||||
}
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
switch (err) {
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
case DB_SUCCESS:
|
||||
break;
|
||||
default:
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
|
|
@ -1877,7 +1881,11 @@ row_ins_duplicate_error_in_clust(
|
|||
rec, cursor->index, offsets, thr);
|
||||
}
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
switch (err) {
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
case DB_SUCCESS:
|
||||
break;
|
||||
default:
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue