Commit 2d01238e authored by ram@gw.mysql.r18.ru's avatar ram@gw.mysql.r18.ru

Merge rkalimullin@bk-internal.mysql.com:/home/bk/mysql-4.0

into gw.mysql.r18.ru:/usr/home/ram/work/4.0
parents edba2b9b 344b774d
......@@ -1632,12 +1632,12 @@ if test "$with_debug" = "yes"
then
# Medium debug.
CFLAGS="$DEBUG_CFLAGS $DEBUG_OPTIMIZE_CC -DDBUG_ON -DSAFE_MUTEX $CFLAGS"
CXXFLAGS="$DEBUG_CXXFLAGS $DEBUG_OPTIMIZE_CXX -DSAFE_MUTEX $CXXFLAGS"
CXXFLAGS="$DEBUG_CXXFLAGS $DEBUG_OPTIMIZE_CXX -DDBUG_ON -DSAFE_MUTEX $CXXFLAGS"
elif test "$with_debug" = "full"
then
# Full debug. Very slow in some cases
CFLAGS="$DEBUG_CFLAGS -DDBUG_ON -DSAFE_MUTEX -DSAFEMALLOC $CFLAGS"
CXXFLAGS="$DEBUG_CXXFLAGS -DSAFE_MUTEX -DSAFEMALLOC $CXXFLAGS"
CXXFLAGS="$DEBUG_CXXFLAGS -DDBUG_ON -DSAFE_MUTEX -DSAFEMALLOC $CXXFLAGS"
else
# Optimized version. No debug
CFLAGS="$OPTIMIZE_CFLAGS -DDBUG_OFF $CFLAGS"
......
......@@ -27,7 +27,8 @@ extern os_event_t srv_lock_timeout_thread_event;
/* If the last data file is auto-extended, we add this many pages to it
at a time */
#define SRV_AUTO_EXTEND_INCREMENT (8 * ((1024 * 1024) / UNIV_PAGE_SIZE))
#define SRV_AUTO_EXTEND_INCREMENT \
(srv_auto_extend_increment * ((1024 * 1024) / UNIV_PAGE_SIZE))
/* This is set to TRUE if the MySQL user has set it in MySQL */
extern ibool srv_lower_case_table_names;
......@@ -49,6 +50,7 @@ extern ulint* srv_data_file_is_raw_partition;
extern ibool srv_auto_extend_last_data_file;
extern ulint srv_last_file_size_max;
extern ulint srv_auto_extend_increment;
extern ibool srv_created_new_raw;
......
......@@ -86,6 +86,9 @@ ulint srv_last_file_size_max = 0; /* if != 0, this tells
the max size auto-extending
may increase the last data
file size */
ulint srv_auto_extend_increment = 8; /* If the last data file is
auto-extended, we add this
many pages to it at a time */
ulint* srv_data_file_is_raw_partition = NULL;
/* If the following is TRUE we do not allow inserts etc. This protects
......
slave stop;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
slave start;
CREATE TABLE t1 (
a int unsigned not null auto_increment primary key,
b int unsigned
) TYPE=MyISAM;
CREATE TABLE t2 (
a int unsigned not null auto_increment primary key,
b int unsigned
) TYPE=MyISAM;
INSERT INTO t1 VALUES (NULL, 0);
INSERT INTO t1 SELECT NULL, 0 FROM t1;
INSERT INTO t2 VALUES (NULL, 0), (NULL,1);
SELECT * FROM t1 ORDER BY a;
a b
1 0
2 0
SELECT * FROM t2 ORDER BY a;
a b
1 0
2 1
UPDATE t1, t2 SET t1.b = (t2.b+4) WHERE t1.a = t2.a;
SELECT * FROM t1 ORDER BY a;
a b
1 4
2 5
SELECT * FROM t2 ORDER BY a;
a b
1 0
2 1
SELECT * FROM t1 ORDER BY a;
a b
1 4
2 5
SELECT * FROM t2 ORDER BY a;
a b
1 0
2 1
--replicate-ignore-table=nothing.sensible
# Let's verify that multi-update is not always skipped by slave if
# some replicate-* rules exist.
# (BUG#7011)
source include/master-slave.inc;
CREATE TABLE t1 (
a int unsigned not null auto_increment primary key,
b int unsigned
) TYPE=MyISAM;
CREATE TABLE t2 (
a int unsigned not null auto_increment primary key,
b int unsigned
) TYPE=MyISAM;
INSERT INTO t1 VALUES (NULL, 0);
INSERT INTO t1 SELECT NULL, 0 FROM t1;
INSERT INTO t2 VALUES (NULL, 0), (NULL,1);
SELECT * FROM t1 ORDER BY a;
SELECT * FROM t2 ORDER BY a;
UPDATE t1, t2 SET t1.b = (t2.b+4) WHERE t1.a = t2.a;
SELECT * FROM t1 ORDER BY a;
SELECT * FROM t2 ORDER BY a;
save_master_pos;
connection slave;
sync_with_master;
SELECT * FROM t1 ORDER BY a;
SELECT * FROM t2 ORDER BY a;
......@@ -4346,12 +4346,12 @@ ha_innobase::update_table_comment(
(ulong) innobase_get_free_space());
dict_print_info_on_foreign_keys(FALSE, file, prebuilt->table);
flen = ftell(file);
if(length + flen + 3 > 64000) {
if (flen < 0) {
flen = 0;
} else if (length + flen + 3 > 64000) {
flen = 64000 - 3 - length;
}
ut_ad(flen > 0);
/* allocate buffer for the full string, and
read the contents of the temporary file */
......@@ -4414,12 +4414,12 @@ ha_innobase::get_foreign_key_create_info(void)
prebuilt->trx->op_info = (char*)"";
flen = ftell(file);
if(flen > 64000 - 1) {
if (flen < 0) {
flen = 0;
} else if(flen > 64000 - 1) {
flen = 64000 - 1;
}
ut_ad(flen >= 0);
/* allocate buffer for the string, and
read the contents of the temporary file */
......@@ -4800,12 +4800,12 @@ innodb_show_status(
srv_printf_innodb_monitor(srv_monitor_file);
flen = ftell(srv_monitor_file);
os_file_set_eof(srv_monitor_file);
if(flen > 64000 - 1) {
if (flen < 0) {
flen = 0;
} else if (flen > 64000 - 1) {
flen = 64000 - 1;
}
ut_ad(flen > 0);
/* allocate buffer for the string, and
read the contents of the temporary file */
......
......@@ -208,6 +208,7 @@ extern my_bool innobase_log_archive,
extern "C" {
extern ulong srv_max_buf_pool_modified_pct;
extern ulong srv_max_purge_lag;
extern ulong srv_auto_extend_increment;
}
extern TYPELIB innobase_lock_typelib;
......
......@@ -469,6 +469,9 @@ int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields,
List<Item> &values,COND *conds,
ORDER *order, ha_rows limit,
enum enum_duplicates handle_duplicates);
int mysql_multi_update_lock(THD *thd,
TABLE_LIST *table_list,
List<Item> *fields);
int mysql_multi_update(THD *thd, TABLE_LIST *table_list,
List<Item> *fields, List<Item> *values,
COND *conds, ulong options,
......
......@@ -3518,6 +3518,7 @@ enum options_mysqld {
OPT_INNODB_FORCE_RECOVERY,
OPT_INNODB_STATUS_FILE,
OPT_INNODB_MAX_DIRTY_PAGES_PCT,
OPT_INNODB_AUTOEXTEND_INCREMENT,
OPT_INNODB_TABLE_LOCKS,
OPT_BDB_CACHE_SIZE,
OPT_BDB_LOG_BUFFER_SIZE,
......@@ -3659,6 +3660,11 @@ struct my_option my_long_options[] =
"Path to individual files and their sizes",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_INNOBASE_DB
{"innodb_autoextend_increment", OPT_INNODB_AUTOEXTEND_INCREMENT,
"Data file autoextend increment in megabytes",
(gptr*) &srv_auto_extend_increment,
(gptr*) &srv_auto_extend_increment,
0, GET_LONG, REQUIRED_ARG, 8L, 1L, 1000L, 0, 1L, 0},
{"innodb_data_home_dir", OPT_INNODB_DATA_HOME_DIR,
"The common part for Innodb table spaces", (gptr*) &innobase_data_home_dir,
(gptr*) &innobase_data_home_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0,
......
......@@ -265,6 +265,8 @@ sys_var_long_ptr sys_innodb_max_dirty_pages_pct("innodb_max_dirty_pages_p
&srv_max_buf_pool_modified_pct);
sys_var_long_ptr sys_innodb_max_purge_lag("innodb_max_purge_lag",
&srv_max_purge_lag);
sys_var_long_ptr sys_innodb_autoextend_increment("innodb_autoextend_increment",
&srv_auto_extend_increment);
sys_var_thd_bool sys_innodb_table_locks("innodb_table_locks",
&SV::innodb_table_locks);
#endif
......@@ -454,6 +456,7 @@ sys_var *sys_variables[]=
#ifdef HAVE_INNOBASE_DB
&sys_innodb_max_dirty_pages_pct,
&sys_innodb_max_purge_lag,
&sys_innodb_autoextend_increment,
&sys_innodb_table_locks,
#endif
&sys_unique_checks
......@@ -508,6 +511,7 @@ struct show_var_st init_vars[]= {
{"init_file", (char*) &opt_init_file, SHOW_CHAR_PTR},
#ifdef HAVE_INNOBASE_DB
{"innodb_additional_mem_pool_size", (char*) &innobase_additional_mem_pool_size, SHOW_LONG },
{sys_innodb_autoextend_increment.name, (char*) &sys_innodb_autoextend_increment, SHOW_SYS},
{"innodb_buffer_pool_size", (char*) &innobase_buffer_pool_size, SHOW_LONG },
{"innodb_data_file_path", (char*) &innobase_data_file_path, SHOW_CHAR_PTR},
{"innodb_data_home_dir", (char*) &innobase_data_home_dir, SHOW_CHAR_PTR},
......
......@@ -56,6 +56,8 @@ static int check_for_max_user_connections(USER_CONN *uc);
static void decrease_user_connections(USER_CONN *uc);
static bool check_db_used(THD *thd,TABLE_LIST *tables);
static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables);
static bool check_multi_update_lock(THD *thd, TABLE_LIST *tables,
List<Item> *fields);
static void mysql_init_query(THD *thd);
static void remove_escape(char *name);
static void refresh_status(void);
......@@ -1338,10 +1340,28 @@ mysql_execute_command(void)
LEX *lex= &thd->lex;
TABLE_LIST *tables=(TABLE_LIST*) lex->select_lex.table_list.first;
SELECT_LEX *select_lex = lex->select;
bool slave_fake_lock= 0;
MYSQL_LOCK *fake_prev_lock= 0;
DBUG_ENTER("mysql_execute_command");
if (thd->slave_thread)
{
if (lex->sql_command == SQLCOM_MULTI_UPDATE)
{
DBUG_PRINT("info",("need faked locked tables"));
if (check_multi_update_lock(thd, tables, &select_lex->item_list))
goto error;
/* Fix for replication, the tables are opened and locked,
now we pretend that we have performed a LOCK TABLES action */
fake_prev_lock= thd->locked_tables;
if (thd->lock)
thd->locked_tables= thd->lock;
thd->lock= 0;
slave_fake_lock= 1;
}
/*
Skip if we are in the slave thread, some table rules have been
given and the table list says the query should not be replicated
......@@ -1949,7 +1969,7 @@ mysql_execute_command(void)
if (select_lex->item_list.elements != lex->value_list.elements)
{
send_error(&thd->net,ER_WRONG_VALUE_COUNT);
DBUG_VOID_RETURN;
goto error;
}
{
const char *msg= 0;
......@@ -2641,6 +2661,14 @@ mysql_execute_command(void)
send_error(&thd->net,thd->killed ? ER_SERVER_SHUTDOWN : 0);
error:
if (unlikely(slave_fake_lock))
{
DBUG_PRINT("info",("undoing faked lock"));
thd->lock= thd->locked_tables;
thd->locked_tables= fake_prev_lock;
if (thd->lock == thd->locked_tables)
thd->lock= 0;
}
DBUG_VOID_RETURN;
}
......@@ -3907,3 +3935,54 @@ bool check_simple_select()
}
return 0;
}
/*
Setup locking for multi-table updates. Used by the replication slave.
Replication slave SQL thread examines (all_tables_not_ok()) the
locking state of referenced tables to determine if the query has to
be executed or ignored. Since in multi-table update, the
'default' lock is read-only, this lock is corrected early enough by
calling this function, before the slave decides to execute/ignore.
SYNOPSIS
check_multi_update_lock()
thd Current thread
tables List of user-supplied tables
fields List of fields requiring update
RETURN VALUES
0 ok
1 error
*/
static bool check_multi_update_lock(THD *thd, TABLE_LIST *tables,
List<Item> *fields)
{
bool res= 1;
TABLE_LIST *table;
DBUG_ENTER("check_multi_update_lock");
if (check_db_used(thd, tables))
goto error;
/*
Ensure that we have UPDATE or SELECT privilege for each table
The exact privilege is checked in mysql_multi_update()
*/
for (table= tables ; table ; table= table->next)
{
TABLE_LIST *save= table->next;
table->next= 0;
if (check_one_table_access(thd, UPDATE_ACL, table, 1) &&
check_one_table_access(thd, SELECT_ACL, table, 0))
goto error;
table->next= save;
}
if (mysql_multi_update_lock(thd, tables, fields))
goto error;
res= 0;
error:
DBUG_RETURN(res);
}
......@@ -403,26 +403,20 @@ static table_map get_table_map(List<Item> *items)
}
/*
Setup multi-update handling and call SELECT to do the join
Prepare tables for multi-update
Analyse which tables need specific privileges and perform locking
as required
*/
int mysql_multi_update(THD *thd,
int mysql_multi_update_lock(THD *thd,
TABLE_LIST *table_list,
List<Item> *fields,
List<Item> *values,
COND *conds,
ulong options,
enum enum_duplicates handle_duplicates)
List<Item> *fields)
{
int res;
multi_update *result;
TABLE_LIST *tl;
const bool using_lock_tables= thd->locked_tables != 0;
DBUG_ENTER("mysql_multi_update");
thd->select_limit= HA_POS_ERROR;
DBUG_ENTER("mysql_multi_update_lock");
for (;;)
{
......@@ -490,7 +484,7 @@ int mysql_multi_update(THD *thd,
(grant_option && check_grant(thd, wants, tl, 0, 0)))
{
tl->next= save;
DBUG_RETURN(0);
DBUG_RETURN(1);
}
tl->next= save;
}
......@@ -498,11 +492,7 @@ int mysql_multi_update(THD *thd,
/* Relock the tables with the correct modes */
res= lock_tables(thd,table_list);
if (using_lock_tables)
{
if (res)
DBUG_RETURN(res);
break; // Don't have to do setup_field()
}
/*
We must setup fields again as the file may have been reopened
......@@ -536,6 +526,31 @@ int mysql_multi_update(THD *thd,
close_thread_tables(thd);
}
DBUG_RETURN(res);
}
/*
Setup multi-update handling and call SELECT to do the join
*/
int mysql_multi_update(THD *thd,
TABLE_LIST *table_list,
List<Item> *fields,
List<Item> *values,
COND *conds,
ulong options,
enum enum_duplicates handle_duplicates)
{
int res;
TABLE_LIST *tl;
multi_update *result;
DBUG_ENTER("mysql_multi_update");
thd->select_limit= HA_POS_ERROR;
if ((res= mysql_multi_update_lock(thd, table_list, fields)))
DBUG_RETURN(res);
/*
Count tables and setup timestamp handling
*/
......
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