Commit a7316cba authored by inaam's avatar inaam

branches/innodb+: Merge revisions 6448:6504 from branches/zip:

  ------------------------------------------------------------------------
  r6449 | marko | 2010-01-13 15:38:53 -0500 (Wed, 13 Jan 2010) | 18 lines
  
  branches/zip: lock_rec_validate_page(): Only validate the record
  queues when the thread is not holding a space->latch.
  
  When UNIV_DEBUG is defined while UNIV_SYNC_DEBUG is not,
  latching order violations will still occur and deadlocks will be possible.
  
  sync_thread_levels_nonempty_gen(): Renamed from
  sync_thread_levels_empty_gen().  Return the violating latch or NULL
  instead of FALSE or TRUE, except that there will be a ut_error before
  the non-NULL return.
  
  sync_thread_levels_empty_gen(): A macro that negates the return value of
  sync_thread_levels_nonempty_gen().
  
  sync_thread_levels_contains(): New function, based on
  sync_thread_levels_nonempty_gen().
  
  This should fix Issue #441.
  ------------------------------------------------------------------------
  r6463 | marko | 2010-01-14 08:43:37 -0500 (Thu, 14 Jan 2010) | 5 lines
  
  branches/zip: page_copy_rec_list_end(), page_copy_rec_list_start():
  Update PAGE_MAX_TRX_ID before attempting to compress the page.  This
  fixes Issue #382 (a debug assertion failure in page_zip_reorganize())
  and reduces the generated redo log.  There was no bug or crash in
  non-debug builds.
  ------------------------------------------------------------------------
  r6467 | inaam | 2010-01-14 13:46:00 -0500 (Thu, 14 Jan 2010) | 10 lines
  
  branches/zip rb://226
  
  log_sys->written_to_all_lsn does not accurately represent the LSN
  upto which write and flush has taken place. Under a race condition
  it can fall behind log_sys->flushed_to_disk_lsn which is accurate.
  Besides written_to_all_lsn is redundant as currently InnoDB supports
  only one log group.
  
  Approved by: Heikki
  
  ------------------------------------------------------------------------
  r6472 | calvin | 2010-01-15 18:53:47 -0500 (Fri, 15 Jan 2010) | 12 lines
  
  branches/zip: Merge revisions 6425:6471 from branches/5.1
  to pick up the first part fix of bug49396.
  
      ------------------------------------------------------------------------
      r6471 | calvin | 2010-01-15 17:43:27 -0600 (Fri, 15 Jan 2010) | 4 lines
  
      branches/5.1: fix bug#49396: main.innodb test fails in embedded mode
  
      Change replace_result by using $MYSQLD_DATADIR. Tested in both embedded
      mode and normal server mode.
      ------------------------------------------------------------------------
  
  ------------------------------------------------------------------------
  r6473 | calvin | 2010-01-15 18:58:16 -0500 (Fri, 15 Jan 2010) | 6 lines
  
  branches/zip: fix bug#49396: innodb.innodb-index test fails in
  embedded mode
  
  This is 2nd part of the fix for bug#49396. The 1st part is
  innodb.test. Tested in both embedded mode and normal server mode.
  
  ------------------------------------------------------------------------
  r6498 | marko | 2010-01-21 04:22:52 -0500 (Thu, 21 Jan 2010) | 15 lines
  
  branches/zip: buf_page_get_gen(): Obey recv_no_ibuf_operations
  and do not call ibuf_merge_or_delete_for_page() in crash recovery,
  before the redo log has been applied.
  This could cure some hard-to-repeat, hard-to-explain bugs
  related to secondary indexes.
  
  A possible recipe to repeat the bug:
  
  1. update a secondary index leaf page on a compressed table
  2. evict the page from the buffer pool while it is still dirty
  3. ibuf_insert() something for the page
  4. crash
  5. crash recovery; ibuf merge would be done too early,
  before applying redo log to the sec index page or the ibuf pages
  
  ------------------------------------------------------------------------
parent c8201405
2010-01-21 The InnoDB Team
* buf/buf0buf.c:
Do not merge buffered inserts to compressed pages before
the redo log has been applied in crash recovery.
2010-01-13 The InnoDB Team
* row/row0sel.c:
......
......@@ -2311,7 +2311,7 @@ buf_page_get_gen(
while not holding buf_pool_mutex or block->mutex. */
success = buf_zip_decompress(block, srv_use_checksums);
if (UNIV_LIKELY(success)) {
if (UNIV_LIKELY(success && !recv_no_ibuf_operations)) {
ibuf_merge_or_delete_for_page(block, space, offset,
zip_size, TRUE);
}
......
......@@ -825,7 +825,17 @@ struct log_struct{
written to some log group; for this to
be advanced, it is enough that the
write i/o has been completed for all
log groups */
log groups.
Note that since InnoDB currently
has only one log group therefore
this value is redundant. Also it
is possible that this value
falls behind the
flushed_to_disk_lsn transiently.
It is appropriate to use either
flushed_to_disk_lsn or
write_lsn which are always
up-to-date and accurate. */
ib_uint64_t write_lsn; /*!< end lsn for the current running
write */
ulint write_end_offset;/*!< the data in buffer has
......
......@@ -238,16 +238,27 @@ ibool
sync_thread_levels_empty(void);
/*==========================*/
/******************************************************************//**
Checks that the level array for the current thread is empty.
@return TRUE if empty except the exceptions specified below */
Checks if the level array for the current thread contains a
mutex or rw-latch at the specified level.
@return a matching latch, or NULL if not found */
UNIV_INTERN
ibool
sync_thread_levels_empty_gen(
/*=========================*/
void*
sync_thread_levels_contains(
/*========================*/
ulint level); /*!< in: latching order level
(SYNC_DICT, ...)*/
/******************************************************************//**
Checks if the level array for the current thread is empty.
@return a latch, or NULL if empty except the exceptions specified below */
UNIV_INTERN
void*
sync_thread_levels_nonempty_gen(
/*============================*/
ibool dict_mutex_allowed); /*!< in: TRUE if dictionary mutex is
allowed to be owned by the thread,
also purge_is_running mutex is
allowed */
#define sync_thread_levels_empty_gen(d) (!sync_thread_levels_nonempty_gen(d))
/******************************************************************//**
Gets the debug information for a reserved mutex. */
UNIV_INTERN
......
......@@ -4766,6 +4766,13 @@ lock_rec_validate_page(
|| lock->trx->conc_state == TRX_PREPARED
|| lock->trx->conc_state == TRX_COMMITTED_IN_MEMORY);
# ifdef UNIV_SYNC_DEBUG
/* Only validate the record queues when this thread is not
holding a space->latch. Deadlocks are possible due to
latching order violation when UNIV_DEBUG is defined while
UNIV_SYNC_DEBUG is not. */
if (!sync_thread_levels_contains(SYNC_FSP))
# endif /* UNIV_SYNC_DEBUG */
for (i = nth_bit; i < lock_rec_get_n_bits(lock); i++) {
if (i == 1 || lock_rec_get_nth_bit(lock, i)) {
......
......@@ -2013,7 +2013,7 @@ log_checkpoint(
return(TRUE);
}
ut_ad(log_sys->written_to_all_lsn >= oldest_lsn);
ut_ad(log_sys->flushed_to_disk_lsn >= oldest_lsn);
if (log_sys->n_pending_checkpoint_writes > 0) {
/* A checkpoint write is running */
......
-- source include/have_innodb.inc
let $MYSQLD_DATADIR= `select @@datadir`;
let $innodb_file_format_check_orig=`select @@innodb_file_format_check`;
create table t1(a int not null, b int, c char(10) not null, d varchar(20)) engine = innodb;
......@@ -136,7 +138,9 @@ delete from t1;
--error ER_CANT_DROP_FIELD_OR_KEY
drop index dc on t4;
# there is no foreign key dc on t3
--replace_regex /'\.\/test\/#sql2-[0-9a-f-]*'/'#sql2-temporary'/
--replace_regex /'[^']*test\/#sql2-[0-9a-f-]*'/'#sql2-temporary'/
# Embedded server doesn't chdir to data directory
--replace_result $MYSQLD_DATADIR ./ master-data/ ''
--error ER_ERROR_ON_RENAME
alter table t3 drop foreign key dc;
alter table t4 drop foreign key dc;
......
......@@ -15,6 +15,8 @@
-- source include/have_innodb.inc
let $MYSQLD_DATADIR= `select @@datadir`;
# Save the original values of some variables in order to be able to
# estimate how much they have changed during the tests. Previously this
# test assumed that e.g. rows_deleted is 0 here and after deleting 23
......@@ -1700,7 +1702,7 @@ set foreign_key_checks=0;
create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8;
# Embedded server doesn't chdir to data directory
--replace_result $MYSQLTEST_VARDIR . master-data/ ''
--replace_result $MYSQLD_DATADIR ./ master-data/ ''
-- error 1025
rename table t3 to t1;
set foreign_key_checks=1;
......@@ -2340,7 +2342,7 @@ ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1 (a) ON DELETE SET NULL;
# mysqltest first does replace_regex, then replace_result
--replace_regex /'[^']*test\/#sql-[0-9a-f_]*'/'#sql-temporary'/
# Embedded server doesn't chdir to data directory
--replace_result $MYSQLTEST_VARDIR . master-data/ ''
--replace_result $MYSQLD_DATADIR ./ master-data/ ''
--error 1025
ALTER TABLE t2 MODIFY a INT NOT NULL;
DELETE FROM t1;
......
......@@ -658,6 +658,14 @@ page_copy_rec_list_end(
index, mtr);
}
/* Update PAGE_MAX_TRX_ID on the uncompressed page.
Modifications will be redo logged and copied to the compressed
page in page_zip_compress() or page_zip_reorganize() below. */
if (dict_index_is_sec_or_ibuf(index) && page_is_leaf(page)) {
page_update_max_trx_id(new_block, NULL,
page_get_max_trx_id(page), mtr);
}
if (UNIV_LIKELY_NULL(new_page_zip)) {
mtr_set_log_mode(mtr, log_mode);
......@@ -696,15 +704,10 @@ page_copy_rec_list_end(
}
}
/* Update the lock table, MAX_TRX_ID, and possible hash index */
/* Update the lock table and possible hash index */
lock_move_rec_list_end(new_block, block, rec);
if (dict_index_is_sec_or_ibuf(index) && page_is_leaf(page)) {
page_update_max_trx_id(new_block, new_page_zip,
page_get_max_trx_id(page), mtr);
}
btr_search_move_or_delete_hash_entries(new_block, block, index);
return(ret);
......@@ -772,6 +775,16 @@ page_copy_rec_list_start(
mem_heap_free(heap);
}
/* Update PAGE_MAX_TRX_ID on the uncompressed page.
Modifications will be redo logged and copied to the compressed
page in page_zip_compress() or page_zip_reorganize() below. */
if (dict_index_is_sec_or_ibuf(index)
&& page_is_leaf(page_align(rec))) {
page_update_max_trx_id(new_block, NULL,
page_get_max_trx_id(page_align(rec)),
mtr);
}
if (UNIV_LIKELY_NULL(new_page_zip)) {
mtr_set_log_mode(mtr, log_mode);
......@@ -809,14 +822,7 @@ page_copy_rec_list_start(
}
}
/* Update MAX_TRX_ID, the lock table, and possible hash index */
if (dict_index_is_sec_or_ibuf(index)
&& page_is_leaf(page_align(rec))) {
page_update_max_trx_id(new_block, new_page_zip,
page_get_max_trx_id(page_align(rec)),
mtr);
}
/* Update the lock table and possible hash index */
lock_move_rec_list_start(new_block, block, rec, ret);
......
......@@ -957,13 +957,63 @@ sync_thread_levels_contain(
return(FALSE);
}
/******************************************************************//**
Checks if the level array for the current thread contains a
mutex or rw-latch at the specified level.
@return a matching latch, or NULL if not found */
UNIV_INTERN
void*
sync_thread_levels_contains(
/*========================*/
ulint level) /*!< in: latching order level
(SYNC_DICT, ...)*/
{
sync_level_t* arr;
sync_thread_t* thread_slot;
sync_level_t* slot;
ulint i;
if (!sync_order_checks_on) {
return(NULL);
}
mutex_enter(&sync_thread_mutex);
thread_slot = sync_thread_level_arrays_find_slot();
if (thread_slot == NULL) {
mutex_exit(&sync_thread_mutex);
return(NULL);
}
arr = thread_slot->levels;
for (i = 0; i < SYNC_THREAD_N_LEVELS; i++) {
slot = sync_thread_levels_get_nth(arr, i);
if (slot->latch != NULL && slot->level == level) {
mutex_exit(&sync_thread_mutex);
return(slot->latch);
}
}
mutex_exit(&sync_thread_mutex);
return(NULL);
}
/******************************************************************//**
Checks that the level array for the current thread is empty.
@return TRUE if empty except the exceptions specified below */
@return a latch, or NULL if empty except the exceptions specified below */
UNIV_INTERN
ibool
sync_thread_levels_empty_gen(
/*=========================*/
void*
sync_thread_levels_nonempty_gen(
/*============================*/
ibool dict_mutex_allowed) /*!< in: TRUE if dictionary mutex is
allowed to be owned by the thread,
also purge_is_running mutex is
......@@ -976,7 +1026,7 @@ sync_thread_levels_empty_gen(
if (!sync_order_checks_on) {
return(TRUE);
return(NULL);
}
mutex_enter(&sync_thread_mutex);
......@@ -987,7 +1037,7 @@ sync_thread_levels_empty_gen(
mutex_exit(&sync_thread_mutex);
return(TRUE);
return(NULL);
}
arr = thread_slot->levels;
......@@ -1004,13 +1054,13 @@ sync_thread_levels_empty_gen(
mutex_exit(&sync_thread_mutex);
ut_error;
return(FALSE);
return(slot->latch);
}
}
mutex_exit(&sync_thread_mutex);
return(TRUE);
return(NULL);
}
/******************************************************************//**
......
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