An error occurred fetching the project authors.
- 29 Jun, 2010 2 commits
-
-
Konstantin Osipov authored
Bug#52114 and Bug#50788. The bugs themselves are regressions that are introduced by an incomplete fix for Bug#36171 and will not be pushed.
-
Konstantin Osipov authored
Remove mysql_lock_have_duplicate(), since now we always have TABLE_LIST objects for MyISAMMRG children in lex->query_tables and keep it till the end of the statement (sub-statement). mysql-test/r/merge.result: Update results (Bug#54811). mysql-test/t/merge-big.test: Update to new wait state. mysql-test/t/merge.test: Add a test case for Bug#54811. sql/lock.cc: Remove a function that is now unused. sql/lock.h: Remove a function that is now unused. sql/sql_base.cc: Don't try to search for duplicate table among THR_LOCK objects, TABLE_LIST list contains all used tables.
-
- 25 Jun, 2010 1 commit
-
-
Jon Olav Hauglid authored
The assert was triggered if a connection executing TRUNCATE on a InnoDB table was killed during open_tables. This bug was fixed in the scope of Bug #45643 "InnoDB does not support replication of TRUNCATE TABLE". This patch adds test coverage to innodb_mysql_sync.test.
-
- 18 Jun, 2010 1 commit
-
-
Konstantin Osipov authored
subsystem. Fix a number of caveates that the previous implementation suffered from, including unprotected access to shared data and lax resource accounting (share->ref_count) that could lead to deadlocks. The new implementation still suffers from a number of potential deadlocks in some edge cases, and this is still not enabled by default. Especially since performance testing has shown that it gives only marginable (not even exceeding measuring accuracy) improvements. @todo: - Remove calls to close_cached_tables() with REFRESH_FAST, and have_lock, because they break the MDL cache. - rework FLUSH TABLES <list> to not use close_cached_tables() - make sure that whenever we set TABLE_SHARE::version to 0 we free MDL cache references to it. sql/mdl.cc: We may cache references to TABLE_SHARE objects in MDL_lock objects for tables. Create a separate MDL_lock class to represent a table. sql/mdl.h: Adjust the MDL caching API to avoid races. sql/sql_base.cc: Move all caching functionality close together. Implement a solution for deadlocks caused by close_cached_tables() when MDL cache is enabled (incomplete). sql/sql_yacc.yy: Adjust FLUSH rule to do the necessary initialization of TABLE_LIST elements used in for FLUSH TABLES <list>, and thus work OK with flush_mdl_cache() function.
-
- 11 Jun, 2010 1 commit
-
-
Konstantin Osipov authored
an atomic counter" Split the large LOCK_open section in open_table(). Do not call open_table_from_share() under LOCK_open. Remove thd->version. This fixes Bug#50589 "Server hang on a query evaluated using a temporary table" Bug#51557 "LOCK_open and kernel_mutex are not happy together" Bug#49463 "LOCK_table and innodb are not nice when handler instances are created". This patch has effect on storage engines that rely on ha_open() PSEA method being called under LOCK_open. In particular: 1) NDB is broken and left unfixed. NDB relies on LOCK_open being kept as part of ha_open(), since it uses auto-discovery. While previously the NDB open code was race-prone, now it simply fails on asserts. 2) HEAP engine had a race in ha_heap::open() when a share for the same table could be added twice to the list of shares, or a dangling reference to a share stored in HEAP handler. This patch aims to address this problem by 'pinning' the newly created share in the internal HEAP engine share list until at least one handler instance is created using that share. include/heap.h: Add members to HP_CREATE_INFO. Declare heap_release_share(). sql/lock.cc: Remove thd->version, use thd->open_tables->s->version instead. sql/repl_failsafe.cc: Remove thd->version. sql/sql_base.cc: - close_thread_table(): move handler cleanup code outside the critical section protected by LOCK_open. - remove thd->version - split the large critical section in open_table() that opens a new table from share and is protected by LOCK_open into 2 critical sections, thus reducing the critical path. - make check_if_table_exists() acquire LOCK_open internally. - use thd->open_tables->s->version instead of thd->refresh_version to make sure that all tables in thd->open_tables are in the same refresh series. sql/sql_base.h: Add declaration for check_if_table_exists(). sql/sql_class.cc: Remove init_open_tables_state(), it's now equal to reset_open_tables_state(). sql/sql_class.h: Remove thd->version, THD::init_open_tables_state(). sql/sql_plugin.cc: Use table->m_needs_reopen to mark the table as stale rather than manipulate with thd->version, which is no more. sql/sql_udf.cc: Use table->m_needs_reopen to mark the table as stale rather than manipulate with thd->version, which is no more. sql/table.h: Remove an unused variable. sql/tztime.cc: Use table->m_needs_reopen to mark the table as stale rather than manipulate with thd->version, which is no more. storage/heap/CMakeLists.txt: Add heap tests to cmake build files. storage/heap/ha_heap.cc: Fix a race when ha_heap::ha_open() could insert two HP_SHARE objects into the internal share list or store a dangling reference to a share in ha_heap instance, or wrongly set implicit_emptied. storage/heap/hp_create.c: Optionally pin a newly created share in the list of shares by increasing its open_count. This is necessary to make sure that a newly created share doesn't disappear while a HP_INFO object is being created to reference it. storage/heap/hp_open.c: When adding a new HP_INFO object to the list of objects in the heap share, make sure the open_count is not increased twice. storage/heap/hp_test1.c: Adjust the test to new function signatures. storage/heap/hp_test2.c: Adjust the test to new function signatures.
-
- 10 Jun, 2010 2 commits
-
-
Konstantin Osipov authored
make tdc_refresh_version an atomic counter". Backport the trivial changes from mysql-trunk-iplus.
-
Konstantin Osipov authored
make tdc_refresh_version an atomic counter". To avoid orphaned TABLE_SHARE objects left in the cache, make sure that wherever we set table->s->version we take care of removing all unused table share objects from the table cache. Always set table->s->version under LOCK_open, to make sure that no other connection sees an old value of the version and adds the table to unused_tables list. Add an assert to table_def_unuse_table() that we never 'unuse' a talbe of a share that has an old version. With this patch, only three places are left in the code that manipulate with table->s->version: - tdc_remove_table(). In most cases we have an X mdl lock in tdc_remove_table(), the two remaining cases when we don't are 'FLUSH TABLE' and mysql_admin_table(). - sql_view.cc - a crude hack that needs a separate fix - initial assignment from refresh_version in table.cc. sql/sql_base.cc: Add an assert. Don't manipulate with table->s->version in auto-repair, auto-discover. Use tdc_remove_table() in auto_repair_table() and drop_open_table(). sql/sql_table.cc: Remove dead code from mysql_admin_table(). Manipulate with table->s->version through the TDC API.
-
- 09 Jun, 2010 1 commit
-
-
Konstantin Osipov authored
mutex protecting thd->open_tables". We should not manipulate with table->s->version outside the table definition cache code, but use the TDC API to achieve the desired result. Fix one violation: close_all_tables_for_name(). sql/sql_base.cc: Use tdc_remove_table(TDC_RT_REMOVE_ALL) to expel the table share in close_all_tables_for_name, rather than manipulate with the table cache explicitly. Make sure that close_cached_tables() calls close_all_tables_for_name() after closing all the involved handlers. The rest of the code was inspected to make sure that mysql_ha_rm_tables() is called. sql/sql_handler.cc: Add a method to close all HANDLER cursors for a list of tables. sql/sql_handler.h: Add declaration for mysql_ha_flush_tables().
-
- 08 Jun, 2010 1 commit
-
-
Konstantin Osipov authored
thd->open_tables" thd->open_tables list is not normally accessed concurrently except for one case: when the connection has open SQL HANDLER tables, and we want to perform a DDL on the table, we want to abort waits on MyISAM thr_lock of those connections that prevent the DDL from proceeding, and iterate over thd->open_tables list to find out the tables on which the thread is waiting. In 5.5 we mostly use deadlock detection and soft deadlock prevention, as opposed to "hard" deadlock prevention of 5.1, which would abort any transaction that may cause a deadlock. The only remaining case when neither deadlock detection nor deadlock prevention is implemented in 5.5 is HANDLER SQL, where we use old good thr_lock_abort() technique form 5.1. Thus, replace use of LOCK_open to protect thd->open_tables with thd->LOCK_ha_data (a lock protecting various session private data). This is a port of the work done for 5.5.4 for review and inclusion into 5.5.5. sql/sql_base.cc: Use thd->LOCK_ha_data (systematically) to set thd->open_tables. sql/sql_class.h: Implement THD::set_open_tables(). sql/sql_cursor.cc: Use thd->LOCK_ha_data (systematically) to set thd->open_tables. sql/sql_handler.cc: Use thd->LOCK_ha_data (systematically) to set thd->open_tables. Acquisition of LOCK_open is moved inside close_thread_table(). sql/sql_table.cc: Acquisition of LOCK_open is moved inside close_thread_tables().
-
- 07 Jun, 2010 2 commits
-
-
Konstantin Osipov authored
1) No mutex and no function call if we're not using plugins. 2) If we're above the table definition cache limit, delete the oldest unused share, not the share on our hands. sql/sql_base.cc: If we're above the table definition cache limit, delete the oldest unused share, not the share on our hands. sql/sql_lex.cc: No mutex and no function call if we're not using plugins.
-
Dmitry Lenev authored
locks for DML statements and changes the way MDL locks are acquired/granted in contended case. Instead of backing-off when a lock conflict is encountered and waiting for it to go away before restarting open_tables() process we now wait for lock to be released without releasing any previously acquired locks. If conflicting lock goes away we resume opening tables. If waiting leads to a deadlock we try to resolve it by backing-off and restarting open_tables() immediately. As result both waiting for possibility to acquire and acquiring of a metadata lock now always happen within the same MDL API call. This has allowed to make release of a lock and granting it to the most appropriate pending request an atomic operation. Thanks to this it became possible to wake up during release of lock only those waiters which requests can be satisfied at the moment as well as wake up only one waiter in case when granting its request would prevent all other requests from being satisfied. This solves thundering herd problem which occured in cases when we were releasing some lock and woke up many waiters for SNRW or X locks (this was the issue in bug#52289 "performance regression for MyISAM in sysbench OLTP_RW test". This also allowed to implement more fair (FIFO) scheduling among waiters with the same priority. It also opens the door for introducing new types of requests for metadata locks such as low-prio SNRW lock which is necessary in order to support LOCK TABLES LOW_PRIORITY WRITE. Notice that after this sometimes can report ER_LOCK_DEADLOCK error in cases in which it has not happened before. Particularly we will always report this error if waiting for conflicting lock has happened in the middle of transaction and resulted in a deadlock. Before this patch the error was not reported if deadlock could have been resolved by backing off all metadata locks acquired by the current statement. mysql-test/r/mdl_sync.result: Added test coverage for some aspects of deadlock handling in metadata locking subsystem. Adjusted test case after removing back-off in general case when conflicting metadata lock is encountered during open_tables() (now this happens only if waiting for conflicting lock to go away leads to a deadlock). mysql-test/r/sp_sync.result: Adjusted test case after removing back-off in general case when conflicting metadata lock is encountered during open_tables() (now this happens only if waiting for conflicting lock to go away leads to a deadlock). mysql-test/suite/perfschema/r/dml_setup_instruments.result: Adjusted test results after renaming MDL_context:: m_waiting_for_lock rwlock to m_LOCK_waiting_for. mysql-test/suite/rpl/r/rpl_sp.result: Adjusted test case after implementing new approach to acquiring metadata locks in open_tables(). We no longer release all MDL locks acquired by statement before waiting for conflicting lock to go away. As result DROP FUNCTION statement has to wait for DML statement which managed to acquire metadata lock on function being dropped and now waits for other conflicting metadata lock to go away. mysql-test/suite/rpl/t/rpl_sp.test: Adjusted test case after implementing new approach to acquiring metadata locks in open_tables(). We no longer release all MDL locks acquired by statement before waiting for conflicting lock to go away. As result DROP FUNCTION statement has to wait for DML statement which managed to acquire metadata lock on function being dropped and now waits for other conflicting metadata lock to go away. mysql-test/t/mdl_sync.test: Added test coverage for some aspects of deadlock handling in metadata locking subsystem. Adjusted test case after removing back-off in general case when conflicting metadata lock is encountered during open_tables() (now this happens only if waiting for conflicting lock to go away leads to a deadlock). mysql-test/t/sp_sync.test: Adjusted test case after removing back-off in general case when conflicting metadata lock is encountered during open_tables() (now this happens only if waiting for conflicting lock to go away leads to a deadlock). sql/mdl.cc: Changed MDL subsystem to support new approach to acquring metadata locks in open tables and more fair and efficient scheduling of metadata locks. To implement this: - Made releasing of the lock and granting it to the most appropriate pending request atomic operation. As result it became possible to wake up only those waiters requests from which can be satisfied at the moment as well as wake-up only one waiter in case when granting its request would prevent all other requests from being satisfied. This solved thundering herd problem which occured in cases when we were releasing some lock and woke up many waiters for SNRW or X locks (this was the issue in Bug #52289 "performance regression for MyISAM in sysbench OLTP_RW test". To emphasize above changes wake_up_waiters() was renamed to MDL_context::reschedule_waiters(). - Changed code to add tickets for new requests to the back of waiters queue and to select tickets to be satisfied from the head of the queue if possible (this makes scheduling of requests with the same priority fair). To be able to do this efficiently we now use for waiting and granted queues version of I_P_List class which provides fast push_back() method. - Members and methods of MDL_context related to sending and waiting for signal were moved to separate MDL_wait class. - Since in order to avoid race conditions we must grant the lock only to the context which was not chosen as a victim of deadlock, killed or aborted due to timeout MDL_wait::set_status() (former awake()) was changed not to send signal if signal slot is already occupied and to indicate this fact through its return value. As another consequence MDL_wait::timed_wait() method was changed to handle timeout (optionally) and abort due to kill as signals which make signal slot occupied. - Renamed MDL_context::acquire_lock_impl() to acquire_lock(). Changed it to be able correctly process requests for shared locks when there are open HANDLERs, made this method more optimized for acquisition of shared locks. As part of this change moved code common between try_acquire_lock() and acquire_lock() to new try_acquire_lock_impl() method. Also adjusted acquire_lock()'s code to take into account the fact that in cases when lock is granted as result of MDL_context::reschedule_waiters() call (i.e. when it is granted after waiting for lock conflict to go away) updating MDL_lock state is responsibility of the thread calling reschedule_waiters(). - Changed MDL_context::find_deadlock() to send VICTIM signal even if victim is the context which has initiated deadlock detection. This is required in order to avoid races in cases when the same context simultaneously is chosen as a victim and its request for lock is satisfied. As result return value of this method became unnecessary and it was changed to return void. Adjusted MDL_lock::find_deadlock() method to take into account that now there can be a discrepancy between MDL_context::m_waiting_for value being set and real state of the ticket this member points to. - Renamed MDL_context::m_waiting_for_lock to m_LOCK_waiting_for and MDL_context::stop_waiting() to done_waiting_for(). - Finally, removed MDL_context::wait_for_lock() method. sql/mdl.h: Changed MDL subsystem to support new approach to acquring metadata locks in open tables and more fair and efficient scheduling of metadata locks. To implement this: - Members and methods of MDL_context related to sending and waiting for signal were moved to separate MDL_wait class. - Since now in order to avoid race conditions we must grant the lock only to the context which was not chosen as a victim of deadlock, killed or aborted due to timeout MDL_wait::set_status (former awake()) was changed not to send signal if signal slot is already occupied and to indicate this fact through its return value. Also NORMAL_WAKE_UP signal became GRANTED, and timeouts and aborts due to kill became full blown signals rather than simple return values. - MDL_wait::timed_wait() now takes extra parameter that indicates whether signal should be set if timeout is reached. - Enabled fast push_back() operation in MDL_context::m_tickets list to make move_ticket_after_trans_sentinel() method more efficient. - Removed MDL_context::wait_for_lock() method. - Renamed MDL_context::m_waiting_for_lock to m_LOCK_waiting_for and MDL_context::stop_waiting() to done_waiting_for(). - MDL_context::acquire_lock_impl() became acquire_lock(). - Introduced MDL_context::try_acquire_lock_impl() as a place for code shared by try_acquire_lock and acquire_lock(). - Due to fact that now VICTIM signal is sent even if victim is the context which has initiated deadlock detection find_deadlock() no longer needs a return value. sql/sql_base.cc: Implemented new approach to acquiring metadata locks in open_tables(). We no longer perform back-off when conflicting metadata lock is encountered. Instead we wait for this lock to go away while holding all locks which were acquired so far. Back-off is only used in situation when further waiting will cause a deadlock which could be avoided by performing back-off and restarting open_tables() process. Absence of waiting between back-off and restart of acquiring metadata locks can't lead to livelocks as MDL subsystem was changed to make release of lock and granting it to waiting lock an atomic action, so back-off will automatically give way to other participants of deadlock loop. Accordingly: - open_table_get_mdl_lock() and open_and_process_routine() were changed to wait for conflicting metadata lock to go away without back-off. Only if such wait leads to a deadlock back-off is requested. As part of this change new error handler class was introduced which converts, if possible, ER_LOCK_DEADLOCK error to a request for back-off and re-start of open_tables() process. - Open_table_context::recover_from_failed_open() was changed not to wait in case of metadata lock conflict. Instead we immediately proceed to re-acquiring locks. - Open_table_context::request_backoff_action() now always emits error if back-off is requested in the middle of transaction as we can't be sure that releasing lock which were acquired only by current statement will resolve a deadlock. Before this patch such situations were successfully detected thanks to the fact that we called MDL_context::wait_for_lock() method in recover_from_failed_open(). - In order to avoid deadlocks open_tables() code was adjusted to flush open HANDLERs for which there are pending requests for X locks before restarting the process of acquiring metadata locks. - Changed close_tables_for_reopen() not to reset MDL_request for tables belonging to the tail of prelocking list. It is no longer necessary as these MDL_request objects won't be used for any waiting. - Adjusted comment in tdc_wait_for_old_version() to avoid mentioning removed MDL_context::wait_for_lock() method. sql/sql_base.h: As we no longer wait for conflicting metadata lock away in Open_table_context::recover_from_failed_open() method, Open_table_context::OT_WAIT_MDL_LOCK action was renamed to OT_MDL_CONFLICT. Also Open_table_context::m_failed_mdl_request became unnecessary and was removed. sql/sql_plist.h: Extended I_P_List template to support efficient push_back() operation if it is parameterized with an appropriate policy class. sql/sql_show.cc: Adjusted code after removal of MDL_context::wait_for_lock() method. Now if one needs to acquire metadata lock with waiting one has to use a variant of MDL_context::acquire_lock() method.
-
- 01 Jun, 2010 2 commits
-
-
Konstantin Osipov authored
transactional SELECT and ALTER TABLE ... REBUILD PARTITION". Make open flags part of Open_table_context. This allows to simplify some code and (in future) enforce the invariant that we don't, say, request a back off on the table when there is MYSQL_OPEN_IGNORE_FLUSH flag. sql/sql_base.cc: open_table() flags are part of Open_table_context. Remove dead code that would check for OPEN_VIEW_NO_PARSE, which is not an open table flag. sql/sql_base.h: Move flags to Open_table_context. Reorder Open_table_context members to compact the structure footprint. sql/sql_insert.cc: Update with a new calling signature of open_table(). sql/sql_table.cc: Update with a new calling signature of open_table().
-
Konstantin Osipov authored
transactional SELECT and ALTER TABLE ... REBUILD PARTITION". Move declarations of sql_base.cc classes to sql_base.h (previously declared in sql_class.h). Became possible after a header file split. sql/sql_base.cc: Make sql_base.h the first include in sql_base.cc. sql/sql_base.h: Add declarations of Prelocking_strategy and Open_table_context. sql/sql_class.h: Remove declarations of Prelocking_strategy and Open_table_context (moved).
-
- 27 May, 2010 2 commits
-
-
Dmitry Lenev authored
without FOR UPDATE is causing a lock". SELECT statements with subqueries referencing InnoDB tables were acquiring shared locks on rows in these tables when they were executed in REPEATABLE-READ mode and with statement or mixed mode binary logging turned on. This was a regression which were introduced when fixing bug 39843. The problem was that for tables belonging to subqueries parser set TL_READ_DEFAULT as a lock type. In cases when statement/mixed binary logging at open_tables() time this type of lock was converted to TL_READ_NO_INSERT lock at open_tables() time and caused InnoDB engine to acquire shared locks on reads from these tables. Although in some cases such behavior was correct (e.g. for subqueries in DELETE) in case of SELECT it has caused unnecessary locking. This patch implements minimal version of the fix for the specific problem described in the bug-report which supposed to be not too risky for pushing into 5.1 tree. The 5.5 tree already contains a more appropriate solution which also addresses other related issues like bug 53921 "Wrong locks for SELECTs used stored functions may lead to broken SBR". This patch tries to solve the problem by ensuring that TL_READ_DEFAULT lock which is set in the parser for tables participating in subqueries at open_tables() time is interpreted as TL_READ_NO_INSERT or TL_READ. TL_READ is used only if we know that this is a SELECT and that this particular table is not used by a stored function. Test coverage is added for both InnoDB and MyISAM. This patch introduces an "incompatible" change in locking scheme for subqueries used in SELECT ... FOR UPDATE and SELECT .. IN SHARE MODE. In 4.1 (as well as in 5.0 and 5.1 before fix for bug 39843) the server would use a snapshot InnoDB read for subqueries in SELECT FOR UPDATE and SELECT .. IN SHARE MODE statements, regardless of whether the binary log is on or off. If the user required a different type of read (i.e. locking read), he/she could request so explicitly by providing FOR UPDATE/IN SHARE MODE clause for each individual subquery. The patch for bug 39843 broke this behaviour (which was not documented or tested), and started to use locking reads for all subqueries in SELECT ... FOR UPDATE/IN SHARE MODE. This patch restores 4.1 behaviour. This patch should be mostly null-merged into 5.5 tree. mysql-test/include/check_concurrent_insert.inc: Added auxiliary script which allows to check if statement reading table allows concurrent inserts in it. mysql-test/include/check_no_concurrent_insert.inc: Added auxiliary script which allows to check that statement reading table doesn't allow concurrent inserts in it. mysql-test/include/check_no_row_lock.inc: Added auxiliary script which allows to check if statement reading table doesn't take locks on its rows. mysql-test/include/check_shared_row_lock.inc: Added auxiliary script which allows to check if statement reading table takes shared locks on some of its rows. mysql-test/r/bug39022.result: After bug #46947 'Embedded SELECT without FOR UPDATE is causing a lock' was fixed test case for bug 39022 has to be adjusted in order to trigger execution path on which original problem was encountered. mysql-test/r/innodb_mysql_lock2.result: Added coverage for handling of locking in various cases when we read data from InnoDB tables (includes test case for bug #46947 'Embedded SELECT without FOR UPDATE is causing a lock'). mysql-test/r/lock_sync.result: Added coverage for handling of locking in various cases when we read data from MyISAM tables. mysql-test/t/bug39022.test: After bug #46947 'Embedded SELECT without FOR UPDATE is causing a lock' was fixed test case for bug 39022 has to be adjusted in order to trigger execution path on which original problem was encountered. mysql-test/t/innodb_mysql_lock2.test: Added coverage for handling of locking in various cases when we read data from InnoDB tables (includes test case for bug #46947 'Embedded SELECT without FOR UPDATE is causing a lock'). mysql-test/t/lock_sync.test: Added coverage for handling of locking in various cases when we read data from MyISAM tables. sql/mysql_priv.h: Function read_lock_type_for_table() now takes pointers to LEX and TABLE_LIST elements as its arguments since to correctly determine lock type it needs to know what statement is being performed and whether table element for which lock type to be determined belongs to prelocking list. sql/sql_base.cc: Changed read_lock_type_for_table() to return a weak TL_READ type of lock in cases when we are executing SELECT (and so won't update tables directly) and table doesn't belong to statement's prelocking list and thus can't be used by a stored function. It is OK to do so since in this case table won't be used by statement or function call which will be written to the binary log, so serializability requirements for it can be relaxed. One of results from this change is that SELECTs on InnoDB tables no longer takes shared row locks for tables which are used in subqueries (i.e. bug #46947 is fixed). Another result is that for similar SELECTs on MyISAM tables concurrent inserts are allowed. In order to implement this change signature of read_lock_type_for_table() function was changed to take pointers to LEX and TABLE_LIST objects. sql/sql_update.cc: Function read_lock_type_for_table() now takes pointers to LEX and TABLE_LIST elements as its arguments since to correctly determine lock type it needs to know what statement is being performed and whether table element for which lock type to be determined belongs to prelocking list.
-
Alfranio Correia authored
The thd->variables.option_bits & OPTION_BIN_LOG is currently abused: it's both a system variable and an implementation switch. The current approach to this option bit breaks the session variable encapsulation. Besides it is allowed to change @@session.sql_bin_log within a transaction what may lead to not correctly logging a transaction. To fix the problems, we created a thd->variables variable to represent the "sql_log_bin" and prohibited its update inside a transaction or sub-statement. mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result: Updated result file. The reason the warnings are removed is related to BUG#50312. mysql-test/suite/binlog/r/binlog_switch_inside_trans.result: Checks when is possible to change the option @@session.sql_log_bin. mysql-test/suite/binlog/t/binlog_switch_inside_trans.test: Checks when is possible to change the option @@session.sql_log_bin. mysql-test/suite/rpl/r/rpl_non_direct_stm_mixing_engines.result: Updated the result file with warnings that were being printed due to the wrong use of the thd->variables.option_bits and sql_log_bin_top_level variables. mysql-test/suite/rpl/r/rpl_stm_mixing_engines.result: Updated the result file with warnings that were being printed due to the wrong use of the thd->variables.option_bits and sql_log_bin_top_level variables. sql/share/errmsg-utf8.txt: Introduces two error messages to notify that the @@session.sql_log_bin cannot be changed inside a sub-statement or transaction. sql/sql_base.cc: Removes the variable sql_log_bin_toplevel and uses the session variable sql_log_bin. sql/sql_class.cc: Replaces the variable sql_log_bin_toplevel by the (variables.option_bits & OPTION_BIN_LOG). sql/sql_class.h: Removes the variable sql_log_bin_toplevel and creates a session variable sql_log_bin. sql/sys_vars.cc: Checks when the sql_log_bin can be correctly updated.
-
- 26 May, 2010 1 commit
-
-
Dmitry Lenev authored
SELECT and ALTER TABLE ... REBUILD PARTITION". ALTER TABLE on InnoDB table (including partitioned tables) acquired exclusive locks on rows of table being altered. In cases when there was concurrent transaction which did locking reads from this table this sometimes led to a deadlock which was not detected by MDL subsystem nor by InnoDB engine (and was reported only after exceeding innodb_lock_wait_timeout). This problem stemmed from the fact that ALTER TABLE acquired TL_WRITE_ALLOW_READ lock on table being altered. This lock was interpreted as a write lock and thus for table being altered handler::external_lock() method was called with F_WRLCK as an argument. As result InnoDB engine treated ALTER TABLE as an operation which is going to change data and acquired LOCK_X locks on rows being read from old version of table. In case when there was a transaction which already acquired SR metadata lock on table and some LOCK_S locks on its rows (e.g. by using it in subquery of DML statement) concurrent ALTER TABLE was blocked at the moment when it tried to acquire LOCK_X lock before reading one of these rows. The transaction's attempt to acquire SW metadata lock on table being altered led to deadlock, since it had to wait for ALTER TABLE to release SNW lock. This deadlock was not detected and got resolved only after timeout expiring because waiting were happening in two different subsystems. Similar deadlocks could have occured in other situations. This patch tries to solve the problem by changing ALTER TABLE implementation to use TL_READ_NO_INSERT lock instead of TL_WRITE_ALLOW_READ. After this step handler::external_lock() is called with F_RDLCK as an argument and InnoDB engine correctly interprets ALTER TABLE as operation which only reads data from original version of table. Thanks to this ALTER TABLE acquires only LOCK_S locks on rows it reads. This, in its turn, causes inter-subsystem deadlocks to go away, as all potential lock conflicts and thus deadlocks will be limited to metadata locking subsystem: - When ALTER TABLE reads rows from table being altered it can't encounter any locks which conflict with LOCK_S row locks. There should be no concurrent transactions holding LOCK_X row locks. Such a transaction should have been acquired SW metadata lock on table first which would have conflicted with ALTER's SNW lock. - Vice versa, when DML which runs concurrently with ALTER TABLE tries to lock row it should be requesting only LOCK_S lock which is compatible with locks acquired by ALTER, as otherwise such DML must own an SW metadata lock on table which would be incompatible with ALTER's SNW lock. mysql-test/r/innodb_mysql_lock2.result: Added test for bug #51263 "Deadlock between transactional SELECT and ALTER TABLE ... REBUILD PARTITION". mysql-test/suite/rpl_ndb/r/rpl_ndb_binlog_format_errors.result: Since CREATE TRIGGER no longer acquires write lock on table it is no longer interpreted as an operation which modifies table data and therefore no longer fails if invoked for SBR-only engine in ROW mode. mysql-test/suite/rpl_ndb/t/rpl_ndb_binlog_format_errors.test: Since CREATE TRIGGER no longer acquires write lock on table it is no longer interpreted as an operation which modifies table data and therefore no longer fails if invoked for SBR-only engine in ROW mode. mysql-test/t/innodb_mysql_lock2.test: Added test for bug #51263 "Deadlock between transactional SELECT and ALTER TABLE ... REBUILD PARTITION". sql/ha_partition.cc: When ALTER TABLE creates a new partition to be filled from other partition lock it in F_WRLCK mode instead of using mode which was used for locking the whole table (it is F_RDLCK now). sql/lock.cc: Replaced conditions which used TL_WRITE_ALLOW_READ lock type with equivalent conditions using TL_WRITE_ALLOW_WRITE. This should allow to get rid of TL_WRITE_ALLOW_READ lock type eventually. sql/mdl.cc: Updated outdated comment to reflect current situation. sql/sql_base.cc: Replaced conditions which used TL_WRITE_ALLOW_READ lock type with equivalent conditions using TL_WRITE_ALLOW_WRITE. This should allow to get rid of TL_WRITE_ALLOW_READ lock type eventually. sql/sql_table.cc: mysql_admin_table(): Use TL_WRITE_ALLOW_WRITE lock type instead of TL_WRITE_ALLOW_READ to determine that we need to acquire upgradable metadata lock. This should allow to completely get rid of TL_WRITE_ALLOW_READ in long term. mysql_recreate_table(): ALTER TABLE now requires TL_READ_NO_INSERT thr_lock.c lock instead of TL_WRITE_ALLOW_READ. sql/sql_trigger.cc: Changed CREATE/DROP TRIGGER implementation to use TL_READ_NO_INSERT lock instead of TL_WRITE_ALLOW_READ lock. The latter is no longer necessary since: a) We now can rely on metadata locks to achieve proper isolation between two DDL statements or DDL and DML statements. b) This statement does not change any data in table so there is no need to inform storage engine about it. sql/sql_yacc.yy: Changed implementation of ALTER TABLE (and CREATE/DROP INDEX as a consequence) to use TL_READ_NO_INSERT lock instead of TL_WRITE_ALLOW_READ lock. This is possible since: a) We now can rely on metadata locks to achieve proper isolation between two DDL statements or DDL and DML statements. b) This statement only reads data in table being open. We write data only to the new version of table and then replace with it old version of table under X metadata lock. Thanks to this change InnoDB will no longer acquire LOCK_X locks on rows being read by ALTER TABLE (instead LOCK_S locks will be acquired) and thus cause of bug #51263 "Deadlock between transactional SELECT and ALTER TABLE ... REBUILD PARTITION" is removed. Did the similar change for CREATE TRIGGER (see comments for sql_trigger.cc for details).
-
- 25 May, 2010 2 commits
-
-
Davi Arnaut authored
The problem was that TRUNCATE TABLE didn't take a exclusive lock on a table if it resorted to truncating via delete of all rows in the table. Specifically for InnoDB tables, this could break proper isolation as InnoDB ends up aborting some granted locks when truncating a table. The solution is to take a exclusive metadata lock before TRUNCATE TABLE can proceed. This guarantees that no other transaction is using the table. Incompatible change: Truncate via delete no longer fails if sql_safe_updates is activated (this was a undocumented side effect). libmysqld/CMakeLists.txt: Add new files to the build list. libmysqld/Makefile.am: Add new files to the build list. mysql-test/extra/binlog_tests/binlog_truncate.test: Add test case for Bug#42643 mysql-test/include/mix1.inc: Update test case as TRUNCATE TABLE now grabs a exclusive lock. Ensure that TRUNCATE waits for granted locks on the table. mysql-test/suite/binlog/t/binlog_truncate_innodb.test: As with other data modifying statements, TRUNCATE is still not possible in a transaction with isolation level READ COMMITTED or READ UNCOMMITED. It would be possible to implement so, but it is not worth the effort. mysql-test/suite/binlog/t/binlog_truncate_myisam.test: Test under different binlog formats. mysql-test/suite/binlog/t/disabled.def: Re-enable test case. mysql-test/t/innodb_bug38231.test: Truncate no longer works with row-level locks. mysql-test/t/mdl_sync.test: Ensure that a acquired lock is not given up due to a conflict. mysql-test/t/partition_innodb_semi_consistent.test: End transaction as to release metadata locks. mysql-test/t/truncate.test: A metadata lock is now taken before the object is verified. sql/CMakeLists.txt: Add new files to the build list. sql/Makefile.am: Add new files to the build list. sql/datadict.cc: Introduce a new file specific for data dictionary operations. sql/datadict.h: Add header file. sql/sql_base.cc: Rename data dictionary function. sql/sql_bitmap.h: Include dependency. sql/sql_delete.cc: Move away from relying on mysql_delete() to delete all rows of a table. Thus, move any bits related to truncate to sql_truncate.cc sql/sql_delete.h: Remove parameter. sql/sql_parse.cc: Add protection against the global read lock -- a intention exclusive lock can be acquired in the truncate path. sql/sql_show.cc: Add sync point for testing scenarios where a pending flush is ignored. sql/sql_truncate.cc: Acquire a shared metadata lock before accessing table metadata. Upgrade the lock to a exclusive one if the table can be re-created. Rework binlog rules to better reflect the requirements. sql/sql_yacc.yy: Set appropriate lock types for table to be truncated. sql/table.h: Move to data dictionary header.
-
Dmitry Lenev authored
transactional SELECT and ALTER TABLE ... REBUILD PARTITION". The goal of this patch is to decouple type of metadata lock acquired for table by open_tables() from type of table-level lock to be acquired on it. To achieve this we change approach to how we determine what type of metadata lock should be acquired on table to be open. Now instead of inferring it at open_tables() time from flags and type of table-level lock we rely on that type of metadata lock is properly set at parsing time and is not changed further. sql/ha_ndbcluster.cc: Now one needs to properly initialize table list element's MDL_request object before calling mysql_rm_table_part2(). sql/lock.cc: lock_table_names() no longer initializes table list elements' MDL_request objects. Now proper initialization of these requests is a responsibility of the caller. sql/lock.h: Removed MYSQL_OPEN_TAKE_UPGRADABLE_MDL flag which became unnecessary. Thanks to the fact that we don't reset type of requests for metadata locks between re-executions we now can figure out that upgradable locks are requested by simply looking at their type which were set in the parser. As result this flag became redundant. sql/mdl.h: Added version of new operator which simplifies allocation of MDL_request objects on a MEM_ROOT. sql/sp_head.cc: Added comment explaining why it is OK to infer type of metadata lock to request from type of table-level lock for prelocking. Added enum_mdl_type argument to sp_add_to_query_tables() to simplify its usage in trigger implementation. sql/sp_head.h: Added enum_mdl_type argument to sp_add_to_query_tables() to simplify its usage in trigger implementation. sql/sql_base.cc: - open_table_get_mdl_lock(): Preserve type of MDL_request for table list element which was set in the parser by creating MDL_request objects on memory root if MYSQL_OPEN_FORCE_SHARED_MDL or MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL flag were specified. Thanks to this and to the fact that we no longer reset type of requests for metadata locks between re-executions we no longer need to acquire exclusive metadata lock on table to be created in a special way. This lock is acquired by code handling acquiring of upgradable locks. Also changed signature/calling convention for this function to simplify its usage. - Accordingly special lock strategy for table list elements which was used for such locks became unnecessary and was removed. Other strategies were renamed. - Since we no longer have guarantee that MDL_request object which were not satisfied due to lock conflict belongs to table list element Open_table_context class and its methods were extended to remember pointer to MDL_request which has caused problem at request_backoff_action() time and use it in recover_from_failed_open(). Similar approach is used for cases when problem from which we need to recover is not related to MDL but to the table itself. In this case we store pointer to the element of table list. - Changed open_tables()/open_tables_check_upgradable_mdl()/ open_tables_acquire_upgradable_mdl() not to rely on MYSQL_OPEN_TAKE_UPGRADABLE_MDL flag to understand when upgradable metadata locks should be acquired and not to infer type of MDL lock from type of table-level lock. Instead we assume that type of MDL to be acquired was set in the parser (we can do this as type of MDL_request is no longer reset between re-executions). sql/sql_class.h: Since we no longer have guarantee that MDL_request object which were not satisfied due to lock conflict belongs to table list element Open_table_context class and its methods were extended to remember pointer to MDL_request which has caused problem at request_backoff_action() time and use it in recover_from_failed_open(). Similar approach is used for cases when problem from which we need to recover is not related to MDL but to the table itself. In this case we store pointer to the element of table list. sql/sql_db.cc: Now one needs to properly initialize table list element's MDL_request object before calling mysql_rm_table_part2() or mysql_rename_tables(). sql/sql_lex.cc: st_select_lex/st_select_lex_node::add_table_to_list() method now has argument which allows specify type of metadata lock to be requested for table list element being added. sql/sql_lex.h: - st_select_lex/st_select_lex_node::add_table_to_list() method now has argument which specifies type of metadata lock to be requested for table list element being added. This allows to explicitly set type of MDL lock to be acquired for a DDL statement in parser. It is also more future-proof than inferring type of MDL request from type of table-level lock. - Added Yacc_state::m_mdl_type member which specifies which type of metadata lock should be requested for tables to be added to table list by a grammar rule in cases when the same rule is used in several statements requiring different kinds of metadata locks. sql/sql_parse.cc: - st_select_lex::add_table_to_list() method now has argument which specifies type of metadata lock to be requested for table list element being added. This allows to explicitly set type of MDL lock to be acquired for a DDL statement in parser. It is also more future-proof than inferring type of MDL request from type of table-level lock. - EXCLUSIVE_DOWNGRADABLE_MDL lock strategy has a new name - OTLS_DOWNGRADE_IF_EXISTS. - Adjusted LOCK TABLES implementation to the fact that we no longer infer type of metadata lock to be acquired from table level lock and that type of MDL request is set at parsing. And thus MYSQL_OPEN_TAKE_UPGRADABLE_MDL flag became unnecessary. sql/sql_prepare.cc: TABLE_LIST's lock strategy SHARED_MDL was renamed to OTLS_NONE as now it means that metadata lock should not be changed during call to open_table() (if it has been already acquired) and is also used for exclusive metadata lock. sql/sql_show.cc: st_select_lex::add_table_to_list() method now has argument which specifies type of metadata lock to be requested for table list element being added. sql/sql_table.cc: - Adjusted mysql_admin_table()'s code to the fact that open_tables() no longer determines what kind of metadata lock should be obtained basing on type of table-level lock and flags. Instead type of metadata lock for table to be open should be set before calling open_tables(). - Changed mysql_alter_table() code to the facts: a) that now it is responsibility of caller to properly initalize MDL_request in table list elements before calling lock_table_names() b) and that MYSQL_OPEN_TAKE_UPGRADABLE_MDL is no longer necessary since type of metadata lock to be obtained at open_tables() time is set during parsing. - Changed code of mysql_recreate_table() to properly set type of metadata and table-level lock to be obtained by mysql_alter_table() which it calls. sql/sql_trigger.cc: Instead of relying on MYSQL_OPEN_TAKE_UPGRADABLE_MDL flag to force open_tables() to take an upgradable lock we now specify exact type of lock to be taken when constructing table list element for table to be open for CREATE/DROP TRIGGER. sql/sql_view.cc: We no longer use TABLE_LIST::EXCLUSIVE_MDL strategy to force open_tables() to take an exclusive metadata lock on view to be created. Instead we rely on parser setting proper type of metadata lock to request and open_tables() acquiring it. This became possible thanks to the fact that we no longer reset type of MDL_request between statement re-executions. sql/sql_yacc.yy: Instead of inferring type of MDL_request for table to be open from type of table-level lock and flags passed to open_tables() we now explicitly specify them at parsing. This became possible thanks to the fact that we no longer reset type of MDL_request between statement re-executions. In future this should allow to decouple type of metadata lock from type of table-level lock. The only exception to this approach is statements implemented through mysql_admin_table() which re-uses same table list element several times with different types of table-level and metadata locks. We now also properly initialize MDL_request objects for table list elements which are later passed to lock_table_names() function. sql/table.cc: Do not reset type of MDL_request between statement re-executions. This became unnecessesary as we no longer change type of MDL_request residing in table list element. In its turn this change allows to set type of MDL_request only once - at parsing time. sql/table.h: Got rid of TABLE_LIST::EXCLUSIVE_MDL lock strategy. Now we can specify that we need to acquire exclusive lock on table to be processed by open_tables() through setting an appropriate type of MDL_request at parsing time (this became possible thanks to the fact that we no longer reset types of MDL_request's belonging to table list elements between statement re-execution). Strategy SHARED_MDL was renamed to OTLS_NONE as now it means that metadata lock should not be changed during call to open_table() (if it has been already acquired) and is also used for exclusive metadata lock. Strategy EXCLUSIVE_DOWNGRADABLE_MDL was renamed to OTLS_DOWNGRADE_IF_EXISTS.
-
- 21 May, 2010 1 commit
-
-
Dmitry Lenev authored
FOR UPDATE is causing a lock". This patch tries to address problems which were exposed during backporting of original patch to 5.1 tree. - It ensures that we don't change locking behavior of simple SELECT statements on InnoDB tables when they are executed under LOCK TABLES ... READ and with @@innodb_table_locks=0. Also we no longer pass TL_READ_DEFAULT/TL_WRITE_DEFAULT lock types, which are supposed to be parser-only, to handler::start_stmt() method. - It makes check_/no_concurrent_insert.inc auxiliary scripts more robust against changes in test cases that use them and also ensures that they don't unnecessarily change environment of caller. mysql-test/include/check_concurrent_insert.inc: Reset DEBUG_SYNC facility before and after using it in auxiliary script. This makes this script more robust against changes in test cases calling it. It also ensures that script does not unnecessarily change environment of caller. mysql-test/include/check_no_concurrent_insert.inc: Reset DEBUG_SYNC facility before and after using it in auxiliary script. This makes this script more robust against changes in test cases calling it. It also ensures that script does not unnecessarily change environment of caller. mysql-test/r/innodb-lock.result: Added coverage for LOCK TABLES ... READ behavior in @@innodb_table_locks = 0 mode. This test also checks that an appropriate type of lock is passed to handler::start_stmt() method. mysql-test/t/innodb-lock.test: Added coverage for LOCK TABLES ... READ behavior in @@innodb_table_locks = 0 mode. This test also checks that an appropriate type of lock is passed to handler::start_stmt() method. sql/sql_base.cc: Since we no longer set TL_READ as lock type for tables used in simple SELECT right in the parser, in order to preserve behavior for such statements on InnoDB tables when in LOCK TABLES mode with @innodb_table_locks = 0, check_lock_and_start_stmt() had to be changed to convert TL_READ_DEFAULT to an appropriate type of read lock before passing it to handler::start_stmt() method. We do similar thing for TL_WRITE_DEFAULT as this lock type is also supposed to be parser-only type. As consequence read_lock_type_for_table() had to be adjusted to behave properly when it is called from check_lock_and_start_stmt() in prelocked mode.
-
- 16 May, 2010 1 commit
-
-
Alfranio Correia authored
mode Post-push fix after backporting the patch to 5.1-bugteam: 1 - changed the name of some variables to be equivalent to pe. 2 - fixed that patch to mark a statement as unsafe when both a self-logging eng. and regular eng. are accessed and one of them is updated.
-
- 09 May, 2010 1 commit
-
-
Alfranio Correia authored
Backport of the patch for 5.1-bugteam.
-
- 05 May, 2010 1 commit
-
-
Konstantin Osipov authored
thd->in_multi_stmt_transaction() and thd->active_transaction(). include/mysql_com.h: Comment SERVER_STATUS_IN_TRANS flag. sql/ha_ndbcluster.cc: Rename: thd->in_multi_stmt_transaction() -> thd->in_multi_stmt_transaction_mode(). sql/handler.cc: Add comments. sql/log.cc: Rename: thd->in_multi_stmt_transaction() -> thd->in_multi_stmt_transaction_mode(). sql/log_event.cc: Rename: thd->in_multi_stmt_transaction() -> thd->in_multi_stmt_transaction_mode(). sql/sql_base.cc: Rename: thd->in_multi_stmt_transaction() -> thd->in_multi_stmt_transaction_mode(). sql/sql_cache.cc: Rename: thd->active_transaction() -> thd->in_active_multi_stmt_transaction(). sql/sql_class.cc: Rename: thd->in_multi_stmt_transaction() -> thd->in_multi_stmt_transaction_mode(). sql/sql_class.h: Rename and comment two transaction processing- related methods. sql/sql_parse.cc: Rename: thd->in_multi_stmt_transaction() -> thd->in_multi_stmt_transaction_mode(). Rename: thd->active_transaction() -> thd->in_active_multi_stmt_transaction(). sql/sql_prepare.cc: Rename: thd->in_multi_stmt_transaction() -> thd->in_multi_stmt_transaction_mode(). sql/sql_rename.cc: Rename: thd->active_transaction() -> thd->in_active_multi_stmt_transaction(). sql/sql_table.cc: Rename: thd->active_transaction() -> thd->in_active_multi_stmt_transaction(). sql/sys_vars.cc: Rename: thd->active_transaction() -> thd->in_active_multi_stmt_transaction(). sql/transaction.cc: Rename: thd->in_multi_stmt_transaction() -> thd->in_multi_stmt_transaction_mode(). Rename: thd->active_transaction() -> thd->in_active_multi_stmt_transaction().
-
- 28 Apr, 2010 1 commit
-
-
Konstantin Osipov authored
Fix for bug #46947 "Embedded SELECT without FOR UPDATE is causing a lock", with after-review fixes. SELECT statements with subqueries referencing InnoDB tables were acquiring shared locks on rows in these tables when they were executed in REPEATABLE-READ mode and with statement or mixed mode binary logging turned on. This was a regression which were introduced when fixing bug 39843. The problem was that for tables belonging to subqueries parser set TL_READ_DEFAULT as a lock type. In cases when statement/mixed binary logging at open_tables() time this type of lock was converted to TL_READ_NO_INSERT lock at open_tables() time and caused InnoDB engine to acquire shared locks on reads from these tables. Although in some cases such behavior was correct (e.g. for subqueries in DELETE) in case of SELECT it has caused unnecessary locking. This patch tries to solve this problem by rethinking our approach to how we handle locking for SELECT and subqueries. Now we always set TL_READ_DEFAULT lock type for all cases when we read data. When at open_tables() time this lock is interpreted as TL_READ_NO_INSERT or TL_READ depending on whether this statement as a whole or call to function which uses particular table should be written to the binary log or not (if yes then statement should be properly serialized with concurrent statements and stronger lock should be acquired). Test coverage is added for both InnoDB and MyISAM. This patch introduces an "incompatible" change in locking scheme for subqueries used in SELECT ... FOR UPDATE and SELECT .. IN SHARE MODE. In 4.1 the server would use a snapshot InnoDB read for subqueries in SELECT FOR UPDATE and SELECT .. IN SHARE MODE statements, regardless of whether the binary log is on or off. If the user required a different type of read (i.e. locking read), he/she could request so explicitly by providing FOR UPDATE/IN SHARE MODE clause for each individual subquery. On of the patches for 5.0 broke this behaviour (which was not documented or tested), and started to use locking reads fora all subqueries in SELECT ... FOR UPDATE/IN SHARE MODE. This patch restored 4.1 behaviour. mysql-test/include/check_concurrent_insert.inc: Added auxiliary script which allows to check if statement reading table allows concurrent inserts in it. mysql-test/include/check_no_concurrent_insert.inc: Added auxiliary script which allows to check that statement reading table doesn't allow concurrent inserts in it. mysql-test/include/check_no_row_lock.inc: Added auxiliary script which allows to check if statement reading table doesn't take locks on its rows. mysql-test/include/check_shared_row_lock.inc: Added auxiliary script which allows to check if statement reading table takes shared locks on some of its rows. mysql-test/r/bug39022.result: After bug #46947 'Embedded SELECT without FOR UPDATE is causing a lock' was fixed test case for bug 39022 has to be adjusted in order to trigger execution path on which original problem was encountered. mysql-test/r/innodb_mysql_lock2.result: Added coverage for handling of locking in various cases when we read data from InnoDB tables (includes test case for bug #46947 'Embedded SELECT without FOR UPDATE is causing a lock'). mysql-test/r/lock_sync.result: Added coverage for handling of locking in various cases when we read data from MyISAM tables. mysql-test/t/bug39022.test: After bug #46947 'Embedded SELECT without FOR UPDATE is causing a lock' was fixed test case for bug 39022 has to be adjusted in order to trigger execution path on which original problem was encountered. mysql-test/t/innodb_mysql_lock2.test: Added coverage for handling of locking in various cases when we read data from InnoDB tables (includes test case for bug #46947 'Embedded SELECT without FOR UPDATE is causing a lock'). mysql-test/t/lock_sync.test: Added coverage for handling of locking in various cases when we read data from MyISAM tables. sql/log_event.cc: Since LEX::lock_option member was removed we no longer can rely on its value in Load_log_event::print_query() to determine that log event correponds to LOAD DATA CONCURRENT statement (this was not correct in all situations anyway). A new Load_log_event's member was introduced as a replacement. It is initialized at event object construction time and explicitly indicates whether LOAD DATA was concurrent. sql/log_event.h: Since LEX::lock_option member was removed we no longer can rely on its value in Load_log_event::print_query() to determine that log event correponds to LOAD DATA CONCURRENT statement (this was not correct in all situations anyway). A new Load_log_event's member was introduced as a replacement. It is initialized at event object construction time and explicitly indicates whether LOAD DATA was concurrent. sql/sp_head.cc: sp_head::reset_lex(): Before parsing substatement reset part of parser state which needs this (e.g. set Yacc_state::m_lock_type to default value). sql/sql_acl.cc: Since LEX::reset_n_backup_query_tables_list() now also resets LEX::sql_command member (as it became part of Query_tables_list class) we have to restore it in cases when while working with proxy Query_table_list we assume that LEX::sql_command still corresponds to original SQL command being executed (for example, when we are logging statement to the binary log while having Query_tables_list reset and backed up). sql/sql_base.cc: Changed read_lock_type_for_table() to return a weak TL_READ type of lock in cases when we are executing statement which won't update tables directly and table doesn't belong to statement's prelocking list and thus can't be used by a stored function. It is OK to do so since in this case table won't be used by statement or function call which will be written to the binary log, so serializability requirements for it can be relaxed. One of results from this change is that SELECTs on InnoDB tables no longer takes shared row locks for tables which are used in subqueries (i.e. bug #46947 is fixed). Another result is that for similar SELECTs on MyISAM tables concurrent inserts are allowed. In order to implement this change signature of read_lock_type_for_table() function was changed to take pointers to Query_tables_list and TABLE_LIST objects. sql/sql_base.h: - Function read_lock_type_for_table() now takes pointers to Query_tables_list and TABLE_LIST elements as its arguments since to correctly determine lock type it needs to know what statement is being performed and whether table element for which lock type to be determined belongs to prelocking list. sql/sql_lex.cc: - Removed LEX::lock_option and st_select_lex::lock_option members. Places in parser that were using them now use Yacc_state::m_lock_type instead. - To emphasize that LEX::sql_command member is used during process of opening and locking of tables it was moved to Query_tables_list class. It is now reset by Query_tables_list::reset_query_tables_list() method. sql/sql_lex.h: - Removed st_select_lex::lock_option member as there is no real need for per-SELECT lock type (HIGH_PRIORITY option should apply to the whole statement. FOR UPDATE/LOCK IN SHARE MODE clauses can be handled without this member). The main effect which was achieved by introduction of this member, i.e. using TL_READ_DEFAULT lock type for subqueries, is now achieved by setting LEX::lock_option (or rather its replacement - Yacc_state::m_lock_type) to TL_READ_DEFAULT in almost all cases. - To emphasize that LEX::sql_command member is used during process of opening and locking of tables it was moved to Query_tables_list class. - Replaced LEX::lock_option with Yacc_state::m_lock_type in order to emphasize that this value is relevant only during parsing. Unlike for LEX::lock_option the default value for Yacc_state::m_lock_type is TL_READ_DEFAULT. Note that for cases when it is OK to take a "weak" read lock (e.g. simple SELECT) this lock type will be converted to TL_READ at open_tables() time. So this change won't cause negative change in behavior for such statements. OTOH this change ensures that, for example, for SELECTs which are used in stored functions TL_READ_NO_INSERT lock is taken when necessary and as result calls to such stored functions can be written to the binary log with correct serialization. sql/sql_load.cc: Load_log_event constructor now requires a parameter that indicates whether LOAD DATA is concurrent. sql/sql_parse.cc: LEX::lock_option was replaced with Yacc_state::m_lock_type. And instead of resetting the latter implicitly in mysql_init_multi_delete() we do it explicitly in the places in parser which call this function. sql/sql_priv.h: - To be able more easily distinguish high-priority SELECTs in st_select_lex::print() method added flag for HIGH_PRIORITY option. sql/sql_select.cc: Changed code not to rely on LEX::lock_option to determine that it is high-priority SELECT. It was replaced with Yacc_state::m_lock_type which is accessible only at parse time. So instead of LEX::lock_option we now rely on a newly introduced flag for st_select_lex::options - SELECT_HIGH_PRIORITY. sql/sql_show.cc: Since LEX::reset_n_backup_query_tables_list() now also resets LEX::sql_command member (as it became part of Query_tables_list class) we have to restore it in cases when while working with proxy Query_table_list we assume that LEX::sql_command still corresponds to original SQL command being executed. sql/sql_table.cc: Since LEX::reset_query_tables_list() now also resets LEX::sql_command member (as it became part of Query_tables_list class) we have to restore value of this member when this method is called by mysql_admin_table(), to make this code safe for re-execution. sql/sql_trigger.cc: Since LEX::reset_n_backup_query_tables_list() now also resets LEX::sql_command member (as it became part of Query_tables_list class) we have to restore it in cases when while working with proxy Query_table_list we assume that LEX::sql_command still corresponds to original SQL command being executed (for example, when we are logging statement to the binary log while having Query_tables_list reset and backed up). sql/sql_update.cc: Function read_lock_type_for_table() now takes pointers to Query_tables_list and TABLE_LIST elements as its arguments since to correctly determine lock type it needs to know what statement is being performed and whether table element for which lock type to be determined belongs to prelocking list. sql/sql_yacc.yy: - Removed st_select_lex::lock_option member as there is no real need for per-SELECT lock type (HIGH_PRIORITY option should apply to the whole statement. FOR UPDATE/LOCK IN SHARE MODE clauses can be handled without this member). The main effect which was achieved by introduction of this member, i.e. using TL_READ_DEFAULT lock type for subqueries, is now achieved by setting LEX::lock_option (or rather its replacement - Yacc_state::m_lock_type) to TL_READ_DEFAULT in almost all cases. - Replaced LEX::lock_option with Yacc_state::m_lock_type in order to emphasize that this value is relevant only during parsing. Unlike for LEX::lock_option the default value for Yacc_state::m_lock_type is TL_READ_DEFAULT. Note that for cases when it is OK to take a "weak" read lock (e.g. simple SELECT) this lock type will be converted to TL_READ at open_tables() time. So this change won't cause negative change in behavior for such statements. OTOH this change ensures that, for example, for SELECTs which are used in stored functions TL_READ_NO_INSERT lock is taken when necessary and as result calls to such stored functions can be written to the binary log with correct serialization. - To be able more easily distinguish high-priority SELECTs in st_select_lex::print() method we now use new flag in st_select_lex::options bit-field.
-
- 07 Apr, 2010 1 commit
-
-
Mats Kindahl authored
Adding my_global.h first in all files using NO_EMBEDDED_ACCESS_CHECKS. Correcting a merge problem resulting from a changed definition of check_some_access compared to the original patches.
-
- 31 Mar, 2010 1 commit
-
-
Mats Kindahl authored
This patch: - Moves all definitions from the mysql_priv.h file into header files for the component where the variable is defined - Creates header files if the component lacks one - Eliminates all include directives from mysql_priv.h - Eliminates all circular include cycles - Rename time.cc to sql_time.cc - Rename mysql_priv.h to sql_priv.h
-
- 18 Mar, 2010 1 commit
-
-
Mattias Jonsson authored
due to DBUG_ASSERT. (added in bug#50561) sql/sql_base.cc: DEBUG_SYNC asserts that thd->debug_sync_control is set.
-
- 17 Mar, 2010 2 commits
-
-
Mattias Jonsson authored
concurrent I_S query There were two problem: 1) MYSQL_LOCK_IGNORE_FLUSH also ignored name locks 2) there was a race between abort_and_upgrade_locks and alter_close_tables (i.e. remove_table_from_cache and close_data_files_and_morph_locks) Which allowed the table to be opened with MYSQL_LOCK_IGNORE_FLUSH flag resulting in renaming a partition that was already in use, which could cause the table to be unusable. Solution was to not allow IGNORE_FLUSH to skip waiting for a named locked table. And to not release the LOCK_open mutex between the calls to remove_table_from_cache and close_data_files_and_morph_locks by merging the functions abort_and_upgrade_locks and alter_close_tables. mysql-test/suite/parts/r/partition_debug_sync_innodb.result: Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with concurrent I_S query Added test result mysql-test/suite/parts/t/partition_debug_sync_innodb-master.opt: Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with concurrent I_S query Added test option mysql-test/suite/parts/t/partition_debug_sync_innodb.test: Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with concurrent I_S query Added test file sql/authors.h: Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with concurrent I_S query Time to be acknowledged :) sql/ha_partition.cc: Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with concurrent I_S query Added DEBUG_SYNC for deterministic testing sql/mysql_priv.h: Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with concurrent I_S query Renamed function since merging alter_close_tables into abort_and_upgrade_lock. sql/sql_base.cc: Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with concurrent I_S query Changed MYSQL_LOCK_IGNORE_FLUSH to not ignore name locks (open_placeholder). Merged alter_close_tables into abort_and_upgrade_locks (and added _and_close_table to the name) to not release LOCK_open between remove_table_from_cache and close_data_files_and_morph_locks. Added DEBUG_SYNC for deterministic testing. sql/sql_partition.cc: Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with concurrent I_S query Removed alter_close_tables, (merged it into abort_and_upgrad_lock) so that LOCK_open never is released between remove_table_from_cache and close_data_files_and_morph_locks. sql/sql_show.cc: Bug#50561: ALTER PARTITIONS does not have adequate lock, breaks with concurrent I_S query Added DEBUG_SYNC for deterministic testing
-
Davi Arnaut authored
sql/handler.cc: Initialize the "comment" member of the structure. sql/sql_base.cc: Compile out unused function. sql/sql_update.cc: Remove unused variable. sql/sys_vars.cc: Use correct format specifier.
-
- 13 Mar, 2010 1 commit
-
-
Konstantin Osipov authored
Remove unnecessary need_reopen loops.
-
- 03 Mar, 2010 1 commit
-
-
Luis Soares authored
+ failing statements Implicit DROP event for temporary table is not getting LOG_EVENT_THREAD_SPECIFIC_F flag, because, in the previous executed statement in the same thread, which might even be a failed statement, the thread_specific_used flag is set to FALSE (in mysql_reset_thd_for_next_command) and not set to TRUE before connection is shutdown. This means that implicit DROP event will take the FALSE value from thread_specific_used and will not set LOG_EVENT_THREAD_SPECIFIC_F in the event header. As a consequence, mysqlbinlog will not print the pseudo_thread_id from the DROP event, because one of the requirements for the printout is that this flag is set to TRUE. We fix this by setting thread_specific_used whenever we are binlogging a DROP in close_temporary_tables, and resetting it to its previous value afterward.
-
- 01 Mar, 2010 1 commit
-
-
Mattias Jonsson authored
-
- 26 Feb, 2010 1 commit
-
-
Jon Olav Hauglid authored
The problem was that ALTER TABLE on a merge table which was locked using LOCK TABLE ... WRITE, by mistake gave ER_TABLE_NOT_LOCKED_FOR_WRITE. During opening of the table to be ALTERed, open_table() tried to get an upgradable metadata lock. In LOCK TABLEs mode, this lock must already exist (i.e. taken by LOCK TABLE) as new locks of this type cannot be acquired for fear of deadlock. So in LOCK TABLEs mode, open_table() tried to find an existing upgradable lock for the table to be altered. The problem was that open_table() also tried to find upgradable metadata locks for children of merge tables even if no such locks are needed to execute ALTER TABLE on merge tables. This patch fixes the problem by making sure that open tables code only searches for upgradable metadata locks for the merge table and not for the merge children tables. The patch also fixes a related bug where an upgradable metadata lock was aquired outside of LOCK TABLEs mode even if the table in question was temporary. This bug meant that LOCK TABLES or DDL on temporary tables by mistake could be blocked/aborted by locks held on base tables with the same table name by other connections. Test cases added to merge.test and lock_multi.test.
-
- 24 Feb, 2010 1 commit
-
-
Jon Olav Hauglid authored
This patch prevents system threads and system table accesses from using user-specified values for "lock_wait_timeout". Instead all such accesses are done using the default value (1 year). This prevents background tasks (such as replication, events, accessing stored function definitions, logging, reading time-zone information, etc.) from failing in cases where the global value of "lock_wait_timeout" is set very low. The patch also simplifies the open tables API. Rather than adding another convenience function for opening and locking system tables, this patch removes most of the existing convenience functions for open_and_lock_tables_derived(). Before, open_and_lock_tables() was a convenience function that enforced derived tables handling, while open_and_lock_tables_derived() was the main function where derived tables handling was optional. Now, this convencience function is gone and the main function is renamed to open_and_lock_tables(). No test case added as it would have required the use of --sleep to check that system threads and system tables have a different timeout value from the user-specified "lock_wait_timeout" system variable.
-
- 18 Feb, 2010 1 commit
-
-
Jon Olav Hauglid authored
an INFORMATION_SCHEMA table When a prepared statement using a merged view containing an information schema table was executed, a metadata lock of the view was not taken. This meant that it was possible for concurrent view DDL to execute, thereby breaking the binary log. For example, it was possible for DROP VIEW to appear in the binary log before a query using the view. This also happened when a statement in a stored routine was executed a second time. For such views, the information schema table is merged into the view during the prepare phase (or first execution of a statement in a routine). The problem was that we took a short cut and were not executing full-blown view opening during subsequent executions of the statement. As a result, a metadata lock on the view was not taken to protect the view definition. This patch resolves the problem by making sure a metadata lock is taken for views even after information schema tables are merged into them. Test cased added to view.test.
-
- 11 Feb, 2010 1 commit
-
-
Jon Olav Hauglid authored
This patch introduces timeouts for metadata locks. The timeout is specified in seconds using the new dynamic system variable "lock_wait_timeout" which has both GLOBAL and SESSION scopes. Allowed values range from 1 to 31536000 seconds (= 1 year). The default value is 1 year. The new server parameter "lock-wait-timeout" can be used to set the default value parameter upon server startup. "lock_wait_timeout" applies to all statements that use metadata locks. These include DML and DDL operations on tables, views, stored procedures and stored functions. They also include LOCK TABLES, FLUSH TABLES WITH READ LOCK and HANDLER statements. The patch also changes thr_lock.c code (table data locks used by MyISAM and other simplistic engines) to use the same system variable. InnoDB row locks are unaffected. One exception to the handling of the "lock_wait_timeout" variable is delayed inserts. All delayed inserts are executed with a timeout of 1 year regardless of the setting for the global variable. As the connection issuing the delayed insert gets no notification of delayed insert timeouts, we want to avoid unnecessary timeouts. It's important to note that the timeout value is used for each lock acquired and that one statement can take more than one lock. A statement can therefore block for longer than the lock_wait_timeout value before reporting a timeout error. When lock timeout occurs, ER_LOCK_WAIT_TIMEOUT is reported. Test case added to lock_multi.test. include/my_pthread.h: Added macros for comparing two timespec structs. include/thr_lock.h: Introduced timeouts for thr_lock.c locks. mysql-test/r/mysqld--help-notwin.result: Updated result file with the new server variable. mysql-test/r/mysqld--help-win.result: Updated result file with the new server variable. mysql-test/suite/sys_vars/r/lock_wait_timeout_basic.result: Added basic test for the new server variable. mysql-test/suite/sys_vars/t/lock_wait_timeout_basic.test: Added basic test for the new server variable. mysys/thr_lock.c: Introduced timeouts for thr_lock.c locks. sql/mdl.cc: Introduced timeouts for metadata locks. sql/mdl.h: Introduced timeouts for metadata locks. sql/sql_base.cc: Introduced timeouts in tdc_wait_for_old_versions(). sql/sql_class.h: Added new server variable lock_wait_timeout. sql/sys_vars.cc: Added new server variable lock_wait_timeout.
-
- 10 Feb, 2010 1 commit
-
-
Luis Soares authored
A closely related problem, hardly worth a new bug report: Removed a spurious call to: thd->set_current_stmt_binlog_format_row_if_mixed() in sql_base.cc:lock_tables().
-
- 08 Feb, 2010 1 commit
-
-
Dmitry Lenev authored
and MDL". Concurrent execution of a multi-DELETE statement and ALTER TABLE statement which affected one of the tables used in the multi-DELETE sometimes led to deadlock. Similar deadlocks might have occured when one performed INSERT/UPDATE/DELETE on a view and concurrently executed ALTER TABLE for the view's underlying table, or when one concurrently executed TRUNCATE TABLE for InnoDB table and ALTER TABLE for the same table. These deadlocks were caused by a discrepancy between types of metadata and thr_lock.cc locks acquired by those statements. What happened was that multi-DELETE/TRUNCATE/DML-through-the- view statement in the first connection acquired SR lock on a table, then ALTER TABLE would come in in the second connection and acquire SNW metadata lock and TL_WRITE_ALLOW_READ thr_lock.c lock and then would start waiting for the first connection during lock upgrade. After that the statement in the first connection would try to acquire TL_WRITE lock on table and would start waiting for the second connection, creating a deadlock. This patch solves this problem by ensuring that we acquire SW metadata lock in all cases in which we acquiring write thr_lock.c lock. This guarantees that deadlocks like the one described above won't occur since all lock conflicts in such situation are resolved within MDL subsystem. This patch also adds assert which should guarantee that such situations won't arise in future. mysql-test/r/lock_multi.result: Added main test for bug #50913 "Deadlock between open_and_lock_tables_derived and MDL". mysql-test/r/mdl_sync.result: Added additional coverage for bug #50913 "Deadlock between open_and_lock_tables_derived and MDL". mysql-test/t/lock_multi.test: Added main test for bug #50913 "Deadlock between open_and_lock_tables_derived and MDL". mysql-test/t/mdl_sync.test: Added additional coverage for bug #50913 "Deadlock between open_and_lock_tables_derived and MDL". sql/lock.cc: Added assert that enforces that when we are locking a non-temporary table we have an appropriate type of metadata lock on this table. sql/mysql_priv.h: Added separate flag for open_tables() to be able specify that SH metadata locks on table to be open should be acquired. We can no longer use MYSQL_LOCK_IGNORE_FLUSH flag for this as in addition to use in I_S implementation it is also used for opening system tables. Since in the latter case we also acquire thr_lock.c locks using SH metadata lock in it instead of SR or SW locks may lead to deadlock. sql/sql_base.cc: When opening tables don't interpret MYSQL_LOCK_IGNORE_FLUSH flag as request to acquire SH metadata locks. This flag is also used for opening system tables for which we also take thr_lock.c locks and thus proper metadata lock to take in this case is SR or SW lock (otherwise deadlocks can occur). In cases when SH lock is really required (e.g. when tables are open by I_S implementation) we rely on that newly introduced MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL flag is used. sql/sql_delete.cc: mysql_truncate_by_delete(): Adjust type of metadata lock to be requested after changing type of thr_lock.c lock for table list element from one which was set in parser to TL_WRITE. This removes discrepancy between types of these locks which allowed deadlocks to creep in. sql/sql_handler.cc: When closing table which was open by HANDLER statement clear TABLE::open_by_handler flag. This allows to use this flag as a reliable indication that TABLE instance was open by HANDLER statement in assert which was added to mysql_lock_tables(). sql/sql_parse.cc: multi_delete_set_locks_and_link_aux_tables(): Adjust type of metadata lock to be requested after changing type of thr_lock.c lock for table list element from one which was set in parser to TL_WRITE. This removes discrepancy between types of these locks which allowed deadlocks to creep in. sql/sql_show.cc: Use newly introduced MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL flag in order to acquire SH metadata locks when opening tables in I_S implementation. sql/sql_update.cc: Added comment explaining why in multi-update after deciding that we need weaker thr_lock.c lock on a table we don't downgrade metadata lock on it. sql/sql_view.cc: When merging view into main statement adjust type of metadata lock to be requested after changing type of thr_lock.c lock for table. This removes discrepancy between types of these locks which allowed deadlocks to creep in.
-
- 04 Feb, 2010 1 commit
-
-
Konstantin Osipov authored
Cherry-pick a fix Bug#37148 from next-mr, to preserve file ids of the added files, and ensure that all the necessary changes have been pulled. Since initially Bug#37148 was null-merged into 6.0, the changeset that is now being cherry-picked was likewise null merged into next-4284. Now that Bug#37148 has been reapplied to 6.0, try to make it work with next-4284. This is also necessary to be able to pull other changes from 5.1-rep into next-4284. To resolve the merge issues use this changeset applied to 6.0: revid:jperkin@sun.com-20091216103628-ylhqf7s6yegui2t9 revno: 3776.1.1 committer: He Zhenxing <zhenxing.he@sun.com> branch nick: 6.0-codebase-bugfixing timestamp: Thu 2009-12-17 17:02:50 +0800 message: Fix merge problem with Bug#37148
-
- 03 Feb, 2010 2 commits
-
-
MySQL Build Team authored
> ------------------------------------------------------------ > revno: 2818.1.40 [merge] > revision-id: epotemkin@mysql.com-20091202134712-4muwnr152xqkcwm7 > parent: gshchepa@mysql.com-20091201102444-yw166t3audrojo9s > parent: epotemkin@mysql.com-20091201182845-aw0uawt6c6gwi98c > committer: Evgeny Potemkin <epotemkin@mysql.com> > branch nick: mysql-5.0-bugteam > timestamp: Wed 2009-12-02 16:47:12 +0300 > message: > Auto-merged fix for the bug#48508. > ------------------------------------------------------------ > Use --include-merges or -n0 to see merged revisions.
-
MySQL Build Team authored
> ------------------------------------------------------------ > revno: 2818.1.18 > revision-id: li-bing.song@sun.com-20091103090041-zj7nedx6ok5jgges > parent: davi.arnaut@sun.com-20091102201021-1brn7cjb1kvqg9gr > committer: <Li-Bing.Song@sun.com> > branch nick: mysql-5.0-bugteam > timestamp: Tue 2009-11-03 17:00:41 +0800 > message: > BUG#48216 Replication fails on all slaves after upgrade to 5.0.86 on master > > When a sessione is closed, all temporary tables of the session are automatically > dropped and are binlogged. But it will be binlogged with wrong database names when > the length of the temporary tables' database names are greater than the > length of the current database name or the current database is not set. > > Query_log_event's db_len is forgot to set when Query_log_event's db is set. > This patch wrote code to set db_len immediately after db has set.
-