-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
MDEV-39344: trx_disconnect_prepared() uses wrong mutex #5094
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 10.6
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1534,42 +1534,6 @@ inline void buf_pool_t::page_hash_table::write_unlock_all() noexcept | |
| } | ||
|
|
||
|
|
||
| namespace | ||
| { | ||
|
|
||
| struct find_interesting_trx | ||
| { | ||
| void operator()(const trx_t &trx) | ||
| { | ||
| if (!trx.is_started()) | ||
| return; | ||
| if (trx.mysql_thd == nullptr) | ||
| return; | ||
| if (withdraw_started <= trx.start_time_micro) | ||
| return; | ||
|
|
||
| if (!found) | ||
| { | ||
| sql_print_warning("InnoDB: The following trx might hold " | ||
| "the blocks in buffer pool to " | ||
| "be withdrawn. Buffer pool " | ||
| "resizing can complete only " | ||
| "after all the transactions " | ||
| "below release the blocks."); | ||
| found= true; | ||
| } | ||
|
|
||
| lock_trx_print_wait_and_mvcc_state(stderr, &trx, current_time); | ||
| } | ||
|
|
||
| bool &found; | ||
| /** microsecond_interval_timer() */ | ||
| const ulonglong withdraw_started; | ||
| const my_hrtime_t current_time; | ||
| }; | ||
|
|
||
| } // namespace | ||
|
|
||
| /** Resize from srv_buf_pool_old_size to srv_buf_pool_size. */ | ||
| inline void buf_pool_t::resize() | ||
| { | ||
|
|
@@ -1656,15 +1620,37 @@ inline void buf_pool_t::resize() | |
| message_interval *= 2; | ||
| } | ||
|
|
||
| bool found= false; | ||
| find_interesting_trx f | ||
| {found, withdraw_started, my_hrtime_coarse()}; | ||
| withdraw_started = current_time; | ||
| const my_hrtime_t current_hrtime{my_hrtime_coarse()}; | ||
| bool found{false}; | ||
|
|
||
| /* This is going to exceed the maximum size of a | ||
| memory transaction. */ | ||
| LockMutexGuard g{SRW_LOCK_CALL}; | ||
| trx_sys.trx_list.for_each(f); | ||
| for (const trx_t& trx: trx_sys.trx_list) { | ||
| if (!trx.is_started() || !trx.mysql_thd | ||
| || withdraw_started <= trx.start_time_micro) { | ||
|
Comment on lines
+1631
to
+1632
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Accessing |
||
| continue; | ||
| } | ||
|
|
||
| if (!found) { | ||
| sql_print_warning("InnoDB: The following " | ||
| "trx might hold " | ||
| "the blocks in " | ||
| "buffer pool to " | ||
| "be withdrawn. " | ||
| "Buffer pool " | ||
| "resizing can " | ||
| "complete only " | ||
| "after all " | ||
| "the transactions " | ||
| "below release the blocks."); | ||
| found = true; | ||
| } | ||
|
|
||
| lock_trx_print_wait_and_mvcc_state(stderr, &trx, | ||
| current_hrtime); | ||
| } | ||
| } | ||
|
|
||
| if (should_retry_withdraw) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -781,58 +781,6 @@ class rw_trx_hash_t | |
| } | ||
| }; | ||
|
|
||
| class thread_safe_trx_ilist_t | ||
| { | ||
| public: | ||
| void create() { mysql_mutex_init(trx_sys_mutex_key, &mutex, nullptr); } | ||
| void close() { mysql_mutex_destroy(&mutex); } | ||
|
Comment on lines
-787
to
-788
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, I forgot to remove the |
||
|
|
||
| bool empty() const | ||
| { | ||
| mysql_mutex_lock(&mutex); | ||
| auto result= trx_list.empty(); | ||
| mysql_mutex_unlock(&mutex); | ||
| return result; | ||
| } | ||
|
|
||
| void push_front(trx_t &trx) | ||
| { | ||
| mysql_mutex_lock(&mutex); | ||
| trx_list.push_front(trx); | ||
| mysql_mutex_unlock(&mutex); | ||
| } | ||
|
|
||
| void remove(trx_t &trx) | ||
| { | ||
| mysql_mutex_lock(&mutex); | ||
| trx_list.remove(trx); | ||
| mysql_mutex_unlock(&mutex); | ||
| } | ||
|
|
||
| template <typename Callable> void for_each(Callable &&callback) const | ||
| { | ||
| mysql_mutex_lock(&mutex); | ||
| for (const auto &trx : trx_list) | ||
| callback(trx); | ||
| mysql_mutex_unlock(&mutex); | ||
| } | ||
|
|
||
| template <typename Callable> void for_each(Callable &&callback) | ||
| { | ||
| mysql_mutex_lock(&mutex); | ||
| for (auto &trx : trx_list) | ||
| callback(trx); | ||
| mysql_mutex_unlock(&mutex); | ||
| } | ||
|
|
||
| void freeze() const { mysql_mutex_lock(&mutex); } | ||
| void unfreeze() const { mysql_mutex_unlock(&mutex); } | ||
|
|
||
| private: | ||
| alignas(CPU_LEVEL1_DCACHE_LINESIZE) mutable mysql_mutex_t mutex; | ||
| alignas(CPU_LEVEL1_DCACHE_LINESIZE) ilist<trx_t> trx_list; | ||
| }; | ||
|
|
||
| /** The transaction system central memory data structure. */ | ||
| class trx_sys_t | ||
| { | ||
|
|
@@ -858,9 +806,10 @@ class trx_sys_t | |
| bool m_initialised; | ||
|
|
||
| public: | ||
| /** List of all transactions. */ | ||
| thread_safe_trx_ilist_t trx_list; | ||
| /** List of all transactions; protected by lock_sys.latch */ | ||
| ilist<trx_t> trx_list; | ||
|
|
||
| alignas(CPU_LEVEL1_DCACHE_LINESIZE) | ||
| /** Temporary rollback segments */ | ||
| trx_rseg_t temp_rsegs[TRX_SYS_N_RSEGS]; | ||
|
|
||
|
|
@@ -1102,7 +1051,7 @@ class trx_sys_t | |
| void close(); | ||
|
|
||
| /** @return total number of active (non-prepared) transactions */ | ||
| size_t any_active_transactions(size_t *prepared= nullptr); | ||
| size_t any_active_transactions(size_t *prepared= nullptr) noexcept; | ||
|
|
||
|
|
||
| /** | ||
|
|
@@ -1179,21 +1128,15 @@ class trx_sys_t | |
|
|
||
| @param trx transaction | ||
| */ | ||
| void register_trx(trx_t *trx) | ||
| { | ||
| trx_list.push_front(*trx); | ||
| } | ||
| inline void register_trx(trx_t *trx) noexcept; | ||
|
|
||
|
|
||
| /** | ||
| Deregisters transaction in trx_sys. | ||
|
|
||
| @param trx transaction | ||
| */ | ||
| void deregister_trx(trx_t *trx) | ||
| { | ||
| trx_list.remove(*trx); | ||
| } | ||
| inline void deregister_trx(trx_t *trx) noexcept; | ||
|
|
||
|
|
||
| /** | ||
|
|
@@ -1207,17 +1150,7 @@ class trx_sys_t | |
|
|
||
|
|
||
| /** @return the number of active views */ | ||
| size_t view_count() const | ||
| { | ||
| size_t count= 0; | ||
|
|
||
| trx_list.for_each([&count](const trx_t &trx) { | ||
| if (trx.read_view.is_open()) | ||
| ++count; | ||
| }); | ||
|
|
||
| return count; | ||
| } | ||
| size_t view_count() const noexcept; | ||
|
|
||
| /** Disable further allocation of transactions in a rollback segment | ||
| that are subject to innodb_undo_log_truncate=ON | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -695,6 +695,20 @@ static void srv_refresh_innodb_monitor_stats(time_t current_time) | |
| mysql_mutex_unlock(&srv_innodb_monitor_mutex); | ||
| } | ||
|
|
||
| size_t trx_sys_t::view_count() const noexcept | ||
| { | ||
| ut_ad(lock_sys.is_holder()); | ||
|
|
||
| size_t count{0}; | ||
|
|
||
| for (const trx_t &trx : trx_list) | ||
| if (trx.read_view.is_open()) | ||
| ++count; | ||
|
|
||
| return count; | ||
| } | ||
|
|
||
|
|
||
| /******************************************************************//** | ||
| Outputs to a file the output of the InnoDB Monitor. | ||
| @return FALSE if not all information printed | ||
|
|
@@ -760,6 +774,7 @@ srv_printf_innodb_monitor( | |
| ut_copy_file(file, dict_foreign_err_file); | ||
| } | ||
|
|
||
| size_t view_count{0}; | ||
| mysql_mutex_unlock(&dict_foreign_err_mutex); | ||
|
|
||
| /* Only if lock_print_info_summary proceeds correctly, | ||
|
|
@@ -778,6 +793,8 @@ srv_printf_innodb_monitor( | |
| } | ||
| } | ||
|
|
||
| view_count = trx_sys.view_count(); | ||
|
|
||
| /* NOTE: The following function will release the lock_sys.latch | ||
| that lock_print_info_summary() acquired. */ | ||
|
|
||
|
|
@@ -848,11 +865,11 @@ srv_printf_innodb_monitor( | |
|
|
||
| buf_print_io(file); | ||
|
|
||
| fputs("--------------\n" | ||
| "ROW OPERATIONS\n" | ||
| "--------------\n", file); | ||
| fprintf(file, ULINTPF " read views open inside InnoDB\n", | ||
| trx_sys.view_count()); | ||
| fprintf(file, | ||
| "--------------\n" | ||
| "ROW OPERATIONS\n" | ||
| "--------------\n" | ||
| "%zu read views open inside InnoDB\n", view_count); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was intentional, but not mentioned in the commit message. If we need to protect |
||
|
|
||
| if (ulint n_reserved = fil_system.sys_space->n_reserved_extents) { | ||
| fprintf(file, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes to this file
buf0buf.ccare only applicable to the 10.6 branches that do not include #3107. We’re only replacing callback-based traversal with an inline rangeforloop here.