From 6fbcf4134af1f0df21fbcc06870f50b6cb2d3c41 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 30 Mar 2017 15:26:10 +0200 Subject: [PATCH 1/9] properly close the table in fill_schema_table_from_frm() this closes the memory leak, that started to appear after da5c3e03f62 --- sql/sql_show.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 18bc19bb85eff..6564504eff471 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4667,7 +4667,7 @@ static int fill_schema_table_from_frm(THD *thd, TABLE *table, table_list.view= (LEX*) share->is_view; res= schema_table->process_table(thd, &table_list, table, res, db_name, table_name); - free_root(&tbl.mem_root, MYF(0)); + closefrm(&tbl); } From 0b9a13a8fc2e8f0da5a0bc925ffe9cb471da677a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 31 Mar 2017 15:03:02 +0200 Subject: [PATCH 2/9] update C/C to fix main.mysql_client_test_nonblock failures --- libmariadb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmariadb b/libmariadb index e9868bfce0d30..be34e12ba0f9a 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit e9868bfce0d30e789d89272f190c1fcb64f78904 +Subproject commit be34e12ba0f9a23074be5051259db954b3a302d9 From 124bae082bf17e9af1fc77f78bbebd019635be5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 30 Mar 2017 13:11:34 +0300 Subject: [PATCH 3/9] MDEV-12289 Keep 128 persistent rollback segments for compatibility and performance InnoDB divides the allocation of undo logs into rollback segments. The DB_ROLL_PTR system column of clustered indexes can address up to 128 rollback segments (TRX_SYS_N_RSEGS). Originally, InnoDB only created one rollback segment. In MySQL 5.5 or in the InnoDB Plugin for MySQL 5.1, all 128 rollback segments were created. MySQL 5.7 hard-codes the rollback segment IDs 1..32 for temporary undo logs. On upgrade, unless a slow shutdown (innodb_fast_shutdown=0) was performed on the old server instance, these rollback segments could be in use by transactions that are in XA PREPARE state or transactions that were left behind by a server kill followed by a normal shutdown immediately after restart. Persistent tables cannot refer to temporary undo logs or vice versa. Therefore, we should keep two distinct sets of rollback segments: one for persistent tables and another for temporary tables. In this way, all 128 rollback segments will be available for both types of tables, which could improve performance. Also, MariaDB 10.2 will remain more compatible than MySQL 5.7 with data files from earlier versions of MySQL or MariaDB. trx_sys_t::temp_rsegs[TRX_SYS_N_RSEGS]: A new array of temporary rollback segments. The trx_sys_t::rseg_array[TRX_SYS_N_RSEGS] will be solely for persistent undo logs. srv_tmp_undo_logs. Remove. Use the constant TRX_SYS_N_RSEGS. srv_available_undo_logs: Change the type to ulong. trx_rseg_get_on_id(): Remove. Instead, let the callers refer to trx_sys directly. trx_rseg_create(), trx_sysf_rseg_find_free(): Remove unneeded parameters. These functions only deal with persistent undo logs. trx_temp_rseg_create(): New function, to create all temporary rollback segments at server startup. trx_rseg_t::is_persistent(): Determine if the rollback segment is for persistent tables. trx_sys_is_noredo_rseg_slot(): Remove. The callers must know based on context (such as table handle) whether the DB_ROLL_PTR is referring to a persistent undo log. trx_sys_create_rsegs(): Remove all parameters, which were always passed as global variables. Instead, modify the global variables directly. enum trx_rseg_type_t: Remove. trx_t::get_temp_rseg(): A method to ensure that a temporary rollback segment has been assigned for the transaction. trx_t::assign_temp_rseg(): Replaces trx_assign_rseg(). trx_purge_free_segment(), trx_purge_truncate_rseg_history(): Remove the redundant variable noredo=false. Temporary undo logs are discarded immediately at transaction commit or rollback, not lazily by purge. trx_purge_mark_undo_for_truncate(): Remove references to the temporary rollback segments. trx_purge_mark_undo_for_truncate(): Remove a check for temporary rollback segments. Only the dedicated persistent undo log tablespaces can be truncated. trx_undo_get_undo_rec_low(), trx_undo_get_undo_rec(): Add the parameter is_temp. trx_rseg_mem_restore(): Split from trx_rseg_mem_create(). Initialize the undo log and the rollback segment from the file data structures. trx_sysf_get_n_rseg_slots(): Renamed from trx_sysf_used_slots_for_redo_rseg(). Count the persistent rollback segment headers that have been initialized. trx_sys_close(): Also free trx_sys->temp_rsegs[]. get_next_redo_rseg(): Merged to trx_assign_rseg_low(). trx_assign_rseg_low(): Remove the parameters and access the global variables directly. Revert to simple round-robin, now that the whole trx_sys->rseg_array[] is for persistent undo log again. get_next_noredo_rseg(): Moved to trx_t::assign_temp_rseg(). srv_undo_tablespaces_init(): Remove some parameters and use the global variables directly. Clarify some error messages. Adjust the test innodb.log_file. Apparently, before these changes, InnoDB somehow ignored missing dedicated undo tablespace files that are pointed by the TRX_SYS header page, possibly losing part of essential transaction system state. --- libmariadb | 2 +- mysql-test/suite/innodb/r/log_file.result | 4 +- mysql-test/suite/innodb/t/log_file.test | 6 +- storage/innobase/handler/ha_innodb.cc | 2 +- storage/innobase/include/srv0srv.h | 6 +- storage/innobase/include/trx0rseg.h | 32 ++- storage/innobase/include/trx0sys.h | 49 ++--- storage/innobase/include/trx0sys.ic | 12 - storage/innobase/include/trx0trx.h | 30 +-- storage/innobase/row/row0purge.cc | 5 +- storage/innobase/srv/srv0srv.cc | 53 +++-- storage/innobase/srv/srv0start.cc | 72 ++---- storage/innobase/trx/trx0purge.cc | 51 ++--- storage/innobase/trx/trx0rec.cc | 47 ++-- storage/innobase/trx/trx0rseg.cc | 144 ++++++------ storage/innobase/trx/trx0sys.cc | 220 ++++++------------- storage/innobase/trx/trx0trx.cc | 253 +++++++--------------- storage/innobase/trx/trx0undo.cc | 6 +- 18 files changed, 369 insertions(+), 625 deletions(-) diff --git a/libmariadb b/libmariadb index be34e12ba0f9a..cae391f7bf47f 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit be34e12ba0f9a23074be5051259db954b3a302d9 +Subproject commit cae391f7bf47f17fb246cded8ddf0ef19dbfbdec diff --git a/mysql-test/suite/innodb/r/log_file.result b/mysql-test/suite/innodb/r/log_file.result index 352e4b76cf1f1..918faec8adae5 100644 --- a/mysql-test/suite/innodb/r/log_file.result +++ b/mysql-test/suite/innodb/r/log_file.result @@ -207,7 +207,7 @@ SELECT * FROM INFORMATION_SCHEMA.ENGINES WHERE engine = 'innodb' AND support IN ('YES', 'DEFAULT', 'ENABLED'); ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS -FOUND /Expected to open 3 undo tablespaces but was able to find only 1 undo tablespaces/ in mysqld.1.err +FOUND /InnoDB: Unable to open undo tablespace.*undo002/ in mysqld.1.err bak_ib_logfile0 bak_ib_logfile1 bak_ib_logfile2 @@ -244,7 +244,7 @@ SELECT * FROM INFORMATION_SCHEMA.ENGINES WHERE engine = 'innodb' AND support IN ('YES', 'DEFAULT', 'ENABLED'); ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS -FOUND /Expected to open 3 undo tablespaces but was able to find only 0 undo tablespaces/ in mysqld.1.err +FOUND /InnoDB: Unable to open undo tablespace.*undo001/ in mysqld.1.err bak_ib_logfile0 bak_ib_logfile1 bak_ib_logfile2 diff --git a/mysql-test/suite/innodb/t/log_file.test b/mysql-test/suite/innodb/t/log_file.test index c50257a69bed8..e0f4b85c6825b 100644 --- a/mysql-test/suite/innodb/t/log_file.test +++ b/mysql-test/suite/innodb/t/log_file.test @@ -41,7 +41,7 @@ AND support IN ('YES', 'DEFAULT', 'ENABLED'); --let $ibp=$ibp --innodb-data-file-path=ibdata1:16M;ibdata2:10M:autoextend --echo # Start mysqld without the possibility to create innodb_undo_tablespaces ---let $restart_parameters= $ibp --innodb-undo-tablespaces=3 +--let $restart_parameters= $ibp --mkdir $bugdir/undo002 --source include/restart_mysqld.inc eval $check_no_innodb; @@ -172,7 +172,7 @@ let SEARCH_PATTERN=undo tablespace .*undo003.* exists\. Creating system tablespa --source include/start_mysqld.inc eval $check_no_innodb; --source include/shutdown_mysqld.inc -let SEARCH_PATTERN=Expected to open 3 undo tablespaces but was able to find only 1 undo tablespaces; +let SEARCH_PATTERN=InnoDB: Unable to open undo tablespace.*undo002; --source include/search_pattern_in_file.inc # clean up & Restore --source ../include/log_file_cleanup.inc @@ -184,7 +184,7 @@ let SEARCH_PATTERN=Expected to open 3 undo tablespaces but was able to find only --source include/start_mysqld.inc eval $check_no_innodb; --source include/shutdown_mysqld.inc -let SEARCH_PATTERN=Expected to open 3 undo tablespaces but was able to find only 0 undo tablespaces; +let SEARCH_PATTERN=InnoDB: Unable to open undo tablespace.*undo001; --source include/search_pattern_in_file.inc # clean up & Restore diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 3dc22fe58d857..6aacdd48ad853 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -22140,7 +22140,7 @@ innobase_undo_logs_init_default_max() { MYSQL_SYSVAR_NAME(undo_logs).max_val = MYSQL_SYSVAR_NAME(undo_logs).def_val - = static_cast(srv_available_undo_logs); + = srv_available_undo_logs; } /**************************************************************************** diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index e469cd90737e0..eb08c47896522 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -334,9 +334,6 @@ extern my_bool srv_undo_log_truncate; /* Enables or disables this prefix optimization. Disabled by default. */ extern my_bool srv_prefix_index_cluster_optimization; -/** UNDO logs not redo logged, these logs reside in the temp tablespace.*/ -extern const ulong srv_tmp_undo_logs; - /** Default size of UNDO tablespace while it is created new. */ extern const ulint SRV_UNDO_TABLESPACE_SIZE_IN_PAGES; @@ -518,7 +515,8 @@ extern uint srv_spin_wait_delay; extern ibool srv_priority_boost; extern ulint srv_truncated_status_writes; -extern ulint srv_available_undo_logs; +/** Number of initialized rollback segments for persistent undo log */ +extern ulong srv_available_undo_logs; #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG extern my_bool srv_ibuf_disable_background_merge; diff --git a/storage/innobase/include/trx0rseg.h b/storage/innobase/include/trx0rseg.h index e17d11b383e75..95774cbf476e6 100644 --- a/storage/innobase/include/trx0rseg.h +++ b/storage/innobase/include/trx0rseg.h @@ -85,16 +85,6 @@ trx_rsegf_undo_find_free( /*=====================*/ trx_rsegf_t* rsegf, /*!< in: rollback segment header */ mtr_t* mtr); /*!< in: mtr */ -/** Get a rollback segment. -@param[in] id rollback segment id -@return rollback segment */ -UNIV_INLINE -trx_rseg_t* -trx_rseg_get_on_id(ulint id) -{ - ut_a(id < TRX_SYS_N_RSEGS); - return(trx_sys->rseg_array[id]); -} /** Creates a rollback segment header. This function is called only when a new rollback segment is created in @@ -119,14 +109,14 @@ trx_rseg_array_init(); void trx_rseg_mem_free(trx_rseg_t* rseg); -/********************************************************************* -Creates a rollback segment. */ +/** Create a persistent rollback segment. +@param[in] space_id system or undo tablespace id */ trx_rseg_t* -trx_rseg_create( -/*============*/ - ulint space_id, /*!< in: id of UNDO tablespace */ - ulint nth_free_slot); /*!< in: allocate nth free slot. - 0 means next free slots. */ +trx_rseg_create(ulint space_id); + +/** Create the temporary rollback segments. */ +void +trx_temp_rseg_create(); /******************************************************************** Get the number of unique rollback tablespaces in use except space id 0. @@ -205,6 +195,14 @@ struct trx_rseg_t { /** If true, then skip allocating this rseg as it reside in UNDO-tablespace marked for truncate. */ bool skip_allocation; + + /** @return whether the rollback segment is persistent */ + bool is_persistent() const + { + ut_ad(space == SRV_TMP_SPACE_ID + || space <= srv_undo_tablespaces); + return(space != SRV_TMP_SPACE_ID); + } }; /* Undo log segment slot in a rollback segment header */ diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h index 8ebb74e3d86f8..b867600653d8c 100644 --- a/storage/innobase/include/trx0sys.h +++ b/storage/innobase/include/trx0sys.h @@ -75,17 +75,10 @@ Creates and initializes the transaction system at the database creation. */ void trx_sys_create_sys_pages(void); /*==========================*/ -/****************************************************************//** -Looks for a free slot for a rollback segment in the trx system file copy. -@return slot index or ULINT_UNDEFINED if not found */ +/** @return an unallocated rollback segment slot in the TRX_SYS header +@retval ULINT_UNDEFINED if not found */ ulint -trx_sysf_rseg_find_free( -/*====================*/ - mtr_t* mtr, /*!< in/out: mtr */ - bool include_tmp_slots, /*!< in: if true, report slots reserved - for temp-tablespace as free slots. */ - ulint nth_free_slots); /*!< in: allocate nth free slot. - 0 means next free slot. */ +trx_sysf_rseg_find_free(mtr_t* mtr); /**********************************************************************//** Gets a pointer to the transaction system file copy and x-locks its page. @return pointer to system file copy, page x-locked */ @@ -160,14 +153,6 @@ trx_sys_get_max_trx_id(void); extern uint trx_rseg_n_slots_debug; #endif -/*****************************************************************//** -Check if slot-id is reserved slot-id for noredo rsegs. */ -UNIV_INLINE -bool -trx_sys_is_noredo_rseg_slot( -/*========================*/ - ulint slot_id); /*!< in: slot_id to check */ - /*****************************************************************//** Writes a trx id to an index page. In case that the id size changes in some future version, this function should be used instead of @@ -319,16 +304,10 @@ trx_sys_file_format_max_set( ulint format_id, /*!< in: file format id */ const char** name); /*!< out: max file format name or NULL if not needed. */ -/********************************************************************* -Creates the rollback segments -@return number of rollback segments that are active. */ -ulint -trx_sys_create_rsegs( -/*=================*/ - ulint n_spaces, /*!< number of tablespaces for UNDO logs */ - ulint n_rsegs, /*!< number of rollback segments to create */ - ulint n_tmp_rsegs); /*!< number of rollback segments reserved for - temp-tables. */ +/** Create the rollback segments. +@return whether the creation succeeded */ +bool +trx_sys_create_rsegs(); /*****************************************************************//** Get the number of transaction in the system, independent of their state. @return count of transactions in trx_sys_t::trx_list */ @@ -556,13 +535,15 @@ struct trx_sys_t { transactions which exist or existed */ #endif /* UNIV_DEBUG */ - char pad1[64]; /*!< To avoid false sharing */ + /** Avoid false sharing */ + const char pad1[CACHE_LINE_SIZE]; trx_ut_list_t rw_trx_list; /*!< List of active and committed in memory read-write transactions, sorted on trx id, biggest first. Recovered transactions are always on this list. */ - char pad2[64]; /*!< To avoid false sharing */ + /** Avoid false sharing */ + const char pad2[CACHE_LINE_SIZE]; trx_ut_list_t mysql_trx_list; /*!< List of transactions created for MySQL. All user transactions are on mysql_trx_list. The rw_trx_list @@ -582,7 +563,13 @@ struct trx_sys_t { to ensure right order of removal and consistent snapshot. */ - char pad3[64]; /*!< To avoid false sharing */ + /** Avoid false sharing */ + const char pad3[CACHE_LINE_SIZE]; + /** Temporary rollback segments */ + trx_rseg_t* temp_rsegs[TRX_SYS_N_RSEGS]; + /** Avoid false sharing */ + const char pad4[CACHE_LINE_SIZE]; + trx_rseg_t* rseg_array[TRX_SYS_N_RSEGS]; /*!< Pointer array to rollback segments; NULL if slot not in use; diff --git a/storage/innobase/include/trx0sys.ic b/storage/innobase/include/trx0sys.ic index f03535c53b311..1c805ead4b31d 100644 --- a/storage/innobase/include/trx0sys.ic +++ b/storage/innobase/include/trx0sys.ic @@ -191,18 +191,6 @@ trx_write_trx_id( mach_write_to_6(ptr, id); } -/*****************************************************************//** -Check if slot-id is reserved slot-id for noredo rsegs. */ -UNIV_INLINE -bool -trx_sys_is_noredo_rseg_slot( -/*========================*/ - ulint slot_id) /*!< in: slot_id to check */ -{ - /* Slots allocated from temp-tablespace are no-redo slots. */ - return(slot_id > 0 && slot_id < (srv_tmp_undo_logs + 1)); -} - /*****************************************************************//** Reads a trx id from an index page. In case that the id size changes in some future version, this function should be used instead of diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 7da3bfb5459d4..d0a67a7ed284b 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -507,14 +507,6 @@ trx_id_t trx_get_id_for_print( const trx_t* trx); -/****************************************************************//** -Assign a transaction temp-tablespace bound rollback-segment. */ -void -trx_assign_rseg( -/*============*/ - trx_t* trx); /*!< transaction that involves write - to temp-table. */ - /** Create the trx_t pool */ void trx_pool_init(); @@ -869,12 +861,6 @@ struct trx_rsegs_t { trx_temp_undo_t m_noredo; }; -enum trx_rseg_type_t { - TRX_RSEG_TYPE_NONE = 0, /*!< void rollback segment type. */ - TRX_RSEG_TYPE_REDO, /*!< redo rollback segment. */ - TRX_RSEG_TYPE_NOREDO /*!< non-redo rollback segment. */ -}; - struct TrxVersion { TrxVersion(trx_t* trx); @@ -1295,6 +1281,22 @@ struct trx_t { { return(has_logged_persistent() || rsegs.m_noredo.undo); } + + /** @return rollback segment for modifying temporary tables */ + trx_rseg_t* get_temp_rseg() + { + if (trx_rseg_t* rseg = rsegs.m_noredo.rseg) { + ut_ad(id != 0); + return(rseg); + } + + return(assign_temp_rseg()); + } + +private: + /** Assign a rollback segment for modifying temporary tables. + @return the assigned rollback segment */ + trx_rseg_t* assign_temp_rseg(); }; /** diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc index ce9a265bd8c12..2a13203b74764 100644 --- a/storage/innobase/row/row0purge.cc +++ b/storage/innobase/row/row0purge.cc @@ -741,10 +741,11 @@ row_purge_upd_exist_or_extern_func( &is_insert, &rseg_id, &page_no, &offset); - rseg = trx_rseg_get_on_id(rseg_id); + rseg = trx_sys->rseg_array[rseg_id]; ut_a(rseg != NULL); - ut_a(rseg->id == rseg_id); + ut_ad(rseg->id == rseg_id); + ut_ad(rseg->is_persistent()); mtr_start(&mtr); diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index b689cd012c6a6..a05bb5300a34b 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -139,10 +139,6 @@ my_bool srv_undo_log_truncate = FALSE; /** Maximum size of undo tablespace. */ unsigned long long srv_max_undo_log_size; -/** UNDO logs that are not redo logged. -These logs reside in the temp tablespace.*/ -const ulong srv_tmp_undo_logs = 32; - /** Default undo tablespace size in UNIV_PAGEs count (10MB). */ const ulint SRV_UNDO_TABLESPACE_SIZE_IN_PAGES = ((1024 * 1024) * 10) / UNIV_PAGE_SIZE_DEF; @@ -403,37 +399,38 @@ UNIV_INTERN ulong srv_n_spin_wait_rounds = 15; uint srv_spin_wait_delay; ibool srv_priority_boost = TRUE; -static ulint srv_n_rows_inserted_old = 0; -static ulint srv_n_rows_updated_old = 0; -static ulint srv_n_rows_deleted_old = 0; -static ulint srv_n_rows_read_old = 0; -static ulint srv_n_system_rows_inserted_old = 0; -static ulint srv_n_system_rows_updated_old = 0; -static ulint srv_n_system_rows_deleted_old = 0; -static ulint srv_n_system_rows_read_old = 0; - -ulint srv_truncated_status_writes = 0; -ulint srv_available_undo_logs = 0; - -UNIV_INTERN ib_uint64_t srv_page_compression_saved = 0; -UNIV_INTERN ib_uint64_t srv_page_compression_trim_sect512 = 0; -UNIV_INTERN ib_uint64_t srv_page_compression_trim_sect4096 = 0; -UNIV_INTERN ib_uint64_t srv_index_pages_written = 0; -UNIV_INTERN ib_uint64_t srv_non_index_pages_written = 0; -UNIV_INTERN ib_uint64_t srv_pages_page_compressed = 0; -UNIV_INTERN ib_uint64_t srv_page_compressed_trim_op = 0; -UNIV_INTERN ib_uint64_t srv_page_compressed_trim_op_saved = 0; -UNIV_INTERN ib_uint64_t srv_index_page_decompressed = 0; +static ulint srv_n_rows_inserted_old; +static ulint srv_n_rows_updated_old; +static ulint srv_n_rows_deleted_old; +static ulint srv_n_rows_read_old; +static ulint srv_n_system_rows_inserted_old; +static ulint srv_n_system_rows_updated_old; +static ulint srv_n_system_rows_deleted_old; +static ulint srv_n_system_rows_read_old; + +ulint srv_truncated_status_writes; +/** Number of initialized rollback segments for persistent undo log */ +ulong srv_available_undo_logs; + +UNIV_INTERN ib_uint64_t srv_page_compression_saved; +UNIV_INTERN ib_uint64_t srv_page_compression_trim_sect512; +UNIV_INTERN ib_uint64_t srv_page_compression_trim_sect4096; +UNIV_INTERN ib_uint64_t srv_index_pages_written; +UNIV_INTERN ib_uint64_t srv_non_index_pages_written; +UNIV_INTERN ib_uint64_t srv_pages_page_compressed; +UNIV_INTERN ib_uint64_t srv_page_compressed_trim_op; +UNIV_INTERN ib_uint64_t srv_page_compressed_trim_op_saved; +UNIV_INTERN ib_uint64_t srv_index_page_decompressed; /* Defragmentation */ -UNIV_INTERN my_bool srv_defragment = FALSE; +UNIV_INTERN my_bool srv_defragment; UNIV_INTERN uint srv_defragment_n_pages = 7; -UNIV_INTERN uint srv_defragment_stats_accuracy = 0; +UNIV_INTERN uint srv_defragment_stats_accuracy; UNIV_INTERN uint srv_defragment_fill_factor_n_recs = 20; UNIV_INTERN double srv_defragment_fill_factor = 0.9; UNIV_INTERN uint srv_defragment_frequency = SRV_DEFRAGMENT_FREQUENCY_DEFAULT; -UNIV_INTERN ulonglong srv_defragment_interval = 0; +UNIV_INTERN ulonglong srv_defragment_interval; /* Set the following to 0 if you want InnoDB to write messages on stderr on startup/shutdown. */ diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 7c16ce1e58f4f..bcb52fc5bfb57 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -804,20 +804,12 @@ srv_check_undo_redo_logs_exists() undo::undo_spaces_t undo::Truncate::s_fix_up_spaces; -/******************************************************************** -Opens the configured number of undo tablespaces. +/** Open the configured number of dedicated undo tablespaces. +@param[in] create_new_db whether the database is being initialized @return DB_SUCCESS or error code */ static dberr_t -srv_undo_tablespaces_init( -/*======================*/ - bool create_new_db, /*!< in: TRUE if new db being - created */ - const ulint n_conf_tablespaces, /*!< in: configured undo - tablespaces */ - ulint* n_opened) /*!< out: number of UNDO - tablespaces successfully - discovered and opened */ +srv_undo_tablespaces_init(bool create_new_db) { ulint i; dberr_t err = DB_SUCCESS; @@ -825,9 +817,9 @@ srv_undo_tablespaces_init( ulint n_undo_tablespaces; ulint undo_tablespace_ids[TRX_SYS_N_RSEGS + 1]; - *n_opened = 0; + srv_undo_tablespaces_open = 0; - ut_a(n_conf_tablespaces <= TRX_SYS_N_RSEGS); + ut_a(srv_undo_tablespaces <= TRX_SYS_N_RSEGS); memset(undo_tablespace_ids, 0x0, sizeof(undo_tablespace_ids)); @@ -839,7 +831,7 @@ srv_undo_tablespaces_init( the location of the undo tablespaces and their space ids this restriction will/should be lifted. */ - for (i = 0; create_new_db && i < n_conf_tablespaces; ++i) { + for (i = 0; create_new_db && i < srv_undo_tablespaces; ++i) { char name[OS_FILE_MAX_PATH]; ut_snprintf( @@ -902,7 +894,7 @@ srv_undo_tablespaces_init( } } } else { - n_undo_tablespaces = n_conf_tablespaces; + n_undo_tablespaces = srv_undo_tablespaces; for (i = 1; i <= n_undo_tablespaces; ++i) { undo_tablespace_ids[i - 1] = i; @@ -944,7 +936,7 @@ srv_undo_tablespaces_init( prev_space_id = undo_tablespace_ids[i]; - ++*n_opened; + ++srv_undo_tablespaces_open; } /* Open any extra unused undo tablespaces. These must be contiguous. @@ -968,19 +960,17 @@ srv_undo_tablespaces_init( ++n_undo_tablespaces; - ++*n_opened; + ++srv_undo_tablespaces_open; } /* If the user says that there are fewer than what we find we tolerate that discrepancy but not the inverse. Because there could be unused undo tablespaces for future use. */ - if (n_conf_tablespaces > n_undo_tablespaces) { - ib::error() << "Expected to open " << n_conf_tablespaces - << " undo tablespaces but was able to find only " - << n_undo_tablespaces << " undo tablespaces. Set the" - " innodb_undo_tablespaces parameter to the correct" - " value and retry. Suggested value is " + if (srv_undo_tablespaces > n_undo_tablespaces) { + ib::error() << "Expected to open innodb_undo_tablespaces=" + << srv_undo_tablespaces + << " but was able to find only " << n_undo_tablespaces; return(err != DB_SUCCESS ? err : DB_ERROR); @@ -988,15 +978,13 @@ srv_undo_tablespaces_init( } else if (n_undo_tablespaces > 0) { ib::info() << "Opened " << n_undo_tablespaces - << " undo tablespaces"; - - ib::info() << srv_undo_tablespaces_active << " undo tablespaces" - << " made active"; + << " undo tablespaces (" + << srv_undo_tablespaces_active + << " active)"; - if (n_conf_tablespaces == 0) { - ib::warn() << "Will use system tablespace for all newly" - << " created rollback-segment as" - << " innodb_undo_tablespaces=0"; + if (srv_undo_tablespaces == 0) { + ib::warn() << "innodb_undo_tablespaces=0 disables" + " dedicated undo log tablespaces"; } } @@ -2087,10 +2075,7 @@ innobase_start_or_create_for_mysql(void) fil_open_log_and_system_tablespace_files(); ut_d(fil_space_get(0)->recv_size = srv_sys_space_size_debug); - err = srv_undo_tablespaces_init( - create_new_db, - srv_undo_tablespaces, - &srv_undo_tablespaces_open); + err = srv_undo_tablespaces_init(create_new_db); /* If the force recovery is set very high then we carry on regardless of all errors. Basically this is fingers crossed mode. */ @@ -2512,22 +2497,7 @@ innobase_start_or_create_for_mysql(void) ut_a(srv_undo_logs > 0); ut_a(srv_undo_logs <= TRX_SYS_N_RSEGS); - /* The number of rsegs that exist in InnoDB is given by status - variable srv_available_undo_logs. The number of rsegs to use can - be set using the dynamic global variable srv_undo_logs. */ - - srv_available_undo_logs = trx_sys_create_rsegs( - srv_undo_tablespaces, srv_undo_logs, srv_tmp_undo_logs); - - if (srv_available_undo_logs == ULINT_UNDEFINED) { - /* Can only happen if server is read only. */ - ut_a(srv_read_only_mode); - srv_undo_logs = ULONG_UNDEFINED; - } else if (srv_available_undo_logs < srv_undo_logs - && !srv_force_recovery && !recv_needed_recovery) { - ib::error() << "System or UNDO tablespace is running of out" - << " of space"; - /* Should due to out of file space. */ + if (!trx_sys_create_rsegs()) { return(srv_init_abort(DB_ERROR)); } diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc index 6ff4c882be8d9..f83d93778521b 100644 --- a/storage/innobase/trx/trx0purge.cc +++ b/storage/innobase/trx/trx0purge.cc @@ -327,17 +327,12 @@ trx_purge_remove_log_hdr( my_atomic_addlint(&trx_sys->rseg_history_len, -1); } -/** Frees an undo log segment which is in the history list. Removes the -undo log hdr from the history list. +/** Free an undo log segment, and remove the header from the history list. @param[in,out] rseg rollback segment -@param[in] hdr_addr file address of log_hdr -@param[in] noredo skip redo logging. */ +@param[in] hdr_addr file address of log_hdr */ static void -trx_purge_free_segment( - trx_rseg_t* rseg, - fil_addr_t hdr_addr, - bool noredo) +trx_purge_free_segment(trx_rseg_t* rseg, fil_addr_t hdr_addr) { mtr_t mtr; trx_rsegf_t* rseg_hdr; @@ -345,16 +340,12 @@ trx_purge_free_segment( trx_usegf_t* seg_hdr; ulint seg_size; ulint hist_size; - bool marked = noredo; + bool marked = false; for (;;) { page_t* undo_page; mtr_start(&mtr); - if (noredo) { - mtr.set_log_mode(MTR_LOG_NO_REDO); - } - ut_ad(noredo == trx_sys_is_noredo_rseg_slot(rseg->id)); mutex_enter(&rseg->mutex); @@ -428,14 +419,12 @@ trx_purge_free_segment( mtr_commit(&mtr); } -/********************************************************************//** -Removes unnecessary history data from a rollback segment. */ +/** Remove unnecessary history data from a rollback segment. +@param[in,out] rseg rollback segment +@param[in] limit truncate offset */ static void -trx_purge_truncate_rseg_history( -/*============================*/ - trx_rseg_t* rseg, /*!< in: rollback segment */ - const purge_iter_t* limit) /*!< in: truncate offset */ +trx_purge_truncate_rseg_history(trx_rseg_t* rseg, const purge_iter_t* limit) { fil_addr_t hdr_addr; fil_addr_t prev_hdr_addr; @@ -445,13 +434,9 @@ trx_purge_truncate_rseg_history( trx_usegf_t* seg_hdr; mtr_t mtr; trx_id_t undo_trx_no; - const bool noredo = trx_sys_is_noredo_rseg_slot( - rseg->id); mtr_start(&mtr); - if (noredo) { - mtr.set_log_mode(MTR_LOG_NO_REDO); - } + ut_ad(rseg->is_persistent()); mutex_enter(&(rseg->mutex)); rseg_hdr = trx_rsegf_get(rseg->space, rseg->page_no, &mtr); @@ -509,7 +494,7 @@ trx_purge_truncate_rseg_history( /* calls the trx_purge_remove_log_hdr() inside trx_purge_free_segment(). */ - trx_purge_free_segment(rseg, hdr_addr, noredo); + trx_purge_free_segment(rseg, hdr_addr); } else { /* Remove the log hdr from the rseg history. */ trx_purge_remove_log_hdr(rseg_hdr, log_hdr, &mtr); @@ -519,9 +504,6 @@ trx_purge_truncate_rseg_history( } mtr_start(&mtr); - if (noredo) { - mtr.set_log_mode(MTR_LOG_NO_REDO); - } mutex_enter(&(rseg->mutex)); rseg_hdr = trx_rsegf_get(rseg->space, rseg->page_no, &mtr); @@ -806,10 +788,9 @@ trx_purge_mark_undo_for_truncate( /* Step-2: Validation/Qualification checks a. At-least 2 UNDO tablespaces so even if one UNDO tablespace is being truncated server can continue to operate. - b. At-least 2 UNDO redo rseg/undo logs (besides the default rseg-0) + b. At-least 2 persistent UNDO logs (besides the default rseg-0) b. At-least 1 UNDO tablespace size > threshold. */ - if (srv_undo_tablespaces_active < 2 - || (srv_undo_logs < (1 + srv_tmp_undo_logs + 2))) { + if (srv_undo_tablespaces_active < 2 || srv_undo_logs < 3) { return; } @@ -846,11 +827,9 @@ trx_purge_mark_undo_for_truncate( /* Step-3: Iterate over all the rsegs of selected UNDO tablespace and mark them temporarily unavailable for allocation.*/ for (ulint i = 0; i < TRX_SYS_N_RSEGS; ++i) { - trx_rseg_t* rseg = trx_sys->rseg_array[i]; - - if (rseg != NULL && !trx_sys_is_noredo_rseg_slot(rseg->id)) { - if (rseg->space - == undo_trunc->get_marked_space_id()) { + if (trx_rseg_t* rseg = trx_sys->rseg_array[i]) { + ut_ad(rseg->is_persistent()); + if (rseg->space == undo_trunc->get_marked_space_id()) { /* Once set this rseg will not be allocated to new booting transaction but we will wait diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc index 481e14d44dea6..47d24b631141b 100644 --- a/storage/innobase/trx/trx0rec.cc +++ b/storage/innobase/trx/trx0rec.cc @@ -1893,13 +1893,7 @@ trx_undo_report_row_operation( if (is_temp) { mtr.set_log_mode(MTR_LOG_NO_REDO); - rseg = trx->rsegs.m_noredo.rseg; - - if (!rseg) { - trx_assign_rseg(trx); - rseg = trx->rsegs.m_noredo.rseg; - } - + rseg = trx->get_temp_rseg(); pundo = &trx->rsegs.m_noredo.undo; } else { ut_ad(!trx->read_only); @@ -2057,16 +2051,16 @@ trx_undo_report_row_operation( /*============== BUILDING PREVIOUS VERSION OF A RECORD ===============*/ -/******************************************************************//** -Copies an undo record to heap. This function can be called if we know that -the undo log record exists. -@return own: copy of the record */ +/** Copy an undo record to heap. +@param[in] roll_ptr roll pointer to a record that exists +@param[in] is_temp whether this is a temporary table +@param[in,out] heap memory heap where copied */ static trx_undo_rec_t* trx_undo_get_undo_rec_low( -/*======================*/ - roll_ptr_t roll_ptr, /*!< in: roll pointer to record */ - mem_heap_t* heap) /*!< in: memory heap where copied */ + roll_ptr_t roll_ptr, + bool is_temp, + mem_heap_t* heap) { trx_undo_rec_t* undo_rec; ulint rseg_id; @@ -2079,7 +2073,10 @@ trx_undo_get_undo_rec_low( trx_undo_decode_roll_ptr(roll_ptr, &is_insert, &rseg_id, &page_no, &offset); - rseg = trx_rseg_get_on_id(rseg_id); + rseg = is_temp + ? trx_sys->temp_rsegs[rseg_id] + : trx_sys->rseg_array[rseg_id]; + ut_ad(is_temp == !rseg->is_persistent()); mtr_start(&mtr); @@ -2093,13 +2090,13 @@ trx_undo_get_undo_rec_low( return(undo_rec); } -/******************************************************************//** -Copies an undo record to heap. +/** Copy an undo record to heap. @param[in] roll_ptr roll pointer to record +@param[in] is_temp whether this is a temporary table +@param[in,out] heap memory heap where copied @param[in] trx_id id of the trx that generated the roll pointer: it points to an undo log of this transaction -@param[in] heap memory heap where copied @param[in] name table name @param[out] undo_rec own: copy of the record @retval true if the undo log has been @@ -2109,10 +2106,10 @@ NOTE: the caller must have latches on the clustered index page. */ static MY_ATTRIBUTE((warn_unused_result)) bool trx_undo_get_undo_rec( -/*==================*/ roll_ptr_t roll_ptr, - trx_id_t trx_id, + bool is_temp, mem_heap_t* heap, + trx_id_t trx_id, const table_name_t& name, trx_undo_rec_t** undo_rec) { @@ -2122,7 +2119,7 @@ trx_undo_get_undo_rec( missing_history = purge_sys->view.changes_visible(trx_id, name); if (!missing_history) { - *undo_rec = trx_undo_get_undo_rec_low(roll_ptr, heap); + *undo_rec = trx_undo_get_undo_rec_low(roll_ptr, is_temp, heap); } rw_lock_s_unlock(&purge_sys->latch); @@ -2203,13 +2200,17 @@ trx_undo_prev_version_build( return(true); } + const bool is_temp = dict_table_is_temporary(index->table); rec_trx_id = row_get_rec_trx_id(rec, index, offsets); if (trx_undo_get_undo_rec( - roll_ptr, rec_trx_id, heap, index->table->name, &undo_rec)) { + roll_ptr, is_temp, heap, rec_trx_id, index->table->name, + &undo_rec)) { if (v_status & TRX_UNDO_PREV_IN_PURGE) { /* We are fetching the record being purged */ - undo_rec = trx_undo_get_undo_rec_low(roll_ptr, heap); + ut_ad(!is_temp); + undo_rec = trx_undo_get_undo_rec_low( + roll_ptr, is_temp, heap); } else { /* The undo record may already have been purged, during purge or semi-consistent read. */ diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc index 883e2eb60b2b5..3393a0464a856 100644 --- a/storage/innobase/trx/trx0rseg.cc +++ b/storage/innobase/trx/trx0rseg.cc @@ -90,12 +90,7 @@ trx_rseg_header_create( trx_rsegf_set_nth_undo(rsegf, i, FIL_NULL, mtr); } - if (!trx_sys_is_noredo_rseg_slot(rseg_slot_no)) { - /* Non-redo rseg are re-created on restart and so no need - to persist this information in sys-header. Anyway, on restart - this information is not valid too as there is no space with - persisted space-id on restart. */ - + if (space != SRV_TMP_SPACE_ID) { /* Add the rollback segment info to the free slot in the trx system header */ @@ -152,51 +147,48 @@ trx_rseg_mem_free(trx_rseg_t* rseg) ut_free(rseg); } -/** Creates and initializes a rollback segment object. -The values for the fields are read from the header. The object is inserted to -the rseg list of the trx system object and a pointer is inserted in the rseg -array in the trx system object. +/** Create a rollback segment object. @param[in] id rollback segment id @param[in] space space where the segment is placed -@param[in] page_no page number of the segment header -@param[in,out] mtr mini-transaction */ +@param[in] page_no page number of the segment header */ static -void -trx_rseg_mem_create( - ulint id, - ulint space, - ulint page_no, - mtr_t* mtr) +trx_rseg_t* +trx_rseg_mem_create(ulint id, ulint space, ulint page_no) { - ulint len; - trx_rseg_t* rseg; - fil_addr_t node_addr; - trx_rsegf_t* rseg_header; - trx_ulogf_t* undo_log_hdr; - ulint sum_of_undo_sizes; - - rseg = static_cast(ut_zalloc_nokey(sizeof(trx_rseg_t))); + trx_rseg_t* rseg = static_cast( + ut_zalloc_nokey(sizeof *rseg)); rseg->id = id; rseg->space = space; rseg->page_no = page_no; - rseg->trx_ref_count = 0; - rseg->skip_allocation = false; + rseg->last_page_no = FIL_NULL; - if (fsp_is_system_temporary(space)) { - mutex_create(LATCH_ID_NOREDO_RSEG, &rseg->mutex); - } else { - mutex_create(LATCH_ID_REDO_RSEG, &rseg->mutex); - } + mutex_create(rseg->is_persistent() + ? LATCH_ID_REDO_RSEG : LATCH_ID_NOREDO_RSEG, + &rseg->mutex); UT_LIST_INIT(rseg->update_undo_list, &trx_undo_t::undo_list); UT_LIST_INIT(rseg->update_undo_cached, &trx_undo_t::undo_list); UT_LIST_INIT(rseg->insert_undo_list, &trx_undo_t::undo_list); UT_LIST_INIT(rseg->insert_undo_cached, &trx_undo_t::undo_list); - trx_sys->rseg_array[id] = rseg; + return(rseg); +} + +/** Restore the state of a persistent rollback segment. +@param[in,out] rseg persistent rollback segment +@param[in,out] mtr mini-transaction */ +static +void +trx_rseg_mem_restore(trx_rseg_t* rseg, mtr_t* mtr) +{ + ulint len; + fil_addr_t node_addr; + trx_rsegf_t* rseg_header; + trx_ulogf_t* undo_log_hdr; + ulint sum_of_undo_sizes; - rseg_header = trx_rsegf_get_new(space, page_no, mtr); + rseg_header = trx_rsegf_get_new(rseg->space, rseg->page_no, mtr); rseg->max_size = mtr_read_ulint( rseg_header + TRX_RSEG_MAX_SIZE, MLOG_4BYTES, mtr); @@ -240,8 +232,6 @@ trx_rseg_mem_create( purge_sys->purge_queue.push(elem); } - } else { - rseg->last_page_no = FIL_NULL; } } @@ -252,54 +242,45 @@ trx_rseg_array_init() mtr_t mtr; for (ulint i = 0; i < TRX_SYS_N_RSEGS; i++) { - ut_ad(!trx_rseg_get_on_id(i)); mtr.start(); trx_sysf_t* sys_header = trx_sysf_get(&mtr); ulint page_no = trx_sysf_rseg_get_page_no( sys_header, i, &mtr); if (page_no != FIL_NULL) { - trx_rseg_mem_create( + trx_rseg_t* rseg = trx_rseg_mem_create( i, trx_sysf_rseg_get_space(sys_header, i, &mtr), - page_no, &mtr); + page_no); + ut_ad(rseg->is_persistent()); + ut_ad(!trx_sys->rseg_array[rseg->id]); + trx_sys->rseg_array[rseg->id] = rseg; + trx_rseg_mem_restore(rseg, &mtr); } mtr.commit(); } } -/********************************************************************* -Creates a rollback segment. -@return pointer to new rollback segment if create successful */ +/** Create a persistent rollback segment. +@param[in] space_id system or undo tablespace id */ trx_rseg_t* -trx_rseg_create( -/*============*/ - ulint space_id, /*!< in: id of UNDO tablespace */ - ulint nth_free_slot) /*!< in: allocate nth free slot. - 0 means next free slots. */ +trx_rseg_create(ulint space_id) { - mtr_t mtr; + trx_rseg_t* rseg = NULL; + mtr_t mtr; mtr.start(); /* To obey the latching order, acquire the file space x-latch before the trx_sys->mutex. */ - const fil_space_t* space = mtr_x_lock_space(space_id, &mtr); +#ifdef UNIV_DEBUG + const fil_space_t* space = +#endif /* UNIV_DEBUG */ + mtr_x_lock_space(space_id, &mtr); + ut_ad(space->purpose == FIL_TYPE_TABLESPACE); - switch (space->purpose) { - case FIL_TYPE_LOG: - case FIL_TYPE_IMPORT: - ut_ad(0); - case FIL_TYPE_TEMPORARY: - mtr.set_log_mode(MTR_LOG_NO_REDO); - break; - case FIL_TYPE_TABLESPACE: - break; - } - - ulint slot_no = trx_sysf_rseg_find_free( - &mtr, space->purpose == FIL_TYPE_TEMPORARY, nth_free_slot); + ulint slot_no = trx_sysf_rseg_find_free(&mtr); ulint page_no = slot_no == ULINT_UNDEFINED ? FIL_NULL : trx_rseg_header_create(space_id, ULINT_MAX, slot_no, &mtr); @@ -309,14 +290,45 @@ trx_rseg_create( ulint id = trx_sysf_rseg_get_space( sys_header, slot_no, &mtr); - ut_a(id == space_id || trx_sys_is_noredo_rseg_slot(slot_no)); + ut_a(id == space_id); - trx_rseg_mem_create(slot_no, space_id, page_no, &mtr); + rseg = trx_rseg_mem_create(slot_no, space_id, page_no); + ut_ad(rseg->is_persistent()); + ut_ad(!trx_sys->rseg_array[rseg->id]); + trx_sys->rseg_array[rseg->id] = rseg; + trx_rseg_mem_restore(rseg, &mtr); } mtr.commit(); - return(page_no == FIL_NULL ? NULL : trx_sys->rseg_array[slot_no]); + return(rseg); +} + +/** Create the temporary rollback segments. */ +void +trx_temp_rseg_create() +{ + mtr_t mtr; + + for (ulong i = 0; i < TRX_SYS_N_RSEGS; i++) { + mtr.start(); + mtr.set_log_mode(MTR_LOG_NO_REDO); +#ifdef UNIV_DEBUG + const fil_space_t* space = +#endif /* UNIV_DEBUG */ + mtr_x_lock_space(SRV_TMP_SPACE_ID, &mtr); + ut_ad(space->purpose == FIL_TYPE_TEMPORARY); + + ulint page_no = trx_rseg_header_create( + SRV_TMP_SPACE_ID, ULINT_MAX, i, &mtr); + trx_rseg_t* rseg = trx_rseg_mem_create( + i, SRV_TMP_SPACE_ID, page_no); + ut_ad(!rseg->is_persistent()); + ut_ad(!trx_sys->temp_rsegs[i]); + trx_sys->temp_rsegs[i] = rseg; + trx_rseg_mem_restore(rseg, &mtr); + mtr.commit(); + } } /******************************************************************** diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc index f08736ae1f128..24983dcc2a3bc 100644 --- a/storage/innobase/trx/trx0sys.cc +++ b/storage/innobase/trx/trx0sys.cc @@ -394,76 +394,41 @@ trx_sys_read_wsrep_checkpoint( #endif /* WITH_WSREP */ -/****************************************************************//** -Looks for a free slot for a rollback segment in the trx system file copy. -@return slot index or ULINT_UNDEFINED if not found */ +/** @return an unallocated rollback segment slot in the TRX_SYS header +@retval ULINT_UNDEFINED if not found */ ulint -trx_sysf_rseg_find_free( -/*====================*/ - mtr_t* mtr, /*!< in/out: mtr */ - bool include_tmp_slots, /*!< in: if true, report slots reserved - for temp-tablespace as free slots. */ - ulint nth_free_slots) /*!< in: allocate nth free slot. - 0 means next free slot. */ +trx_sysf_rseg_find_free(mtr_t* mtr) { - ulint i; - trx_sysf_t* sys_header; - - sys_header = trx_sysf_get(mtr); - - ulint found_free_slots = 0; - for (i = 0; i < TRX_SYS_N_RSEGS; i++) { - ulint page_no; - - if (!include_tmp_slots && trx_sys_is_noredo_rseg_slot(i)) { - continue; - } - - page_no = trx_sysf_rseg_get_page_no(sys_header, i, mtr); + trx_sysf_t* sys_header = trx_sysf_get(mtr); - if (page_no == FIL_NULL - || (include_tmp_slots - && trx_sys_is_noredo_rseg_slot(i))) { - - if (found_free_slots++ >= nth_free_slots) { - return(i); - } + for (ulint i = 0; i < TRX_SYS_N_RSEGS; i++) { + if (trx_sysf_rseg_get_page_no(sys_header, i, mtr) + == FIL_NULL) { + return(i); } } return(ULINT_UNDEFINED); } -/****************************************************************//** -Looks for used slots for redo rollback segment. -@return number of used slots */ +/** Count the number of initialized persistent rollback segment slots. */ static -ulint -trx_sysf_used_slots_for_redo_rseg( -/*==============================*/ - mtr_t* mtr) /*!< in: mtr */ +void +trx_sysf_get_n_rseg_slots() { - trx_sysf_t* sys_header; - ulint n_used = 0; + mtr_t mtr; + mtr.start(); - sys_header = trx_sysf_get(mtr); + trx_sysf_t* sys_header = trx_sysf_get(&mtr); + srv_available_undo_logs = 0; for (ulint i = 0; i < TRX_SYS_N_RSEGS; i++) { - - if (trx_sys_is_noredo_rseg_slot(i)) { - continue; - } - - ulint page_no; - - page_no = trx_sysf_rseg_get_page_no(sys_header, i, mtr); - - if (page_no != FIL_NULL) { - ++n_used; - } + srv_available_undo_logs + += trx_sysf_rseg_get_page_no(sys_header, i, &mtr) + != FIL_NULL; } - return(n_used); + mtr.commit(); } /*****************************************************************//** @@ -532,7 +497,7 @@ trx_sysf_create( + page - sys_header, mtr); /* Create the first rollback segment in the SYSTEM tablespace */ - slot_no = trx_sysf_rseg_find_free(mtr, false, 0); + slot_no = trx_sysf_rseg_find_free(mtr); page_no = trx_rseg_header_create(TRX_SYS_SPACE, ULINT_MAX, slot_no, mtr); @@ -904,118 +869,69 @@ trx_sys_file_format_close(void) mutex_free(&file_format_max.mutex); } -/********************************************************************* -Creates non-redo rollback segments. -@return number of non-redo rollback segments created. */ -static -ulint -trx_sys_create_noredo_rsegs( -/*========================*/ - ulint n_nonredo_rseg) /*!< number of non-redo rollback segment - to create. */ -{ - ulint n_created = 0; - - /* Create non-redo rollback segments residing in temp-tablespace. - non-redo rollback segments don't perform redo logging and so - are used for undo logging of objects/table that don't need to be - recover on crash. - (Non-Redo rollback segments are created on every server startup). - Slot-0: reserved for system-tablespace. - Slot-1....Slot-N: reserved for temp-tablespace. - Slot-N+1....Slot-127: reserved for system/undo-tablespace. */ - for (ulint i = 0; i < n_nonredo_rseg; i++) { - if (trx_rseg_create(SRV_TMP_SPACE_ID, i) == NULL) { - break; - } - ++n_created; - } - - return(n_created); -} - -/********************************************************************* -Creates the rollback segments. -@return number of rollback segments that are active. */ -ulint -trx_sys_create_rsegs( -/*=================*/ - ulint n_spaces, /*!< number of tablespaces for UNDO logs */ - ulint n_rsegs, /*!< number of rollback segments to create */ - ulint n_tmp_rsegs) /*!< number of rollback segments reserved for - temp-tables. */ +/** Create the rollback segments. +@return whether the creation succeeded */ +bool +trx_sys_create_rsegs() { - mtr_t mtr; - ulint n_used; - ulint n_noredo_created; + /* srv_available_undo_logs reflects the number of persistent + rollback segments that have been initialized in the + transaction system header page. - ut_a(n_spaces < TRX_SYS_N_RSEGS); - ut_a(n_rsegs <= TRX_SYS_N_RSEGS); - ut_a(n_tmp_rsegs > 0 && n_tmp_rsegs < TRX_SYS_N_RSEGS); + srv_undo_logs determines how many of the + srv_available_undo_logs rollback segments may be used for + logging new transactions. */ + ut_ad(srv_undo_tablespaces < TRX_SYS_N_RSEGS); + ut_ad(srv_undo_logs <= TRX_SYS_N_RSEGS); if (srv_read_only_mode) { - return(ULINT_UNDEFINED); + srv_undo_logs = srv_available_undo_logs = ULONG_UNDEFINED; + return(true); } - /* Create non-redo rollback segments. */ - n_noredo_created = trx_sys_create_noredo_rsegs(n_tmp_rsegs); + /* Create temporary rollback segments. */ + trx_temp_rseg_create(); /* This is executed in single-threaded mode therefore it is not necessary to use the same mtr in trx_rseg_create(). n_used cannot change while the function is executing. */ - mtr_start(&mtr); - n_used = trx_sysf_used_slots_for_redo_rseg(&mtr) + n_noredo_created; - mtr_commit(&mtr); + trx_sysf_get_n_rseg_slots(); - ut_ad(n_used <= TRX_SYS_N_RSEGS); + ut_ad(srv_available_undo_logs <= TRX_SYS_N_RSEGS); - /* By default 1 redo rseg is always active that is hosted in - system tablespace. */ - ulint n_redo_active; - if (n_rsegs <= n_tmp_rsegs) { - n_redo_active = 1; - } else if (n_rsegs > n_used) { - n_redo_active = n_used - n_tmp_rsegs; - } else { - n_redo_active = n_rsegs - n_tmp_rsegs; - } - - /* Do not create additional rollback segments if innodb_force_recovery - has been set and the database was not shutdown cleanly. */ - if (!srv_force_recovery && !recv_needed_recovery && n_used < n_rsegs) { - ulint i; - ulint new_rsegs = n_rsegs - n_used; - - for (i = 0; i < new_rsegs; ++i) { - ulint space; - - /* Tablespace 0 is the system tablespace. All UNDO - log tablespaces start from 1. */ + /* The first persistent rollback segment is always initialized + in the system tablespace. */ + ut_a(srv_available_undo_logs > 0); - if (n_spaces > 0) { - space = (i % n_spaces) + 1; - } else { - space = 0; /* System tablespace */ - } - - if (trx_rseg_create(space, 0) != NULL) { - ++n_used; - ++n_redo_active; - } else { - break; + if (srv_force_recovery) { + /* Do not create additional rollback segments if + innodb_force_recovery has been set. */ + if (srv_undo_logs > srv_available_undo_logs) { + srv_undo_logs = srv_available_undo_logs; + } + } else { + for (ulint i = 0; srv_available_undo_logs < srv_undo_logs; + i++, srv_available_undo_logs++) { + /* Tablespace 0 is the system tablespace. + Dedicated undo log tablespaces start from 1. */ + ulint space = srv_undo_tablespaces > 0 + ? (i % srv_undo_tablespaces) + 1 + : TRX_SYS_SPACE; + + if (!trx_rseg_create(space)) { + ib::error() << "Unable to allocate the" + " requested innodb_undo_logs"; + return(false); } } } - ib::info() << n_used - srv_tmp_undo_logs - << " redo rollback segment(s) found. " - << n_redo_active - << " redo rollback segment(s) are active."; + ut_ad(srv_undo_logs <= srv_available_undo_logs); - ib::info() << n_noredo_created << " non-redo rollback segment(s) are" - " active."; + ib::info() << srv_undo_logs << " out of " << srv_available_undo_logs + << " rollback segments are active."; - return(n_used); + return(true); } /********************************************************************* @@ -1027,9 +943,7 @@ trx_sys_close(void) ut_ad(trx_sys != NULL); ut_ad(srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS); - ulint size = trx_sys->mvcc->size(); - - if (size > 0) { + if (ulint size = trx_sys->mvcc->size()) { ib::error() << "All read views were not closed before" " shutdown: " << size << " read views open"; } @@ -1060,6 +974,10 @@ trx_sys_close(void) if (trx_rseg_t* rseg = trx_sys->rseg_array[i]) { trx_rseg_mem_free(rseg); } + + if (trx_rseg_t* rseg = trx_sys->temp_rsegs[i]) { + trx_rseg_mem_free(rseg); + } } UT_DELETE(trx_sys->mvcc); diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index b687f8e899020..db09f7894a71e 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -1090,42 +1090,33 @@ trx_lists_init_at_db_start() } } -/******************************************************************//** -Get next redo rollback segment. (Segment are assigned in round-robin fashion). -@return assigned rollback segment instance */ +/** Assign a persistent rollback segment in a round-robin fashion, +evenly distributed between 0 and innodb_undo_logs-1 +@return persistent rollback segment +@retval NULL if innodb_read_only */ static trx_rseg_t* -get_next_redo_rseg( -/*===============*/ - ulong max_undo_logs, /*!< in: maximum number of UNDO logs to use */ - ulint n_tablespaces) /*!< in: number of rollback tablespaces */ +trx_assign_rseg_low() { - trx_rseg_t* rseg; - static ulint redo_rseg_slot = 0; - ulint slot = 0; - - slot = redo_rseg_slot++; - slot = slot % max_undo_logs; - - /* Skip slots alloted to non-redo also ensure even distribution - in selecting next redo slots. - For example: If we don't do even distribution then for any value of - slot between 1 - 32 ... 33rd slots will be alloted creating - skewed distribution. */ - if (trx_sys_is_noredo_rseg_slot(slot)) { - - if (max_undo_logs > srv_tmp_undo_logs) { + if (srv_read_only_mode) { + ut_ad(srv_undo_logs == ULONG_UNDEFINED); + return(NULL); + } - slot %= (max_undo_logs - srv_tmp_undo_logs); + /* The first slot is always assigned to the system tablespace. */ + ut_ad(trx_sys->rseg_array[0]->space == TRX_SYS_SPACE); - if (trx_sys_is_noredo_rseg_slot(slot)) { - slot += srv_tmp_undo_logs; - } + /* Choose a rollback segment evenly distributed between 0 and + innodb_undo_logs-1 in a round-robin fashion, skipping those + undo tablespaces that are scheduled for truncation. - } else { - slot = 0; - } - } + Because rseg_slot is not protected by atomics or any mutex, race + conditions are possible, meaning that multiple transactions + that start modifications concurrently will write their undo + log to the same rollback segment. */ + static ulong rseg_slot; + ulint slot = rseg_slot++ % srv_undo_logs; + trx_rseg_t* rseg; #ifdef UNIV_DEBUG ulint start_scan_slot = slot; @@ -1134,8 +1125,7 @@ get_next_redo_rseg( bool allocated = false; - while (!allocated) { - + do { for (;;) { rseg = trx_sys->rseg_array[slot]; @@ -1148,37 +1138,31 @@ get_next_redo_rseg( look_for_rollover = true; #endif /* UNIV_DEBUG */ - slot = (slot + 1) % max_undo_logs; - - /* Skip slots allocated for noredo rsegs */ - while (trx_sys_is_noredo_rseg_slot(slot)) { - slot = (slot + 1) % max_undo_logs; - } + slot = (slot + 1) % srv_undo_logs; if (rseg == NULL) { continue; - } else if (rseg->space == srv_sys_space.space_id() - && n_tablespaces > 0 - && trx_sys->rseg_array[slot] != NULL - && trx_sys->rseg_array[slot]->space - != srv_sys_space.space_id()) { - /** If undo-tablespace is configured, skip - rseg from system-tablespace and try to use - undo-tablespace rseg unless it is not possible - due to lower limit of undo-logs. */ - continue; - } else if (rseg->skip_allocation) { - /** This rseg resides in the tablespace that - has been marked for truncate so avoid using this - rseg. Also, this is possible only if there are - at-least 2 UNDO tablespaces active and 2 redo - rsegs active (other than default system bound - rseg-0). */ - ut_ad(n_tablespaces > 1); - ut_ad(max_undo_logs - >= (1 + srv_tmp_undo_logs + 2)); - continue; } + + ut_ad(rseg->is_persistent()); + + if (rseg->space != TRX_SYS_SPACE) { + ut_ad(srv_undo_tablespaces > 1); + if (rseg->skip_allocation) { + continue; + } + } else if (trx_rseg_t* next + = trx_sys->rseg_array[slot]) { + if (next->space != TRX_SYS_SPACE + && srv_undo_tablespaces > 0) { + /** If dedicated + innodb_undo_tablespaces have + been configured, try to use them + instead of the system tablespace. */ + continue; + } + } + break; } @@ -1191,129 +1175,43 @@ get_next_redo_rseg( allocated = true; } mutex_exit(&rseg->mutex); - } + } while (!allocated); ut_ad(rseg->trx_ref_count > 0); - ut_ad(!trx_sys_is_noredo_rseg_slot(rseg->id)); - return(rseg); -} - -/******************************************************************//** -Get next noredo rollback segment. -@return assigned rollback segment instance */ -static -trx_rseg_t* -get_next_noredo_rseg( -/*=================*/ - ulong max_undo_logs) /*!< in: maximum number of UNDO logs to use */ -{ - trx_rseg_t* rseg; - static ulint noredo_rseg_slot = 1; - ulint slot = 0; - - slot = noredo_rseg_slot++; - slot = slot % max_undo_logs; - while (!trx_sys_is_noredo_rseg_slot(slot)) { - slot = (slot + 1) % max_undo_logs; - } - - for (;;) { - rseg = trx_sys->rseg_array[slot]; - - slot = (slot + 1) % max_undo_logs; - - while (!trx_sys_is_noredo_rseg_slot(slot)) { - slot = (slot + 1) % max_undo_logs; - } - - if (rseg != NULL) { - break; - } - } - - ut_ad(fsp_is_system_temporary(rseg->space)); - ut_ad(trx_sys_is_noredo_rseg_slot(rseg->id)); + ut_ad(rseg->is_persistent()); return(rseg); } -/******************************************************************//** -Assigns a rollback segment to a transaction in a round-robin fashion. -@return assigned rollback segment instance */ -static +/** Assign a rollback segment for modifying temporary tables. +@return the assigned rollback segment */ trx_rseg_t* -trx_assign_rseg_low( -/*================*/ - ulong max_undo_logs, /*!< in: maximum number of UNDO logs - to use */ - ulint n_tablespaces, /*!< in: number of rollback - tablespaces */ - trx_rseg_type_t rseg_type) /*!< in: type of rseg to assign. */ -{ - if (srv_read_only_mode) { - ut_a(max_undo_logs == ULONG_UNDEFINED); - return(NULL); - } - - /* This breaks true round robin but that should be OK. */ - ut_ad(max_undo_logs > 0 && max_undo_logs <= TRX_SYS_N_RSEGS); - - /* Note: The assumption here is that there can't be any gaps in - the array. Once we implement more flexible rollback segment - management this may not hold. The assertion checks for that case. */ - ut_ad(trx_sys->rseg_array[0] != NULL); - ut_ad(rseg_type == TRX_RSEG_TYPE_REDO - || trx_sys->rseg_array[1] != NULL); - - /* Slot-0 is always assigned to system-tablespace rseg. */ - ut_ad(trx_sys->rseg_array[0]->space == srv_sys_space.space_id()); - - /* Slot-1 is always assigned to temp-tablespace rseg. */ - ut_ad(rseg_type == TRX_RSEG_TYPE_REDO - || fsp_is_system_temporary(trx_sys->rseg_array[1]->space)); - - trx_rseg_t* rseg = 0; - - switch (rseg_type) { - case TRX_RSEG_TYPE_NONE: - ut_error; - - case TRX_RSEG_TYPE_REDO: - rseg = get_next_redo_rseg(max_undo_logs, n_tablespaces); - break; - - case TRX_RSEG_TYPE_NOREDO: - rseg = get_next_noredo_rseg(srv_tmp_undo_logs + 1); - break; - } - - return(rseg); -} - -/****************************************************************//** -Assign a transaction temp-tablespace bounded rollback-segment. */ -void -trx_assign_rseg( -/*============*/ - trx_t* trx) /*!< transaction that involves write - to temp-table. */ -{ - ut_a(trx->rsegs.m_noredo.rseg == 0); - ut_a(!trx_is_autocommit_non_locking(trx)); - - trx->rsegs.m_noredo.rseg = trx_assign_rseg_low( - srv_undo_logs, srv_undo_tablespaces, TRX_RSEG_TYPE_NOREDO); - - if (trx->id == 0) { +trx_t::assign_temp_rseg() +{ + ut_ad(!rsegs.m_noredo.rseg); + ut_ad(!trx_is_autocommit_non_locking(this)); + compile_time_assert(ut_is_2pow(TRX_SYS_N_RSEGS)); + + /* Choose a temporary rollback segment between 0 and 127 + in a round-robin fashion. Because rseg_slot is not protected by + atomics or any mutex, race conditions are possible, meaning that + multiple transactions that start modifications concurrently + will write their undo log to the same rollback segment. */ + static ulong rseg_slot; + trx_rseg_t* rseg = trx_sys->temp_rsegs[ + rseg_slot++ & (TRX_SYS_N_RSEGS - 1)]; + ut_ad(!rseg->is_persistent()); + rsegs.m_noredo.rseg = rseg; + + if (id == 0) { mutex_enter(&trx_sys->mutex); - - trx->id = trx_sys_get_new_trx_id(); - - trx_sys->rw_trx_ids.push_back(trx->id); - - trx_sys->rw_trx_set.insert(TrxTrack(trx->id, trx)); - + id = trx_sys_get_new_trx_id(); + trx_sys->rw_trx_ids.push_back(id); + trx_sys->rw_trx_set.insert(TrxTrack(id, this)); mutex_exit(&trx_sys->mutex); } + + ut_ad(!rseg->is_persistent()); + return(rseg); } /****************************************************************//** @@ -1388,9 +1286,7 @@ trx_start_low( if (!trx->read_only && (trx->mysql_thd == 0 || read_write || trx->ddl)) { - trx->rsegs.m_redo.rseg = trx_assign_rseg_low( - srv_undo_logs, srv_undo_tablespaces, - TRX_RSEG_TYPE_REDO); + trx->rsegs.m_redo.rseg = trx_assign_rseg_low(); /* Temporary rseg is assigned only if the transaction updates a temporary table */ @@ -2969,8 +2865,6 @@ trx_start_if_not_started_xa_low( trx_sys_t::rw_trx_list. */ if (!trx->read_only) { trx_set_rw_mode(trx); - } else if (!srv_read_only_mode) { - trx_assign_rseg(trx); } } return; @@ -3116,8 +3010,7 @@ trx_set_rw_mode( that both threads are synced by acquring trx->mutex to avoid decision based on in-consistent view formed during promotion. */ - trx->rsegs.m_redo.rseg = trx_assign_rseg_low( - srv_undo_logs, srv_undo_tablespaces, TRX_RSEG_TYPE_REDO); + trx->rsegs.m_redo.rseg = trx_assign_rseg_low(); ut_ad(trx->rsegs.m_redo.rseg != 0); diff --git a/storage/innobase/trx/trx0undo.cc b/storage/innobase/trx/trx0undo.cc index 92e18c1c37202..3eab3733f8fdf 100644 --- a/storage/innobase/trx/trx0undo.cc +++ b/storage/innobase/trx/trx0undo.cc @@ -1027,7 +1027,7 @@ void trx_undo_truncate_end(trx_undo_t* undo, undo_no_t limit, bool is_temp) { ut_ad(mutex_own(&undo->rseg->mutex)); - ut_ad(is_temp == trx_sys_is_noredo_rseg_slot(undo->rseg->id)); + ut_ad(is_temp == !undo->rseg->is_persistent()); for (;;) { mtr_t mtr; @@ -1102,7 +1102,7 @@ trx_undo_truncate_start( loop: mtr_start(&mtr); - if (trx_sys_is_noredo_rseg_slot(rseg->id)) { + if (!rseg->is_persistent()) { mtr.set_log_mode(MTR_LOG_NO_REDO); } @@ -1856,7 +1856,7 @@ void trx_undo_commit_cleanup(trx_undo_t* undo, bool is_temp) { trx_rseg_t* rseg = undo->rseg; - ut_ad(is_temp == trx_sys_is_noredo_rseg_slot(rseg->id)); + ut_ad(is_temp == !rseg->is_persistent()); mutex_enter(&rseg->mutex); From 6315426565590982b096344df61cae4b64ab2eb0 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 31 Mar 2017 19:56:15 +0200 Subject: [PATCH 4/9] restore libmariadb state that was destroyed in a previous commit --- libmariadb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmariadb b/libmariadb index cae391f7bf47f..be34e12ba0f9a 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit cae391f7bf47f17fb246cded8ddf0ef19dbfbdec +Subproject commit be34e12ba0f9a23074be5051259db954b3a302d9 From 22d8bb27066fa841548d57b6d110162093be535a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 1 Apr 2017 15:58:29 +0200 Subject: [PATCH 5/9] MDEV-12421 Check constraint with query crashes server and renders DB unusable parse CHECK constraint *before* Column_definition validity checks --- mysql-test/r/check_constraint.result | 4 ++++ mysql-test/t/check_constraint.test | 8 ++++++++ sql/sql_yacc.yy | 8 +++++--- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/check_constraint.result b/mysql-test/r/check_constraint.result index 1743bb9704716..7447550ed0937 100644 --- a/mysql-test/r/check_constraint.result +++ b/mysql-test/r/check_constraint.result @@ -140,3 +140,7 @@ create table t1 (a int, b int, check(a>0)); alter table t1 drop column a; ERROR 42S22: Unknown column 'a' in 'CHECK' drop table t1; +create table t1 (a int check (@b in (select user from mysql.user))); +ERROR HY000: Function or expression 'select ...' cannot be used in the CHECK clause of `a` +create table t1 (a int check (a > @b)); +ERROR HY000: Function or expression '@b' cannot be used in the CHECK clause of `a` diff --git a/mysql-test/t/check_constraint.test b/mysql-test/t/check_constraint.test index 7c5d30b6cd328..437463ee45736 100644 --- a/mysql-test/t/check_constraint.test +++ b/mysql-test/t/check_constraint.test @@ -86,3 +86,11 @@ create table t1 (a int, b int, check(a>0)); --error ER_BAD_FIELD_ERROR alter table t1 drop column a; drop table t1; + +# +# MDEV-12421 Check constraint with query crashes server and renders DB unusable +# +--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int check (@b in (select user from mysql.user))); +--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a int check (a > @b)); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 412fcce862559..fdb40407ffb89 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -6013,8 +6013,8 @@ field_list_item: ; column_def: - field_spec opt_check_constraint - { $$= $1; $$->check_constraint= $2; } + field_spec + { $$= $1; } | field_spec references { $$= $1; } ; @@ -6152,11 +6152,13 @@ field_spec: lex->init_last_field(f, $1.str, NULL); $$= f; } - field_type_or_serial + field_type_or_serial opt_check_constraint { LEX *lex=Lex; $$= $2; + $$->check_constraint= $4; + if ($$->check(thd)) MYSQL_YYABORT; From e68f7402c5b918d8143c2b67dfe6db3eb184d8be Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 1 Apr 2017 15:59:45 +0200 Subject: [PATCH 6/9] Avoid TARGET_LINK_LIBRARIES() for plugins as a plugin can be disabled, so the target doesn't necessarily exist --- plugin/aws_key_management/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugin/aws_key_management/CMakeLists.txt b/plugin/aws_key_management/CMakeLists.txt index 9e012b646966c..d83c483018333 100644 --- a/plugin/aws_key_management/CMakeLists.txt +++ b/plugin/aws_key_management/CMakeLists.txt @@ -137,8 +137,8 @@ ELSE() INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/aws_sdk_cpp/include) ENDIF() -MYSQL_ADD_PLUGIN(aws_key_management aws_key_management_plugin.cc - COMPONENT aws-key-management) ADD_DEFINITIONS(${SSL_DEFINES}) # Need to know whether openssl should be initialized SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX11_FLAGS}") -TARGET_LINK_LIBRARIES(aws_key_management ${AWS_SDK_LIBS}) +MYSQL_ADD_PLUGIN(aws_key_management aws_key_management_plugin.cc + LINK_LIBRARIES ${AWS_SDK_LIBS} + COMPONENT aws-key-management) From 190591968ec3f38a2c33fc15e9b157f3dc8e3209 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 1 Apr 2017 18:54:15 +0200 Subject: [PATCH 7/9] vcol.wrong_arena fails in fulltest vcols in the table definition are intentionaly bad and produce warnings when a table is opened. In some cases (depending on the TDC/TC state as left by earlier tests) a table might be opened in the middle of the test, resulting in spurious warnings. Suppress them. Also, don't run main.mdev-504 for ps-protocol at all (instead of disabling ps-protocol inside the test, but still running the test) --- mysql-test/suite/vcol/r/wrong_arena.result | 6 ------ mysql-test/suite/vcol/t/wrong_arena.test | 4 ++++ mysql-test/t/mdev-504.test | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/mysql-test/suite/vcol/r/wrong_arena.result b/mysql-test/suite/vcol/r/wrong_arena.result index 8a07c828288bf..e86026852e4b1 100644 --- a/mysql-test/suite/vcol/r/wrong_arena.result +++ b/mysql-test/suite/vcol/r/wrong_arena.result @@ -40,12 +40,6 @@ connection default; select * from t1; a b c d e 2010-10-10 10:10:10 1 0 0 NULL -Warnings: -Warning 1292 Incorrect datetime value: '1' -Warning 1292 Incorrect datetime value: '2' -Warning 1292 Incorrect datetime value: '1' -Warning 1292 Incorrect datetime value: '1' -Warning 1292 Incorrect datetime value: '2' drop table t1; connect con1, localhost, root; create table t1 (a datetime, diff --git a/mysql-test/suite/vcol/t/wrong_arena.test b/mysql-test/suite/vcol/t/wrong_arena.test index 484f1fe685df6..340634422ae65 100644 --- a/mysql-test/suite/vcol/t/wrong_arena.test +++ b/mysql-test/suite/vcol/t/wrong_arena.test @@ -16,11 +16,15 @@ create table t1 (a datetime, ); show create table t1; connect con1, localhost, root; +disable_warnings; insert t1 (a) values ('2010-10-10 10:10:10'); +enable_warnings; select * from t1; disconnect con1; connection default; +disable_warnings; select * from t1; +enable_warnings; drop table t1; connect con1, localhost, root; diff --git a/mysql-test/t/mdev-504.test b/mysql-test/t/mdev-504.test index 76232927cd98d..551c21c37d015 100644 --- a/mysql-test/t/mdev-504.test +++ b/mysql-test/t/mdev-504.test @@ -1,5 +1,5 @@ --source include/not_valgrind.inc ---disable_ps_protocol +--source include/no_protocol.inc SET GLOBAL net_write_timeout = 900; From 238c6700dd52c00e99a24126379b85657d3e3442 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 1 Apr 2017 18:55:42 +0200 Subject: [PATCH 8/9] include C/C fix for binding of int values to string variables fixes many test failures in optimized builds in --ps-protocol --- libmariadb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmariadb b/libmariadb index be34e12ba0f9a..d1387356292fb 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit be34e12ba0f9a23074be5051259db954b3a302d9 +Subproject commit d1387356292fb840c7736aeb8f449310c3139087 From c07bb700c897ee36d97a6c694582c69959bbcaef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 29 Mar 2017 08:08:50 +0300 Subject: [PATCH 9/9] MDEV-11629: Unknown table 'innodb_cmp_per_index_reset' in information_schema. Added .opt file to enable running this test as a part of innodb_zip suite and recorded current correct results. --- mysql-test/suite/innodb_zip/disabled.def | 2 +- .../suite/innodb_zip/r/cmp_per_index.result | 17 +++++++++++------ mysql-test/suite/innodb_zip/t/cmp_per_index.opt | 2 ++ 3 files changed, 14 insertions(+), 7 deletions(-) create mode 100644 mysql-test/suite/innodb_zip/t/cmp_per_index.opt diff --git a/mysql-test/suite/innodb_zip/disabled.def b/mysql-test/suite/innodb_zip/disabled.def index 294204f409c4f..8b137891791fe 100644 --- a/mysql-test/suite/innodb_zip/disabled.def +++ b/mysql-test/suite/innodb_zip/disabled.def @@ -1 +1 @@ -cmp_per_index: MDEV-11629 + diff --git a/mysql-test/suite/innodb_zip/r/cmp_per_index.result b/mysql-test/suite/innodb_zip/r/cmp_per_index.result index 5b899e9ff7105..b380071c623aa 100644 --- a/mysql-test/suite/innodb_zip/r/cmp_per_index.result +++ b/mysql-test/suite/innodb_zip/r/cmp_per_index.result @@ -39,13 +39,13 @@ BEGIN; COMMIT; ALTER TABLE t DROP INDEX c; GRANT USAGE ON *.* TO 'tuser01'@'localhost' IDENTIFIED BY 'cDJvI9s_Uq'; -Warnings: -Level Warning -Code 1287 -Message Using GRANT for creating new user is deprecated and will be removed in future release. Create new user with CREATE USER statement. FLUSH PRIVILEGES; +connect con1,localhost,tuser01,cDJvI9s_Uq,; +connection con1; SELECT * FROM information_schema.innodb_cmp_per_index; ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation +connection default; +disconnect con1; DROP USER 'tuser01'@'localhost'; SELECT database_name, @@ -70,7 +70,6 @@ index_name PRIMARY compress_ops 65 compress_ops_ok 65 uncompress_ops 0 -# restart SET GLOBAL innodb_cmp_per_index_enabled=ON; SELECT COUNT(*) FROM t; COUNT(*) 128 @@ -86,9 +85,15 @@ FROM information_schema.innodb_cmp_per_index ORDER BY 1, 2, 3; database_name test table_name t +index_name b +compress_ops 0 +compress_ops_ok 0 +uncompress_ops 6 +database_name test +table_name t index_name PRIMARY compress_ops 0 compress_ops_ok 0 -uncompress_ops 9 +uncompress_ops 5 DROP TABLE t; SET GLOBAL innodb_cmp_per_index_enabled=default; diff --git a/mysql-test/suite/innodb_zip/t/cmp_per_index.opt b/mysql-test/suite/innodb_zip/t/cmp_per_index.opt new file mode 100644 index 0000000000000..a031a64fc6ca8 --- /dev/null +++ b/mysql-test/suite/innodb_zip/t/cmp_per_index.opt @@ -0,0 +1,2 @@ +--innodb_log_compressed_pages=on +--innodb_cmp_per_index_reset