From 52090a443493f5a8410094b43bfa5cdde8c32f5d Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Wed, 24 Nov 2010 00:08:48 +0200 Subject: Code cleanup to get fewer reallocs() during execution. - Changed TABLE->alias to String to get fewer reallocs when alias are used. - Preallocate some buffers Changed some String->c_ptr() -> String->ptr() when \0 is not needed. Fixed wrong usage of String->ptr() when we need a \0 terminated string. Use my_strtod() instead of my_atof() to avoid having to add \0 to string. c_ptr() -> c_ptr_safe() to avoid warnings from valgrind. zr sql/event_db_repository.cc: Update usage of TABLE->alias sql/event_scheduler.cc: c_ptr() -> c_ptr_safe() sql/events.cc: c_ptr() -> ptr() as \0 was not needed sql/field.cc: Update usage of TABLE->alias sql/field.h: Update usage of TABLE->alias sql/ha_partition.cc: Update usage of TABLE->alias sql/handler.cc: Update usage of TABLE->alias Fixed wrong usage of str.ptr() sql/item.cc: Fixed error where code wrongly assumed string was \0 terminated. sql/item_func.cc: c_ptr() -> c_ptr_safe() Update usage of TABLE->alias sql/item_sum.h: Use my_strtod() instead of my_atof() to avoid having to add \0 to string sql/lock.cc: Update usage of TABLE->alias sql/log.cc: c_ptr() -> ptr() as \0 was not needed sql/log_event.cc: c_ptr_quick() -> ptr() as \0 was not needed sql/opt_range.cc: ptr() -> c_ptr() as \0 is needed sql/opt_subselect.cc: Update usage of TABLE->alias sql/opt_table_elimination.cc: Update usage of TABLE->alias sql/set_var.cc: ptr() -> c_ptr() as \0 is needed c_ptr() -> c_ptr_safe() sql/sp.cc: c_ptr() -> ptr() as \0 was not needed sql/sp_rcontext.cc: Update usage of TABLE->alias sql/sql_base.cc: Preallocate buffers Update usage of TABLE->alias sql/sql_class.cc: Fix arguments to sprintf() to work even if string is not \0 terminated sql/sql_insert.cc: Update usage of TABLE->alias c_ptr() -> ptr() as \0 was not needed sql/sql_load.cc: Preallocate buffers Trivial optimizations sql/sql_parse.cc: Trivial optimization sql/sql_plugin.cc: c_ptr() -> ptr() as \0 was not needed sql/sql_select.cc: Update usage of TABLE->alias sql/sql_show.cc: Update usage of TABLE->alias sql/sql_string.h: Added move() function to move allocated memory from one object to another. sql/sql_table.cc: Update usage of TABLE->alias c_ptr() -> c_ptr_safe() sql/sql_test.cc: ptr() -> c_ptr_safe() sql/sql_trigger.cc: Update usage of TABLE->alias c_ptr() -> c_ptr_safe() sql/sql_update.cc: Update usage of TABLE->alias sql/sql_view.cc: ptr() -> c_ptr_safe() sql/sql_yacc.yy: ptr() -> c_ptr() sql/table.cc: Update usage of TABLE->alias sql/table.h: Changed TABLE->alias to String to get fewer reallocs when alias are used. storage/federatedx/ha_federatedx.cc: Use c_ptr_safe() to ensure strings are \0 terminated. storage/maria/ha_maria.cc: Update usage of TABLE->alias storage/myisam/ha_myisam.cc: Update usage of TABLE->alias storage/xtradb/row/row0sel.c: Ensure that null bits in record are properly reset. (Old code didn't work as row_search_for_mysql() can be called twice while reading fields from one row. --- sql/lock.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql/lock.cc') diff --git a/sql/lock.cc b/sql/lock.cc index 566275c5ea2..7c569bf7cfc 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -903,7 +903,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, *write_lock_used=table; if (table->db_stat & HA_READ_ONLY) { - my_error(ER_OPEN_AS_READONLY,MYF(0),table->alias); + my_error(ER_OPEN_AS_READONLY,MYF(0),table->alias.c_ptr()); /* Clear the lock type of the lock data that are stored already. */ sql_lock->lock_count= (uint) (locks - sql_lock->locks); reset_lock_data(sql_lock); -- cgit v1.2.1 From e63b5546c597f65696868eaf69159107bc4a8e44 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Tue, 4 Jan 2011 00:55:41 +0200 Subject: Implementation of MWL#172: Add support for prepared statements to HANDLER READ It includes speed optimizations for HANDLER READ by caching as much as possible in HANDLER OPEN Other things: - Added mysqld option --disable-thr-alarm to be able to benchmark things without thr_alarm - Changed 'Locked' state to 'System lock' and 'Table lock' (these where used in the code but never shown to end user) - Better error message if mysql_install_db.sh fails - Moved handler function prototypes to sql_handler.h - Remove not anymore used 'thd->locked' member include/thr_alarm.h: Added my_disable_thr_alarm include/thr_lock.h: Add new member to THR_LOCK_DATA to remember original lock type state. This is needed as thr_unlock() resets type to TL_UNLOCK. mysql-test/include/check_no_concurrent_insert.inc: Locked -> Table lock mysql-test/include/handler.inc: Locked -> Table lock mysql-test/r/handler_innodb.result: Updated results for new tests mysql-test/r/handler_myisam.result: Updated results for new tests mysql-test/r/sp-threads.result: Locked -> Table lock mysql-test/suite/binlog/t/binlog_stm_row.test: Locked -> Table lock mysql-test/suite/funcs_1/datadict/processlist_val.inc: Locked -> Table lock mysql-test/suite/pbxt/t/lock_multi.test: Locked -> Table lock mysql-test/suite/sys_vars/r/concurrent_insert_func.result: Locked -> Table lock mysql-test/suite/sys_vars/t/concurrent_insert_func.test: Locked -> Table lock mysql-test/suite/sys_vars/t/delayed_insert_limit_func.test: Locked -> Table lock mysql-test/suite/sys_vars/t/query_cache_wlock_invalidate_func.test: Locked -> Table lock mysql-test/suite/sys_vars/t/sql_low_priority_updates_func.test: Locked -> Table lock mysql-test/t/insert_notembedded.test: Locked -> Table lock mysql-test/t/lock_multi.test: Locked -> Table lock mysql-test/t/merge-big.test: Locked -> Table lock mysql-test/t/multi_update.test: Locked -> Table lock mysql-test/t/query_cache_28249.test: Locked -> Table lock mysql-test/t/sp_notembedded.test: Locked -> Table lock mysql-test/t/sp_sync.test: Locked -> Table lock mysql-test/t/status.test: Locked -> Table lock mysql-test/t/trigger_notembedded.test: Locked -> Table lock mysys/thr_alarm.c: Added option to disable thr_alarm mysys/thr_lock.c: Detect loops scripts/mysql_install_db.sh: Give better error message if something goes wrong sql/Makefile.am: Added sql_handler.h sql/lock.cc: Split functions to allow one to cache value if store_lock() (for HANDLER functions). - Split mysql_lock_tables() into two functions, where first one allocates MYSQL_LOCK and other other one uses it. - Made get_lock_data() an external function. - Added argument to mysql_unlock_tables() to not free sql_lock. - Added argument to reset_lock_data() to reset lock structure to initial state (as after get_lock_data()) sql/mysql_priv.h: Moved handler function prototypes to sql_handler.h Added new lock functions. sql/mysqld.cc: Added --thread-alarm startup option sql/net_serv.cc: Don't call vio_blocking() if not needed sql/sql_base.cc: include sql_handler.h sql/sql_class.cc: include sql_handler.h Remove not anymore used 'thd->locked' member sql/sql_class.h: Remove not anymore used 'thd->locked' member sql/sql_db.cc: include sql_handler.h sql/sql_delete.cc: include sql_handler.h sql/sql_handler.cc: Rewrote all code to use SQL_HANDLER instead of TABLE_LIST (original interface) Rewrote mysql_ha_open() to cache all things from TABLE_LIST and items for field list, where etc. In mysql_ha_open() also cache MYSQL_LOCK structure from get_lock_data(). Split functions into smaller sub functions (needed to be able to implement mysql_ha_read_prepare()) Added mysql_ha_read_prepare() to allow one to prepare HANDLER READ. sql/sql_handler.h: Interface to sql_handler.cc sql/sql_parse.cc: include sql_handler.h sql/sql_prepare.cc: Added mysql_test_handler_read(), prepare for HANDLER READ sql/sql_rename.cc: include sql_handler.h sql/sql_show.cc: Removed usage of thd->locked sql/sql_table.cc: include sql_handler.h sql/sql_trigger.cc: include sql_handler.h --- sql/lock.cc | 304 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 156 insertions(+), 148 deletions(-) (limited to 'sql/lock.cc') diff --git a/sql/lock.cc b/sql/lock.cc index 8f5b5ac233f..49f0cfdfa90 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -84,41 +84,11 @@ extern HASH open_cache; -/* flags for get_lock_data */ -#define GET_LOCK_UNLOCK 1 -#define GET_LOCK_STORE_LOCKS 2 - -static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table,uint count, - uint flags, TABLE **write_locked); -static void reset_lock_data(MYSQL_LOCK *sql_lock); +static void reset_lock_data(MYSQL_LOCK *sql_lock, bool unlock); static int lock_external(THD *thd, TABLE **table,uint count); static int unlock_external(THD *thd, TABLE **table,uint count); static void print_lock_error(int error, const char *); -/* - Lock tables. - - SYNOPSIS - mysql_lock_tables() - thd The current thread. - tables An array of pointers to the tables to lock. - count The number of tables to lock. - flags Options: - MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK Ignore a global read lock - MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY Ignore SET GLOBAL READ_ONLY - MYSQL_LOCK_IGNORE_FLUSH Ignore a flush tables. - MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN Instead of reopening altered - or dropped tables by itself, - mysql_lock_tables() should - notify upper level and rely - on caller doing this. - need_reopen Out parameter, TRUE if some tables were altered - or deleted and should be reopened by caller. - - RETURN - A lock structure pointer on success. - NULL on error or if some tables should be reopen. -*/ /* Map the return value of thr_lock to an error from errmsg.txt */ static int thr_lock_errno_to_mysql[]= @@ -132,6 +102,7 @@ static int thr_lock_errno_to_mysql[]= @param flags Lock flags @return 0 if all the check passed, non zero if a check failed. */ + int mysql_lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags) { bool log_table_write_query; @@ -194,81 +165,118 @@ int mysql_lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags) DBUG_RETURN(0); } + +/* + Lock tables. + + SYNOPSIS + mysql_lock_tables() + thd The current thread. + tables An array of pointers to the tables to lock. + count The number of tables to lock. + flags Options: + MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK Ignore a global read lock + MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY Ignore SET GLOBAL READ_ONLY + MYSQL_LOCK_IGNORE_FLUSH Ignore a flush tables. + MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN Instead of reopening altered + or dropped tables by itself, + mysql_lock_tables() should + notify upper level and rely + on caller doing this. + need_reopen Out parameter, TRUE if some tables were altered + or deleted and should be reopened by caller. + + RETURN + A lock structure pointer on success. + NULL on error or if some tables should be reopen. +*/ + MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, uint flags, bool *need_reopen) { - MYSQL_LOCK *sql_lock; TABLE *write_lock_used; - int rc; - - DBUG_ENTER("mysql_lock_tables"); + MYSQL_LOCK *sql_lock; + DBUG_ENTER("mysql_lock_tables(tables)"); *need_reopen= FALSE; - if (mysql_lock_tables_check(thd, tables, count, flags)) - DBUG_RETURN (NULL); + DBUG_RETURN(NULL); - for (;;) + if (!(sql_lock= get_lock_data(thd, tables, count, GET_LOCK_STORE_LOCKS, + &write_lock_used)) || + ! sql_lock->table_count) + DBUG_RETURN(sql_lock); + + if (mysql_lock_tables(thd, sql_lock, write_lock_used != 0, flags, + need_reopen)) { - if (! (sql_lock= get_lock_data(thd, tables, count, GET_LOCK_STORE_LOCKS, - &write_lock_used)) || - ! sql_lock->table_count) - break; + /* Clear the lock type of all lock data to avoid reusage. */ + reset_lock_data(sql_lock, 1); + my_free(sql_lock, MYF(0)); + sql_lock= 0; + } + DBUG_RETURN(sql_lock); +} + + +/** + Lock a table based on a MYSQL_LOCK structure. - if (global_read_lock && write_lock_used && - ! (flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK)) + mysql_lock_tables() + + @param thd The current thread. + @param sql_lock Tables that should be locked + @param write_lock_used 1 if any of the tables are write locked + @param flags See mysql_lock_tables() + @param need_reopen Out parameter, TRUE if some tables were altered + or deleted and should be reopened by caller. + + @return 0 ok + @return 1 error +*/ + +bool mysql_lock_tables(THD *thd, MYSQL_LOCK *sql_lock, + bool write_lock_used, + uint flags, bool *need_reopen) +{ + int rc; + bool error= 1; + DBUG_ENTER("mysql_lock_tables(sql_lock)"); + + *need_reopen= FALSE; + for (;;) + { + if (write_lock_used && !(flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK)) { - /* - Someone has issued LOCK ALL TABLES FOR READ and we want a write lock - Wait until the lock is gone - */ - if (wait_if_global_read_lock(thd, 1, 1)) + if (global_read_lock) { - /* Clear the lock type of all lock data to avoid reusage. */ - reset_lock_data(sql_lock); - my_free((uchar*) sql_lock,MYF(0)); - sql_lock=0; - break; + /* + Someone has issued LOCK ALL TABLES FOR READ and we want a write lock + Wait until the lock is gone + */ + if (wait_if_global_read_lock(thd, 1, 1)) + break; + if (thd->version != refresh_version) + goto retry; } - if (thd->version != refresh_version) + + if (opt_readonly && + !(thd->security_ctx->master_access & SUPER_ACL) && + !thd->slave_thread) { - /* Clear the lock type of all lock data to avoid reusage. */ - reset_lock_data(sql_lock); - my_free((uchar*) sql_lock,MYF(0)); - goto retry; + /* + Someone has issued SET GLOBAL READ_ONLY=1 and we want a write lock. + We do not wait for READ_ONLY=0, and fail. + */ + my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only"); + break; } } - if (!(flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY) && - write_lock_used && - opt_readonly && - !(thd->security_ctx->master_access & SUPER_ACL) && - !thd->slave_thread) - { - /* - Someone has issued SET GLOBAL READ_ONLY=1 and we want a write lock. - We do not wait for READ_ONLY=0, and fail. - */ - reset_lock_data(sql_lock); - my_free((uchar*) sql_lock, MYF(0)); - sql_lock=0; - my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only"); - break; - } - thd_proc_info(thd, "System lock"); - DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info)); if (lock_external(thd, sql_lock->table, sql_lock->table_count)) - { - /* Clear the lock type of all lock data to avoid reusage. */ - reset_lock_data(sql_lock); - my_free((uchar*) sql_lock,MYF(0)); - sql_lock=0; break; - } thd_proc_info(thd, "Table lock"); - DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info)); - thd->locked=1; /* Copy the lock data array. thr_multi_lock() reorders its contens. */ memcpy(sql_lock->locks + sql_lock->lock_count, sql_lock->locks, sql_lock->lock_count * sizeof(*sql_lock->locks)); @@ -277,70 +285,66 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, sql_lock->lock_count, sql_lock->lock_count, thd->lock_id)]; - if (rc > 1) /* a timeout or a deadlock */ + if (rc) /* Locking failed */ { VOID(unlock_external(thd, sql_lock->table, sql_lock->table_count)); - my_error(rc, MYF(0)); - my_free((uchar*) sql_lock,MYF(0)); - sql_lock= 0; - break; - } - else if (rc == 1) /* aborted */ - { - /* - reset_lock_data is required here. If thr_multi_lock fails it - resets lock type for tables, which were locked before (and - including) one that caused error. Lock type for other tables - preserved. - */ - reset_lock_data(sql_lock); - thd->some_tables_deleted=1; // Try again - sql_lock->lock_count= 0; // Locks are already freed + if (rc > 1) + { + /* a timeout or a deadlock */ + my_error(rc, MYF(0)); + break; + } + /* We where aborted and should try again from upper level*/ + thd->some_tables_deleted= 1; } - else if (!thd->some_tables_deleted || (flags & MYSQL_LOCK_IGNORE_FLUSH)) + else { /* - Thread was killed or lock aborted. Let upper level close all - used tables and retry or give error. + Lock worked. Now check that nothing happend while we where waiting + to get the lock that would require us to free it. */ - thd->locked=0; - break; - } - else if (!thd->open_tables) - { - // Only using temporary tables, no need to unlock - thd->some_tables_deleted=0; - thd->locked=0; - break; + error= 0; + if (!thd->some_tables_deleted || (flags & MYSQL_LOCK_IGNORE_FLUSH)) + { + /* + Table was not signaled for deletion or we don't care if it was. + Return with table as locked. + */ + break; + } + else if (!thd->open_tables && !(flags & MYSQL_LOCK_NOT_TEMPORARY)) + { + /* + Only using temporary tables, no need to unlock. + We need the flag as open_tables is not enough to distingush if + we are only using temporary tables for tables used trough + the HANDLER interface. + + We reset some_tables_deleted as it doesn't make sense to have this + one when we are only using temporary tables. + */ + thd->some_tables_deleted=0; + break; + } + /* some table was altered or deleted. reopen tables marked deleted */ + error= 1; + mysql_unlock_tables(thd, sql_lock, 0); } - thd_proc_info(thd, 0); - /* some table was altered or deleted. reopen tables marked deleted */ - mysql_unlock_tables(thd,sql_lock); - thd->locked=0; retry: - sql_lock=0; if (flags & MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN) { *need_reopen= TRUE; break; } if (wait_for_tables(thd)) - break; // Couldn't open tables - } - thd_proc_info(thd, 0); - if (thd->killed) - { - thd->send_kill_message(); - if (sql_lock) - { - mysql_unlock_tables(thd,sql_lock); - sql_lock=0; - } + break; // Couldn't open tables + reset_lock_data(sql_lock, 0); // Set org locks and retry } + thd_proc_info(thd, 0); thd->set_time_after_lock(); - DBUG_RETURN (sql_lock); + DBUG_RETURN(error); } @@ -380,15 +384,15 @@ static int lock_external(THD *thd, TABLE **tables, uint count) DBUG_RETURN(0); } - -void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock) +void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock, bool free_lock) { DBUG_ENTER("mysql_unlock_tables"); if (sql_lock->table_count) VOID(unlock_external(thd,sql_lock->table,sql_lock->table_count)); if (sql_lock->lock_count) thr_multi_unlock(sql_lock->locks,sql_lock->lock_count, 0); - my_free((uchar*) sql_lock,MYF(0)); + if (free_lock) + my_free((uchar*) sql_lock,MYF(0)); DBUG_VOID_RETURN; } @@ -847,12 +851,12 @@ static int unlock_external(THD *thd, TABLE **table,uint count) @param write_lock_used Store pointer to last table with WRITE_ALLOW_WRITE */ -static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, - uint flags, TABLE **write_lock_used) +MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, + uint flags, TABLE **write_lock_used) { uint i,tables,lock_count; MYSQL_LOCK *sql_lock; - THR_LOCK_DATA **locks, **locks_buf, **locks_start; + THR_LOCK_DATA **locks, **locks_buf; TABLE **to, **table_buf; DBUG_ENTER("get_lock_data"); @@ -891,7 +895,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, { TABLE *table; enum thr_lock_type lock_type; - + THR_LOCK_DATA **locks_start; if ((table=table_ptr[i])->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE) continue; lock_type= table->reginfo.lock_type; @@ -904,12 +908,11 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, my_error(ER_OPEN_AS_READONLY,MYF(0),table->alias.c_ptr()); /* Clear the lock type of the lock data that are stored already. */ sql_lock->lock_count= (uint) (locks - sql_lock->locks); - reset_lock_data(sql_lock); + reset_lock_data(sql_lock, 1); my_free((uchar*) sql_lock,MYF(0)); DBUG_RETURN(0); } } - THR_LOCK_DATA **org_locks = locks; locks_start= locks; locks= table->file->store_lock(thd, locks, (flags & GET_LOCK_UNLOCK) ? TL_IGNORE : @@ -922,8 +925,13 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, } *to++= table; if (locks) - for ( ; org_locks != locks ; org_locks++) - (*org_locks)->debug_print_param= (void *) table; + { + for ( ; locks_start != locks ; locks_start++) + { + (*locks_start)->debug_print_param= (void *) table; + (*locks_start)->org_type= (*locks_start)->type; + } + } } /* We do not use 'tables', because there are cases where store_lock() @@ -964,10 +972,13 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, Clear the lock type of all lock data. This ensures that the next lock request will set its lock type properly. - @param sql_lock The MySQL lock. + @param sql_lock The MySQL lock. + @param unlock If set, then set lock type to TL_UNLOCK, + otherwise set to original lock type from + get_store_lock(). */ -static void reset_lock_data(MYSQL_LOCK *sql_lock) +static void reset_lock_data(MYSQL_LOCK *sql_lock, bool unlock) { THR_LOCK_DATA **ldata; THR_LOCK_DATA **ldata_end; @@ -975,10 +986,7 @@ static void reset_lock_data(MYSQL_LOCK *sql_lock) for (ldata= sql_lock->locks, ldata_end= ldata + sql_lock->lock_count; ldata < ldata_end; ldata++) - { - /* Reset lock type. */ - (*ldata)->type= TL_UNLOCK; - } + (*ldata)->type= unlock ? TL_UNLOCK : (*ldata)->org_type; } -- cgit v1.2.1 From 69fe020f01a7eefa9f737291f0da2be56f42a6a0 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Wed, 26 Jan 2011 15:17:46 +0200 Subject: Fixed bugs found by buildbot: - Use -Wno-uninitialized if -DFORCE_INIT_OF_VARS is not used, to avoid warnings about not initialized variables. - Fixed compiler warnings - Added a name for each thr_lock to get better error messages (This is needed to find out why 'archive.test' sometimes fails) BUILD/SETUP.sh: Use -Wno-uninitialized if -DFORCE_INIT_OF_VARS is not used, to avoid warnings about not initialized variables. BUILD/build_mccge.sh: Use -Wno-uninitialized if -DFORCE_INIT_OF_VARS is not used, to avoid warnings about not initialized variables. client/mysqltest.cc: Fixed bug in remove_files_wildcards (the orignal code never removed anything) extra/libevent/devpoll.c: Fixed compiler warning include/thr_lock.h: Added a name for each thr_lock to get better error messages. mysql-test/suite/maria/t/maria3.test: Speed up test. mysys/thr_lock.c: Added a name for each thr_lock to get better error messages. Added a second 'check_locks' to find if something goes wrong in 'wake_up_waiters'. sql/lock.cc: Added a name for each thr_lock to get better error messages. storage/xtradb/fil/fil0fil.c: Fixed compiler warning --- sql/lock.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sql/lock.cc') diff --git a/sql/lock.cc b/sql/lock.cc index e5ea85e7ce7..c59ec0e90e2 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -923,7 +923,10 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, *to++= table; if (locks) for ( ; org_locks != locks ; org_locks++) + { (*org_locks)->debug_print_param= (void *) table; + (*org_locks)->lock->name= table->alias; + } } /* We do not use 'tables', because there are cases where store_lock() -- cgit v1.2.1 From ff3da0f963b28d128005da8ca5d0c93a72d34b27 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Mon, 28 Feb 2011 12:48:50 +0200 Subject: Change TABLE->alias to String for less memory reallocation Changed some String.ptr() -> String.c_ptr() for String that are not guaranteed to end with \0 Removed some c_ptr() usage from parameters to functions that takes ptr & length Use preallocate buffers to avoid calling malloc() for most operations. sql/event_db_repository.cc: alias is now a String sql/event_scheduler.cc: c_ptr -> c_ptr_safe() to avoid warnings from valgrind. sql/events.cc: c_ptr -> c_ptr_safe() to avoid warnings from valgrind. c_ptr -> ptr() as function takes ptr & length sql/field.cc: alias is now a String sql/field.h: alias is now a String sql/ha_partition.cc: alias is now a String sql/handler.cc: alias is now a String ptr() -> c_ptr() as string is not guaranteed to be \0 terminated sql/item.cc: Store error parameter in separarte buffer to ensure correct error message sql/item_func.cc: ptr() -> c_ptr_safe() as string is not guaranteed to be \0 terminated sql/item_sum.h: Use my_strtod() instead of my_atof() to not have to make string \0 terminated sql/lock.cc: alias is now a String sql/log.cc: c_ptr() -> ptr() as function takes ptr & length sql/log_event.cc: c_ptr_quick() -> ptr() as we only want to get the pointer to String buffer sql/opt_range.cc: ptr() -> c_ptr() as string is not guaranteed to be \0 terminated sql/opt_table_elimination.cc: alias is now a String sql/set_var.cc: ptr() -> c_ptr() as string is not guaranteed to be \0 terminated c_ptr() -> c_ptr_safe() to avoid warnings from valgrind. c_ptr() -> ptr() as function takes ptr & length Simplify some code. sql/sp.cc: c_ptr() -> ptr() as function takes ptr & length sql/sp_rcontext.cc: alias is now a String sql/sql_base.cc: alias is now a String. Here we win a realloc() for most alias usage. sql/sql_class.cc: Use size descriptor for printf() to avoid accessing bytes outside of buffer sql/sql_insert.cc: Change allocation of TABLE as it's now contains a String _ptr() -> ptr() as function takes ptr & length sql/sql_load.cc: Use preallocate buffers to avoid calling malloc() for most operations. sql/sql_parse.cc: Use c_ptr_safe() to ensure string is \0 terminated. sql/sql_plugin.cc: c_ptr_quick() -> ptr() as function takes ptr & length sql/sql_select.cc: alias is now a String sql/sql_show.cc: alias is now a String sql/sql_string.h: Added move() function to change who owns the string (owner does the free) sql/sql_table.cc: alias is now a String c_ptr() -> c_ptr_safe() to avoid warnings from valgrind. sql/sql_test.cc: c_ptr() -> c_ptr_safe() to avoid warnings from valgrind. alias is now a String sql/sql_trigger.cc: c_ptr() -> c_ptr_safe() to avoid warnings from valgrind. Use field->init() to setup pointers to alias. sql/sql_update.cc: alias is now a String sql/sql_view.cc: ptr() -> c_ptr_safe() as string is not guaranteed to be \0 terminated sql/sql_yacc.yy: r() -> c_ptr() as string is not guaranteed to be \0 terminated sql/table.cc: alias is now a String sql/table.h: alias is now a String storage/federatedx/ha_federatedx.cc: Remove extra 1 byte alloc that is automaticly done by strmake() Ensure that error message ends with \0 storage/maria/ha_maria.cc: alias is now a String storage/myisam/ha_myisam.cc: alias is now a String --- sql/lock.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql/lock.cc') diff --git a/sql/lock.cc b/sql/lock.cc index 566275c5ea2..7c569bf7cfc 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -903,7 +903,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, *write_lock_used=table; if (table->db_stat & HA_READ_ONLY) { - my_error(ER_OPEN_AS_READONLY,MYF(0),table->alias); + my_error(ER_OPEN_AS_READONLY,MYF(0),table->alias.c_ptr()); /* Clear the lock type of the lock data that are stored already. */ sql_lock->lock_count= (uint) (locks - sql_lock->locks); reset_lock_data(sql_lock); -- cgit v1.2.1 From 6da8ac5f71a6501cb0fb1304ff144ec41b4d9389 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Thu, 28 Apr 2011 18:02:26 +0300 Subject: Added option "AND DISABLE CHECKPOINT" to "FLUSH TABLES WITH READ LOCK" This makes it possible to do safe multi volume snapshots as long as one snapshots the volume with the transaction logs last. include/mysql_com.h: Added REFRESH_CHECKPOINT mysql-test/r/flush.result: Added test of new FLUSH TABLES syntax + calls to checkpoint_status handler calls mysql-test/t/flush.test: Added test of new FLUSH TABLES syntax + calls to checkpoint_status handler calls sql/handler.cc: Added code to call checkpoint_state for all handlertons that supports it sql/handler.h: Added new checkpoint_state() handlerton call to temporarly disable checkpoints. sql/lex.h: Added CHECKPOINT keyword sql/sql_yacc.yy: Added support for FLUSH TABLES WITH READ LOCK AND DISABLE CHECKPOINT storage/maria/ha_maria.cc: Added handlerton call to disable checkpoints. storage/maria/ma_checkpoint.c: Don't do checkpoint if checkpoints are disabled. storage/maria/ma_static.c: Added maria_checkpoint_disabled storage/maria/maria_def.h: Added maria_checkpoint_disabled storage/xtradb/handler/ha_innodb.cc: Added handlerton call to disable checkpoints. storage/xtradb/include/log0log.h: Added option to log_checkpoint() to allow one to ignore not critical checkpoints during the time checkpoints are disabled. storage/xtradb/log/log0log.c: Added code to allow one to disable checkpoints during a FLUSH TABLES ... DISABLE CHECKPOINT This was done by adding a new argument to log_checkpoint() which tells us when the checkpoint is called by srv_master_thread (which are safe to ignore) storage/xtradb/srv/srv0srv.c: Tell log_checkpoint() that checkpoints from srv_master_thread() are safe to ignore (will just delay recovery time a bit). --- sql/lock.cc | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'sql/lock.cc') diff --git a/sql/lock.cc b/sql/lock.cc index 740b54f9153..2dc6bc357f4 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -1449,7 +1449,7 @@ static void print_lock_error(int error, const char *table) ****************************************************************************/ -volatile uint global_read_lock=0; +volatile uint global_read_lock=0, global_disable_checkpoint= 0; volatile uint global_read_lock_blocks_commit=0; static volatile uint protect_against_global_read_lock=0; static volatile uint waiting_for_read_lock=0; @@ -1508,6 +1508,14 @@ void unlock_global_read_lock(THD *thd) tmp= --global_read_lock; if (thd->global_read_lock == MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT) --global_read_lock_blocks_commit; + if (thd->global_disable_checkpoint) + { + thd->global_disable_checkpoint= 0; + if (!--global_disable_checkpoint) + { + ha_checkpoint_state(0); // Enable checkpoints + } + } pthread_mutex_unlock(&LOCK_global_read_lock); /* Send the signal outside the mutex to avoid a context switch */ if (!tmp) @@ -1629,6 +1637,24 @@ bool make_global_read_lock_block_commit(THD *thd) } +/** + Disable checkpoints for all handlers + This is released in unlock_global_read_lock() +*/ + +void disable_checkpoints(THD *thd) +{ + pthread_mutex_lock(&LOCK_global_read_lock); + if (!thd->global_disable_checkpoint) + { + thd->global_disable_checkpoint= 1; + if (!global_disable_checkpoint++) + ha_checkpoint_state(1); // Disable checkpoints + } + pthread_mutex_unlock(&LOCK_global_read_lock); +} + + /** Broadcast COND_refresh and COND_global_read_lock. -- cgit v1.2.1