mirror of
https://github.com/MariaDB/server.git
synced 2025-01-19 05:22:25 +01:00
branches/innodb+: Merge revisions 3602:3931 from branches/zip:
------------------------------------------------------------------------ r3607 | marko | 2008-12-30 22:33:31 +0200 (Tue, 30 Dec 2008) | 20 lines branches/zip: Remove the dependency on the MySQL HASH table implementation. Use the InnoDB hash table for keeping track of INNOBASE_SHARE objects. struct st_innobase_share: Make table_name const uchar*. Add the member table_name_hash. innobase_open_tables: Change the type from HASH to hash_table_t*. innobase_get_key(): Remove. innobase_fold_name(): New function, for computing the fold value for the InnoDB hash table. get_share(), free_share(): Use the InnoDB hash functions. innobase_end(): Free innobase_open_tables before shutting down InnoDB. Shutting down InnoDB will invalidate all memory allocated via InnoDB. rb://65 approved by Heikki Tuuri. This addresses Issue #104. ------------------------------------------------------------------------ r3608 | marko | 2008-12-30 22:45:04 +0200 (Tue, 30 Dec 2008) | 22 lines branches/zip: When setting the PAGE_LEVEL of a compressed B-tree page from or to 0, compress the page at the same time. This is necessary, because the column information stored on the compressed page will differ between leaf and non-leaf pages. Leaf pages are identified by PAGE_LEVEL=0. This bug was reported as Issue #150. Document the similarity between btr_page_create() and btr_page_empty(). Make the function signature of btr_page_empty() identical with btr_page_create(). (This will add the parameter "level".) btr_root_raise_and_insert(): Replace some code with a call to btr_page_empty(). btr_attach_half_pages(): Assert that the page level has already been set on both block and new_block. Do not set it again. btr_discard_only_page_on_level(): Document that this function is probably never called. Make it work on any height tree. (Tested on 2-high tree by disabling btr_lift_page_up().) rb://68 ------------------------------------------------------------------------ r3612 | marko | 2009-01-02 11:02:44 +0200 (Fri, 02 Jan 2009) | 14 lines branches/zip: Merge c2998 from branches/6.0, so that the same InnoDB Plugin source tree will work both under 5.1 and 6.0. Do not add the test case innodb_ctype_ldml.test, because it would not work under MySQL 5.1. Refuse to create tables whose columns contain collation IDs above 255. This removes an assertion failure that was introduced in WL#4164 (Two-byte collation IDs). create_table_def(): Do not fail an assertion if a column contains a charset-collation ID greater than 256. Instead, issue an error and refuse to create the table. The original change (branches/6.0 r2998) was rb://51 approved by Calvin Sun. ------------------------------------------------------------------------ r3613 | inaam | 2009-01-02 15:10:50 +0200 (Fri, 02 Jan 2009) | 6 lines branches/zip: Implement the parameter innodb_use_sys_malloc (false by default), for disabling InnoDB's internal memory allocator and using system malloc/free instead. rb://62 approved by Marko ------------------------------------------------------------------------ r3614 | marko | 2009-01-02 15:55:12 +0200 (Fri, 02 Jan 2009) | 1 line branches/zip: ChangeLog: Document r3608 and r3613. ------------------------------------------------------------------------ r3615 | marko | 2009-01-02 15:57:51 +0200 (Fri, 02 Jan 2009) | 1 line branches/zip: ChangeLog: Clarify the impact of r3608. ------------------------------------------------------------------------ r3616 | marko | 2009-01-03 00:23:30 +0200 (Sat, 03 Jan 2009) | 1 line branches/zip: srv_suspend_mysql_thread(): Add some clarifying comments. ------------------------------------------------------------------------ r3618 | marko | 2009-01-05 12:54:53 +0200 (Mon, 05 Jan 2009) | 15 lines branches/zip: Merge revisions 3598:3601 from branches/5.1: ------------------------------------------------------------------------ r3601 | marko | 2008-12-22 16:05:19 +0200 (Mon, 22 Dec 2008) | 9 lines branches/5.1: Make SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED a true replacement of SET GLOBAL INNODB_LOCKS_UNSAFE_FOR_BINLOG=1. This fixes an error that was introduced in r370, causing semi-consistent read not to not unlock rows in READ COMMITTED mode. (Bug #41671, Issue #146) rb://67 approved by Heikki Tuuri ------------------------------------------------------------------------ ------------------------------------------------------------------------ r3623 | vasil | 2009-01-06 09:56:32 +0200 (Tue, 06 Jan 2009) | 7 lines branches/zip: Add patch to fix the failing main.variables mysql-test. It started failing after the variable innodb_use_sys_malloc was added because it matches '%alloc%' and the test is badly written and expects that no new variables like that will ever be added. ------------------------------------------------------------------------ r3795 | marko | 2009-01-07 16:17:47 +0200 (Wed, 07 Jan 2009) | 7 lines branches/zip: row_merge_tuple_cmp(): Do not report a duplicate key value if any of the fields are NULL. While the tuples are equal in the sorting order, SQL NULL is defined to be logically inequal to anything else. (Bug #41904) rb://70 approved by Heikki Tuuri ------------------------------------------------------------------------ r3796 | marko | 2009-01-07 16:19:32 +0200 (Wed, 07 Jan 2009) | 1 line branches/zip: Add the tests that were forgotten from r3795. ------------------------------------------------------------------------ r3797 | marko | 2009-01-07 16:22:18 +0200 (Wed, 07 Jan 2009) | 22 lines branches/zip: Do not call trx_allocate_for_mysql() directly, but use helper functions that initialize some members of the transaction struct. (Bug #41680) innobase_trx_init(): New function: initialize some fields of a transaction struct from a MySQL THD object. innobase_trx_allocate(): New function: allocate and initialize a transaction struct. check_trx_exists(): Use the above two functions. ha_innobase::delete_table(), ha_innobase::rename_table(), ha_innobase::add_index(), ha_innobase::final_drop_index(): Use innobase_trx_allocate(). innobase_drop_database(): In the Windows plugin, initialize the trx_t specially, because the THD is not available. Otherwise, use innobase_trx_allocate(). rb://69 accepted by Heikki Tuuri ------------------------------------------------------------------------ r3798 | marko | 2009-01-07 16:42:42 +0200 (Wed, 07 Jan 2009) | 8 lines branches/zip: row_merge_drop_temp_indexes(): Do not lock the rows of SYS_INDEXES when looking for partially created indexes. Use the transaction isolation level READ UNCOMMITTED to avoid interfering with locks held by incomplete transactions that will be rolled back in a subsequent step in the recovery. (Issue #152) Approved by Heikki Tuuri ------------------------------------------------------------------------ r3852 | vasil | 2009-01-08 22:10:10 +0200 (Thu, 08 Jan 2009) | 4 lines branches/zip: Add ChangeLog entries for r3795 r3796 r3797 r3798. ------------------------------------------------------------------------ r3866 | marko | 2009-01-09 15:09:51 +0200 (Fri, 09 Jan 2009) | 2 lines branches/zip: buf_flush_try_page(): Move some common code from each switch case before the switch block. ------------------------------------------------------------------------ r3867 | marko | 2009-01-09 15:13:14 +0200 (Fri, 09 Jan 2009) | 2 lines branches/zip: buf_flush_try_page(): Introduce the variable is_compressed for caching the result of buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE. ------------------------------------------------------------------------ r3868 | marko | 2009-01-09 15:40:11 +0200 (Fri, 09 Jan 2009) | 4 lines branches/zip: buf_flush_insert_into_flush_list(), buf_flush_insert_sorted_into_flush_list(): Remove unused code. Change the parameter to buf_block_t* block and assert that block->state == BUF_BLOCK_FILE_PAGE. This is part of Issue #155. ------------------------------------------------------------------------ r3873 | marko | 2009-01-09 22:27:40 +0200 (Fri, 09 Jan 2009) | 17 lines branches/zip: Some non-functional changes related to Issue #155. buf_page_struct: Note that space and offset are also protected by buf_pool_mutex. They are only assigned to by buf_block_set_file_page(). Thus, it suffices for buf_flush_batch() to hold just buf_pool_mutex when checking these fields. buf_flush_try_page(): Rename "locked" to "is_s_latched", per Heikki's request. buf_flush_batch(): Move the common statement mutex_exit(block_mutex) from all if-else if-else branches before the if block. Remove the redundant test (buf_pool->init_flush[flush_type] == FALSE) that was apparently copied from buf_flush_write_complete(). buf_flush_write_block_low(): Note why it is safe not to hold buf_pool_mutex or block_mutex. Enumerate the assumptions in debug assertions. ------------------------------------------------------------------------ r3874 | marko | 2009-01-09 23:09:06 +0200 (Fri, 09 Jan 2009) | 4 lines branches/zip: Add comments related to Issue #155. buf_flush_try_page(): Note why it is safe to access bpage without holding buf_pool_mutex or block_mutex. ------------------------------------------------------------------------ r3875 | marko | 2009-01-09 23:15:12 +0200 (Fri, 09 Jan 2009) | 11 lines branches/zip: Non-functional change: Tighten debug assertions and remove dead code. buf_flush_ready_for_flush(), buf_flush_try_page(): Assert that flush_type is one of BUF_FLUSH_LRU or BUF_FLUSH_LIST. The flush_type comes from buf_flush_batch(), which already asserts this. The assertion holds for all calls in the source code. buf_flush_try_page(): Remove the dead case BUF_FLUSH_SINGLE_PAGE of switch (flush_type). ------------------------------------------------------------------------ r3879 | marko | 2009-01-12 12:46:44 +0200 (Mon, 12 Jan 2009) | 14 lines branches/zip: Simplify the flushing of dirty pages from the buffer pool. buf_flush_try_page(): Rename to buf_flush_page(), and change the return type to void. Replace the parameters space, offset with bpage, and remove the second page hash lookup. Note and assert that both buf_pool_mutex and block_mutex must now be held upon entering the function. They will still be released by this function. buf_flush_try_neighbors(): Replace buf_flush_try_page() with buf_flush_page(). Make the logic easier to follow by not negating the precondition of buf_flush_page(). rb://73 approved by Sunny Bains. This is related to Issue #157. ------------------------------------------------------------------------ r3880 | marko | 2009-01-12 13:24:37 +0200 (Mon, 12 Jan 2009) | 2 lines branches/zip: buf_flush_page(): Fix a comment that should have been fixed in r3879. Spotted by Sunny. ------------------------------------------------------------------------ r3881 | marko | 2009-01-12 14:25:22 +0200 (Mon, 12 Jan 2009) | 2 lines branches/zip: buf_page_get_newest_modification(): Use the block mutex instead of the buffer pool mutex. This is related to Issue #157. ------------------------------------------------------------------------ r3882 | marko | 2009-01-12 14:40:08 +0200 (Mon, 12 Jan 2009) | 3 lines branches/zip: struct mtr_struct: Remove the unused field magic_n unless UNIV_DEBUG is defined. mtr->magic_n is only assigned to and checked in UNIV_DEBUG builds. ------------------------------------------------------------------------ r3883 | marko | 2009-01-12 14:48:59 +0200 (Mon, 12 Jan 2009) | 1 line branches/zip: Non-functional change: Use ut_d when assigning to mtr->state. ------------------------------------------------------------------------ r3884 | marko | 2009-01-12 18:56:11 +0200 (Mon, 12 Jan 2009) | 16 lines branches/zip: Non-functional change: Add some debug assertions and comments. buf_page_t: Note that the LRU fields are protected by buf_pool_mutex only, not block->mutex or buf_pool_zip_mutex. buf_page_get_freed_page_clock(): Note that this is sometimes invoked without mutex protection. buf_pool_get_oldest_modification(): Note that the result may be out of date. buf_page_get_LRU_position(), buf_page_is_old(): Assert that the buffer pool mutex is being held. buf_page_release(): Assert that dirty blocks are in the flush list. ------------------------------------------------------------------------ r3896 | marko | 2009-01-13 09:30:26 +0200 (Tue, 13 Jan 2009) | 2 lines branches/zip: buf_flush_try_neighbors(): Fix a bug that was introduced in r3879 (rb://73). ------------------------------------------------------------------------ r3900 | marko | 2009-01-13 10:32:24 +0200 (Tue, 13 Jan 2009) | 1 line branches/zip: Fix some comments to say buf_pool_mutex. ------------------------------------------------------------------------ r3907 | marko | 2009-01-13 11:54:01 +0200 (Tue, 13 Jan 2009) | 3 lines branches/zip: row_merge_create_temporary_table(): On error, row_create_table_for_mysql() already frees new_table. Do not attempt to free it again. ------------------------------------------------------------------------ r3908 | marko | 2009-01-13 12:34:32 +0200 (Tue, 13 Jan 2009) | 1 line branches/zip: Enable HASH_ASSERT_OWNED independently of UNIV_SYNC_DEBUG. ------------------------------------------------------------------------ r3914 | marko | 2009-01-13 21:46:22 +0200 (Tue, 13 Jan 2009) | 37 lines branches/zip: In hash table lookups, assert that the traversed items satisfy some conditions when UNIV_DEBUG is defined. HASH_SEARCH(): New parameter: ASSERTION. All users will pass an appropriate ut_ad() or nothing. dict_table_add_to_columns(): Assert that the table being added to the data dictionary cache is not already being pointed to by the name_hash and id_hash tables. HASH_SEARCH_ALL(): New macro, for use in dict_table_add_to_columns(). dict_mem_table_free(): Set ut_d(table->cached = FALSE), so that we can check ut_ad(table->cached) when traversing the hash tables, as in HASH_SEARCH(name_hash, dict_sys->table_hash, ...) and HASH_SEARCH(id_hash, dict_sys->table_id_hash, ...). dict_table_get_low(), dict_table_get_on_id_low(): Assert ut_ad(!table || table->cached). fil_space_get_by_id(): Check ut_ad(space->magic_n == FIL_SPACE_MAGIC_N) in HASH_SEARCH(hash, fil_system->spaces, ...). fil_space_get_by_name(): Check ut_ad(space->magic_n == FIL_SPACE_MAGIC_N) in HASH_SEARCH(name_hash, fil_system->name_hash, ...). buf_buddy_block_free(): Check that the blocks are in valid state in HASH_SEARCH(hash, buf_pool->zip_hash, ...). buf_page_hash_get(): Check that the blocks are in valid state in HASH_SEARCH(hash, buf_pool->page_hash, ...). get_share(), free_share(): Check ut_ad(share->use_count > 0) in HASH_SEARCH(table_name_hash, innobase_open_tables, ...). This was posted as rb://75 for tracking down errors similar to Issue #153. ------------------------------------------------------------------------ r3931 | marko | 2009-01-14 16:06:22 +0200 (Wed, 14 Jan 2009) | 26 lines branches/zip: Merge revisions 3601:3930 from branches/5.1: ------------------------------------------------------------------------ r3911 | sunny | 2009-01-13 14:15:24 +0200 (Tue, 13 Jan 2009) | 13 lines branches/5.1: Fix Bug#38187 Error 153 when creating savepoints InnoDB previously treated savepoints as a stack e.g., SAVEPOINT a; SAVEPOINT b; SAVEPOINT c; SAVEPOINT b; <- This would delete b and c. This fix changes the behavior to: SAVEPOINT a; SAVEPOINT b; SAVEPOINT c; SAVEPOINT b; <- Does not delete savepoint c ------------------------------------------------------------------------ r3930 | marko | 2009-01-14 15:51:30 +0200 (Wed, 14 Jan 2009) | 4 lines branches/5.1: dict_load_table(): If dict_load_indexes() fails, invoke dict_table_remove_from_cache() instead of dict_mem_table_free(), so that the data dictionary will not point to freed data. (Bug #42075, Issue #153, rb://76 approved by Heikki Tuuri) ------------------------------------------------------------------------ ------------------------------------------------------------------------
This commit is contained in:
parent
c922320f49
commit
86b8525254
43 changed files with 684 additions and 340 deletions
60
ChangeLog
60
ChangeLog
|
@ -1,3 +1,63 @@
|
|||
2009-01-13 The InnoDB Team
|
||||
|
||||
* include/hash0hash.h, include/dict0dict.ic, dict/dict0dict.c,
|
||||
include/buf0buf.ic, buf/buf0buddy.c, trx/trx0i_s.c,
|
||||
handler/ha_innodb.cc, handler/win_delay_loader.cc,
|
||||
dict/dict0mem.c, ha/ha0storage.c, thr/thr0loc.c, fil/fil0fil.c:
|
||||
Add the parameter ASSERTION to HASH_SEARCH() macro, and use it for
|
||||
light validation of the traversed items in hash table lookups when
|
||||
UNIV_DEBUG is enabled.
|
||||
|
||||
2009-01-09 The InnoDB Team
|
||||
|
||||
* include/buf0flu.h, include/buf0flu.ic, buf/buf0flu.c:
|
||||
Remove unused code from the functions
|
||||
buf_flush_insert_into_flush_list() and
|
||||
buf_flush_insert_sorted_into_flush_list().
|
||||
|
||||
2009-01-09 The InnoDB Team
|
||||
|
||||
* buf/buf0flu.c: Simplify the functions buf_flush_try_page() and
|
||||
buf_flush_batch(). Add debug assertions and an explanation to
|
||||
buf_flush_write_block_low().
|
||||
|
||||
2009-01-07 The InnoDB Team
|
||||
|
||||
* row/row0merge.c:
|
||||
Fix a bug in recovery when dropping temporary indexes
|
||||
|
||||
2009-01-07 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, handler/ha_innodb.h, handler/handler0alter.cc:
|
||||
Fix Bug#41680 calls to trx_allocate_for_mysql are not consistent
|
||||
|
||||
2009-01-07 The InnoDB Team
|
||||
|
||||
* mysql-test/innodb_bug41904.result, mysql-test/innodb_bug41904.test,
|
||||
row/row0merge.c:
|
||||
Fix Bug#41904 create unique index problem
|
||||
|
||||
2009-01-02 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, include/srv0srv.h, srv/srv0srv.c,
|
||||
srv/srv0start.c, mem/mem0pool.c,
|
||||
mysql-test/innodb-use-sys-malloc-master.opt,
|
||||
mysql-test/innodb-use-sys-malloc.result,
|
||||
mysql-test/innodb-use-sys-malloc.test:
|
||||
Implement the configuration parameter innodb_use_sys_malloc
|
||||
(false by default), for disabling InnoDB's internal memory allocator
|
||||
and using system malloc/free instead.
|
||||
|
||||
2008-12-30 The InnoDB Team
|
||||
|
||||
* btr/btr0btr.c:
|
||||
When setting the PAGE_LEVEL of a compressed B-tree page from or to
|
||||
0, compress the page at the same time. This is necessary, because
|
||||
the column information stored on the compressed page will differ
|
||||
between leaf and non-leaf pages. Leaf pages are identified by
|
||||
PAGE_LEVEL=0. This bug can make InnoDB crash when all rows of a
|
||||
compressed table are deleted.
|
||||
|
||||
2008-12-17 The InnoDB Team
|
||||
|
||||
* include/row0upd.h, include/row0sel.h, pars/pars0pars.c,
|
||||
|
|
|
@ -172,6 +172,8 @@ buf_buddy_block_free(
|
|||
ut_a(!ut_align_offset(buf, UNIV_PAGE_SIZE));
|
||||
|
||||
HASH_SEARCH(hash, buf_pool->zip_hash, fold, buf_page_t*, bpage,
|
||||
ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_MEMORY
|
||||
&& bpage->in_zip_hash && !bpage->in_page_hash),
|
||||
((buf_block_t*) bpage)->frame == buf);
|
||||
ut_a(bpage);
|
||||
ut_a(buf_page_get_state(bpage) == BUF_BLOCK_MEMORY);
|
||||
|
|
|
@ -245,7 +245,7 @@ static ulint buf_dbg_counter = 0; /* This is used to insert validation
|
|||
operations in excution in the
|
||||
debug version */
|
||||
/** Flag to forbid the release of the buffer pool mutex.
|
||||
Protected by buf_pool->mutex. */
|
||||
Protected by buf_pool_mutex. */
|
||||
UNIV_INTERN ulint buf_pool_mutex_exit_forbidden = 0;
|
||||
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
|
||||
#ifdef UNIV_DEBUG
|
||||
|
|
269
buf/buf0flu.c
269
buf/buf0flu.c
|
@ -179,44 +179,27 @@ UNIV_INTERN
|
|||
void
|
||||
buf_flush_insert_into_flush_list(
|
||||
/*=============================*/
|
||||
buf_page_t* bpage) /* in: block which is modified */
|
||||
buf_block_t* block) /* in/out: block which is modified */
|
||||
{
|
||||
ut_ad(buf_pool_mutex_own());
|
||||
ut_ad((UT_LIST_GET_FIRST(buf_pool->flush_list) == NULL)
|
||||
|| (UT_LIST_GET_FIRST(buf_pool->flush_list)->oldest_modification
|
||||
<= bpage->oldest_modification));
|
||||
<= block->page.oldest_modification));
|
||||
|
||||
/* If we are in the recovery then we need to update the flush
|
||||
red-black tree as well. */
|
||||
if (UNIV_LIKELY_NULL(buf_pool->flush_rbt)) {
|
||||
buf_flush_insert_sorted_into_flush_list(bpage);
|
||||
buf_flush_insert_sorted_into_flush_list(block);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (buf_page_get_state(bpage)) {
|
||||
case BUF_BLOCK_ZIP_PAGE:
|
||||
mutex_enter(&buf_pool_zip_mutex);
|
||||
buf_page_set_state(bpage, BUF_BLOCK_ZIP_DIRTY);
|
||||
mutex_exit(&buf_pool_zip_mutex);
|
||||
UT_LIST_REMOVE(list, buf_pool->zip_clean, bpage);
|
||||
/* fall through */
|
||||
case BUF_BLOCK_ZIP_DIRTY:
|
||||
case BUF_BLOCK_FILE_PAGE:
|
||||
ut_ad(bpage->in_LRU_list);
|
||||
ut_ad(bpage->in_page_hash);
|
||||
ut_ad(!bpage->in_zip_hash);
|
||||
ut_ad(!bpage->in_flush_list);
|
||||
ut_d(bpage->in_flush_list = TRUE);
|
||||
UT_LIST_ADD_FIRST(list, buf_pool->flush_list, bpage);
|
||||
break;
|
||||
case BUF_BLOCK_ZIP_FREE:
|
||||
case BUF_BLOCK_NOT_USED:
|
||||
case BUF_BLOCK_READY_FOR_USE:
|
||||
case BUF_BLOCK_MEMORY:
|
||||
case BUF_BLOCK_REMOVE_HASH:
|
||||
ut_error;
|
||||
return;
|
||||
}
|
||||
ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
|
||||
ut_ad(block->page.in_LRU_list);
|
||||
ut_ad(block->page.in_page_hash);
|
||||
ut_ad(!block->page.in_zip_hash);
|
||||
ut_ad(!block->page.in_flush_list);
|
||||
ut_d(block->page.in_flush_list = TRUE);
|
||||
UT_LIST_ADD_FIRST(list, buf_pool->flush_list, &block->page);
|
||||
|
||||
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
|
||||
ut_a(buf_flush_validate_low());
|
||||
|
@ -231,36 +214,19 @@ UNIV_INTERN
|
|||
void
|
||||
buf_flush_insert_sorted_into_flush_list(
|
||||
/*====================================*/
|
||||
buf_page_t* bpage) /* in: block which is modified */
|
||||
buf_block_t* block) /* in/out: block which is modified */
|
||||
{
|
||||
buf_page_t* prev_b;
|
||||
buf_page_t* b;
|
||||
|
||||
ut_ad(buf_pool_mutex_own());
|
||||
ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
|
||||
|
||||
switch (buf_page_get_state(bpage)) {
|
||||
case BUF_BLOCK_ZIP_PAGE:
|
||||
mutex_enter(&buf_pool_zip_mutex);
|
||||
buf_page_set_state(bpage, BUF_BLOCK_ZIP_DIRTY);
|
||||
mutex_exit(&buf_pool_zip_mutex);
|
||||
UT_LIST_REMOVE(list, buf_pool->zip_clean, bpage);
|
||||
/* fall through */
|
||||
case BUF_BLOCK_ZIP_DIRTY:
|
||||
case BUF_BLOCK_FILE_PAGE:
|
||||
ut_ad(bpage->in_LRU_list);
|
||||
ut_ad(bpage->in_page_hash);
|
||||
ut_ad(!bpage->in_zip_hash);
|
||||
ut_ad(!bpage->in_flush_list);
|
||||
ut_d(bpage->in_flush_list = TRUE);
|
||||
break;
|
||||
case BUF_BLOCK_ZIP_FREE:
|
||||
case BUF_BLOCK_NOT_USED:
|
||||
case BUF_BLOCK_READY_FOR_USE:
|
||||
case BUF_BLOCK_MEMORY:
|
||||
case BUF_BLOCK_REMOVE_HASH:
|
||||
ut_error;
|
||||
return;
|
||||
}
|
||||
ut_ad(block->page.in_LRU_list);
|
||||
ut_ad(block->page.in_page_hash);
|
||||
ut_ad(!block->page.in_zip_hash);
|
||||
ut_ad(!block->page.in_flush_list);
|
||||
ut_d(block->page.in_flush_list = TRUE);
|
||||
|
||||
prev_b = NULL;
|
||||
|
||||
|
@ -272,14 +238,14 @@ buf_flush_insert_sorted_into_flush_list(
|
|||
linear search in the else block. */
|
||||
if (buf_pool->flush_rbt) {
|
||||
|
||||
prev_b = buf_flush_insert_in_flush_rbt(bpage);
|
||||
prev_b = buf_flush_insert_in_flush_rbt(&block->page);
|
||||
|
||||
} else {
|
||||
|
||||
b = UT_LIST_GET_FIRST(buf_pool->flush_list);
|
||||
|
||||
while (b && b->oldest_modification
|
||||
> bpage->oldest_modification) {
|
||||
> block->page.oldest_modification) {
|
||||
ut_ad(b->in_flush_list);
|
||||
prev_b = b;
|
||||
b = UT_LIST_GET_NEXT(list, b);
|
||||
|
@ -287,10 +253,10 @@ buf_flush_insert_sorted_into_flush_list(
|
|||
}
|
||||
|
||||
if (prev_b == NULL) {
|
||||
UT_LIST_ADD_FIRST(list, buf_pool->flush_list, bpage);
|
||||
UT_LIST_ADD_FIRST(list, buf_pool->flush_list, &block->page);
|
||||
} else {
|
||||
UT_LIST_INSERT_AFTER(list, buf_pool->flush_list,
|
||||
prev_b, bpage);
|
||||
prev_b, &block->page);
|
||||
}
|
||||
|
||||
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
|
||||
|
@ -345,6 +311,7 @@ buf_flush_ready_for_flush(
|
|||
ut_a(buf_page_in_file(bpage));
|
||||
ut_ad(buf_pool_mutex_own());
|
||||
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
|
||||
ut_ad(flush_type == BUF_FLUSH_LRU || BUF_FLUSH_LIST);
|
||||
|
||||
if (bpage->oldest_modification != 0
|
||||
&& buf_page_get_io_fix(bpage) == BUF_IO_NONE) {
|
||||
|
@ -910,6 +877,16 @@ buf_flush_write_block_low(
|
|||
|
||||
ut_ad(buf_page_in_file(bpage));
|
||||
|
||||
/* We are not holding buf_pool_mutex or block_mutex here.
|
||||
Nevertheless, it is safe to access bpage, because it is
|
||||
io_fixed and oldest_modification != 0. Thus, it cannot be
|
||||
relocated in the buffer pool or removed from flush_list or
|
||||
LRU_list. */
|
||||
ut_ad(!buf_pool_mutex_own());
|
||||
ut_ad(!mutex_own(buf_page_get_mutex(bpage)));
|
||||
ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_WRITE);
|
||||
ut_ad(bpage->oldest_modification != 0);
|
||||
|
||||
#ifdef UNIV_IBUF_COUNT_DEBUG
|
||||
ut_a(ibuf_count_get(bpage->space, bpage->offset) == 0);
|
||||
#endif
|
||||
|
@ -971,68 +948,55 @@ buf_flush_write_block_low(
|
|||
}
|
||||
|
||||
/************************************************************************
|
||||
Writes a page asynchronously from the buffer buf_pool to a file, if it can be
|
||||
found in the buf_pool and it is in a flushable state. NOTE: in simulated aio
|
||||
we must call os_aio_simulated_wake_handler_threads after we have posted a batch
|
||||
of writes! */
|
||||
Writes a flushable page asynchronously from the buffer pool to a file.
|
||||
NOTE: in simulated aio we must call
|
||||
os_aio_simulated_wake_handler_threads after we have posted a batch of
|
||||
writes! NOTE: buf_pool_mutex and buf_page_get_mutex(bpage) must be
|
||||
held upon entering this function, and they will be released by this
|
||||
function. */
|
||||
static
|
||||
ulint
|
||||
buf_flush_try_page(
|
||||
/*===============*/
|
||||
/* out: 1 if a page was
|
||||
flushed, 0 otherwise */
|
||||
ulint space, /* in: space id */
|
||||
ulint offset, /* in: page offset */
|
||||
enum buf_flush flush_type) /* in: BUF_FLUSH_LRU, BUF_FLUSH_LIST,
|
||||
or BUF_FLUSH_SINGLE_PAGE */
|
||||
void
|
||||
buf_flush_page(
|
||||
/*===========*/
|
||||
buf_page_t* bpage, /* in: buffer control block */
|
||||
enum buf_flush flush_type) /* in: BUF_FLUSH_LRU
|
||||
or BUF_FLUSH_LIST */
|
||||
{
|
||||
buf_page_t* bpage;
|
||||
mutex_t* block_mutex;
|
||||
ibool locked;
|
||||
ibool is_uncompressed;
|
||||
|
||||
ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST
|
||||
|| flush_type == BUF_FLUSH_SINGLE_PAGE);
|
||||
ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST);
|
||||
ut_ad(buf_pool_mutex_own());
|
||||
ut_ad(buf_page_in_file(bpage));
|
||||
|
||||
buf_pool_mutex_enter();
|
||||
|
||||
bpage = buf_page_hash_get(space, offset);
|
||||
|
||||
if (!bpage) {
|
||||
buf_pool_mutex_exit();
|
||||
return(0);
|
||||
}
|
||||
|
||||
ut_a(buf_page_in_file(bpage));
|
||||
block_mutex = buf_page_get_mutex(bpage);
|
||||
ut_ad(mutex_own(block_mutex));
|
||||
|
||||
mutex_enter(block_mutex);
|
||||
ut_ad(buf_flush_ready_for_flush(bpage, flush_type));
|
||||
|
||||
if (!buf_flush_ready_for_flush(bpage, flush_type)) {
|
||||
mutex_exit(block_mutex);
|
||||
buf_pool_mutex_exit();
|
||||
return(0);
|
||||
buf_page_set_io_fix(bpage, BUF_IO_WRITE);
|
||||
|
||||
buf_page_set_flush_type(bpage, flush_type);
|
||||
|
||||
if (buf_pool->n_flush[flush_type] == 0) {
|
||||
|
||||
os_event_reset(buf_pool->no_flush[flush_type]);
|
||||
}
|
||||
|
||||
buf_pool->n_flush[flush_type]++;
|
||||
|
||||
is_uncompressed = (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE);
|
||||
ut_ad(is_uncompressed == (block_mutex != &buf_pool_zip_mutex));
|
||||
|
||||
switch (flush_type) {
|
||||
ibool is_s_latched;
|
||||
case BUF_FLUSH_LIST:
|
||||
buf_page_set_io_fix(bpage, BUF_IO_WRITE);
|
||||
|
||||
buf_page_set_flush_type(bpage, flush_type);
|
||||
|
||||
if (buf_pool->n_flush[flush_type] == 0) {
|
||||
|
||||
os_event_reset(buf_pool->no_flush[flush_type]);
|
||||
}
|
||||
|
||||
buf_pool->n_flush[flush_type]++;
|
||||
|
||||
/* If the simulated aio thread is not running, we must
|
||||
not wait for any latch, as we may end up in a deadlock:
|
||||
if buf_fix_count == 0, then we know we need not wait */
|
||||
|
||||
locked = bpage->buf_fix_count == 0;
|
||||
if (locked
|
||||
&& buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE) {
|
||||
is_s_latched = (bpage->buf_fix_count == 0);
|
||||
if (is_s_latched && is_uncompressed) {
|
||||
rw_lock_s_lock_gen(&((buf_block_t*) bpage)->lock,
|
||||
BUF_IO_WRITE);
|
||||
}
|
||||
|
@ -1040,10 +1004,16 @@ buf_flush_try_page(
|
|||
mutex_exit(block_mutex);
|
||||
buf_pool_mutex_exit();
|
||||
|
||||
if (!locked) {
|
||||
/* Even though bpage is not protected by any mutex at
|
||||
this point, it is safe to access bpage, because it is
|
||||
io_fixed and oldest_modification != 0. Thus, it
|
||||
cannot be relocated in the buffer pool or removed from
|
||||
flush_list or LRU_list. */
|
||||
|
||||
if (!is_s_latched) {
|
||||
buf_flush_buffered_writes();
|
||||
|
||||
if (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE) {
|
||||
if (is_uncompressed) {
|
||||
rw_lock_s_lock_gen(&((buf_block_t*) bpage)
|
||||
->lock, BUF_IO_WRITE);
|
||||
}
|
||||
|
@ -1056,22 +1026,10 @@ buf_flush_try_page(
|
|||
Because any thread may call the LRU flush, even when owning
|
||||
locks on pages, to avoid deadlocks, we must make sure that the
|
||||
s-lock is acquired on the page without waiting: this is
|
||||
accomplished because in the if-condition above we require
|
||||
the page not to be bufferfixed (in function
|
||||
..._ready_for_flush). */
|
||||
accomplished because buf_flush_ready_for_flush() must hold,
|
||||
and that requires the page not to be bufferfixed. */
|
||||
|
||||
buf_page_set_io_fix(bpage, BUF_IO_WRITE);
|
||||
|
||||
buf_page_set_flush_type(bpage, flush_type);
|
||||
|
||||
if (buf_pool->n_flush[flush_type] == 0) {
|
||||
|
||||
os_event_reset(buf_pool->no_flush[flush_type]);
|
||||
}
|
||||
|
||||
buf_pool->n_flush[flush_type]++;
|
||||
|
||||
if (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE) {
|
||||
if (is_uncompressed) {
|
||||
rw_lock_s_lock_gen(&((buf_block_t*) bpage)->lock,
|
||||
BUF_IO_WRITE);
|
||||
}
|
||||
|
@ -1084,31 +1042,15 @@ buf_flush_try_page(
|
|||
buf_pool_mutex_exit();
|
||||
break;
|
||||
|
||||
case BUF_FLUSH_SINGLE_PAGE:
|
||||
buf_page_set_io_fix(bpage, BUF_IO_WRITE);
|
||||
|
||||
buf_page_set_flush_type(bpage, flush_type);
|
||||
|
||||
if (buf_pool->n_flush[flush_type] == 0) {
|
||||
|
||||
os_event_reset(buf_pool->no_flush[flush_type]);
|
||||
}
|
||||
|
||||
buf_pool->n_flush[flush_type]++;
|
||||
|
||||
mutex_exit(block_mutex);
|
||||
buf_pool_mutex_exit();
|
||||
|
||||
if (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE) {
|
||||
rw_lock_s_lock_gen(&((buf_block_t*) bpage)->lock,
|
||||
BUF_IO_WRITE);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ut_error;
|
||||
}
|
||||
|
||||
/* Even though bpage is not protected by any mutex at this
|
||||
point, it is safe to access bpage, because it is io_fixed and
|
||||
oldest_modification != 0. Thus, it cannot be relocated in the
|
||||
buffer pool or removed from flush_list or LRU_list. */
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
if (buf_debug_prints) {
|
||||
fprintf(stderr,
|
||||
|
@ -1117,8 +1059,6 @@ buf_flush_try_page(
|
|||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
buf_flush_write_block_low(bpage);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
|
@ -1168,21 +1108,20 @@ buf_flush_try_neighbors(
|
|||
for (i = low; i < high; i++) {
|
||||
|
||||
bpage = buf_page_hash_get(space, i);
|
||||
ut_a(!bpage || buf_page_in_file(bpage));
|
||||
|
||||
if (!bpage) {
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
} else if (flush_type == BUF_FLUSH_LRU && i != offset
|
||||
&& !buf_page_is_old(bpage)) {
|
||||
ut_a(buf_page_in_file(bpage));
|
||||
|
||||
/* We avoid flushing 'non-old' blocks in an LRU flush,
|
||||
because the flushed blocks are soon freed */
|
||||
|
||||
continue;
|
||||
} else {
|
||||
/* We avoid flushing 'non-old' blocks in an LRU flush,
|
||||
because the flushed blocks are soon freed */
|
||||
|
||||
if (flush_type != BUF_FLUSH_LRU
|
||||
|| i == offset
|
||||
|| buf_page_is_old(bpage)) {
|
||||
mutex_t* block_mutex = buf_page_get_mutex(bpage);
|
||||
|
||||
mutex_enter(block_mutex);
|
||||
|
@ -1197,18 +1136,9 @@ buf_flush_try_neighbors(
|
|||
flush the doublewrite buffer before we start
|
||||
waiting. */
|
||||
|
||||
buf_pool_mutex_exit();
|
||||
|
||||
mutex_exit(block_mutex);
|
||||
|
||||
/* Note: as we release the buf_pool mutex
|
||||
above, in buf_flush_try_page we cannot be sure
|
||||
the page is still in a flushable state:
|
||||
therefore we check it again inside that
|
||||
function. */
|
||||
|
||||
count += buf_flush_try_page(space, i,
|
||||
flush_type);
|
||||
buf_flush_page(bpage, flush_type);
|
||||
ut_ad(!mutex_own(block_mutex));
|
||||
count++;
|
||||
|
||||
buf_pool_mutex_enter();
|
||||
} else {
|
||||
|
@ -1308,19 +1238,20 @@ flush_next:
|
|||
function a pointer to a block in the list! */
|
||||
|
||||
do {
|
||||
mutex_t* block_mutex = buf_page_get_mutex(bpage);
|
||||
mutex_t*block_mutex = buf_page_get_mutex(bpage);
|
||||
ibool ready;
|
||||
|
||||
ut_a(buf_page_in_file(bpage));
|
||||
|
||||
mutex_enter(block_mutex);
|
||||
ready = buf_flush_ready_for_flush(bpage, flush_type);
|
||||
mutex_exit(block_mutex);
|
||||
|
||||
if (buf_flush_ready_for_flush(bpage, flush_type)) {
|
||||
|
||||
if (ready) {
|
||||
space = buf_page_get_space(bpage);
|
||||
offset = buf_page_get_page_no(bpage);
|
||||
|
||||
buf_pool_mutex_exit();
|
||||
mutex_exit(block_mutex);
|
||||
|
||||
old_page_count = page_count;
|
||||
|
||||
|
@ -1336,15 +1267,10 @@ flush_next:
|
|||
goto flush_next;
|
||||
|
||||
} else if (flush_type == BUF_FLUSH_LRU) {
|
||||
|
||||
mutex_exit(block_mutex);
|
||||
|
||||
bpage = UT_LIST_GET_PREV(LRU, bpage);
|
||||
} else {
|
||||
ut_ad(flush_type == BUF_FLUSH_LIST);
|
||||
|
||||
mutex_exit(block_mutex);
|
||||
|
||||
bpage = UT_LIST_GET_PREV(list, bpage);
|
||||
ut_ad(!bpage || bpage->in_flush_list);
|
||||
}
|
||||
|
@ -1357,8 +1283,7 @@ flush_next:
|
|||
|
||||
buf_pool->init_flush[flush_type] = FALSE;
|
||||
|
||||
if ((buf_pool->n_flush[flush_type] == 0)
|
||||
&& (buf_pool->init_flush[flush_type] == FALSE)) {
|
||||
if (buf_pool->n_flush[flush_type] == 0) {
|
||||
|
||||
/* The running flush batch has ended */
|
||||
|
||||
|
|
|
@ -251,7 +251,7 @@ scan_again:
|
|||
if (num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE) {
|
||||
goto next_page;
|
||||
}
|
||||
/* Array full. We release the buf_pool->mutex to
|
||||
/* Array full. We release the buf_pool_mutex to
|
||||
obey the latching order. */
|
||||
buf_pool_mutex_exit();
|
||||
|
||||
|
|
|
@ -751,18 +751,34 @@ dict_table_add_to_cache(
|
|||
{
|
||||
dict_table_t* table2;
|
||||
HASH_SEARCH(name_hash, dict_sys->table_hash, fold,
|
||||
dict_table_t*, table2,
|
||||
(ut_strcmp(table2->name, table->name) == 0));
|
||||
dict_table_t*, table2, ut_ad(table2->cached),
|
||||
ut_strcmp(table2->name, table->name) == 0);
|
||||
ut_a(table2 == NULL);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/* Look for the same table pointer with a different name */
|
||||
HASH_SEARCH_ALL(name_hash, dict_sys->table_hash,
|
||||
dict_table_t*, table2, ut_ad(table2->cached),
|
||||
table2 == table);
|
||||
ut_ad(table2 == NULL);
|
||||
#endif /* UNIV_DEBUG */
|
||||
}
|
||||
|
||||
/* Look for a table with the same id: error if such exists */
|
||||
{
|
||||
dict_table_t* table2;
|
||||
HASH_SEARCH(id_hash, dict_sys->table_id_hash, id_fold,
|
||||
dict_table_t*, table2,
|
||||
(ut_dulint_cmp(table2->id, table->id) == 0));
|
||||
dict_table_t*, table2, ut_ad(table2->cached),
|
||||
ut_dulint_cmp(table2->id, table->id) == 0);
|
||||
ut_a(table2 == NULL);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/* Look for the same table pointer with a different id */
|
||||
HASH_SEARCH_ALL(id_hash, dict_sys->table_id_hash,
|
||||
dict_table_t*, table2, ut_ad(table2->cached),
|
||||
table2 == table);
|
||||
ut_ad(table2 == NULL);
|
||||
#endif /* UNIV_DEBUG */
|
||||
}
|
||||
|
||||
/* Add table to hash table of tables */
|
||||
|
@ -844,7 +860,7 @@ dict_table_rename_in_cache(
|
|||
{
|
||||
dict_table_t* table2;
|
||||
HASH_SEARCH(name_hash, dict_sys->table_hash, fold,
|
||||
dict_table_t*, table2,
|
||||
dict_table_t*, table2, ut_ad(table2->cached),
|
||||
(ut_strcmp(table2->name, new_name) == 0));
|
||||
if (UNIV_LIKELY_NULL(table2)) {
|
||||
ut_print_timestamp(stderr);
|
||||
|
|
|
@ -949,11 +949,11 @@ err_exit:
|
|||
of the error condition, since the user may want to dump data from the
|
||||
clustered index. However we load the foreign key information only if
|
||||
all indexes were loaded. */
|
||||
if (err != DB_SUCCESS && !srv_force_recovery) {
|
||||
dict_mem_table_free(table);
|
||||
table = NULL;
|
||||
} else if (err == DB_SUCCESS) {
|
||||
if (err == DB_SUCCESS) {
|
||||
err = dict_load_foreigns(table->name, TRUE);
|
||||
} else if (!srv_force_recovery) {
|
||||
dict_table_remove_from_cache(table);
|
||||
table = NULL;
|
||||
}
|
||||
# if 0
|
||||
if (err != DB_SUCCESS && table != NULL) {
|
||||
|
|
|
@ -84,6 +84,7 @@ dict_mem_table_free(
|
|||
{
|
||||
ut_ad(table);
|
||||
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
|
||||
ut_d(table->cached = FALSE);
|
||||
|
||||
mutex_free(&(table->autoinc_mutex));
|
||||
mem_heap_free(table->heap);
|
||||
|
|
|
@ -363,7 +363,9 @@ fil_space_get_by_id(
|
|||
ut_ad(mutex_own(&fil_system->mutex));
|
||||
|
||||
HASH_SEARCH(hash, fil_system->spaces, id,
|
||||
fil_space_t*, space, space->id == id);
|
||||
fil_space_t*, space,
|
||||
ut_ad(space->magic_n == FIL_SPACE_MAGIC_N),
|
||||
space->id == id);
|
||||
|
||||
return(space);
|
||||
}
|
||||
|
@ -384,7 +386,9 @@ fil_space_get_by_name(
|
|||
fold = ut_fold_string(name);
|
||||
|
||||
HASH_SEARCH(name_hash, fil_system->name_hash, fold,
|
||||
fil_space_t*, space, !strcmp(name, space->name));
|
||||
fil_space_t*, space,
|
||||
ut_ad(space->magic_n == FIL_SPACE_MAGIC_N),
|
||||
!strcmp(name, space->name));
|
||||
|
||||
return(space);
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ ha_storage_get(
|
|||
fold, /* key */
|
||||
ha_storage_node_t*, /* type of node->next */
|
||||
node, /* auxiliary variable */
|
||||
, /* assertion */
|
||||
IS_FOUND); /* search criteria */
|
||||
|
||||
if (node == NULL) {
|
||||
|
|
|
@ -1211,6 +1211,53 @@ innobase_next_autoinc(
|
|||
return(next_value);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Initializes some fields in an InnoDB transaction object. */
|
||||
static
|
||||
void
|
||||
innobase_trx_init(
|
||||
/*==============*/
|
||||
THD* thd, /* in: user thread handle */
|
||||
trx_t* trx) /* in/out: InnoDB transaction handle */
|
||||
{
|
||||
DBUG_ENTER("innobase_trx_init");
|
||||
DBUG_ASSERT(EQ_CURRENT_THD(thd));
|
||||
DBUG_ASSERT(thd == trx->mysql_thd);
|
||||
|
||||
trx->check_foreigns = !thd_test_options(
|
||||
thd, OPTION_NO_FOREIGN_KEY_CHECKS);
|
||||
|
||||
trx->check_unique_secondary = !thd_test_options(
|
||||
thd, OPTION_RELAXED_UNIQUE_CHECKS);
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Allocates an InnoDB transaction for a MySQL handler object. */
|
||||
extern "C" UNIV_INTERN
|
||||
trx_t*
|
||||
innobase_trx_allocate(
|
||||
/*==================*/
|
||||
/* out: InnoDB transaction handle */
|
||||
THD* thd) /* in: user thread handle */
|
||||
{
|
||||
trx_t* trx;
|
||||
|
||||
DBUG_ENTER("innobase_trx_allocate");
|
||||
DBUG_ASSERT(thd != NULL);
|
||||
DBUG_ASSERT(EQ_CURRENT_THD(thd));
|
||||
|
||||
trx = trx_allocate_for_mysql();
|
||||
|
||||
trx->mysql_thd = thd;
|
||||
trx->mysql_query_str = thd_query(thd);
|
||||
|
||||
innobase_trx_init(thd, trx);
|
||||
|
||||
DBUG_RETURN(trx);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Gets the InnoDB transaction handle for a MySQL handler object, creates
|
||||
an InnoDB transaction struct if the corresponding MySQL thread struct still
|
||||
|
@ -1227,31 +1274,13 @@ check_trx_exists(
|
|||
ut_ad(EQ_CURRENT_THD(thd));
|
||||
|
||||
if (trx == NULL) {
|
||||
DBUG_ASSERT(thd != NULL);
|
||||
trx = trx_allocate_for_mysql();
|
||||
|
||||
trx->mysql_thd = thd;
|
||||
trx->mysql_query_str = thd_query(thd);
|
||||
|
||||
} else {
|
||||
if (trx->magic_n != TRX_MAGIC_N) {
|
||||
mem_analyze_corruption(trx);
|
||||
|
||||
ut_error;
|
||||
}
|
||||
trx = innobase_trx_allocate(thd);
|
||||
} else if (UNIV_UNLIKELY(trx->magic_n != TRX_MAGIC_N)) {
|
||||
mem_analyze_corruption(trx);
|
||||
ut_error;
|
||||
}
|
||||
|
||||
if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
|
||||
trx->check_foreigns = FALSE;
|
||||
} else {
|
||||
trx->check_foreigns = TRUE;
|
||||
}
|
||||
|
||||
if (thd_test_options(thd, OPTION_RELAXED_UNIQUE_CHECKS)) {
|
||||
trx->check_unique_secondary = FALSE;
|
||||
} else {
|
||||
trx->check_unique_secondary = TRUE;
|
||||
}
|
||||
innobase_trx_init(thd, trx);
|
||||
|
||||
return(trx);
|
||||
}
|
||||
|
@ -4621,7 +4650,8 @@ ha_innobase::unlock_row(void)
|
|||
switch (prebuilt->row_read_type) {
|
||||
case ROW_READ_WITH_LOCKS:
|
||||
if (!srv_locks_unsafe_for_binlog
|
||||
|| prebuilt->trx->isolation_level == TRX_ISO_READ_COMMITTED) {
|
||||
&& prebuilt->trx->isolation_level
|
||||
!= TRX_ISO_READ_COMMITTED) {
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
|
@ -5480,9 +5510,19 @@ create_table_def(
|
|||
|
||||
charset_no = (ulint)field->charset()->number;
|
||||
|
||||
ut_a(charset_no < 256); /* in data0type.h we assume
|
||||
that the number fits in one
|
||||
byte */
|
||||
if (UNIV_UNLIKELY(charset_no >= 256)) {
|
||||
/* in data0type.h we assume that the
|
||||
number fits in one byte in prtype */
|
||||
push_warning_printf(
|
||||
(THD*) trx->mysql_thd,
|
||||
MYSQL_ERROR::WARN_LEVEL_ERROR,
|
||||
ER_CANT_CREATE_TABLE,
|
||||
"In InnoDB, charset-collation codes"
|
||||
" must be below 256."
|
||||
" Unsupported code %lu.",
|
||||
(ulong) charset_no);
|
||||
DBUG_RETURN(ER_CANT_CREATE_TABLE);
|
||||
}
|
||||
}
|
||||
|
||||
ut_a(field->type() < 256); /* we assume in dtype_form_prtype()
|
||||
|
@ -5927,18 +5967,7 @@ ha_innobase::create(
|
|||
|
||||
trx_search_latch_release_if_reserved(parent_trx);
|
||||
|
||||
trx = trx_allocate_for_mysql();
|
||||
|
||||
trx->mysql_thd = thd;
|
||||
trx->mysql_query_str = thd_query(thd);
|
||||
|
||||
if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
|
||||
trx->check_foreigns = FALSE;
|
||||
}
|
||||
|
||||
if (thd_test_options(thd, OPTION_RELAXED_UNIQUE_CHECKS)) {
|
||||
trx->check_unique_secondary = FALSE;
|
||||
}
|
||||
trx = innobase_trx_allocate(thd);
|
||||
|
||||
if (lower_case_table_names) {
|
||||
srv_lower_case_table_names = TRUE;
|
||||
|
@ -6344,25 +6373,14 @@ ha_innobase::delete_table(
|
|||
|
||||
trx_search_latch_release_if_reserved(parent_trx);
|
||||
|
||||
trx = innobase_trx_allocate(thd);
|
||||
|
||||
if (lower_case_table_names) {
|
||||
srv_lower_case_table_names = TRUE;
|
||||
} else {
|
||||
srv_lower_case_table_names = FALSE;
|
||||
}
|
||||
|
||||
trx = trx_allocate_for_mysql();
|
||||
|
||||
trx->mysql_thd = thd;
|
||||
trx->mysql_query_str = thd_query(thd);
|
||||
|
||||
if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
|
||||
trx->check_foreigns = FALSE;
|
||||
}
|
||||
|
||||
if (thd_test_options(thd, OPTION_RELAXED_UNIQUE_CHECKS)) {
|
||||
trx->check_unique_secondary = FALSE;
|
||||
}
|
||||
|
||||
name_len = strlen(name);
|
||||
|
||||
ut_a(name_len < 1000);
|
||||
|
@ -6445,19 +6463,14 @@ innobase_drop_database(
|
|||
#ifdef __WIN__
|
||||
innobase_casedn_str(namebuf);
|
||||
#endif
|
||||
#if defined __WIN__ && !defined MYSQL_SERVER
|
||||
/* In the Windows plugin, thd = current_thd is always NULL */
|
||||
trx = trx_allocate_for_mysql();
|
||||
trx->mysql_thd = thd;
|
||||
if (thd) {
|
||||
trx->mysql_query_str = thd_query(thd);
|
||||
|
||||
if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
|
||||
trx->check_foreigns = FALSE;
|
||||
}
|
||||
} else {
|
||||
/* In the Windows plugin, thd = current_thd is always NULL */
|
||||
trx->mysql_query_str = NULL;
|
||||
}
|
||||
|
||||
trx->mysql_thd = NULL;
|
||||
trx->mysql_query_str = NULL;
|
||||
#else
|
||||
trx = innobase_trx_allocate(thd);
|
||||
#endif
|
||||
error = row_drop_database_for_mysql(namebuf, trx);
|
||||
my_free(namebuf, MYF(0));
|
||||
|
||||
|
@ -6567,13 +6580,7 @@ ha_innobase::rename_table(
|
|||
|
||||
trx_search_latch_release_if_reserved(parent_trx);
|
||||
|
||||
trx = trx_allocate_for_mysql();
|
||||
trx->mysql_thd = thd;
|
||||
trx->mysql_query_str = thd_query(thd);
|
||||
|
||||
if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
|
||||
trx->check_foreigns = FALSE;
|
||||
}
|
||||
trx = innobase_trx_allocate(thd);
|
||||
|
||||
error = innobase_rename_table(trx, from, to, TRUE);
|
||||
|
||||
|
@ -8164,6 +8171,7 @@ static INNOBASE_SHARE* get_share(const char* table_name)
|
|||
|
||||
HASH_SEARCH(table_name_hash, innobase_open_tables, fold,
|
||||
INNOBASE_SHARE*, share,
|
||||
ut_ad(share->use_count > 0),
|
||||
!my_strnncoll(system_charset_info,
|
||||
share->table_name,
|
||||
share->table_name_length,
|
||||
|
@ -8205,6 +8213,7 @@ static void free_share(INNOBASE_SHARE* share)
|
|||
|
||||
HASH_SEARCH(table_name_hash, innobase_open_tables, fold,
|
||||
INNOBASE_SHARE*, share2,
|
||||
ut_ad(share->use_count > 0),
|
||||
!my_strnncoll(system_charset_info,
|
||||
share->table_name,
|
||||
share->table_name_length,
|
||||
|
@ -9580,6 +9589,11 @@ static MYSQL_SYSVAR_STR(version, innodb_version_str,
|
|||
PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_READONLY,
|
||||
"InnoDB version", NULL, NULL, INNODB_VERSION_STR);
|
||||
|
||||
static MYSQL_SYSVAR_BOOL(use_sys_malloc, srv_use_sys_malloc,
|
||||
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
|
||||
"Use OS memory allocator instead of InnoDB's internal memory allocator",
|
||||
NULL, NULL, FALSE);
|
||||
|
||||
static MYSQL_SYSVAR_BOOL(use_native_aio, srv_use_native_aio,
|
||||
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
|
||||
"Use native AIO if supported on this platform.",
|
||||
|
@ -9631,6 +9645,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
|
|||
MYSQL_SYSVAR(thread_sleep_delay),
|
||||
MYSQL_SYSVAR(autoinc_lock_mode),
|
||||
MYSQL_SYSVAR(version),
|
||||
MYSQL_SYSVAR(use_sys_malloc),
|
||||
MYSQL_SYSVAR(use_native_aio),
|
||||
NULL
|
||||
};
|
||||
|
|
|
@ -269,3 +269,12 @@ convert_error_code_to_mysql(
|
|||
int error, /* in: InnoDB error code */
|
||||
ulint flags, /* in: InnoDB table flags, or 0 */
|
||||
MYSQL_THD thd); /* in: user thread handle or NULL */
|
||||
|
||||
/*************************************************************************
|
||||
Allocates an InnoDB transaction for a MySQL handler object. */
|
||||
extern "C"
|
||||
trx_t*
|
||||
innobase_trx_allocate(
|
||||
/*==================*/
|
||||
/* out: InnoDB transaction handle */
|
||||
MYSQL_THD thd); /* in: user thread handle */
|
||||
|
|
|
@ -633,12 +633,9 @@ ha_innobase::add_index(
|
|||
|
||||
/* Create a background transaction for the operations on
|
||||
the data dictionary tables. */
|
||||
trx = trx_allocate_for_mysql();
|
||||
trx = innobase_trx_allocate(user_thd);
|
||||
trx_start_if_not_started(trx);
|
||||
|
||||
trx->mysql_thd = user_thd;
|
||||
trx->mysql_query_str = thd_query(user_thd);
|
||||
|
||||
innodb_table = indexed_table
|
||||
= dict_table_get(prebuilt->table->name, FALSE);
|
||||
|
||||
|
@ -1125,12 +1122,9 @@ ha_innobase::final_drop_index(
|
|||
|
||||
/* Create a background transaction for the operations on
|
||||
the data dictionary tables. */
|
||||
trx = trx_allocate_for_mysql();
|
||||
trx = innobase_trx_allocate(user_thd);
|
||||
trx_start_if_not_started(trx);
|
||||
|
||||
trx->mysql_thd = user_thd;
|
||||
trx->mysql_query_str = thd_query(user_thd);
|
||||
|
||||
/* Flag this transaction as a dictionary operation, so that
|
||||
the data dictionary will be locked in crash recovery. */
|
||||
trx_set_dict_operation(trx, TRX_DICT_OP_INDEX);
|
||||
|
|
|
@ -453,6 +453,7 @@ wdl_get_procaddr_from_map(
|
|||
map_fold,
|
||||
map_hash_chain_t*,
|
||||
hash_chain,
|
||||
,
|
||||
(ut_strcmp(hash_chain->symbol, import_proc) == 0));
|
||||
|
||||
if (hash_chain == NULL) {
|
||||
|
@ -472,6 +473,7 @@ wdl_get_procaddr_from_map(
|
|||
map_fold,
|
||||
map_hash_chain_t*,
|
||||
hash_chain,
|
||||
,
|
||||
(ut_strcmp(hash_chain->symbol, import_proc) == 0));
|
||||
|
||||
if (hash_chain == NULL) {
|
||||
|
@ -515,6 +517,7 @@ wdl_get_varaddr_from_map(
|
|||
map_fold,
|
||||
map_hash_chain_t*,
|
||||
hash_chain,
|
||||
,
|
||||
(ut_strcmp(hash_chain->symbol, import_variable) == 0));
|
||||
|
||||
if (hash_chain == NULL) {
|
||||
|
@ -534,6 +537,7 @@ wdl_get_varaddr_from_map(
|
|||
map_fold,
|
||||
map_hash_chain_t*,
|
||||
hash_chain,
|
||||
,
|
||||
(ut_strcmp(hash_chain->symbol, import_variable) == 0));
|
||||
|
||||
if (hash_chain == NULL) {
|
||||
|
|
|
@ -1010,8 +1010,10 @@ struct buf_page_struct{
|
|||
since they can be stored in the same machine word. Some of them are
|
||||
additionally protected by buf_pool_mutex. */
|
||||
|
||||
unsigned space:32; /* tablespace id */
|
||||
unsigned offset:32; /* page number */
|
||||
unsigned space:32; /* tablespace id; also protected
|
||||
by buf_pool_mutex. */
|
||||
unsigned offset:32; /* page number; also protected
|
||||
by buf_pool_mutex. */
|
||||
|
||||
unsigned state:3; /* state of the control block
|
||||
(@see enum buf_page_state); also
|
||||
|
@ -1080,7 +1082,8 @@ struct buf_page_struct{
|
|||
not yet been flushed on disk; zero if
|
||||
all modifications are on disk */
|
||||
|
||||
/* 3. LRU replacement algorithm fields; protected by buf_pool_mutex */
|
||||
/* 3. LRU replacement algorithm fields; protected by
|
||||
buf_pool_mutex only (not buf_pool_zip_mutex or block->mutex) */
|
||||
|
||||
UT_LIST_NODE_T(buf_page_t) LRU;
|
||||
/* node of the LRU list */
|
||||
|
|
|
@ -20,6 +20,7 @@ buf_page_get_freed_page_clock(
|
|||
/* out: freed_page_clock */
|
||||
const buf_page_t* bpage) /* in: block */
|
||||
{
|
||||
/* This is sometimes read without holding buf_pool_mutex. */
|
||||
return(bpage->freed_page_clock);
|
||||
}
|
||||
|
||||
|
@ -89,6 +90,9 @@ buf_pool_get_oldest_modification(void)
|
|||
|
||||
buf_pool_mutex_exit();
|
||||
|
||||
/* The returned answer may be out of date: the flush_list can
|
||||
change after the mutex has been released. */
|
||||
|
||||
return(lsn);
|
||||
}
|
||||
|
||||
|
@ -261,6 +265,7 @@ buf_page_get_LRU_position(
|
|||
const buf_page_t* bpage) /* in: control block */
|
||||
{
|
||||
ut_ad(buf_page_in_file(bpage));
|
||||
ut_ad(buf_pool_mutex_own());
|
||||
|
||||
return(bpage->LRU_position);
|
||||
}
|
||||
|
@ -429,6 +434,7 @@ buf_page_is_old(
|
|||
const buf_page_t* bpage) /* in: control block */
|
||||
{
|
||||
ut_ad(buf_page_in_file(bpage));
|
||||
ut_ad(buf_pool_mutex_own());
|
||||
|
||||
return(bpage->old);
|
||||
}
|
||||
|
@ -805,8 +811,9 @@ buf_page_get_newest_modification(
|
|||
page frame */
|
||||
{
|
||||
ib_uint64_t lsn;
|
||||
mutex_t* block_mutex = buf_page_get_mutex(bpage);
|
||||
|
||||
buf_pool_mutex_enter();
|
||||
mutex_enter(block_mutex);
|
||||
|
||||
if (buf_page_in_file(bpage)) {
|
||||
lsn = bpage->newest_modification;
|
||||
|
@ -814,7 +821,7 @@ buf_page_get_newest_modification(
|
|||
lsn = 0;
|
||||
}
|
||||
|
||||
buf_pool_mutex_exit();
|
||||
mutex_exit(block_mutex);
|
||||
|
||||
return(lsn);
|
||||
}
|
||||
|
@ -921,6 +928,8 @@ buf_page_hash_get(
|
|||
fold = buf_page_address_fold(space, offset);
|
||||
|
||||
HASH_SEARCH(hash, buf_pool->page_hash, fold, buf_page_t*, bpage,
|
||||
ut_ad(bpage->in_page_hash && !bpage->in_zip_hash
|
||||
&& buf_page_in_file(bpage)),
|
||||
bpage->space == space && bpage->offset == offset);
|
||||
if (bpage) {
|
||||
ut_a(buf_page_in_file(bpage));
|
||||
|
@ -1040,6 +1049,10 @@ buf_page_release(
|
|||
#endif
|
||||
block->page.buf_fix_count--;
|
||||
|
||||
/* Dirty blocks should be in the flush list. */
|
||||
ut_ad(!block->page.oldest_modification
|
||||
|| block->page.in_flush_list);
|
||||
|
||||
mutex_exit(&block->mutex);
|
||||
|
||||
if (rw_latch == RW_S_LATCH) {
|
||||
|
|
|
@ -14,13 +14,6 @@ Created 11/5/1995 Heikki Tuuri
|
|||
#include "ut0byte.h"
|
||||
#include "mtr0types.h"
|
||||
|
||||
/************************************************************************
|
||||
Inserts a modified block into the flush list. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
buf_flush_insert_into_flush_list(
|
||||
/*=============================*/
|
||||
buf_page_t* bpage); /* in: block which is modified */
|
||||
/************************************************************************
|
||||
Remove a block from the flush list of modified blocks. */
|
||||
UNIV_INTERN
|
||||
|
|
|
@ -9,6 +9,13 @@ Created 11/5/1995 Heikki Tuuri
|
|||
#include "buf0buf.h"
|
||||
#include "mtr0mtr.h"
|
||||
|
||||
/************************************************************************
|
||||
Inserts a modified block into the flush list. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
buf_flush_insert_into_flush_list(
|
||||
/*=============================*/
|
||||
buf_block_t* block); /* in/out: block which is modified */
|
||||
/************************************************************************
|
||||
Inserts a modified block into the flush list in the right sorted position.
|
||||
This function is used by recovery, because there the modifications do not
|
||||
|
@ -17,7 +24,7 @@ UNIV_INTERN
|
|||
void
|
||||
buf_flush_insert_sorted_into_flush_list(
|
||||
/*====================================*/
|
||||
buf_page_t* bpage); /* in: block which is modified */
|
||||
buf_block_t* block); /* in/out: block which is modified */
|
||||
|
||||
/************************************************************************
|
||||
This function should be called at a mini-transaction commit, if a page was
|
||||
|
@ -49,7 +56,7 @@ buf_flush_note_modification(
|
|||
block->page.oldest_modification = mtr->start_lsn;
|
||||
ut_ad(block->page.oldest_modification != 0);
|
||||
|
||||
buf_flush_insert_into_flush_list(&block->page);
|
||||
buf_flush_insert_into_flush_list(block);
|
||||
} else {
|
||||
ut_ad(block->page.oldest_modification <= mtr->start_lsn);
|
||||
}
|
||||
|
@ -88,7 +95,7 @@ buf_flush_recv_note_modification(
|
|||
|
||||
ut_ad(block->page.oldest_modification != 0);
|
||||
|
||||
buf_flush_insert_sorted_into_flush_list(&block->page);
|
||||
buf_flush_insert_sorted_into_flush_list(block);
|
||||
} else {
|
||||
ut_ad(block->page.oldest_modification <= start_lsn);
|
||||
}
|
||||
|
|
|
@ -720,7 +720,8 @@ dict_table_check_if_in_cache_low(
|
|||
table_fold = ut_fold_string(table_name);
|
||||
|
||||
HASH_SEARCH(name_hash, dict_sys->table_hash, table_fold,
|
||||
dict_table_t*, table, !strcmp(table->name, table_name));
|
||||
dict_table_t*, table, ut_ad(table->cached),
|
||||
!strcmp(table->name, table_name));
|
||||
return(table);
|
||||
}
|
||||
|
||||
|
@ -745,6 +746,8 @@ dict_table_get_low(
|
|||
table = dict_load_table(table_name);
|
||||
}
|
||||
|
||||
ut_ad(!table || table->cached);
|
||||
|
||||
return(table);
|
||||
}
|
||||
|
||||
|
@ -766,11 +769,14 @@ dict_table_get_on_id_low(
|
|||
fold = ut_fold_dulint(table_id);
|
||||
|
||||
HASH_SEARCH(id_hash, dict_sys->table_id_hash, fold,
|
||||
dict_table_t*, table, !ut_dulint_cmp(table->id, table_id));
|
||||
dict_table_t*, table, ut_ad(table->cached),
|
||||
!ut_dulint_cmp(table->id, table_id));
|
||||
if (table == NULL) {
|
||||
table = dict_load_table_on_id(table_id);
|
||||
}
|
||||
|
||||
ut_ad(!table || table->cached);
|
||||
|
||||
/* TODO: should get the type information from MySQL */
|
||||
|
||||
return(table);
|
||||
|
|
|
@ -66,12 +66,8 @@ hash_calc_hash(
|
|||
hash_table_t* table); /* in: hash table */
|
||||
/************************************************************************
|
||||
Assert that the mutex for the table in a hash operation is owned. */
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
# define HASH_ASSERT_OWNED(TABLE, FOLD) \
|
||||
#define HASH_ASSERT_OWNED(TABLE, FOLD) \
|
||||
ut_ad(!(TABLE)->mutexes || mutex_own(hash_get_mutex(TABLE, FOLD)));
|
||||
#else
|
||||
# define HASH_ASSERT_OWNED(TABLE, FOLD)
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
Inserts a struct to a hash table. */
|
||||
|
@ -151,7 +147,7 @@ Gets the next struct in a hash chain, NULL if none. */
|
|||
|
||||
/************************************************************************
|
||||
Looks for a struct in a hash table. */
|
||||
#define HASH_SEARCH(NAME, TABLE, FOLD, TYPE, DATA, TEST)\
|
||||
#define HASH_SEARCH(NAME, TABLE, FOLD, TYPE, DATA, ASSERTION, TEST)\
|
||||
{\
|
||||
\
|
||||
HASH_ASSERT_OWNED(TABLE, FOLD)\
|
||||
|
@ -160,6 +156,7 @@ Looks for a struct in a hash table. */
|
|||
HASH_ASSERT_VALID(DATA);\
|
||||
\
|
||||
while ((DATA) != NULL) {\
|
||||
ASSERTION;\
|
||||
if (TEST) {\
|
||||
break;\
|
||||
} else {\
|
||||
|
@ -169,6 +166,32 @@ Looks for a struct in a hash table. */
|
|||
}\
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
Looks for an item in all hash buckets. */
|
||||
#define HASH_SEARCH_ALL(NAME, TABLE, TYPE, DATA, ASSERTION, TEST) \
|
||||
do { \
|
||||
ulint i3333; \
|
||||
\
|
||||
for (i3333 = (TABLE)->n_cells; i3333--; ) { \
|
||||
(DATA) = (TYPE) HASH_GET_FIRST(TABLE, i3333); \
|
||||
\
|
||||
while ((DATA) != NULL) { \
|
||||
HASH_ASSERT_VALID(DATA); \
|
||||
ASSERTION; \
|
||||
\
|
||||
if (TEST) { \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
(DATA) = (TYPE) HASH_GET_NEXT(NAME, DATA); \
|
||||
} \
|
||||
\
|
||||
if ((DATA) != NULL) { \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/****************************************************************
|
||||
Gets the nth cell in a hash table. */
|
||||
UNIV_INLINE
|
||||
|
|
|
@ -344,10 +344,14 @@ struct mtr_struct{
|
|||
this mtr */
|
||||
ib_uint64_t end_lsn;/* end lsn of the possible log entry for
|
||||
this mtr */
|
||||
#ifdef UNIV_DEBUG
|
||||
ulint magic_n;
|
||||
#endif /* UNIV_DEBUG */
|
||||
};
|
||||
|
||||
#define MTR_MAGIC_N 54551
|
||||
#ifdef UNIV_DEBUG
|
||||
# define MTR_MAGIC_N 54551
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
#define MTR_ACTIVE 12231
|
||||
#define MTR_COMMITTING 56456
|
||||
|
|
|
@ -28,10 +28,9 @@ mtr_start(
|
|||
mtr->modifications = FALSE;
|
||||
mtr->n_log_recs = 0;
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
mtr->state = MTR_ACTIVE;
|
||||
mtr->magic_n = MTR_MAGIC_N;
|
||||
#endif
|
||||
ut_d(mtr->state = MTR_ACTIVE);
|
||||
ut_d(mtr->magic_n = MTR_MAGIC_N);
|
||||
|
||||
return(mtr);
|
||||
}
|
||||
|
||||
|
|
|
@ -98,6 +98,7 @@ extern ulong srv_flush_log_at_trx_commit;
|
|||
/* The sort order table of the MySQL latin1_swedish_ci character set
|
||||
collation */
|
||||
extern const byte* srv_latin1_ordering;
|
||||
extern my_bool srv_use_sys_malloc;
|
||||
extern ulint srv_buf_pool_size; /* requested size in bytes */
|
||||
extern ulint srv_buf_pool_old_size; /* previously requested size */
|
||||
extern ulint srv_buf_pool_curr_size; /* current size in bytes */
|
||||
|
|
|
@ -15,6 +15,8 @@ Created 3/26/1996 Heikki Tuuri
|
|||
#include "mtr0mtr.h"
|
||||
#include "trx0sys.h"
|
||||
|
||||
#define trx_roll_free_all_savepoints(s) trx_roll_savepoints_free((s), NULL)
|
||||
|
||||
/***********************************************************************
|
||||
Determines if this transaction is rolling back an incomplete transaction
|
||||
in crash recovery. */
|
||||
|
@ -249,8 +251,18 @@ trx_release_savepoint_for_mysql(
|
|||
const char* savepoint_name); /* in: savepoint name */
|
||||
|
||||
/***********************************************************************
|
||||
Frees savepoint structs. */
|
||||
Frees a single savepoint struct. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
trx_roll_savepoint_free(
|
||||
/*=====================*/
|
||||
trx_t* trx, /* in: transaction handle */
|
||||
trx_named_savept_t* savep); /* in: savepoint to free */
|
||||
|
||||
/***********************************************************************
|
||||
Frees savepoint structs starting from savep, if savep == NULL then
|
||||
free all savepoints. */
|
||||
|
||||
void
|
||||
trx_roll_savepoints_free(
|
||||
/*=====================*/
|
||||
|
|
|
@ -11,6 +11,7 @@ Created 5/12/1997 Heikki Tuuri
|
|||
#include "mem0pool.ic"
|
||||
#endif
|
||||
|
||||
#include "srv0srv.h"
|
||||
#include "sync0sync.h"
|
||||
#include "ut0mem.h"
|
||||
#include "ut0lst.h"
|
||||
|
@ -336,6 +337,12 @@ mem_area_alloc(
|
|||
ulint n;
|
||||
ibool ret;
|
||||
|
||||
/* If we are using os allocator just make a simple call
|
||||
to malloc */
|
||||
if (srv_use_sys_malloc) {
|
||||
return(malloc(*psize));
|
||||
}
|
||||
|
||||
size = *psize;
|
||||
n = ut_2_log(ut_max(size + MEM_AREA_EXTRA_SIZE, MEM_AREA_MIN_SIZE));
|
||||
|
||||
|
@ -470,6 +477,10 @@ mem_area_free(
|
|||
ulint size;
|
||||
ulint n;
|
||||
|
||||
if (srv_use_sys_malloc) {
|
||||
return(free(ptr));
|
||||
}
|
||||
|
||||
/* It may be that the area was really allocated from the OS with
|
||||
regular malloc: check if ptr points within our memory pool */
|
||||
|
||||
|
|
|
@ -158,9 +158,8 @@ mtr_commit(
|
|||
ut_ad(mtr);
|
||||
ut_ad(mtr->magic_n == MTR_MAGIC_N);
|
||||
ut_ad(mtr->state == MTR_ACTIVE);
|
||||
#ifdef UNIV_DEBUG
|
||||
mtr->state = MTR_COMMITTING;
|
||||
#endif
|
||||
ut_d(mtr->state = MTR_COMMITTING);
|
||||
|
||||
write_log = mtr->modifications && mtr->n_log_recs;
|
||||
|
||||
if (write_log) {
|
||||
|
@ -181,9 +180,7 @@ mtr_commit(
|
|||
log_release();
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
mtr->state = MTR_COMMITTED;
|
||||
#endif
|
||||
ut_d(mtr->state = MTR_COMMITTED);
|
||||
dyn_array_free(&(mtr->memo));
|
||||
dyn_array_free(&(mtr->log));
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
--innodb_locks_unsafe_for_binlog=true --innodb_lock_wait_timeout=2
|
||||
--innodb_lock_wait_timeout=2
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
drop table if exists t1;
|
||||
set binlog_format=mixed;
|
||||
set session transaction isolation level read committed;
|
||||
set session transaction isolation level repeatable read;
|
||||
create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
|
||||
insert into t1 values (1),(2),(3),(4),(5),(6),(7);
|
||||
set autocommit=0;
|
||||
|
@ -8,11 +8,12 @@ select * from t1 where a=3 lock in share mode;
|
|||
a
|
||||
3
|
||||
set binlog_format=mixed;
|
||||
set session transaction isolation level read committed;
|
||||
set session transaction isolation level repeatable read;
|
||||
set autocommit=0;
|
||||
update t1 set a=10 where a=5;
|
||||
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||
commit;
|
||||
set session transaction isolation level read committed;
|
||||
update t1 set a=10 where a=5;
|
||||
select * from t1 where a=2 for update;
|
||||
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||
|
|
|
@ -11,7 +11,7 @@ connect (a,localhost,root,,);
|
|||
connect (b,localhost,root,,);
|
||||
connection a;
|
||||
set binlog_format=mixed;
|
||||
set session transaction isolation level read committed;
|
||||
set session transaction isolation level repeatable read;
|
||||
create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
|
||||
insert into t1 values (1),(2),(3),(4),(5),(6),(7);
|
||||
set autocommit=0;
|
||||
|
@ -19,13 +19,15 @@ set autocommit=0;
|
|||
select * from t1 where a=3 lock in share mode;
|
||||
connection b;
|
||||
set binlog_format=mixed;
|
||||
set session transaction isolation level read committed;
|
||||
set session transaction isolation level repeatable read;
|
||||
set autocommit=0;
|
||||
-- error ER_LOCK_WAIT_TIMEOUT
|
||||
update t1 set a=10 where a=5;
|
||||
connection a;
|
||||
commit;
|
||||
connection b;
|
||||
# perform a semi-consisent read (and unlock non-matching rows)
|
||||
set session transaction isolation level read committed;
|
||||
update t1 set a=10 where a=5;
|
||||
connection a;
|
||||
-- error ER_LOCK_WAIT_TIMEOUT
|
||||
|
@ -33,6 +35,7 @@ select * from t1 where a=2 for update;
|
|||
# this should lock the records (1),(2)
|
||||
select * from t1 where a=2 limit 1 for update;
|
||||
connection b;
|
||||
# semi-consistent read will skip non-matching locked rows a=1, a=2
|
||||
update t1 set a=11 where a=6;
|
||||
-- error ER_LOCK_WAIT_TIMEOUT
|
||||
update t1 set a=12 where a=2;
|
||||
|
|
2
mysql-test/innodb-use-sys-malloc-master.opt
Normal file
2
mysql-test/innodb-use-sys-malloc-master.opt
Normal file
|
@ -0,0 +1,2 @@
|
|||
--innodb-use-sys-malloc=true
|
||||
--innodb-use-sys-malloc=true
|
48
mysql-test/innodb-use-sys-malloc.result
Normal file
48
mysql-test/innodb-use-sys-malloc.result
Normal file
|
@ -0,0 +1,48 @@
|
|||
SELECT @@GLOBAL.innodb_use_sys_malloc;
|
||||
@@GLOBAL.innodb_use_sys_malloc
|
||||
1
|
||||
1 Expected
|
||||
SET @@GLOBAL.innodb_use_sys_malloc=0;
|
||||
ERROR HY000: Variable 'innodb_use_sys_malloc' is a read only variable
|
||||
Expected error 'Read only variable'
|
||||
SELECT @@GLOBAL.innodb_use_sys_malloc;
|
||||
@@GLOBAL.innodb_use_sys_malloc
|
||||
1
|
||||
1 Expected
|
||||
drop table if exists t1;
|
||||
create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
|
||||
insert into t1 values (1),(2),(3),(4),(5),(6),(7);
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
drop table t1;
|
||||
SELECT @@GLOBAL.innodb_use_sys_malloc;
|
||||
@@GLOBAL.innodb_use_sys_malloc
|
||||
1
|
||||
1 Expected
|
||||
SET @@GLOBAL.innodb_use_sys_malloc=0;
|
||||
ERROR HY000: Variable 'innodb_use_sys_malloc' is a read only variable
|
||||
Expected error 'Read only variable'
|
||||
SELECT @@GLOBAL.innodb_use_sys_malloc;
|
||||
@@GLOBAL.innodb_use_sys_malloc
|
||||
1
|
||||
1 Expected
|
||||
drop table if exists t1;
|
||||
create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
|
||||
insert into t1 values (1),(2),(3),(4),(5),(6),(7);
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
drop table t1;
|
48
mysql-test/innodb-use-sys-malloc.test
Normal file
48
mysql-test/innodb-use-sys-malloc.test
Normal file
|
@ -0,0 +1,48 @@
|
|||
--source include/have_innodb.inc
|
||||
|
||||
#display current value of innodb_use_sys_malloc
|
||||
SELECT @@GLOBAL.innodb_use_sys_malloc;
|
||||
--echo 1 Expected
|
||||
|
||||
#try changing it. Should fail.
|
||||
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
|
||||
SET @@GLOBAL.innodb_use_sys_malloc=0;
|
||||
--echo Expected error 'Read only variable'
|
||||
|
||||
SELECT @@GLOBAL.innodb_use_sys_malloc;
|
||||
--echo 1 Expected
|
||||
|
||||
|
||||
#do some stuff to see if it works.
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
--enable_warnings
|
||||
|
||||
create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
|
||||
insert into t1 values (1),(2),(3),(4),(5),(6),(7);
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
--source include/have_innodb.inc
|
||||
|
||||
#display current value of innodb_use_sys_malloc
|
||||
SELECT @@GLOBAL.innodb_use_sys_malloc;
|
||||
--echo 1 Expected
|
||||
|
||||
#try changing it. Should fail.
|
||||
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
|
||||
SET @@GLOBAL.innodb_use_sys_malloc=0;
|
||||
--echo Expected error 'Read only variable'
|
||||
|
||||
SELECT @@GLOBAL.innodb_use_sys_malloc;
|
||||
--echo 1 Expected
|
||||
|
||||
|
||||
#do some stuff to see if it works.
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
--enable_warnings
|
||||
|
||||
create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
|
||||
insert into t1 values (1),(2),(3),(4),(5),(6),(7);
|
||||
select * from t1;
|
||||
drop table t1;
|
4
mysql-test/innodb_bug41904.result
Normal file
4
mysql-test/innodb_bug41904.result
Normal file
|
@ -0,0 +1,4 @@
|
|||
CREATE TABLE bug41904 (id INT PRIMARY KEY, uniquecol CHAR(15)) ENGINE=InnoDB;
|
||||
INSERT INTO bug41904 VALUES (1,NULL), (2,NULL);
|
||||
CREATE UNIQUE INDEX ui ON bug41904 (uniquecol);
|
||||
DROP TABLE bug41904;
|
14
mysql-test/innodb_bug41904.test
Normal file
14
mysql-test/innodb_bug41904.test
Normal file
|
@ -0,0 +1,14 @@
|
|||
#
|
||||
# Make sure http://bugs.mysql.com/41904 remains fixed.
|
||||
#
|
||||
|
||||
-- source include/not_embedded.inc
|
||||
-- source include/have_innodb.inc
|
||||
|
||||
CREATE TABLE bug41904 (id INT PRIMARY KEY, uniquecol CHAR(15)) ENGINE=InnoDB;
|
||||
|
||||
INSERT INTO bug41904 VALUES (1,NULL), (2,NULL);
|
||||
|
||||
CREATE UNIQUE INDEX ui ON bug41904 (uniquecol);
|
||||
|
||||
DROP TABLE bug41904;
|
87
mysql-test/patches/bug41893.diff
Normal file
87
mysql-test/patches/bug41893.diff
Normal file
|
@ -0,0 +1,87 @@
|
|||
=== modified file 'mysql-test/r/variables.result'
|
||||
--- mysql-test/r/variables.result 2008-11-27 10:50:28 +0000
|
||||
+++ mysql-test/r/variables.result 2009-01-06 07:33:27 +0000
|
||||
@@ -297,14 +297,14 @@
|
||||
select ROUND(RAND(),5);
|
||||
ROUND(RAND(),5)
|
||||
0.02887
|
||||
-show variables like '%alloc%';
|
||||
+show variables where variable_name in ('query_alloc_block_size', 'query_prealloc_size', 'range_alloc_block_size', 'transaction_alloc_block_size', 'transaction_prealloc_size');
|
||||
Variable_name Value
|
||||
query_alloc_block_size 8192
|
||||
query_prealloc_size 8192
|
||||
range_alloc_block_size 4096
|
||||
transaction_alloc_block_size 8192
|
||||
transaction_prealloc_size 4096
|
||||
-select * from information_schema.session_variables where variable_name like '%alloc%' order by 1;
|
||||
+select * from information_schema.session_variables where variable_name in ('query_alloc_block_size', 'query_prealloc_size', 'range_alloc_block_size', 'transaction_alloc_block_size', 'transaction_prealloc_size') order by 1;
|
||||
VARIABLE_NAME VARIABLE_VALUE
|
||||
QUERY_ALLOC_BLOCK_SIZE 8192
|
||||
QUERY_PREALLOC_SIZE 8192
|
||||
@@ -319,14 +319,14 @@
|
||||
select @@query_alloc_block_size;
|
||||
@@query_alloc_block_size
|
||||
17408
|
||||
-show variables like '%alloc%';
|
||||
+show variables where variable_name in ('query_alloc_block_size', 'query_prealloc_size', 'range_alloc_block_size', 'transaction_alloc_block_size', 'transaction_prealloc_size');
|
||||
Variable_name Value
|
||||
query_alloc_block_size 17408
|
||||
query_prealloc_size 18432
|
||||
range_alloc_block_size 16384
|
||||
transaction_alloc_block_size 19456
|
||||
transaction_prealloc_size 20480
|
||||
-select * from information_schema.session_variables where variable_name like '%alloc%' order by 1;
|
||||
+select * from information_schema.session_variables where variable_name in ('query_alloc_block_size', 'query_prealloc_size', 'range_alloc_block_size', 'transaction_alloc_block_size', 'transaction_prealloc_size') order by 1;
|
||||
VARIABLE_NAME VARIABLE_VALUE
|
||||
QUERY_ALLOC_BLOCK_SIZE 17408
|
||||
QUERY_PREALLOC_SIZE 18432
|
||||
@@ -336,14 +336,14 @@
|
||||
set @@range_alloc_block_size=default;
|
||||
set @@query_alloc_block_size=default, @@query_prealloc_size=default;
|
||||
set transaction_alloc_block_size=default, @@transaction_prealloc_size=default;
|
||||
-show variables like '%alloc%';
|
||||
+show variables where variable_name in ('query_alloc_block_size', 'query_prealloc_size', 'range_alloc_block_size', 'transaction_alloc_block_size', 'transaction_prealloc_size');
|
||||
Variable_name Value
|
||||
query_alloc_block_size 8192
|
||||
query_prealloc_size 8192
|
||||
range_alloc_block_size 4096
|
||||
transaction_alloc_block_size 8192
|
||||
transaction_prealloc_size 4096
|
||||
-select * from information_schema.session_variables where variable_name like '%alloc%' order by 1;
|
||||
+select * from information_schema.session_variables where variable_name in ('query_alloc_block_size', 'query_prealloc_size', 'range_alloc_block_size', 'transaction_alloc_block_size', 'transaction_prealloc_size') order by 1;
|
||||
VARIABLE_NAME VARIABLE_VALUE
|
||||
QUERY_ALLOC_BLOCK_SIZE 8192
|
||||
QUERY_PREALLOC_SIZE 8192
|
||||
|
||||
=== modified file 'mysql-test/t/variables.test'
|
||||
--- mysql-test/t/variables.test 2008-11-27 10:50:28 +0000
|
||||
+++ mysql-test/t/variables.test 2009-01-06 07:28:12 +0000
|
||||
@@ -172,21 +172,21 @@
|
||||
set @@rand_seed1=10000000,@@rand_seed2=1000000;
|
||||
select ROUND(RAND(),5);
|
||||
|
||||
-show variables like '%alloc%';
|
||||
-select * from information_schema.session_variables where variable_name like '%alloc%' order by 1;
|
||||
+show variables where variable_name in ('query_alloc_block_size', 'query_prealloc_size', 'range_alloc_block_size', 'transaction_alloc_block_size', 'transaction_prealloc_size');
|
||||
+select * from information_schema.session_variables where variable_name in ('query_alloc_block_size', 'query_prealloc_size', 'range_alloc_block_size', 'transaction_alloc_block_size', 'transaction_prealloc_size') order by 1;
|
||||
set @@range_alloc_block_size=1024*16;
|
||||
set @@query_alloc_block_size=1024*17+2;
|
||||
set @@query_prealloc_size=1024*18;
|
||||
set @@transaction_alloc_block_size=1024*20-1;
|
||||
set @@transaction_prealloc_size=1024*21-1;
|
||||
select @@query_alloc_block_size;
|
||||
-show variables like '%alloc%';
|
||||
-select * from information_schema.session_variables where variable_name like '%alloc%' order by 1;
|
||||
+show variables where variable_name in ('query_alloc_block_size', 'query_prealloc_size', 'range_alloc_block_size', 'transaction_alloc_block_size', 'transaction_prealloc_size');
|
||||
+select * from information_schema.session_variables where variable_name in ('query_alloc_block_size', 'query_prealloc_size', 'range_alloc_block_size', 'transaction_alloc_block_size', 'transaction_prealloc_size') order by 1;
|
||||
set @@range_alloc_block_size=default;
|
||||
set @@query_alloc_block_size=default, @@query_prealloc_size=default;
|
||||
set transaction_alloc_block_size=default, @@transaction_prealloc_size=default;
|
||||
-show variables like '%alloc%';
|
||||
-select * from information_schema.session_variables where variable_name like '%alloc%' order by 1;
|
||||
+show variables where variable_name in ('query_alloc_block_size', 'query_prealloc_size', 'range_alloc_block_size', 'transaction_alloc_block_size', 'transaction_prealloc_size');
|
||||
+select * from information_schema.session_variables where variable_name in ('query_alloc_block_size', 'query_prealloc_size', 'range_alloc_block_size', 'transaction_alloc_block_size', 'transaction_prealloc_size') order by 1;
|
||||
|
||||
#
|
||||
# Bug #10904 Illegal mix of collations between
|
||||
|
|
@ -447,14 +447,29 @@ row_merge_tuple_cmp(
|
|||
int cmp;
|
||||
const dfield_t* field = a;
|
||||
|
||||
/* Compare the fields of the tuples until a difference is
|
||||
found or we run out of fields to compare. If !cmp at the
|
||||
end, the tuples are equal. */
|
||||
do {
|
||||
cmp = cmp_dfield_dfield(a++, b++);
|
||||
} while (!cmp && --n_field);
|
||||
|
||||
if (UNIV_UNLIKELY(!cmp) && UNIV_LIKELY_NULL(dup)) {
|
||||
/* Report a duplicate value error if the tuples are
|
||||
logically equal. NULL columns are logically inequal,
|
||||
although they are equal in the sorting order. Find
|
||||
out if any of the fields are NULL. */
|
||||
for (b = field; b != a; b++) {
|
||||
if (dfield_is_null(b)) {
|
||||
|
||||
goto func_exit;
|
||||
}
|
||||
}
|
||||
|
||||
row_merge_dup_report(dup, field);
|
||||
}
|
||||
|
||||
func_exit:
|
||||
return(cmp);
|
||||
}
|
||||
|
||||
|
@ -1839,7 +1854,7 @@ row_merge_drop_temp_indexes(void)
|
|||
"PROCEDURE DROP_TEMP_INDEXES_PROC () IS\n"
|
||||
"indexid CHAR;\n"
|
||||
"DECLARE CURSOR c IS SELECT ID FROM SYS_INDEXES\n"
|
||||
"WHERE SUBSTR(NAME,0,1)='\377' FOR UPDATE;\n"
|
||||
"WHERE SUBSTR(NAME,0,1)='\377';\n"
|
||||
"BEGIN\n"
|
||||
"\tOPEN c;\n"
|
||||
"\tWHILE 1=1 LOOP\n"
|
||||
|
@ -1848,7 +1863,7 @@ row_merge_drop_temp_indexes(void)
|
|||
"\t\t\tEXIT;\n"
|
||||
"\t\tEND IF;\n"
|
||||
"\t\tDELETE FROM SYS_FIELDS WHERE INDEX_ID = indexid;\n"
|
||||
"\t\tDELETE FROM SYS_INDEXES WHERE CURRENT OF c;\n"
|
||||
"\t\tDELETE FROM SYS_INDEXES WHERE ID = indexid;\n"
|
||||
"\tEND LOOP;\n"
|
||||
"\tCLOSE c;\n"
|
||||
"\tCOMMIT WORK;\n"
|
||||
|
@ -1858,6 +1873,15 @@ row_merge_drop_temp_indexes(void)
|
|||
trx->op_info = "dropping partially created indexes";
|
||||
row_mysql_lock_data_dictionary(trx);
|
||||
|
||||
/* Incomplete transactions may be holding some locks on the
|
||||
data dictionary tables. However, they should never have been
|
||||
able to lock the records corresponding to the partially
|
||||
created indexes that we are attempting to delete, because the
|
||||
table was locked when the indexes were being created. We will
|
||||
drop the partially created indexes before the rollback of
|
||||
incomplete transactions is initiated. Thus, this should not
|
||||
interfere with the incomplete transactions. */
|
||||
trx->isolation_level = TRX_ISO_READ_UNCOMMITTED;
|
||||
err = que_eval_sql(NULL, drop_temp_indexes, FALSE, trx);
|
||||
ut_a(err == DB_SUCCESS);
|
||||
|
||||
|
@ -1974,7 +1998,6 @@ row_merge_create_temporary_table(
|
|||
|
||||
if (error != DB_SUCCESS) {
|
||||
trx->error_state = error;
|
||||
dict_mem_table_free(new_table);
|
||||
new_table = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -1443,12 +1443,13 @@ row_unlock_for_mysql(
|
|||
ut_ad(prebuilt && trx);
|
||||
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
|
||||
|
||||
if (!(srv_locks_unsafe_for_binlog
|
||||
|| trx->isolation_level == TRX_ISO_READ_COMMITTED)) {
|
||||
if (UNIV_UNLIKELY
|
||||
(!srv_locks_unsafe_for_binlog
|
||||
&& trx->isolation_level != TRX_ISO_READ_COMMITTED)) {
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: calling row_unlock_for_mysql though\n"
|
||||
"InnoDB: srv_locks_unsafe_for_binlog is FALSE and\n"
|
||||
"InnoDB: innodb_locks_unsafe_for_binlog is FALSE and\n"
|
||||
"InnoDB: this session is not using"
|
||||
" READ COMMITTED isolation level.\n");
|
||||
|
||||
|
|
|
@ -142,6 +142,8 @@ UNIV_INTERN ulong srv_flush_log_at_trx_commit = 1;
|
|||
collation */
|
||||
UNIV_INTERN const byte* srv_latin1_ordering;
|
||||
|
||||
/* use os/external memory allocator */
|
||||
UNIV_INTERN my_bool srv_use_sys_malloc = FALSE;
|
||||
/* requested size in kilobytes */
|
||||
UNIV_INTERN ulint srv_buf_pool_size = ULINT_MAX;
|
||||
/* previously requested size */
|
||||
|
@ -1463,10 +1465,13 @@ srv_suspend_mysql_thread(
|
|||
|
||||
ut_a(trx->dict_operation_lock_mode == 0);
|
||||
|
||||
/* Wait for the release */
|
||||
/* Suspend this thread and wait for the event. */
|
||||
|
||||
os_event_wait(event);
|
||||
|
||||
/* After resuming, reacquire the data dictionary latch if
|
||||
necessary. */
|
||||
|
||||
switch (had_dict_lock) {
|
||||
case RW_S_LATCH:
|
||||
row_mysql_freeze_data_dictionary(trx);
|
||||
|
|
|
@ -1048,6 +1048,11 @@ innobase_start_or_create_for_mysql(void)
|
|||
"InnoDB: !!!!!!!! UNIV_MEM_DEBUG switched on !!!!!!!!!\n");
|
||||
#endif
|
||||
|
||||
if (srv_use_sys_malloc) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: The InnoDB memory heap is disabled\n");
|
||||
}
|
||||
|
||||
/* Since InnoDB does not currently clean up all its internal data
|
||||
structures in MySQL Embedded Server Library server_end(), we
|
||||
print an error message if someone tries to start up InnoDB a
|
||||
|
|
|
@ -71,7 +71,7 @@ try_again:
|
|||
local = NULL;
|
||||
|
||||
HASH_SEARCH(hash, thr_local_hash, os_thread_pf(id),
|
||||
thr_local_t*, local, os_thread_eq(local->id, id));
|
||||
thr_local_t*, local,, os_thread_eq(local->id, id));
|
||||
if (local == NULL) {
|
||||
mutex_exit(&thr_local_mutex);
|
||||
|
||||
|
@ -195,7 +195,7 @@ thr_local_free(
|
|||
/* Look for the local struct in the hash table */
|
||||
|
||||
HASH_SEARCH(hash, thr_local_hash, os_thread_pf(id),
|
||||
thr_local_t*, local, os_thread_eq(local->id, id));
|
||||
thr_local_t*, local,, os_thread_eq(local->id, id));
|
||||
if (local == NULL) {
|
||||
mutex_exit(&thr_local_mutex);
|
||||
|
||||
|
|
|
@ -821,6 +821,8 @@ search_innodb_locks(
|
|||
i_s_hash_chain_t*,
|
||||
/* auxiliary variable */
|
||||
hash_chain,
|
||||
/* assertion on every traversed item */
|
||||
,
|
||||
/* this determines if we have found the lock */
|
||||
locks_row_eq_lock(hash_chain->value, lock, heap_no));
|
||||
|
||||
|
|
|
@ -171,8 +171,26 @@ trx_rollback_last_sql_stat_for_mysql(
|
|||
}
|
||||
|
||||
/***********************************************************************
|
||||
Frees savepoint structs. */
|
||||
Frees a single savepoint struct. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
trx_roll_savepoint_free(
|
||||
/*=====================*/
|
||||
trx_t* trx, /* in: transaction handle */
|
||||
trx_named_savept_t* savep) /* in: savepoint to free */
|
||||
{
|
||||
ut_a(savep != NULL);
|
||||
ut_a(UT_LIST_GET_LEN(trx->trx_savepoints) > 0);
|
||||
|
||||
UT_LIST_REMOVE(trx_savepoints, trx->trx_savepoints, savep);
|
||||
mem_free(savep->name);
|
||||
mem_free(savep);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Frees savepoint structs starting from savep, if savep == NULL then
|
||||
free all savepoints. */
|
||||
|
||||
void
|
||||
trx_roll_savepoints_free(
|
||||
/*=====================*/
|
||||
|
@ -192,9 +210,7 @@ trx_roll_savepoints_free(
|
|||
while (savep != NULL) {
|
||||
next_savep = UT_LIST_GET_NEXT(trx_savepoints, savep);
|
||||
|
||||
UT_LIST_REMOVE(trx_savepoints, trx->trx_savepoints, savep);
|
||||
mem_free(savep->name);
|
||||
mem_free(savep);
|
||||
trx_roll_savepoint_free(trx, savep);
|
||||
|
||||
savep = next_savep;
|
||||
}
|
||||
|
@ -329,8 +345,8 @@ trx_savepoint_for_mysql(
|
|||
}
|
||||
|
||||
/***********************************************************************
|
||||
Releases a named savepoint. Savepoints which
|
||||
were set after this savepoint are deleted. */
|
||||
Releases only the named savepoint. Savepoints which were set after this
|
||||
savepoint are left as is. */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
trx_release_savepoint_for_mysql(
|
||||
|
@ -346,31 +362,16 @@ trx_release_savepoint_for_mysql(
|
|||
|
||||
savep = UT_LIST_GET_FIRST(trx->trx_savepoints);
|
||||
|
||||
/* Search for the savepoint by name and free if found. */
|
||||
while (savep != NULL) {
|
||||
if (0 == ut_strcmp(savep->name, savepoint_name)) {
|
||||
/* Found */
|
||||
break;
|
||||
trx_roll_savepoint_free(trx, savep);
|
||||
return(DB_SUCCESS);
|
||||
}
|
||||
savep = UT_LIST_GET_NEXT(trx_savepoints, savep);
|
||||
}
|
||||
|
||||
if (savep == NULL) {
|
||||
|
||||
return(DB_NO_SAVEPOINT);
|
||||
}
|
||||
|
||||
/* We can now free all savepoints strictly later than this one */
|
||||
|
||||
trx_roll_savepoints_free(trx, savep);
|
||||
|
||||
/* Now we can free this savepoint too */
|
||||
|
||||
UT_LIST_REMOVE(trx_savepoints, trx->trx_savepoints, savep);
|
||||
|
||||
mem_free(savep->name);
|
||||
mem_free(savep);
|
||||
|
||||
return(DB_SUCCESS);
|
||||
return(DB_NO_SAVEPOINT);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -917,8 +917,8 @@ trx_commit_off_kernel(
|
|||
mutex_enter(&kernel_mutex);
|
||||
}
|
||||
|
||||
/* Free savepoints */
|
||||
trx_roll_savepoints_free(trx, NULL);
|
||||
/* Free all savepoints */
|
||||
trx_roll_free_all_savepoints(trx);
|
||||
|
||||
trx->conc_state = TRX_NOT_STARTED;
|
||||
trx->rseg = NULL;
|
||||
|
|
Loading…
Reference in a new issue