Forward port of r2236
Introduce retry/sleep logic as a workaround for a transient bug
where ::open fails for partitioned tables randomly if we are using
one file per table. (Bug #33349)
Reviewed by: Heikki
buf_pool->mutex: Rename to buf_pool_mutex, so that the wrappers will have
to be used when changes are merged from other source trees.
buf_pool->zip_mutex: Rename to buf_pool_zip_mutex.
buf_pool_mutex_own(), buf_pool_mutex_enter(), buf_pool_mutex_exit():
Wrappers for buf_pool_mutex.
ha_innobase::final_drop_index(): If row_merge_drop_table() fails, clear
the to_be_dropped flags. This was the error fixed in this commit; the rest
is just additional safety.
ha_innobase::final_drop_index(): After dropping the flagged indexes,
assert that none of the remaining indexes are flagged to_be_dropped.
ha_innobase::prepare_drop_index(): Assert that no index has been flagged
for deletion. When checking foreign key constraints, simply traverse the
list of indexes and check if any of the indexes that were just flagged
to_be_dropped. On error, clear the to_be_dropped flags with simple list
traversal.
Change the format of TRX_IDs in INFORMATION_SCHEMA tables from DEC to
HEX.
The current TRX_IDs are hard to remember and track down: 426355, 428466,
428566, etc.
In HEX:
* there are less "digits", the strings are shorter;
* since there are 16 instead of 10 "digits", the chance of having
repeating ones are smaller.
The above look like 68173, 689B2, 68A16 in HEX.
Discussed with: Ken
Approved by: Heikki (via IM)
acquiring the table lock. The data dictionary should not be locked for
long periods. Before this change, in the worst case, the dictionary
would be locked until the expiration of innodb_lock_wait_timeout.
Virtually, transaction-level locks (locks on database objects, such
as records and tables) have a latching order level of SYNC_USER_TRX_LOCK,
which is above any InnoDB rw-locks or mutexes. However, the latching
order of SYNC_USER_TRX_LOCK is never checked, not even by UNIV_SYNC_DEBUG.
ha_innobase::add_index(), ha_innobase::final_drop_index(): Invoke
row_mysql_lock_data_dictionary(trx) only after row_merge_lock_table().
row_merge_lock_table().
ha_innobase::final_drop_index(): Set the dictionary operation mode to
TRX_DICT_OP_INDEX_MAY_WAIT for the duration of the row_merge_lock_table()
call.
Active transactions must not switch table or index definitions on the fly,
for several reasons, including the following:
* copied indexes do not carry any history or locking information;
that is, rollbacks, read views, and record locking would be broken
* huge potential for race conditions, inconsistent reads and writes,
loss of data, and corruption
Instead of trying to track down if the table was changed during a transaction,
acquire appropriate locks that protect the creation and dropping of indexes.
innodb-index.test: Test the locking of CREATE INDEX and DROP INDEX. Test
that consistent reads work across dropped indexes.
lock_rec_insert_check_and_lock(): Relax the lock_table_has() assertion.
When inserting a record into an index, the table must be at least IX-locked.
However, when an index is being created, an IS-lock on the table is
sufficient.
row_merge_lock_table(): Add the parameter enum lock_mode mode, which must
be LOCK_X or LOCK_S.
row_merge_drop_table(): Assert that n_mysql_handles_opened == 0.
Unconditionally drop the table.
ha_innobase::add_index(): Acquire an X or S lock on the table, as appropriate.
After acquiring an X lock, assert that n_mysql_handles_opened == 1.
Remove the comments about dropping tables in the background.
ha_innobase::final_drop_index(): Acquire an X lock on the table.
dict_table_t: Remove version_number, to_be_dropped, and prebuilts.
ins_node_t: Remove table_version_number.
enum lock_mode: Move the definition from lock0lock.h to lock0types.h.
ROW_PREBUILT_OBSOLETE, row_update_prebuilt(), row_prebuilt_table_obsolete():
Remove.
row_prebuilt_t: Remove the declaration from row0types.h.
row_drop_table_for_mysql_no_commit(): Always print a warning if a table
was added to the background drop queue.
kernel_mutex must be released before calling this function.
innobase_mysql_end_print_arbitrary_thd(),
innobase_mysql_prepare_print_arbitrary_thd(): Assert that the
kernel_mutex is not being held by the current thread.
Non-functional change:
Move the prototypes of
innobase_mysql_prepare_print_arbitrary_thd() and
innobase_mysql_end_print_arbitrary_thd() from lock0lock.c to
ha_prototypes.h
Suggested by: Marko
Approved by: Marko
* Change terminology:
wait lock -> requested lock
waited lock -> blocking lock
new: requesting transaction (the trx what owns the requested lock)
new: blocking transaction (the trx that owns the blocking lock)
* Add transaction ids to INFORMATION_SCHEMA.INNODB_LOCK_WAITS. This is
somewhat redundant because transaction ids can be found in INNODB_LOCKS
(which can be joined with INNODB_LOCK_WAITS) but would help users to
write shorter joins (one table less) in some cases where they want to
find which transaction is blocking which.
Suggested by: Ken
Approved by: Heikki
for dropping the index trees, and set the dictionary operation flag, similar
to what ha_innobase::add_index() does. This should ensure correct crash
recovery.
Fix the size of the static buffer for lock_table and lock_index.
I was not realizing that NAME_LEN contains the mbmaxlen multiplier and thus
a quote, when converted to 2 quotes, will take 2 bytes while there are 3
bytes reserved.
Spotted by: Marko
Pointyhat to: Vasil
Bugfix1: Set innodb_locks.lock_index to NOT NULL.
If a column in INFORMATION_SCHEMA table has the flag
MY_I_S_MAYBE_NULL and it is not explicitly marked as NOT NULL
with the method ::set_notnull() then it is always rendered as
NULL by MySQL.
Bugfix2: Avoid crashes if lock_index is NULL. It is NULL for table
level locks.
Pointyhat to: Marko
innodb_information_schema.test. Add tests that display most columns from
INFORMATION_SCHEMA.INNODB_LOCKS. Test that quoting of table names works
and respects SQL_MODE='ANSI_QUOTES'.
innobase_print_identifier(): Remove.
innobase_convert_identifier(): New function,
based on innobase_print_identifier().
innobase_convert_name(): New function, similar to ut_print_namel(), but
using a memory buffer.
ut_print_namel(): Use innobase_convert_name().
fill_innodb_locks_from_cache(): Convert lock_table and lock_index by
calling innobase_convert_name().
Implement a limit on the memory used by the INNODB_TRX, INNODB_LOCKS and
INNODB_LOCK_WAITS tables. The maximum allowed memory is defined with the
macro TRX_I_S_MEM_LIMIT.
Approved by: Marko (via IM)
Add the query in information_schema.innodb_trx.trx_query. Add it even
though it is available in information_schema.processlist.info to make
inconsistencies between those two tables obvious.
It is rather confusting to see a transaction shown in innodb_trx and
innodb_locks that holds a lock on one table and the corresponding query
in processlist executing INSERT on another table. We do not want users
to contact us asking to explain that. It is caused by the fact that the
data for innodb_* tables and processlist is fetched at different time.
Approved by: Marko
Introduce a generic soultion to the common problem that MySQL do not add
functions needed by us in a reasonable time.
Start with a function that retrieves THD::thread_id, this is needed for
the information_schema.innodb_trx.mysql_thread_id column.
Approved by: Marko
a compressed table in the system tablespace.
db0err.h: Introduce the error code DB_TABLE_ZIP_NO_IBD. Replace the
#define directives with an enum, to ease future code merges. These
error codes are never written out to files or displayed to the user.
Thus they need not remain constant.
dict_build_table_def_step(): Return DB_TABLE_ZIP_NO_IBD instead of DB_ERROR.
create_table_def(): Report ER_ILLEGAL_HA_CREATE_OPTION "KEY_BLOCK_SIZE"
when the table creation fails with DB_TABLE_ZIP_NO_IBD.
redefined so that the dynamic plugin can replace the builtin InnoDB
in MySQL 5.1.
ha_innodb.cc, handler0alter.cc: #include "univ.i" before any other InnoDB
header files or before defining any symbols
innodb_redefine.h: New file, to contain a mapping of symbols. The idea
is that this file will be replaced in the build process; because this
is a large file that can be generated automatically, it does not make sense
to keep it under version control.
univ.i: #include "innodb_redefine.h" and #define ha_innobase ha_innodb
Makefile.am (ha_innodb_la_CXXFLAGS): Remove -Dha_innobase=ha_innodb
NOTE: there are still some issues in the source code. One known issue is
the #undef mutex_free in sync0sync.h, which will cause the plugin to call the
function mutex_free in the builtin InnoDB. The preprocessor symbols defined
in innodb_redefine.h must not be undefined or redefined anywhere in the code.
plugin "InnoDB", not "InnoDBzip".
We can disable the builtin InnoDB by mysqld --skip-innodb. If the
builtin InnoDB is not disabled, installing the InnoDB plugin by the same
name will not work.
innodb_plugin_init(): Ignore differences in the PLUGIN_VAR_READONLY flag.
ha_innobase::write_row(): The printf format %p expects const void*.
STRUCT_FLD: Do not use the GCC extension when __STRICT_ANSI__ is defined.
row_merge_read_clustered_index(): Compound initializers must not contain
variables. Assign to struct fields instead.
Add innodb_locks.lock_data column and some relevant tests.
For record locks this column represents the ordering fields of the
locked row in a human readable, SQL-valid, format.
Approved by: Marko
enum trx_dict_op: dictionary operation modes
trx_get_dict_operation(), trx_set_dict_operation(): Accessors for
trx->dict_operation.
lock_table_enqueue_waiting(), lock_rec_enqueue_waiting(): Do not complain
about lock waits if the dictionary mode is TRX_DICT_OP_INDEX_MAY_WAIT.
row_merge_lock_table(): Remove the work-around for avoiding the warning
in lock_table_enqueue_waiting().
trx_undo_mark_as_dict_operation(): Do not write trx->table_id to the
undo log unless the dict_operation is TRX_DICT_OP_TABLE.
ha_innobase::add_index(): Set the dict_operation mode initially to
TRX_DICT_OP_INDEX_MAY_WAIT, then lock the table exclusively, and set the
mode to TRX_DICT_OP_INDEX, and optionally to TRX_DICT_OP_TABLE when
creating a temporary table.
to replace a built-in instance of InnoDB in mysqld. This is work in
progress, with several limitations:
* Other plugins defined in the builtin InnoDB are not disabled.
However, InnoDB in MySQL 5.1 only defines the storage engine plugin,
no INFORMATION_SCHEMA plugins.
* The global C symbols in ha_innodb.so except innodb_hton_ptr and
builtin_innobase_plugin will have to be redefined, e.g., by objcopy.
* The storage engine cannot be called "InnoDB" to avoid a conflict with
the builtin name. Here we call it InnoDBzip.
innobase_hton_name[]: Rename to "InnoDBzip" when building a dynamic plugin.
innodb_plugin_init(): New function for the dynamic plugin, to copy
and redirect configuration parameters from the builtin InnoDB.
innodb_dynamic: New configuration parameter. This has to be added
to the builtin InnoDB in MySQL 5.1. Also, innodb_hton_ptr must be made
global there.
innobase_init(): Interpret the parameter innodb_dynamic.
Makefile.am: Redefine class ha_innobase to ha_innodb by a preprocessor
define. Apparently, C++ classes cannot be easily renamed by objcopy.
INNODB_ZIP and INNODB_ZIP_RESET from ha_innodb.cc to i_s.cc.
plugin_author, END_OF_ST_FIELD_INFO, i_s_info: New common constants.
trx_i_s_common_deinit(): Renamed to i_s_common_deinit().
ha_innobase::update_thd(void): New function, to call the inline function
ha_innobase::update_thd(THD*).
check_trx_exists(): Make static. handler0alter.cc does not need to call
this function.
innobase_col_to_mysql(): New function, adapted from
row_sel_field_store_in_mysql_format().
innobase_rec_to_mysql(): Correct the function comment, which was still
saying "clustered index record", although we can convert any record.
Make use of innobase_col_to_mysql(). Always call field->reset(),
so that innobase_col_to_mysql() will not have to pad anything.
dtuple_create_for_mysql(), dtuple_free_for_mysql(): Remove.
ha_innobase::records_in_range(): Use mem_heap_create(), mem_heap_free(),
and dtuple_create() instead of the removed functions above. Since r1587,
InnoDB C++ functions can invoke inlined C functions.