Commit 47a4352e authored by irana's avatar irana

branches/innodb+ rb://281

changes to mtr_commit:

1) grab log mutex (and do initial mtr commit stuff)
for each dirty block
 2) grab flush_list mutex
 3) Insert into flush list
 4) release flush_list mutex
5) release log_sys mutex

Changed version:

1) grab log mutex (and do initial mtr commit stuff)
2) grab a new flushList order mutex
3) release log mutex
for each dirty block
 4) grab flush_list mutex
 5) Insert into flush list
 6) release flush_list mutex
7) Release new flush list order mutex 

Approved by: Marko has given the initial nod.
parent 5fa48065
...@@ -284,6 +284,7 @@ UNIV_INTERN mysql_pfs_key_t buffer_block_mutex_key; ...@@ -284,6 +284,7 @@ UNIV_INTERN mysql_pfs_key_t buffer_block_mutex_key;
UNIV_INTERN mysql_pfs_key_t buf_pool_mutex_key; UNIV_INTERN mysql_pfs_key_t buf_pool_mutex_key;
UNIV_INTERN mysql_pfs_key_t buf_pool_zip_mutex_key; UNIV_INTERN mysql_pfs_key_t buf_pool_zip_mutex_key;
UNIV_INTERN mysql_pfs_key_t flush_list_mutex_key; UNIV_INTERN mysql_pfs_key_t flush_list_mutex_key;
UNIV_INTERN mysql_pfs_key_t flush_order_mutex_key;
#endif /* UNIV_PFS_MUTEX */ #endif /* UNIV_PFS_MUTEX */
/** A chunk of buffers. The buffer pool is allocated in chunks. */ /** A chunk of buffers. The buffer pool is allocated in chunks. */
...@@ -1006,6 +1007,9 @@ buf_pool_init(void) ...@@ -1006,6 +1007,9 @@ buf_pool_init(void)
mutex_create(flush_list_mutex_key, &buf_pool->flush_list_mutex, mutex_create(flush_list_mutex_key, &buf_pool->flush_list_mutex,
SYNC_BUF_FLUSH_LIST); SYNC_BUF_FLUSH_LIST);
mutex_create(flush_order_mutex_key, &buf_pool->flush_order_mutex,
SYNC_BUF_FLUSH_ORDER);
for (i = BUF_FLUSH_LRU; i < BUF_FLUSH_N_TYPES; i++) { for (i = BUF_FLUSH_LRU; i < BUF_FLUSH_N_TYPES; i++) {
buf_pool->no_flush[i] = os_event_create(NULL); buf_pool->no_flush[i] = os_event_create(NULL);
} }
......
...@@ -228,6 +228,7 @@ buf_flush_insert_into_flush_list( ...@@ -228,6 +228,7 @@ buf_flush_insert_into_flush_list(
ib_uint64_t lsn) /*!< in: oldest modification */ ib_uint64_t lsn) /*!< in: oldest modification */
{ {
ut_ad(!buf_pool_mutex_own()); ut_ad(!buf_pool_mutex_own());
ut_ad(buf_flush_order_mutex_own());
ut_ad(mutex_own(&block->mutex)); ut_ad(mutex_own(&block->mutex));
buf_flush_list_mutex_enter(); buf_flush_list_mutex_enter();
...@@ -273,6 +274,7 @@ buf_flush_insert_sorted_into_flush_list( ...@@ -273,6 +274,7 @@ buf_flush_insert_sorted_into_flush_list(
buf_page_t* b; buf_page_t* b;
ut_ad(!buf_pool_mutex_own()); ut_ad(!buf_pool_mutex_own());
ut_ad(buf_flush_order_mutex_own());
ut_ad(mutex_own(&block->mutex)); ut_ad(mutex_own(&block->mutex));
ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
......
...@@ -1432,6 +1432,14 @@ struct buf_pool_struct{ ...@@ -1432,6 +1432,14 @@ struct buf_pool_struct{
the bpage is on flush_list. It the bpage is on flush_list. It
also protects writes to also protects writes to
bpage::oldest_modification */ bpage::oldest_modification */
mutex_t flush_order_mutex;/*!< mutex to serialize access to
the flush list when we are putting
dirty blocks in the list. The idea
behind this mutex is to be able
to release log_sys->mutex during
mtr_commit and still ensure that
insertions in the flush_list happen
in the LSN order. */
UT_LIST_BASE_NODE_T(buf_page_t) flush_list; UT_LIST_BASE_NODE_T(buf_page_t) flush_list;
/*!< base node of the modified block /*!< base node of the modified block
list */ list */
...@@ -1551,6 +1559,19 @@ Use these instead of accessing buf_pool_mutex directly. */ ...@@ -1551,6 +1559,19 @@ Use these instead of accessing buf_pool_mutex directly. */
mutex_exit(&buf_pool->flush_list_mutex); \ mutex_exit(&buf_pool->flush_list_mutex); \
} while (0) } while (0)
/** Test if flush order mutex is owned. */
#define buf_flush_order_mutex_own() mutex_own(&buf_pool->flush_order_mutex)
/** Acquire the flush order mutex. */
#define buf_flush_order_mutex_enter() do { \
mutex_enter(&buf_pool->flush_order_mutex); \
} while (0)
/** Release the flush order mutex. */
# define buf_flush_order_mutex_exit() do { \
mutex_exit(&buf_pool->flush_order_mutex); \
} while (0)
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/** Flag to forbid the release of the buffer pool mutex. /** Flag to forbid the release of the buffer pool mutex.
Protected by buf_pool_mutex. */ Protected by buf_pool_mutex. */
......
...@@ -66,6 +66,7 @@ buf_flush_note_modification( ...@@ -66,6 +66,7 @@ buf_flush_note_modification(
ut_ad(!buf_pool_mutex_own()); ut_ad(!buf_pool_mutex_own());
ut_ad(!buf_flush_list_mutex_own()); ut_ad(!buf_flush_list_mutex_own());
ut_ad(buf_flush_order_mutex_own());
ut_ad(mtr->start_lsn != 0); ut_ad(mtr->start_lsn != 0);
ut_ad(mtr->modifications); ut_ad(mtr->modifications);
...@@ -107,6 +108,7 @@ buf_flush_recv_note_modification( ...@@ -107,6 +108,7 @@ buf_flush_recv_note_modification(
ut_ad(!buf_pool_mutex_own()); ut_ad(!buf_pool_mutex_own());
ut_ad(!buf_flush_list_mutex_own()); ut_ad(!buf_flush_list_mutex_own());
ut_ad(buf_flush_order_mutex_own());
ut_ad(start_lsn != 0); ut_ad(start_lsn != 0);
ut_ad(block->page.newest_modification <= end_lsn); ut_ad(block->page.newest_modification <= end_lsn);
......
...@@ -655,7 +655,8 @@ or row lock! */ ...@@ -655,7 +655,8 @@ or row lock! */
can call routines there! Otherwise can call routines there! Otherwise
the level is SYNC_MEM_HASH. */ the level is SYNC_MEM_HASH. */
#define SYNC_BUF_POOL 150 /* Buffer pool mutex */ #define SYNC_BUF_POOL 150 /* Buffer pool mutex */
#define SYNC_BUF_BLOCK 149 /* Block mutex */ #define SYNC_BUF_FLUSH_ORDER 147
#define SYNC_BUF_BLOCK 146 /* Block mutex */
#define SYNC_BUF_FLUSH_LIST 145 /* Buffer flush list mutex */ #define SYNC_BUF_FLUSH_LIST 145 /* Buffer flush list mutex */
#define SYNC_DOUBLEWRITE 140 #define SYNC_DOUBLEWRITE 140
#define SYNC_ANY_LATCH 135 #define SYNC_ANY_LATCH 135
......
...@@ -1661,7 +1661,9 @@ recv_recover_page_func( ...@@ -1661,7 +1661,9 @@ recv_recover_page_func(
if (modification_to_page) { if (modification_to_page) {
ut_a(block); ut_a(block);
buf_flush_order_mutex_enter();
buf_flush_recv_note_modification(block, start_lsn, end_lsn); buf_flush_recv_note_modification(block, start_lsn, end_lsn);
buf_flush_order_mutex_exit();
} }
#endif /* !UNIV_HOTBACKUP */ #endif /* !UNIV_HOTBACKUP */
......
...@@ -120,6 +120,7 @@ mtr_memo_slot_note_modification( ...@@ -120,6 +120,7 @@ mtr_memo_slot_note_modification(
ut_ad(mtr); ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N); ut_ad(mtr->magic_n == MTR_MAGIC_N);
ut_ad(mtr->modifications); ut_ad(mtr->modifications);
ut_ad(buf_flush_order_mutex_own());
if (slot->object != NULL && slot->type == MTR_MEMO_PAGE_X_FIX) { if (slot->object != NULL && slot->type == MTR_MEMO_PAGE_X_FIX) {
buf_flush_note_modification((buf_block_t*) slot->object, mtr); buf_flush_note_modification((buf_block_t*) slot->object, mtr);
...@@ -220,11 +221,16 @@ mtr_log_reserve_and_write( ...@@ -220,11 +221,16 @@ mtr_log_reserve_and_write(
mtr->end_lsn = log_close(); mtr->end_lsn = log_close();
func_exit: func_exit:
buf_flush_order_mutex_enter();
/* It is now safe to release the log mutex because the
flush_order mutex will ensure that we are the first one
to insert into the flush list. */
log_release();
if (mtr->modifications) { if (mtr->modifications) {
mtr_memo_note_modifications(mtr); mtr_memo_note_modifications(mtr);
} }
buf_flush_order_mutex_exit();
log_release();
} }
#endif /* !UNIV_HOTBACKUP */ #endif /* !UNIV_HOTBACKUP */
...@@ -318,6 +324,7 @@ mtr_memo_release( ...@@ -318,6 +324,7 @@ mtr_memo_release(
offset = dyn_array_get_data_size(memo); offset = dyn_array_get_data_size(memo);
buf_flush_order_mutex_enter();
while (offset > 0) { while (offset > 0) {
offset -= sizeof(mtr_memo_slot_t); offset -= sizeof(mtr_memo_slot_t);
...@@ -333,6 +340,7 @@ mtr_memo_release( ...@@ -333,6 +340,7 @@ mtr_memo_release(
break; break;
} }
} }
buf_flush_order_mutex_exit();
} }
#endif /* !UNIV_HOTBACKUP */ #endif /* !UNIV_HOTBACKUP */
......
...@@ -1163,6 +1163,7 @@ sync_thread_add_level( ...@@ -1163,6 +1163,7 @@ sync_thread_add_level(
case SYNC_FILE_FORMAT_TAG: case SYNC_FILE_FORMAT_TAG:
case SYNC_DOUBLEWRITE: case SYNC_DOUBLEWRITE:
case SYNC_BUF_FLUSH_LIST: case SYNC_BUF_FLUSH_LIST:
case SYNC_BUF_FLUSH_ORDER:
case SYNC_BUF_POOL: case SYNC_BUF_POOL:
case SYNC_SEARCH_SYS: case SYNC_SEARCH_SYS:
case SYNC_SEARCH_SYS_CONF: case SYNC_SEARCH_SYS_CONF:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment