diff options
author | unknown <heikki@hundin.mysql.fi> | 2003-07-03 21:25:55 +0300 |
---|---|---|
committer | unknown <heikki@hundin.mysql.fi> | 2003-07-03 21:25:55 +0300 |
commit | 5dc1e4b98ac6223b9854f26fd689d7e68897e3c9 (patch) | |
tree | 4bae1e813c986da0cdde9b78f41247a806c985d0 | |
parent | db5283b30667c9d427228069314f53d38c4ef8f1 (diff) | |
download | mariadb-git-5dc1e4b98ac6223b9854f26fd689d7e68897e3c9.tar.gz |
Many files:
Remove potential starvation of a full log buffer flush: only flush up to the lsn which was the largest at the time when we requested the full log buffer flush
os0sync.h, os0sync.c:
Fix a bug in os_event on Unix: even though we signaled the event, some threads could continue waiting if the event became nonsignaled quickly again; this made group commit less efficient than it should be
innobase/os/os0sync.c:
Fix a bug in os_event on Unix: even though we signaled the event, some threads could continue waiting if the event became nonsignaled quickly again; this made group commit less efficient than it should be
innobase/include/os0sync.h:
Fix a bug in os_event on Unix: even though we signaled the event, some threads could continue waiting if the event became nonsignaled quickly again; this made group commit less efficient than it should be
innobase/log/log0log.c:
Remove potential starvation of a full log buffer flush: only flush up to the lsn which was the largest at the time when we requested the full log buffer flush
innobase/include/log0log.h:
Remove potential starvation of a full log buffer flush: only flush up to the lsn which was the largest at the time when we requested the full log buffer flush
innobase/srv/srv0srv.c:
Remove potential starvation of a full log buffer flush: only flush up to the lsn which was the largest at the time when we requested the full log buffer flush
innobase/row/row0mysql.c:
Remove potential starvation of a full log buffer flush: only flush up to the lsn which was the largest at the time when we requested the full log buffer flush
innobase/trx/trx0trx.c:
Remove potential starvation of a full log buffer flush: only flush up to the lsn which was the largest at the time when we requested the full log buffer flush
sql/ha_innodb.cc:
Remove potential starvation of a full log buffer flush: only flush up to the lsn which was the largest at the time when we requested the full log buffer flush
innobase/btr/btr0btr.c:
Remove potential starvation of a full log buffer flush: only flush up to the lsn which was the largest at the time when we requested the full log buffer flush
-rw-r--r-- | innobase/btr/btr0btr.c | 29 | ||||
-rw-r--r-- | innobase/include/log0log.h | 6 | ||||
-rw-r--r-- | innobase/include/os0sync.h | 8 | ||||
-rw-r--r-- | innobase/log/log0log.c | 25 | ||||
-rw-r--r-- | innobase/os/os0sync.c | 15 | ||||
-rw-r--r-- | innobase/row/row0mysql.c | 2 | ||||
-rw-r--r-- | innobase/srv/srv0srv.c | 20 | ||||
-rw-r--r-- | innobase/trx/trx0trx.c | 4 | ||||
-rw-r--r-- | sql/ha_innodb.cc | 10 |
9 files changed, 97 insertions, 22 deletions
diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c index 51c164b7cef..d8a0959e47f 100644 --- a/innobase/btr/btr0btr.c +++ b/innobase/btr/btr0btr.c @@ -822,9 +822,16 @@ btr_page_reorganize_low( { page_t* new_page; ulint log_mode; + ulint data_size1; + ulint data_size2; + ulint max_ins_size1; + ulint max_ins_size2; ut_ad(mtr_memo_contains(mtr, buf_block_align(page), MTR_MEMO_PAGE_X_FIX)); + data_size1 = page_get_data_size(page); + max_ins_size1 = page_get_max_insert_size_after_reorganize(page, 1); + /* Write the log record */ mlog_write_initial_log_record(page, MLOG_PAGE_REORGANIZE, mtr); @@ -859,6 +866,19 @@ btr_page_reorganize_low( lock_move_reorganize_page(page, new_page); } + data_size2 = page_get_data_size(page); + max_ins_size2 = page_get_max_insert_size_after_reorganize(page, 1); + + if (data_size1 != data_size2 || max_ins_size1 != max_ins_size2) { + buf_page_print(page); + buf_page_print(new_page); + fprintf(stderr, +"InnoDB: Error: page old data size %lu new data size %lu\n" +"InnoDB: Error: page old max ins size %lu new max ins size %lu\n" +"InnoDB: Make a detailed bug report and send it to mysql@lists.mysql.com\n", + data_size1, data_size2, max_ins_size1, max_ins_size2); + } + buf_frame_free(new_page); /* Restore logging mode */ @@ -1945,11 +1965,20 @@ btr_compress( btr_page_reorganize(merge_page, mtr); + max_ins_size = page_get_max_insert_size(merge_page, n_recs); + ut_ad(page_validate(merge_page, cursor->index)); ut_ad(page_get_max_insert_size(merge_page, n_recs) == max_ins_size_reorg); } + if (data_size > max_ins_size) { + + /* Add fault tolerance, though this should never happen */ + + return; + } + btr_search_drop_page_hash_index(page); /* Remove the page from the level list */ diff --git a/innobase/include/log0log.h b/innobase/include/log0log.h index 4e1404b15fe..e79e914e4f6 100644 --- a/innobase/include/log0log.h +++ b/innobase/include/log0log.h @@ -173,6 +173,12 @@ log_write_up_to( /* in: TRUE if we want the written log also to be flushed to disk */ /******************************************************************** +Does a syncronous flush of the log buffer to disk. */ + +void +log_buffer_flush_to_disk(void); +/*==========================*/ +/******************************************************************** Advances the smallest lsn for which there are unflushed dirty blocks in the buffer pool and also may make a new checkpoint. NOTE: this function may only be called if the calling thread owns no synchronization objects! */ diff --git a/innobase/include/os0sync.h b/innobase/include/os0sync.h index 634507467f9..e1cf263216e 100644 --- a/innobase/include/os0sync.h +++ b/innobase/include/os0sync.h @@ -36,8 +36,12 @@ typedef os_event_struct_t* os_event_t; struct os_event_struct { os_fast_mutex_t os_mutex; /* this mutex protects the next fields */ - ibool is_set; /* this is TRUE if the next mutex is - not reserved */ + ibool is_set; /* this is TRUE when the event is + in the signaled state, i.e., a thread + does not stop if it tries to wait for + this event */ + ib_longlong signal_count; /* this is incremented each time + the event becomes signaled */ pthread_cond_t cond_var; /* condition variable is used in waiting for the event */ UT_LIST_NODE_T(os_event_struct_t) os_event_list; diff --git a/innobase/log/log0log.c b/innobase/log/log0log.c index b5ce1a3d97b..53ca97baaa0 100644 --- a/innobase/log/log0log.c +++ b/innobase/log/log0log.c @@ -178,7 +178,8 @@ loop: /* Not enough free space, do a syncronous flush of the log buffer */ - log_write_up_to(ut_dulint_max, LOG_WAIT_ALL_GROUPS, TRUE); + + log_buffer_flush_to_disk(); count++; @@ -1365,6 +1366,24 @@ do_waits: } /******************************************************************** +Does a syncronous flush of the log buffer to disk. */ + +void +log_buffer_flush_to_disk(void) +/*==========================*/ +{ + dulint lsn; + + mutex_enter(&(log_sys->mutex)); + + lsn = log_sys->lsn; + + mutex_exit(&(log_sys->mutex)); + + log_write_up_to(lsn, LOG_WAIT_ALL_GROUPS, TRUE); +} + +/******************************************************************** Tries to establish a big enough margin of free space in the log buffer, such that a new log entry can be catenated without an immediate need for a flush. */ static @@ -1374,6 +1393,7 @@ log_flush_margin(void) { ibool do_flush = FALSE; log_t* log = log_sys; + dulint lsn; mutex_enter(&(log->mutex)); @@ -1384,13 +1404,14 @@ log_flush_margin(void) free space */ } else { do_flush = TRUE; + lsn = log->lsn; } } mutex_exit(&(log->mutex)); if (do_flush) { - log_write_up_to(ut_dulint_max, LOG_NO_WAIT, FALSE); + log_write_up_to(lsn, LOG_NO_WAIT, FALSE); } } diff --git a/innobase/os/os0sync.c b/innobase/os/os0sync.c index bf5fc57bf57..827d68501db 100644 --- a/innobase/os/os0sync.c +++ b/innobase/os/os0sync.c @@ -143,6 +143,7 @@ os_event_create( ut_a(0 == pthread_cond_init(&(event->cond_var), NULL)); #endif event->is_set = FALSE; + event->signal_count = 0; #endif /* __WIN__ */ /* Put to the list of events */ @@ -218,6 +219,7 @@ os_event_set( /* Do nothing */ } else { event->is_set = TRUE; + event->signal_count += 1; ut_a(0 == pthread_cond_broadcast(&(event->cond_var))); } @@ -310,9 +312,15 @@ os_event_wait( os_thread_exit(NULL); } #else + ib_longlong old_signal_count; + os_fast_mutex_lock(&(event->os_mutex)); + + old_signal_count = event->signal_count; loop: - if (event->is_set == TRUE) { + if (event->is_set == TRUE + || event->signal_count != old_signal_count) { + os_fast_mutex_unlock(&(event->os_mutex)); if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) { @@ -326,8 +334,9 @@ loop: pthread_cond_wait(&(event->cond_var), &(event->os_mutex)); - /* Solaris manual said that spurious wakeups may occur: we have - to check the 'is_set' variable again */ + /* Solaris manual said that spurious wakeups may occur: we have to + check if the event really has been signaled after we came here to + wait */ goto loop; #endif diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index dc2a50c4f0c..af73c2f62c3 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -1655,7 +1655,7 @@ row_drop_table_for_mysql_in_background( the InnoDB data dictionary get out-of-sync if the user runs with innodb_flush_log_at_trx_commit = 0 */ - log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, TRUE); + log_buffer_flush_to_disk(); trx_commit_for_mysql(trx); diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index d13d499dd17..083cbfd2609 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -2836,7 +2836,7 @@ loop: at transaction commit */ srv_main_thread_op_info = (char*)"flushing log"; - log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, TRUE); + log_buffer_flush_to_disk(); /* If there were less than 5 i/os during the one second sleep, we assume that there is free @@ -2852,10 +2852,9 @@ loop: (char*)"doing insert buffer merge"; ibuf_contract_for_n_pages(TRUE, 5); - srv_main_thread_op_info = - (char*)"flushing log"; - log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, - TRUE); + srv_main_thread_op_info = (char*)"flushing log"; + + log_buffer_flush_to_disk(); } if (buf_get_modified_ratio_pct() > @@ -2905,7 +2904,7 @@ loop: buf_flush_batch(BUF_FLUSH_LIST, 100, ut_dulint_max); srv_main_thread_op_info = (char*) "flushing log"; - log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, TRUE); + log_buffer_flush_to_disk(); } /* We run a batch of insert buffer merge every 10 seconds, @@ -2915,7 +2914,7 @@ loop: ibuf_contract_for_n_pages(TRUE, 5); srv_main_thread_op_info = (char*)"flushing log"; - log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, TRUE); + log_buffer_flush_to_disk(); /* We run a full purge every 10 seconds, even if the server were active */ @@ -2939,8 +2938,7 @@ loop: if (difftime(current_time, last_flush_time) > 1) { srv_main_thread_op_info = (char*) "flushing log"; - log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, - TRUE); + log_buffer_flush_to_disk(); last_flush_time = current_time; } } @@ -3060,6 +3058,10 @@ flush_loop: (char*) "waiting for buffer pool flush to end"; buf_flush_wait_batch_end(BUF_FLUSH_LIST); + srv_main_thread_op_info = (char*) "flushing log"; + + log_buffer_flush_to_disk(); + srv_main_thread_op_info = (char*)"making checkpoint"; log_checkpoint(TRUE, FALSE); diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c index 095a9df9082..0dead50264b 100644 --- a/innobase/trx/trx0trx.c +++ b/innobase/trx/trx0trx.c @@ -1524,6 +1524,8 @@ trx_commit_complete_for_mysql( dulint lsn = trx->commit_lsn; ut_a(trx); + + trx->op_info = (char*)"flushing log"; if (srv_flush_log_at_trx_commit == 0) { /* Do nothing */ @@ -1547,6 +1549,8 @@ trx_commit_complete_for_mysql( ut_a(0); } + trx->op_info = (char*)""; + return(0); } diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 2cc64b18706..8edec984962 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -915,7 +915,7 @@ innobase_flush_logs(void) DBUG_ENTER("innobase_flush_logs"); - log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, TRUE); + log_buffer_flush_to_disk(); DBUG_RETURN(result); } @@ -3538,7 +3538,7 @@ ha_innobase::create( the InnoDB data dictionary get out-of-sync if the user runs with innodb_flush_log_at_trx_commit = 0 */ - log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, TRUE); + log_buffer_flush_to_disk(); innobase_table = dict_table_get(norm_name, NULL); @@ -3613,7 +3613,7 @@ ha_innobase::delete_table( the InnoDB data dictionary get out-of-sync if the user runs with innodb_flush_log_at_trx_commit = 0 */ - log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, TRUE); + log_buffer_flush_to_disk(); /* Tell the InnoDB server that there might be work for utility threads: */ @@ -3683,7 +3683,7 @@ innobase_drop_database( the InnoDB data dictionary get out-of-sync if the user runs with innodb_flush_log_at_trx_commit = 0 */ - log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, TRUE); + log_buffer_flush_to_disk(); /* Tell the InnoDB server that there might be work for utility threads: */ @@ -3755,7 +3755,7 @@ ha_innobase::rename_table( the InnoDB data dictionary get out-of-sync if the user runs with innodb_flush_log_at_trx_commit = 0 */ - log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, TRUE); + log_buffer_flush_to_disk(); /* Tell the InnoDB server that there might be work for utility threads: */ |