btr0pcur.c:

  Fix bug: an index cursor can theoretically be restored in a wrong place
log0log.c:
  Fix bug: if combined log file size is >= 2 GB in a 32-bit computer InnoDB can write log to a wrong position
parent 9ecf9645
...@@ -292,6 +292,11 @@ btr_pcur_restore_position( ...@@ -292,6 +292,11 @@ btr_pcur_restore_position(
mem_heap_free(heap); mem_heap_free(heap);
/* We have to store position information, modify clock value, etc.
because the cursor may now be on a different page */
btr_pcur_store_position(cursor, mtr);
return(FALSE); return(FALSE);
} }
......
...@@ -437,25 +437,29 @@ log_group_calc_lsn_offset( ...@@ -437,25 +437,29 @@ log_group_calc_lsn_offset(
dulint lsn, /* in: lsn, must be within 4 GB of group->lsn */ dulint lsn, /* in: lsn, must be within 4 GB of group->lsn */
log_group_t* group) /* in: log group */ log_group_t* group) /* in: log group */
{ {
dulint gr_lsn; dulint gr_lsn;
ulint gr_lsn_size_offset; ib_longlong gr_lsn_size_offset;
ulint difference; ib_longlong difference;
ulint group_size; ib_longlong group_size;
ulint offset; ib_longlong offset;
ut_ad(mutex_own(&(log_sys->mutex))); ut_ad(mutex_own(&(log_sys->mutex)));
/* If total log file size is > 2 GB we can easily get overflows
with 32-bit integers. Use 64-bit integers instead. */
gr_lsn = group->lsn; gr_lsn = group->lsn;
gr_lsn_size_offset = log_group_calc_size_offset(group->lsn_offset, gr_lsn_size_offset = (ib_longlong)
group); log_group_calc_size_offset(group->lsn_offset, group);
group_size = log_group_get_capacity(group);
group_size = (ib_longlong) log_group_get_capacity(group);
if (ut_dulint_cmp(lsn, gr_lsn) >= 0) { if (ut_dulint_cmp(lsn, gr_lsn) >= 0) {
difference = ut_dulint_minus(lsn, gr_lsn); difference = (ib_longlong) ut_dulint_minus(lsn, gr_lsn);
} else { } else {
difference = ut_dulint_minus(gr_lsn, lsn); difference = (ib_longlong) ut_dulint_minus(gr_lsn, lsn);
difference = difference % group_size; difference = difference % group_size;
...@@ -464,7 +468,13 @@ log_group_calc_lsn_offset( ...@@ -464,7 +468,13 @@ log_group_calc_lsn_offset(
offset = (gr_lsn_size_offset + difference) % group_size; offset = (gr_lsn_size_offset + difference) % group_size;
return(log_group_calc_real_offset(offset, group)); ut_a(offset <= 0xFFFFFFFF);
/* printf("Offset is %lu gr_lsn_offset is %lu difference is %lu\n",
(ulint)offset,(ulint)gr_lsn_size_offset, (ulint)difference);
*/
return(log_group_calc_real_offset((ulint)offset, group));
} }
/*********************************************************************** /***********************************************************************
......
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