Commit 19798cf7 authored by unknown's avatar unknown

InnoDB: Reduce the stack space consumption of ON UPDATE CASCADE

operations.


innobase/include/lock0lock.h:
  Added lock_clust_rec_read_check_and_lock_alt(),
  a variant of lock_clust_rec_read_check_and_lock()
  without the parameter "offsets".
innobase/lock/lock0lock.c:
  Added lock_clust_rec_read_check_and_lock_alt(),
  a variant of lock_clust_rec_read_check_and_lock()
  without the parameter "offsets".
innobase/row/row0ins.c:
  row_ins_foreign_check_on_constraint(): Do not allocate offsets
  from stack. This reduces the stack space consumption of
  ON UPDATE CASCADE operations by 400 bytes per cascaded UPDATE
  operation.
parent d4aed64f
...@@ -345,6 +345,33 @@ lock_clust_rec_read_check_and_lock( ...@@ -345,6 +345,33 @@ lock_clust_rec_read_check_and_lock(
LOCK_REC_NOT_GAP */ LOCK_REC_NOT_GAP */
que_thr_t* thr); /* in: query thread */ que_thr_t* thr); /* in: query thread */
/************************************************************************* /*************************************************************************
Checks if locks of other transactions prevent an immediate read, or passing
over by a read cursor, of a clustered index record. If they do, first tests
if the query thread should anyway be suspended for some reason; if not, then
puts the transaction and the query thread to the lock wait state and inserts a
waiting request for a record lock to the lock queue. Sets the requested mode
lock on the record. This is an alternative version of
lock_clust_rec_read_check_and_lock() that does not require the parameter
"offsets". */
ulint
lock_clust_rec_read_check_and_lock_alt(
/*===================================*/
/* out: DB_SUCCESS, DB_LOCK_WAIT,
DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set,
does nothing */
rec_t* rec, /* in: user record or page supremum record
which should be read or passed over by a read
cursor */
dict_index_t* index, /* in: clustered index */
ulint mode, /* in: mode of the lock which the read cursor
should set on records: LOCK_S or LOCK_X; the
latter is possible in SELECT FOR UPDATE */
ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or
LOCK_REC_NOT_GAP */
que_thr_t* thr); /* in: query thread */
/*************************************************************************
Checks that a record is seen in a consistent read. */ Checks that a record is seen in a consistent read. */
ibool ibool
......
...@@ -5105,3 +5105,45 @@ lock_clust_rec_read_check_and_lock( ...@@ -5105,3 +5105,45 @@ lock_clust_rec_read_check_and_lock(
return(err); return(err);
} }
/*************************************************************************
Checks if locks of other transactions prevent an immediate read, or passing
over by a read cursor, of a clustered index record. If they do, first tests
if the query thread should anyway be suspended for some reason; if not, then
puts the transaction and the query thread to the lock wait state and inserts a
waiting request for a record lock to the lock queue. Sets the requested mode
lock on the record. This is an alternative version of
lock_clust_rec_read_check_and_lock() that does not require the parameter
"offsets". */
ulint
lock_clust_rec_read_check_and_lock_alt(
/*===================================*/
/* out: DB_SUCCESS, DB_LOCK_WAIT,
DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set,
does nothing */
rec_t* rec, /* in: user record or page supremum record
which should be read or passed over by a read
cursor */
dict_index_t* index, /* in: clustered index */
ulint mode, /* in: mode of the lock which the read cursor
should set on records: LOCK_S or LOCK_X; the
latter is possible in SELECT FOR UPDATE */
ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or
LOCK_REC_NOT_GAP */
que_thr_t* thr) /* in: query thread */
{
mem_heap_t* tmp_heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ulint ret;
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &tmp_heap);
ret = lock_clust_rec_read_check_and_lock(flags, rec, index,
offsets, mode, gap_mode, thr);
if (tmp_heap) {
mem_heap_free(tmp_heap);
}
return(ret);
}
...@@ -717,8 +717,6 @@ row_ins_foreign_check_on_constraint( ...@@ -717,8 +717,6 @@ row_ins_foreign_check_on_constraint(
ulint i; ulint i;
trx_t* trx; trx_t* trx;
mem_heap_t* tmp_heap = NULL; mem_heap_t* tmp_heap = NULL;
ulint offsets_[100] = { 100, };
ulint* offsets = offsets_;
ut_a(thr && foreign && pcur && mtr); ut_a(thr && foreign && pcur && mtr);
...@@ -886,10 +884,8 @@ row_ins_foreign_check_on_constraint( ...@@ -886,10 +884,8 @@ row_ins_foreign_check_on_constraint(
we already have a normal shared lock on the appropriate we already have a normal shared lock on the appropriate
gap if the search criterion was not unique */ gap if the search criterion was not unique */
offsets = rec_get_offsets(clust_rec, clust_index, offsets, err = lock_clust_rec_read_check_and_lock_alt(0, clust_rec,
ULINT_UNDEFINED, &tmp_heap); clust_index, LOCK_X, LOCK_REC_NOT_GAP, thr);
err = lock_clust_rec_read_check_and_lock(0, clust_rec,
clust_index, offsets, LOCK_X, LOCK_REC_NOT_GAP, thr);
} }
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment