Index: ut/ut0ut.c =================================================================== --- ut/ut0ut.c (revision 1847) +++ ut/ut0ut.c (working copy) @@ -125,12 +125,37 @@ ut_usectime( ut_gettimeofday(&tv, NULL); *sec = (ulint) tv.tv_sec; *ms = (ulint) tv.tv_usec; } /************************************************************** +Returns the number of microseconds since epoch. Similar to +time(3), the return value is also stored in *tloc, provided +that tloc is non-NULL. */ + +ullint +ut_time_us( +/*=======*/ + /* out: us since epoch */ + ullint* tloc) /* out: us since epoch, if non-NULL */ +{ + struct timeval tv; + ullint us; + + ut_gettimeofday(&tv, NULL); + + us = (ullint) tv.tv_sec * 1000000 + tv.tv_usec; + + if (tloc != NULL) { + *tloc = us; + } + + return(us); +} + +/************************************************************** Returns the difference of two times in seconds. */ double ut_difftime( /*========*/ /* out: time2 - time1 expressed in seconds */ Index: srv/srv0srv.c =================================================================== --- srv/srv0srv.c (revision 1847) +++ srv/srv0srv.c (working copy) @@ -25,12 +25,13 @@ thread library. This might confuse NT th Created 10/8/1995 Heikki Tuuri *******************************************************/ /* Dummy comment */ #include "srv0srv.h" #include "ut0mem.h" +#include "ut0ut.h" #include "os0proc.h" #include "mem0mem.h" #include "mem0pool.h" #include "sync0sync.h" #include "thr0loc.h" #include "que0que.h" @@ -338,12 +339,14 @@ int srv_query_thread_priority = 0; /* TRUE if the Address Windowing Extensions of Windows are used; then we must disable adaptive hash indexes */ ibool srv_use_awe = FALSE; ibool srv_use_adaptive_hash_indexes = TRUE; +ulint srv_replication_delay = 0; + /*-------------------------------------------*/ ulong srv_n_spin_wait_rounds = 20; ulong srv_n_free_tickets_to_enter = 500; ulong srv_thread_sleep_delay = 10000; ulint srv_spin_wait_delay = 5; ibool srv_priority_boost = TRUE; @@ -988,17 +991,16 @@ srv_conc_enter_innodb( srv_conc_slot_t* slot = NULL; ulint i; if (trx->mysql_thd != NULL && thd_is_replication_slave_thread(trx->mysql_thd)) { - /* TODO Do something more interesting (based on a config - parameter). Some users what to give the replication - thread very low priority, see http://bugs.mysql.com/25078 - This can be done by introducing - innodb_replication_delay(ms) config parameter */ + UT_WAIT_FOR(srv_conc_n_threads + < (lint)srv_thread_concurrency, + srv_replication_delay * 1000); + return; } /* If trx has 'free tickets' to enter the engine left, then use one such ticket */ Index: handler/ha_innodb.cc =================================================================== --- handler/ha_innodb.cc (revision 1847) +++ handler/ha_innodb.cc (working copy) @@ -7959,12 +7959,18 @@ static MYSQL_SYSVAR_BOOL(stats_on_metada static MYSQL_SYSVAR_BOOL(use_adaptive_hash_indexes, innobase_use_adaptive_hash_indexes, PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY, "Enable the InnoDB adaptive hash indexes (enabled by default)", NULL, NULL, TRUE); +static MYSQL_SYSVAR_ULONG(replication_delay, srv_replication_delay, + PLUGIN_VAR_RQCMDARG, + "Replication thread delay (ms) on the slave server if " + "innodb_thread_concurrency is reached (0 by default)", + NULL, NULL, 0, 0, ~0UL, 0); + static MYSQL_SYSVAR_LONG(additional_mem_pool_size, innobase_additional_mem_pool_size, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.", NULL, NULL, 1*1024*1024L, 512*1024L, ~0L, 1024); static MYSQL_SYSVAR_ULONG(autoextend_increment, srv_auto_extend_increment, @@ -8088,12 +8094,13 @@ static struct st_mysql_sys_var* innobase MYSQL_SYSVAR(max_purge_lag), MYSQL_SYSVAR(mirrored_log_groups), MYSQL_SYSVAR(open_files), MYSQL_SYSVAR(rollback_on_timeout), MYSQL_SYSVAR(stats_on_metadata), MYSQL_SYSVAR(use_adaptive_hash_indexes), + MYSQL_SYSVAR(replication_delay), MYSQL_SYSVAR(status_file), MYSQL_SYSVAR(support_xa), MYSQL_SYSVAR(sync_spin_loops), MYSQL_SYSVAR(table_locks), MYSQL_SYSVAR(thread_concurrency), MYSQL_SYSVAR(thread_sleep_delay), Index: include/srv0srv.h =================================================================== --- include/srv0srv.h (revision 1847) +++ include/srv0srv.h (working copy) @@ -133,12 +133,14 @@ extern ibool srv_set_thread_priorities; extern int srv_query_thread_priority; extern ulong srv_max_buf_pool_modified_pct; extern ulong srv_max_purge_lag; extern ibool srv_use_awe; extern ibool srv_use_adaptive_hash_indexes; + +extern ulint srv_replication_delay; /*-------------------------------------------*/ extern ulint srv_n_rows_inserted; extern ulint srv_n_rows_updated; extern ulint srv_n_rows_deleted; extern ulint srv_n_rows_read; Index: include/ut0ut.h =================================================================== --- include/ut0ut.h (revision 1847) +++ include/ut0ut.h (working copy) @@ -14,12 +14,27 @@ Created 1/20/1994 Heikki Tuuri #ifndef MYSQL_SERVER #include #endif typedef time_t ib_time_t; +/************************************************************************* +Delays execution for at most max_wait_us microseconds or returns earlier +if cond becomes true; cond is evaluated every 2 ms. */ + +#define UT_WAIT_FOR(cond, max_wait_us) \ +do { \ + ullint start_us; \ + start_us = ut_time_us(NULL); \ + while (!(cond) \ + && ut_time_us(NULL) - start_us < (max_wait_us)) {\ + \ + os_thread_sleep(2000 /* 2 ms */); \ + } \ +} while (0) + /************************************************************ Gets the high 32 bits in a ulint. That is makes a shift >> 32, but since there seem to be compiler bugs in both gcc and Visual C++, we do this by a special conversion. */ ulint @@ -149,12 +164,24 @@ Returns system time. */ void ut_usectime( /*========*/ ulint* sec, /* out: seconds since the Epoch */ ulint* ms); /* out: microseconds since the Epoch+*sec */ + +/************************************************************** +Returns the number of microseconds since epoch. Similar to +time(3), the return value is also stored in *tloc, provided +that tloc is non-NULL. */ + +ullint +ut_time_us( +/*=======*/ + /* out: us since epoch */ + ullint* tloc); /* out: us since epoch, if non-NULL */ + /************************************************************** Returns the difference of two times in seconds. */ double ut_difftime( /*========*/