From: Jon Olav Hauglid Date: November 8 2010 3:04pm Subject: bzr commit into mysql-5.5-runtime branch (jon.hauglid:3179) Bug#57663 List-Archive: http://lists.mysql.com/commits/123102 X-Bug: 57663 Message-Id: <201011081505.oA8BYbEt029244@rcsinet13.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============3827341166988014545==" --===============3827341166988014545== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///export/home/x/mysql-5.5-runtime-refactor/ based on revid:jon.hauglid@stripped 3179 Jon Olav Hauglid 2010-11-08 Bug #57663 Concurrent statement using stored function and DROP DATABASE breaks SBR This is a preliminary version of the patch. The problem was that DROP DATABASE ignores any metadata locks on stored functions and procedures held by other connections. This makes it possible for DROP DATABASE to drop functions/procedures that are in use by other connections and therefore break statement based replication. (DROP DATABASE can appear in the binlog before a statement using a dropped function/procedure.) This problem was an issue left unresolved by the patch for Bug#30977 where metadata locks for stored functions/procedures were introduced. This patch fixes the problem by making sure DROP DATABASE takes exclusive metadata locks on all stored functions/procedures to be dropped. Test case added to sp-lock.test. modified: mysql-test/r/sp-lock.result mysql-test/t/sp-lock.test sql/sql_db.cc sql/sql_table.cc === modified file 'mysql-test/r/sp-lock.result' --- a/mysql-test/r/sp-lock.result 2010-08-06 11:29:37 +0000 +++ b/mysql-test/r/sp-lock.result 2010-11-08 15:04:43 +0000 @@ -735,5 +735,91 @@ END latin1 latin1_swedish_ci latin1_swed # Connection default; DROP PROCEDURE p1; # +# Bug#57663 Concurrent statement using stored function and DROP DATABASE +# breaks SBR +# +DROP DATABASE IF EXISTS db1; +DROP FUNCTION IF EXISTS f1; +# Test 1: Check that DROP DATABASE block if a function is used +# by an active transaction. +# Connection default +CREATE DATABASE db1; +CREATE FUNCTION db1.f1() RETURNS INTEGER RETURN 1; +START TRANSACTION; +SELECT db1.f1(); +db1.f1() +1 +# Connection con1 +# Sending: +DROP DATABASE db1; +# Connection default +COMMIT; +# Connection con1 +# Reaping: DROP DATABASE db1 +# Test 2: Check that DROP DATABASE blocks if a procedure is +# used by an active transaction. +# Connection default +CREATE DATABASE db1; +CREATE PROCEDURE db1.p1() BEGIN END; +CREATE FUNCTION f1() RETURNS INTEGER +BEGIN +CALL db1.p1(); +RETURN 1; +END| +START TRANSACTION; +SELECT f1(); +f1() +1 +# Connection con1 +# Sending: +DROP DATABASE db1; +# Connection default +COMMIT; +# Connection con1 +# Reaping: DROP DATABASE db1 +# Test 3: Check that DROP DATABASE is not selected as a victim if a +# deadlock is discovered with DML statements. +# Connection default +CREATE DATABASE db1; +CREATE FUNCTION db1.f1() RETURNS INTEGER RETURN 1; +CREATE FUNCTION db1.f2() RETURNS INTEGER RETURN 1; +START TRANSACTION; +SELECT db1.f2(); +db1.f2() +1 +# Connection con1 +# Sending: +DROP DATABASE db1; +# Connection default +SELECT db1.f1(); +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +COMMIT; +# Connection con1 +# Reaping: DROP DATABASE db1 +# Test 4: Check that active DROP DATABASE blocks stored routine DDL. +# Connection default +CREATE DATABASE db1; +CREATE FUNCTION db1.f1() RETURNS INTEGER RETURN 1; +CREATE FUNCTION db1.f2() RETURNS INTEGER RETURN 2; +START TRANSACTION; +SELECT db1.f2(); +db1.f2() +2 +# Connection con1 +# Sending: +DROP DATABASE db1; +# Connection con2 +# Sending: +ALTER FUNCTION db1.f1 COMMENT "test"; +# Connection default +COMMIT; +# Connection con1 +# Reaping: DROP DATABASE db1 +# Connection con2 +# Reaping: ALTER FUNCTION f1 COMMENT 'test' +ERROR 42000: FUNCTION db1.f1 does not exist +# Connection default +DROP FUNCTION f1; +# # End of 5.5 tests # === modified file 'mysql-test/t/sp-lock.test' --- a/mysql-test/t/sp-lock.test 2010-08-06 11:29:37 +0000 +++ b/mysql-test/t/sp-lock.test 2010-11-08 15:04:43 +0000 @@ -972,5 +972,165 @@ DROP PROCEDURE p1; --echo # +--echo # Bug#57663 Concurrent statement using stored function and DROP DATABASE +--echo # breaks SBR +--echo # + +--disable_warnings +DROP DATABASE IF EXISTS db1; +DROP FUNCTION IF EXISTS f1; +--enable_warnings + +connect(con1, localhost, root); +connect(con2, localhost, root); + +--echo # Test 1: Check that DROP DATABASE block if a function is used +--echo # by an active transaction. + +--echo # Connection default +connection default; +CREATE DATABASE db1; +CREATE FUNCTION db1.f1() RETURNS INTEGER RETURN 1; +START TRANSACTION; +SELECT db1.f1(); + +--echo # Connection con1 +connection con1; +--echo # Sending: +--send DROP DATABASE db1 + +--echo # Connection default +connection default; +let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist + WHERE state= 'Waiting for stored function metadata lock' + AND info='DROP DATABASE db1'; +--source include/wait_condition.inc +COMMIT; + +--echo # Connection con1 +connection con1; +--echo # Reaping: DROP DATABASE db1 +--reap + +--echo # Test 2: Check that DROP DATABASE blocks if a procedure is +--echo # used by an active transaction. + +--echo # Connection default +connection default; +CREATE DATABASE db1; +CREATE PROCEDURE db1.p1() BEGIN END; +delimiter |; +CREATE FUNCTION f1() RETURNS INTEGER +BEGIN + CALL db1.p1(); + RETURN 1; +END| +delimiter ;| +START TRANSACTION; +SELECT f1(); + +--echo # Connection con1 +connection con1; +--echo # Sending: +--send DROP DATABASE db1 + +--echo # Connection default +connection default; +let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist + WHERE state= 'Waiting for stored procedure metadata lock' + AND info='DROP DATABASE db1'; +--source include/wait_condition.inc +COMMIT; + +--echo # Connection con1 +connection con1; +--echo # Reaping: DROP DATABASE db1 +--reap + +--echo # Test 3: Check that DROP DATABASE is not selected as a victim if a +--echo # deadlock is discovered with DML statements. + +--echo # Connection default +connection default; +CREATE DATABASE db1; +CREATE FUNCTION db1.f1() RETURNS INTEGER RETURN 1; +CREATE FUNCTION db1.f2() RETURNS INTEGER RETURN 1; +START TRANSACTION; +# DROP DATABASE will try to lock f2 before f1 +SELECT db1.f2(); + +--echo # Connection con1 +connection con1; +--echo # Sending: +--send DROP DATABASE db1 + +--echo # Connection default +connection default; +let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist + WHERE state= 'Waiting for stored function metadata lock' + AND info='DROP DATABASE db1'; +--source include/wait_condition.inc +--error ER_LOCK_DEADLOCK +SELECT db1.f1(); +COMMIT; + +--echo # Connection con1 +connection con1; +--echo # Reaping: DROP DATABASE db1 +--reap + +--echo # Test 4: Check that active DROP DATABASE blocks stored routine DDL. + +--echo # Connection default +connection default; +CREATE DATABASE db1; +CREATE FUNCTION db1.f1() RETURNS INTEGER RETURN 1; +CREATE FUNCTION db1.f2() RETURNS INTEGER RETURN 2; +START TRANSACTION; +SELECT db1.f2(); + +--echo # Connection con1 +connection con1; +--echo # Sending: +--send DROP DATABASE db1 + +--echo # Connection con2 +connection con2; +let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist + WHERE state= 'Waiting for stored function metadata lock' + AND info='DROP DATABASE db1'; +--source include/wait_condition.inc +--echo # Sending: +--send ALTER FUNCTION db1.f1 COMMENT "test" + +--echo # Connection default +connection default; +let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist + WHERE state= 'Waiting for schema metadata lock' + AND info='ALTER FUNCTION db1.f1 COMMENT "test"'; +--source include/wait_condition.inc +COMMIT; + +--echo # Connection con1 +connection con1; +--echo # Reaping: DROP DATABASE db1 +--reap +disconnect con1; +--source include/wait_until_disconnected.inc + +--echo # Connection con2 +connection con2; +--echo # Reaping: ALTER FUNCTION f1 COMMENT 'test' +--error ER_SP_DOES_NOT_EXIST +--reap +disconnect con2; +--source include/wait_until_disconnected.inc + +--echo # Connection default +connection default; +DROP FUNCTION f1; + + +--echo # --echo # End of 5.5 tests --echo # === modified file 'sql/sql_db.cc' --- a/sql/sql_db.cc 2010-10-19 10:29:21 +0000 +++ b/sql/sql_db.cc 2010-11-08 15:04:43 +0000 @@ -30,6 +30,9 @@ #include "log_event.h" // Query_log_event #include #include "sp.h" +#include "sp_head.h" // TYPE_ENUM_FUNCTION +#include "sql_base.h" // lock_table_names,close_system_tables +#include "sql_handler.h" // mysql_ha_rm_tables #include "events.h" #include #include @@ -44,8 +47,12 @@ const char *del_exts[]= {".frm", ".BAK", static TYPELIB deletable_extentions= {array_elements(del_exts)-1,"del_exts", del_exts, NULL}; -static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, - const char *db, const char *path, uint level, +static bool lock_db_routines(THD *thd, char *db); +static long find_db_tables(THD *thd, MY_DIR *dirp, const char *db, + const char *path, TABLE_LIST **tables, + ulong *found_other_files); +static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *path, + ulong found_other_files, TABLE_LIST **dropped_tables); long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path); @@ -787,10 +794,27 @@ bool mysql_rm_db(THD *thd,char *db,bool } else { + ulong found_other_files= 0; Drop_table_error_handler err_handler; thd->push_internal_handler(&err_handler); error= -1; + + /* Lock all tables and stored routines about to be dropped. */ + if (find_db_tables(thd, dirp, db, path, &dropped_tables, + &found_other_files) || + lock_table_names(thd, dropped_tables, NULL, + thd->variables.lock_wait_timeout, + MYSQL_OPEN_SKIP_TEMPORARY) || + lock_db_routines(thd, db)) + { + thd->pop_internal_handler(); + goto exit; + } + + if (dropped_tables) + mysql_ha_rm_tables(thd, dropped_tables); + /* We temporarily disable the binary log while dropping the objects in the database. Since the DROP DATABASE statement is always @@ -809,7 +833,7 @@ bool mysql_rm_db(THD *thd,char *db,bool as disabled and will not log the drop database statement on any other connected server. */ - if ((deleted= mysql_rm_known_files(thd, dirp, db, path, 0, + if ((deleted= mysql_rm_known_files(thd, dirp, path, found_other_files, &dropped_tables)) >= 0) { ha_drop_database(path); @@ -932,23 +956,67 @@ exit: DBUG_RETURN(error); } -/* - Removes files with known extensions plus all found subdirectories that - are 2 hex digits (raid directories). - thd MUST be set when calling this function! -*/ -static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, - const char *org_path, uint level, - TABLE_LIST **dropped_tables) +static bool lock_db_routines(THD *thd, char *db) +{ + TABLE *table; + uint key_len; + int nxtres= 0; + Open_tables_backup open_tables_state_backup; + MDL_request_list mdl_requests; + DBUG_ENTER("find_db_routine"); + + table = open_proc_table_for_read(thd, &open_tables_state_backup); + if (!table) + { + /* + mysql.proc will be re-opened during deletion, so we don't need to + report errors here. Also, DROP DB should not fail even if mysql.proc + can't be opened. + */ + thd->warning_info->clear_warning_info(thd->query_id); + thd->clear_error(); + DBUG_RETURN(FALSE); + } + + table->field[MYSQL_PROC_FIELD_DB]->store(db, strlen(db), system_charset_info); + key_len= table->key_info->key_part[0].store_length; + table->file->ha_index_init(0, 1); + + if (! table->file->index_read_map(table->record[0], + table->field[MYSQL_PROC_FIELD_DB]->ptr, + (key_part_map)1, HA_READ_KEY_EXACT)) + { + do + { + char *sp_name= get_field(thd->mem_root, + table->field[MYSQL_PROC_FIELD_NAME]); + longlong sp_type= table->field[MYSQL_PROC_MYSQL_TYPE]->val_int(); + MDL_request *mdl_request= new (thd->mem_root) MDL_request; + mdl_request->init(sp_type == TYPE_ENUM_FUNCTION ? + MDL_key::FUNCTION : MDL_key::PROCEDURE, + db, sp_name, MDL_EXCLUSIVE); + mdl_requests.push_front(mdl_request); + } while (! (nxtres= table->file->index_next_same(table->record[0], + table->field[MYSQL_PROC_FIELD_DB]->ptr, + key_len))); + } + table->file->ha_index_end(); + close_system_tables(thd, &open_tables_state_backup); + if (nxtres != 0 && nxtres != HA_ERR_END_OF_FILE) + DBUG_RETURN(TRUE); + DBUG_RETURN(thd->mdl_context.acquire_locks(&mdl_requests, + thd->variables.lock_wait_timeout)); +} + + +static long find_db_tables(THD *thd, MY_DIR *dirp, const char *db, + const char *path, TABLE_LIST **tables, + ulong *found_other_files) { - long deleted=0; - ulong found_other_files=0; char filePath[FN_REFLEN]; TABLE_LIST *tot_list=0, **tot_list_next_local, **tot_list_next_global; - List raid_dirs; - DBUG_ENTER("mysql_rm_known_files"); - DBUG_PRINT("enter",("path: %s", org_path)); + DBUG_ENTER("find_db_tables"); tot_list_next_local= tot_list_next_global= &tot_list; @@ -965,37 +1033,8 @@ static long mysql_rm_known_files(THD *th (file->name[1] == '.' && !file->name[2]))) continue; - /* Check if file is a raid directory */ - if ((my_isdigit(system_charset_info, file->name[0]) || - (file->name[0] >= 'a' && file->name[0] <= 'f')) && - (my_isdigit(system_charset_info, file->name[1]) || - (file->name[1] >= 'a' && file->name[1] <= 'f')) && - !file->name[2] && !level) - { - char newpath[FN_REFLEN], *copy_of_path; - MY_DIR *new_dirp; - String *dir; - uint length; - - strxmov(newpath,org_path,"/",file->name,NullS); - length= unpack_filename(newpath,newpath); - if ((new_dirp = my_dir(newpath,MYF(MY_DONT_SORT)))) - { - DBUG_PRINT("my",("New subdir found: %s", newpath)); - if ((mysql_rm_known_files(thd, new_dirp, NullS, newpath,1,0)) < 0) - goto err; - if (!(copy_of_path= (char*) thd->memdup(newpath, length+1)) || - !(dir= new (thd->mem_root) String(copy_of_path, length, - &my_charset_bin)) || - raid_dirs.push_back(dir)) - goto err; - continue; - } - found_other_files++; - continue; - } - else if (file->name[0] == 'a' && file->name[1] == 'r' && - file->name[2] == 'c' && file->name[3] == '\0') + if (file->name[0] == 'a' && file->name[1] == 'r' && + file->name[2] == 'c' && file->name[3] == '\0') { /* .frm archive: Those archives are obsolete, but following code should @@ -1003,16 +1042,16 @@ static long mysql_rm_known_files(THD *th */ char newpath[FN_REFLEN]; MY_DIR *new_dirp; - strxmov(newpath, org_path, "/", "arc", NullS); + strxmov(newpath, path, "/", "arc", NullS); (void) unpack_filename(newpath, newpath); if ((new_dirp = my_dir(newpath, MYF(MY_DONT_SORT)))) { DBUG_PRINT("my",("Archive subdir found: %s", newpath)); if ((mysql_rm_arc_files(thd, new_dirp, newpath)) < 0) - goto err; + DBUG_RETURN(TRUE); continue; } - found_other_files++; + (*found_other_files)++; continue; } if (!(extension= strrchr(file->name, '.'))) @@ -1020,7 +1059,7 @@ static long mysql_rm_known_files(THD *th if (find_type(extension, &deletable_extentions,1+2) <= 0) { if (find_type(extension, ha_known_exts(),1+2) <= 0) - found_other_files++; + (*found_other_files)++; continue; } /* just for safety we use files_charset_info */ @@ -1036,7 +1075,7 @@ static long mysql_rm_known_files(THD *th strlen(file->name) + 1); if (!table_list) - goto err; + DBUG_RETURN(TRUE); table_list->db= (char*) (table_list+1); table_list->db_length= strmov(table_list->db, db) - table_list->db; table_list->table_name= table_list->db + table_list->db_length + 1; @@ -1060,47 +1099,60 @@ static long mysql_rm_known_files(THD *th (*tot_list_next_global)= table_list; tot_list_next_local= &table_list->next_local; tot_list_next_global= &table_list->next_global; - deleted++; } else { - strxmov(filePath, org_path, "/", file->name, NullS); + strxmov(filePath, path, "/", file->name, NullS); if (mysql_file_delete_with_symlink(key_file_misc, filePath, MYF(MY_WME))) - { - goto err; - } + DBUG_RETURN(TRUE); } } - if (thd->killed || - (tot_list && mysql_rm_table_part2(thd, tot_list, 1, 0, 1, 1))) - goto err; + *tables= tot_list; + DBUG_RETURN(FALSE); +} + - /* Remove RAID directories */ +/* + Removes files with known extensions. + thd MUST be set when calling this function! +*/ + +static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *path, + ulong found_other_files, + TABLE_LIST **dropped_tables) +{ + long deleted=0; + TABLE_LIST *table; + DBUG_ENTER("mysql_rm_known_files"); + DBUG_PRINT("enter",("path: %s", path)); + + for (table= *dropped_tables; table; table= table->next_local) { - List_iterator it(raid_dirs); - String *dir; - while ((dir= it++)) - if (rmdir(dir->c_ptr()) < 0) - found_other_files++; + tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table->db, table->table_name, + FALSE); + deleted++; } + + if (thd->killed || + (dropped_tables && + mysql_rm_table_part2(thd, *dropped_tables, 1, 0, 1, 1))) + goto err; + my_dirend(dirp); - if (dropped_tables) - *dropped_tables= tot_list; - /* If the directory is a symbolic link, remove the link first, then remove the directory the symbolic link pointed at */ if (found_other_files) { - my_error(ER_DB_DROP_RMDIR, MYF(0), org_path, EEXIST); + my_error(ER_DB_DROP_RMDIR, MYF(0), path, EEXIST); DBUG_RETURN(-1); } else { /* Don't give errors if we can't delete 'RAID' directory */ - if (rm_dir_w_symlink(org_path, level == 0)) + if (rm_dir_w_symlink(path, TRUE)) DBUG_RETURN(-1); } @@ -1108,6 +1160,7 @@ static long mysql_rm_known_files(THD *th err: my_dirend(dirp); + *dropped_tables= NULL; DBUG_RETURN(-1); } === modified file 'sql/sql_table.cc' --- a/sql/sql_table.cc 2010-10-19 10:29:21 +0000 +++ b/sql/sql_table.cc 2010-11-08 15:04:43 +0000 @@ -1851,11 +1851,23 @@ bool mysql_rm_table(THD *thd,TABLE_LIST { bool error; Drop_table_error_handler err_handler; + TABLE_LIST *table; DBUG_ENTER("mysql_rm_table"); /* mark for close and remove all cached entries */ + /* Disable drop of enabled log tables, must be done before name locking */ + for (table= tables; table; table= table->next_local) + { + if (check_if_log_table(table->db_length, table->db, + table->table_name_length, table->table_name, 1)) + { + my_error(ER_BAD_LOG_STATEMENT, MYF(0), "DROP"); + DBUG_RETURN(TRUE); + } + } + if (!drop_temporary) { if (!thd->locked_tables_mode && @@ -1863,10 +1875,69 @@ bool mysql_rm_table(THD *thd,TABLE_LIST DBUG_RETURN(TRUE); } + mysql_ha_rm_tables(thd, tables); + + if (!drop_temporary) + { + if (!thd->locked_tables_mode) + { + if (lock_table_names(thd, tables, NULL, thd->variables.lock_wait_timeout, + MYSQL_OPEN_SKIP_TEMPORARY)) + { + error= TRUE; + goto end; + } + for (table= tables; table; table= table->next_local) + tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table->db, table->table_name, + FALSE); + } + else + { + for (table= tables; table; table= table->next_local) + if (table->open_type != OT_BASE_ONLY && + find_temporary_table(thd, table)) + { + /* + A temporary table. + + Don't try to find a corresponding MDL lock or assign it + to table->mdl_request.ticket. There can't be metadata + locks for temporary tables: they are local to the session. + + Later in this function we release the MDL lock only if + table->mdl_requeset.ticket is not NULL. Thus here we + ensure that we won't release the metadata lock on the base + table locked with LOCK TABLES as a side effect of temporary + table drop. + */ + DBUG_ASSERT(table->mdl_request.ticket == NULL); + } + else + { + /* + Not a temporary table. + + Since 'tables' list can't contain duplicates (this is ensured + by parser) it is safe to cache pointer to the TABLE instances + in its elements. + */ + table->table= find_table_for_mdl_upgrade(thd->open_tables, table->db, + table->table_name, FALSE); + if (!table->table) + { + error= TRUE; + goto end; + } + table->mdl_request.ticket= table->table->mdl_ticket; + } + } + } + thd->push_internal_handler(&err_handler); error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0); thd->pop_internal_handler(); +end: if (thd->global_read_lock.has_protection()) thd->global_read_lock.start_waiting_global_read_lock(thd); @@ -1976,71 +2047,6 @@ int mysql_rm_table_part2(THD *thd, TABLE } } - mysql_ha_rm_tables(thd, tables); - - /* Disable drop of enabled log tables, must be done before name locking */ - for (table= tables; table; table= table->next_local) - { - if (check_if_log_table(table->db_length, table->db, - table->table_name_length, table->table_name, 1)) - { - my_error(ER_BAD_LOG_STATEMENT, MYF(0), "DROP"); - DBUG_RETURN(1); - } - } - - if (!drop_temporary) - { - if (!thd->locked_tables_mode) - { - if (lock_table_names(thd, tables, NULL, thd->variables.lock_wait_timeout, - MYSQL_OPEN_SKIP_TEMPORARY)) - DBUG_RETURN(1); - for (table= tables; table; table= table->next_local) - { - tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table->db, table->table_name, - FALSE); - } - } - else - { - for (table= tables; table; table= table->next_local) - if (table->open_type != OT_BASE_ONLY && - find_temporary_table(thd, table)) - { - /* - A temporary table. - - Don't try to find a corresponding MDL lock or assign it - to table->mdl_request.ticket. There can't be metadata - locks for temporary tables: they are local to the session. - - Later in this function we release the MDL lock only if - table->mdl_requeset.ticket is not NULL. Thus here we - ensure that we won't release the metadata lock on the base - table locked with LOCK TABLES as a side effect of temporary - table drop. - */ - DBUG_ASSERT(table->mdl_request.ticket == NULL); - } - else - { - /* - Not a temporary table. - - Since 'tables' list can't contain duplicates (this is ensured - by parser) it is safe to cache pointer to the TABLE instances - in its elements. - */ - table->table= find_table_for_mdl_upgrade(thd->open_tables, table->db, - table->table_name, FALSE); - if (!table->table) - DBUG_RETURN(1); - table->mdl_request.ticket= table->table->mdl_ticket; - } - } - } - for (table= tables; table; table= table->next_local) { bool is_trans; --===============3827341166988014545== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/jon.hauglid@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: jon.hauglid@stripped # target_branch: file:///export/home/x/mysql-5.5-runtime-refactor/ # testament_sha1: 4fc44dc19b8b02500daec0eef56f0ded66f94ea6 # timestamp: 2010-11-08 16:04:51 +0100 # source_branch: file:///export/home/x/mysql-5.5-bugfixing/ # base_revision_id: jon.hauglid@stripped\ # oc90p0fl571p5dod # # Begin bundle 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 --===============3827341166988014545==--