Commit bc48ebd8 authored by marko's avatar marko

branches/zip: Merge revisions 4976:4994 from branches/5.1:

  ------------------------------------------------------------------------
  r4994 | marko | 2009-05-14 15:04:55 +0300 (Thu, 14 May 2009) | 18 lines

  branches/5.1: Prevent a race condition in innobase_commit() by ensuring
  that innodb_commit_concurrency>0 remains constant at run time. (Bug #42101)

  srv_commit_concurrency: Make this a static variable in ha_innodb.cc.

  innobase_commit_concurrency_validate(): Check that innodb_commit_concurrency
  is not changed from or to 0 at run time.  This is needed, because
  innobase_commit() assumes that innodb_commit_concurrency>0 remains constant.
  Without this limitation, the checks for innodb_commit_concurrency>0
  in innobase_commit() should be removed and that function would have to
  acquire and release commit_cond_m at least twice per invocation.
  Normally, innodb_commit_concurrency=0, and introducing the mutex operations
  would mean significant overhead.

  innodb_bug42101.test, innodb_bug42101-nonzero.test: Test cases.

  rb://123 approved by Heikki Tuuri
  ------------------------------------------------------------------------
parent f42bc56e
...@@ -123,6 +123,7 @@ static long innobase_mirrored_log_groups, innobase_log_files_in_group, ...@@ -123,6 +123,7 @@ static long innobase_mirrored_log_groups, innobase_log_files_in_group,
innobase_additional_mem_pool_size, innobase_file_io_threads, innobase_additional_mem_pool_size, innobase_file_io_threads,
innobase_force_recovery, innobase_open_files, innobase_force_recovery, innobase_open_files,
innobase_autoinc_lock_mode; innobase_autoinc_lock_mode;
static ulong innobase_commit_concurrency = 0;
static long long innobase_buffer_pool_size, innobase_log_file_size; static long long innobase_buffer_pool_size, innobase_log_file_size;
...@@ -236,6 +237,39 @@ innobase_alter_table_flags( ...@@ -236,6 +237,39 @@ innobase_alter_table_flags(
static const char innobase_hton_name[]= "InnoDB"; static const char innobase_hton_name[]= "InnoDB";
/*****************************************************************
Check for a valid value of innobase_commit_concurrency. */
static
int
innobase_commit_concurrency_validate(
/*=================================*/
/* out: 0 for valid
innodb_commit_concurrency */
THD* thd, /* in: thread handle */
struct st_mysql_sys_var* var, /* in: pointer to system
variable */
void* save, /* out: immediate result
for update function */
struct st_mysql_value* value) /* in: incoming string */
{
long long intbuf;
ulong commit_concurrency;
DBUG_ENTER("innobase_commit_concurrency_validate");
if (value->val_int(value, &intbuf)) {
/* The value is NULL. That is invalid. */
DBUG_RETURN(1);
}
*reinterpret_cast<ulong*>(save) = commit_concurrency
= static_cast<ulong>(intbuf);
/* Allow the value to be updated, as long as it remains zero
or nonzero. */
DBUG_RETURN(!(!commit_concurrency == !innobase_commit_concurrency));
}
static MYSQL_THDVAR_BOOL(support_xa, PLUGIN_VAR_OPCMDARG, static MYSQL_THDVAR_BOOL(support_xa, PLUGIN_VAR_OPCMDARG,
"Enable InnoDB support for the XA two-phase commit", "Enable InnoDB support for the XA two-phase commit",
/* check_func */ NULL, /* update_func */ NULL, /* check_func */ NULL, /* update_func */ NULL,
...@@ -2364,11 +2398,11 @@ innobase_commit( ...@@ -2364,11 +2398,11 @@ innobase_commit(
Note, the position is current because of Note, the position is current because of
prepare_commit_mutex */ prepare_commit_mutex */
retry: retry:
if (srv_commit_concurrency > 0) { if (innobase_commit_concurrency > 0) {
pthread_mutex_lock(&commit_cond_m); pthread_mutex_lock(&commit_cond_m);
commit_threads++; commit_threads++;
if (commit_threads > srv_commit_concurrency) { if (commit_threads > innobase_commit_concurrency) {
commit_threads--; commit_threads--;
pthread_cond_wait(&commit_cond, pthread_cond_wait(&commit_cond,
&commit_cond_m); &commit_cond_m);
...@@ -2385,7 +2419,7 @@ retry: ...@@ -2385,7 +2419,7 @@ retry:
innobase_commit_low(trx); innobase_commit_low(trx);
if (srv_commit_concurrency > 0) { if (innobase_commit_concurrency > 0) {
pthread_mutex_lock(&commit_cond_m); pthread_mutex_lock(&commit_cond_m);
commit_threads--; commit_threads--;
pthread_cond_signal(&commit_cond); pthread_cond_signal(&commit_cond);
...@@ -9586,10 +9620,10 @@ static MYSQL_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size, ...@@ -9586,10 +9620,10 @@ static MYSQL_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size,
"The size of the memory buffer InnoDB uses to cache data and indexes of its tables.", "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
NULL, NULL, 8*1024*1024L, 5*1024*1024L, LONGLONG_MAX, 1024*1024L); NULL, NULL, 8*1024*1024L, 5*1024*1024L, LONGLONG_MAX, 1024*1024L);
static MYSQL_SYSVAR_ULONG(commit_concurrency, srv_commit_concurrency, static MYSQL_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
PLUGIN_VAR_RQCMDARG, PLUGIN_VAR_RQCMDARG,
"Helps in performance tuning in heavily concurrent environments.", "Helps in performance tuning in heavily concurrent environments.",
NULL, NULL, 0, 0, 1000, 0); innobase_commit_concurrency_validate, NULL, 0, 0, 1000, 0);
static MYSQL_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter, static MYSQL_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter,
PLUGIN_VAR_RQCMDARG, PLUGIN_VAR_RQCMDARG,
......
...@@ -139,7 +139,6 @@ extern ulint srv_max_dirty_pages_pct; ...@@ -139,7 +139,6 @@ extern ulint srv_max_dirty_pages_pct;
extern ulint srv_force_recovery; extern ulint srv_force_recovery;
extern ulong srv_thread_concurrency; extern ulong srv_thread_concurrency;
extern ulong srv_commit_concurrency;
extern ulint srv_max_n_threads; extern ulint srv_max_n_threads;
......
set global innodb_commit_concurrency=0;
ERROR HY000: Incorrect arguments to SET
select @@innodb_commit_concurrency;
@@innodb_commit_concurrency
1
set global innodb_commit_concurrency=1;
select @@innodb_commit_concurrency;
@@innodb_commit_concurrency
1
set global innodb_commit_concurrency=42;
select @@innodb_commit_concurrency;
@@innodb_commit_concurrency
42
set global innodb_commit_concurrency=0;
ERROR HY000: Incorrect arguments to SET
select @@innodb_commit_concurrency;
@@innodb_commit_concurrency
42
set global innodb_commit_concurrency=1;
select @@innodb_commit_concurrency;
@@innodb_commit_concurrency
1
#
# Bug#42101 Race condition in innodb_commit_concurrency
# http://bugs.mysql.com/42101
#
-- source include/have_innodb.inc
--error ER_WRONG_ARGUMENTS
set global innodb_commit_concurrency=0;
select @@innodb_commit_concurrency;
set global innodb_commit_concurrency=1;
select @@innodb_commit_concurrency;
set global innodb_commit_concurrency=42;
select @@innodb_commit_concurrency;
--error ER_WRONG_ARGUMENTS
set global innodb_commit_concurrency=0;
select @@innodb_commit_concurrency;
set global innodb_commit_concurrency=1;
select @@innodb_commit_concurrency;
set global innodb_commit_concurrency=0;
select @@innodb_commit_concurrency;
@@innodb_commit_concurrency
0
set global innodb_commit_concurrency=1;
ERROR HY000: Incorrect arguments to SET
select @@innodb_commit_concurrency;
@@innodb_commit_concurrency
0
set global innodb_commit_concurrency=42;
ERROR HY000: Incorrect arguments to SET
select @@innodb_commit_concurrency;
@@innodb_commit_concurrency
0
set global innodb_commit_concurrency=0;
select @@innodb_commit_concurrency;
@@innodb_commit_concurrency
0
#
# Bug#42101 Race condition in innodb_commit_concurrency
# http://bugs.mysql.com/42101
#
-- source include/have_innodb.inc
set global innodb_commit_concurrency=0;
select @@innodb_commit_concurrency;
--error ER_WRONG_ARGUMENTS
set global innodb_commit_concurrency=1;
select @@innodb_commit_concurrency;
--error ER_WRONG_ARGUMENTS
set global innodb_commit_concurrency=42;
select @@innodb_commit_concurrency;
set global innodb_commit_concurrency=0;
select @@innodb_commit_concurrency;
...@@ -278,7 +278,6 @@ computer. Bigger computers need bigger values. Value 0 will disable the ...@@ -278,7 +278,6 @@ computer. Bigger computers need bigger values. Value 0 will disable the
concurrency check. */ concurrency check. */
UNIV_INTERN ulong srv_thread_concurrency = 0; UNIV_INTERN ulong srv_thread_concurrency = 0;
UNIV_INTERN ulong srv_commit_concurrency = 0;
/* this mutex protects srv_conc data structures */ /* this mutex protects srv_conc data structures */
UNIV_INTERN os_fast_mutex_t srv_conc_mutex; UNIV_INTERN os_fast_mutex_t srv_conc_mutex;
......
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