|  |  | @ -564,6 +564,108 @@ innodb_stopword_table_validate( | 
			
		
	
		
			
				
					|  |  |  | 						for update function */ | 
			
		
	
		
			
				
					|  |  |  | 	struct st_mysql_value*		value);	/*!< in: incoming string */ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | /** Validate passed-in "value" is a valid directory name.
 | 
			
		
	
		
			
				
					|  |  |  | This function is registered as a callback with MySQL. | 
			
		
	
		
			
				
					|  |  |  | @param[in,out]	thd	thread handle | 
			
		
	
		
			
				
					|  |  |  | @param[in]	var	pointer to system variable | 
			
		
	
		
			
				
					|  |  |  | @param[out]	save	immediate result for update | 
			
		
	
		
			
				
					|  |  |  | @param[in]	value	incoming string | 
			
		
	
		
			
				
					|  |  |  | @return 0 for valid name */ | 
			
		
	
		
			
				
					|  |  |  | static | 
			
		
	
		
			
				
					|  |  |  | int | 
			
		
	
		
			
				
					|  |  |  | innodb_tmpdir_validate( | 
			
		
	
		
			
				
					|  |  |  | 	THD*				thd, | 
			
		
	
		
			
				
					|  |  |  | 	struct st_mysql_sys_var*	var, | 
			
		
	
		
			
				
					|  |  |  | 	void*				save, | 
			
		
	
		
			
				
					|  |  |  | 	struct st_mysql_value*		value) | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	char*	alter_tmp_dir; | 
			
		
	
		
			
				
					|  |  |  | 	char*	innodb_tmp_dir; | 
			
		
	
		
			
				
					|  |  |  | 	char	buff[OS_FILE_MAX_PATH]; | 
			
		
	
		
			
				
					|  |  |  | 	int	len = sizeof(buff); | 
			
		
	
		
			
				
					|  |  |  | 	char	tmp_abs_path[FN_REFLEN + 2]; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	ut_ad(save != NULL); | 
			
		
	
		
			
				
					|  |  |  | 	ut_ad(value != NULL); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	if (check_global_access(thd, FILE_ACL)) { | 
			
		
	
		
			
				
					|  |  |  | 		push_warning_printf( | 
			
		
	
		
			
				
					|  |  |  | 			thd, Sql_condition::WARN_LEVEL_WARN, | 
			
		
	
		
			
				
					|  |  |  | 			ER_WRONG_ARGUMENTS, | 
			
		
	
		
			
				
					|  |  |  | 			"InnoDB: FILE Permissions required"); | 
			
		
	
		
			
				
					|  |  |  | 		*static_cast<const char**>(save) = NULL; | 
			
		
	
		
			
				
					|  |  |  | 		return(1); | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	alter_tmp_dir = (char*) value->val_str(value, buff, &len); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	if (!alter_tmp_dir) { | 
			
		
	
		
			
				
					|  |  |  | 		*static_cast<const char**>(save) = alter_tmp_dir; | 
			
		
	
		
			
				
					|  |  |  | 		return(0); | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	if (strlen(alter_tmp_dir) > FN_REFLEN) { | 
			
		
	
		
			
				
					|  |  |  | 		push_warning_printf( | 
			
		
	
		
			
				
					|  |  |  | 			thd, Sql_condition::WARN_LEVEL_WARN, | 
			
		
	
		
			
				
					|  |  |  | 			ER_WRONG_ARGUMENTS, | 
			
		
	
		
			
				
					|  |  |  | 			"Path length should not exceed %d bytes", FN_REFLEN); | 
			
		
	
		
			
				
					|  |  |  | 		*static_cast<const char**>(save) = NULL; | 
			
		
	
		
			
				
					|  |  |  | 		return(1); | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	my_realpath(tmp_abs_path, alter_tmp_dir, 0); | 
			
		
	
		
			
				
					|  |  |  | 	size_t	tmp_abs_len = strlen(tmp_abs_path); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	if (my_access(tmp_abs_path, F_OK)) { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 		push_warning_printf( | 
			
		
	
		
			
				
					|  |  |  | 			thd, Sql_condition::WARN_LEVEL_WARN, | 
			
		
	
		
			
				
					|  |  |  | 			ER_WRONG_ARGUMENTS, | 
			
		
	
		
			
				
					|  |  |  | 			"InnoDB: Path doesn't exist."); | 
			
		
	
		
			
				
					|  |  |  | 		*static_cast<const char**>(save) = NULL; | 
			
		
	
		
			
				
					|  |  |  | 		return(1); | 
			
		
	
		
			
				
					|  |  |  | 	} else if (my_access(tmp_abs_path, R_OK | W_OK)) { | 
			
		
	
		
			
				
					|  |  |  | 		push_warning_printf( | 
			
		
	
		
			
				
					|  |  |  | 			thd, Sql_condition::WARN_LEVEL_WARN, | 
			
		
	
		
			
				
					|  |  |  | 			ER_WRONG_ARGUMENTS, | 
			
		
	
		
			
				
					|  |  |  | 			"InnoDB: Server doesn't have permission in " | 
			
		
	
		
			
				
					|  |  |  | 			"the given location."); | 
			
		
	
		
			
				
					|  |  |  | 		*static_cast<const char**>(save) = NULL; | 
			
		
	
		
			
				
					|  |  |  | 		return(1); | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	MY_STAT stat_info_dir; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	if (my_stat(tmp_abs_path, &stat_info_dir, MYF(0))) { | 
			
		
	
		
			
				
					|  |  |  | 		if ((stat_info_dir.st_mode & S_IFDIR) != S_IFDIR) { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 			push_warning_printf( | 
			
		
	
		
			
				
					|  |  |  | 				thd, Sql_condition::WARN_LEVEL_WARN, | 
			
		
	
		
			
				
					|  |  |  | 				ER_WRONG_ARGUMENTS, | 
			
		
	
		
			
				
					|  |  |  | 				"Given path is not a directory. "); | 
			
		
	
		
			
				
					|  |  |  | 			*static_cast<const char**>(save) = NULL; | 
			
		
	
		
			
				
					|  |  |  | 			return(1); | 
			
		
	
		
			
				
					|  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	if (!is_mysql_datadir_path(tmp_abs_path)) { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 		push_warning_printf( | 
			
		
	
		
			
				
					|  |  |  | 			thd, Sql_condition::WARN_LEVEL_WARN, | 
			
		
	
		
			
				
					|  |  |  | 			ER_WRONG_ARGUMENTS, | 
			
		
	
		
			
				
					|  |  |  | 			"InnoDB: Path Location should not be same as " | 
			
		
	
		
			
				
					|  |  |  | 			"mysql data directory location."); | 
			
		
	
		
			
				
					|  |  |  | 		*static_cast<const char**>(save) = NULL; | 
			
		
	
		
			
				
					|  |  |  | 		return(1); | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	innodb_tmp_dir = static_cast<char*>( | 
			
		
	
		
			
				
					|  |  |  | 		thd_memdup(thd, tmp_abs_path, tmp_abs_len + 1)); | 
			
		
	
		
			
				
					|  |  |  | 	*static_cast<const char**>(save) = innodb_tmp_dir; | 
			
		
	
		
			
				
					|  |  |  | 	return(0); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | /** "GEN_CLUST_INDEX" is the name reserved for InnoDB default
 | 
			
		
	
		
			
				
					|  |  |  | system clustered index when there is no primary key. */ | 
			
		
	
		
			
				
					|  |  |  | const char innobase_index_reserve_name[] = "GEN_CLUST_INDEX"; | 
			
		
	
	
		
			
				
					|  |  | @ -651,6 +753,10 @@ static MYSQL_THDVAR_BOOL(fake_changes, PLUGIN_VAR_OPCMDARG, | 
			
		
	
		
			
				
					|  |  |  |   "This is to cause replication prefetch IO. ATTENTION: the transaction started after enabled is affected.", | 
			
		
	
		
			
				
					|  |  |  |   NULL, NULL, FALSE); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | static MYSQL_THDVAR_STR(tmpdir, | 
			
		
	
		
			
				
					|  |  |  |   PLUGIN_VAR_OPCMDARG|PLUGIN_VAR_MEMALLOC, | 
			
		
	
		
			
				
					|  |  |  |   "Directory for temporary non-tablespace files.", | 
			
		
	
		
			
				
					|  |  |  |   innodb_tmpdir_validate, NULL, NULL); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | static SHOW_VAR innodb_status_variables[]= { | 
			
		
	
		
			
				
					|  |  |  |   {"buffer_pool_dump_status", | 
			
		
	
	
		
			
				
					|  |  | @ -1242,6 +1348,28 @@ normalize_table_name_low( | 
			
		
	
		
			
				
					|  |  |  | 	ibool           set_lower_case); /* in: TRUE if we want to set
 | 
			
		
	
		
			
				
					|  |  |  | 					 name to lower case */ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | /*************************************************************//**
 | 
			
		
	
		
			
				
					|  |  |  | Checks if buffer pool is big enough to enable backoff algorithm. | 
			
		
	
		
			
				
					|  |  |  | InnoDB empty free list algorithm backoff requires free pages | 
			
		
	
		
			
				
					|  |  |  | from LRU for the best performance. | 
			
		
	
		
			
				
					|  |  |  | buf_LRU_buf_pool_running_out cancels query if 1/4 of  | 
			
		
	
		
			
				
					|  |  |  | buffer pool belongs to LRU or freelist. | 
			
		
	
		
			
				
					|  |  |  | At the same time buf_flush_LRU_list_batch | 
			
		
	
		
			
				
					|  |  |  | keeps up to BUF_LRU_MIN_LEN in LRU. | 
			
		
	
		
			
				
					|  |  |  | In order to avoid deadlock baclkoff requires buffer pool | 
			
		
	
		
			
				
					|  |  |  | to be at least 4*BUF_LRU_MIN_LEN, | 
			
		
	
		
			
				
					|  |  |  | but flush peformance is bad because of trashing | 
			
		
	
		
			
				
					|  |  |  | and additional BUF_LRU_MIN_LEN pages are requested. | 
			
		
	
		
			
				
					|  |  |  | @return	true if it's possible to enable backoff. */ | 
			
		
	
		
			
				
					|  |  |  | static | 
			
		
	
		
			
				
					|  |  |  | bool | 
			
		
	
		
			
				
					|  |  |  | innodb_empty_free_list_algorithm_backoff_allowed( | 
			
		
	
		
			
				
					|  |  |  | 	srv_empty_free_list_t | 
			
		
	
		
			
				
					|  |  |  | 			algorithm,		/*!< in: desired algorithm
 | 
			
		
	
		
			
				
					|  |  |  | 						from srv_empty_free_list_t */ | 
			
		
	
		
			
				
					|  |  |  | 	long long	buf_pool_pages);	/*!< in: total number
 | 
			
		
	
		
			
				
					|  |  |  | 						of pages inside buffer pool */ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | /*************************************************************//**
 | 
			
		
	
		
			
				
					|  |  |  | Removes old archived transaction log files. | 
			
		
	
		
			
				
					|  |  |  | @return	true on error */ | 
			
		
	
	
		
			
				
					|  |  | @ -1520,6 +1648,26 @@ thd_supports_xa( | 
			
		
	
		
			
				
					|  |  |  | 	return(THDVAR(thd, support_xa)); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | /** Get the value of innodb_tmpdir.
 | 
			
		
	
		
			
				
					|  |  |  | @param[in]	thd	thread handle, or NULL to query | 
			
		
	
		
			
				
					|  |  |  | 			the global innodb_tmpdir. | 
			
		
	
		
			
				
					|  |  |  | @retval NULL if innodb_tmpdir="" */ | 
			
		
	
		
			
				
					|  |  |  | UNIV_INTERN | 
			
		
	
		
			
				
					|  |  |  | const char* | 
			
		
	
		
			
				
					|  |  |  | thd_innodb_tmpdir( | 
			
		
	
		
			
				
					|  |  |  | 	THD*	thd) | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  | #ifdef UNIV_SYNC_DEBUG
 | 
			
		
	
		
			
				
					|  |  |  | 	ut_ad(!sync_thread_levels_nonempty_trx(false)); | 
			
		
	
		
			
				
					|  |  |  | #endif /* UNIV_SYNC_DEBUG */
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	const char*	tmp_dir = THDVAR(thd, tmpdir); | 
			
		
	
		
			
				
					|  |  |  | 	if (tmp_dir != NULL && *tmp_dir == '\0') { | 
			
		
	
		
			
				
					|  |  |  | 		tmp_dir = NULL; | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	return(tmp_dir); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | /******************************************************************//**
 | 
			
		
	
		
			
				
					|  |  |  | Check the status of fake changes mode (innodb_fake_changes) | 
			
		
	
		
			
				
					|  |  |  | @return	true	if fake change mode is enabled. */ | 
			
		
	
	
		
			
				
					|  |  | @ -2096,13 +2244,14 @@ innobase_get_lower_case_table_names(void) | 
			
		
	
		
			
				
					|  |  |  | 	return(lower_case_table_names); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | /*********************************************************************//**
 | 
			
		
	
		
			
				
					|  |  |  | Creates a temporary file. | 
			
		
	
		
			
				
					|  |  |  | /** Create a temporary file in the location specified by the parameter
 | 
			
		
	
		
			
				
					|  |  |  | path. If the path is null, then it will be created in tmpdir. | 
			
		
	
		
			
				
					|  |  |  | @param[in]	path	location for creating temporary file | 
			
		
	
		
			
				
					|  |  |  | @return	temporary file descriptor, or < 0 on error */ | 
			
		
	
		
			
				
					|  |  |  | UNIV_INTERN | 
			
		
	
		
			
				
					|  |  |  | int | 
			
		
	
		
			
				
					|  |  |  | innobase_mysql_tmpfile(void) | 
			
		
	
		
			
				
					|  |  |  | /*========================*/ | 
			
		
	
		
			
				
					|  |  |  | innobase_mysql_tmpfile( | 
			
		
	
		
			
				
					|  |  |  | 	const char*	path) | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  | 	int	fd2 = -1; | 
			
		
	
		
			
				
					|  |  |  | 	File	fd; | 
			
		
	
	
		
			
				
					|  |  | @ -2112,7 +2261,11 @@ innobase_mysql_tmpfile(void) | 
			
		
	
		
			
				
					|  |  |  | 		return(-1); | 
			
		
	
		
			
				
					|  |  |  | 	); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	if (path == NULL) { | 
			
		
	
		
			
				
					|  |  |  | 		fd = mysql_tmpfile("ib"); | 
			
		
	
		
			
				
					|  |  |  | 	} else { | 
			
		
	
		
			
				
					|  |  |  | 		fd = mysql_tmpfile_path(path, "ib"); | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	if (fd >= 0) { | 
			
		
	
		
			
				
					|  |  |  | 		/* Copy the file descriptor, so that the additional resources
 | 
			
		
	
	
		
			
				
					|  |  | @ -3110,6 +3263,13 @@ ha_innobase::reset_template(void) | 
			
		
	
		
			
				
					|  |  |  | 	ut_ad(prebuilt->magic_n == ROW_PREBUILT_ALLOCATED); | 
			
		
	
		
			
				
					|  |  |  | 	ut_ad(prebuilt->magic_n2 == prebuilt->magic_n); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	/* Force table to be freed in close_thread_table(). */ | 
			
		
	
		
			
				
					|  |  |  | 	DBUG_EXECUTE_IF("free_table_in_fts_query", | 
			
		
	
		
			
				
					|  |  |  | 		if (prebuilt->in_fts_query) { | 
			
		
	
		
			
				
					|  |  |  | 			table->m_needs_reopen = true; | 
			
		
	
		
			
				
					|  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  | 	); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	prebuilt->keep_other_fields_on_keyread = 0; | 
			
		
	
		
			
				
					|  |  |  | 	prebuilt->read_just_key = 0; | 
			
		
	
		
			
				
					|  |  |  | 	prebuilt->in_fts_query = 0; | 
			
		
	
	
		
			
				
					|  |  | @ -3691,6 +3851,22 @@ innobase_change_buffering_inited_ok: | 
			
		
	
		
			
				
					|  |  |  | 	srv_kill_idle_transaction = 0; | 
			
		
	
		
			
				
					|  |  |  | #endif
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	/* Do not enable backoff algorithm for small buffer pool. */ | 
			
		
	
		
			
				
					|  |  |  | 	if (!innodb_empty_free_list_algorithm_backoff_allowed( | 
			
		
	
		
			
				
					|  |  |  | 			static_cast<srv_empty_free_list_t>( | 
			
		
	
		
			
				
					|  |  |  | 				srv_empty_free_list_algorithm), | 
			
		
	
		
			
				
					|  |  |  | 			innobase_buffer_pool_size / srv_page_size)) { | 
			
		
	
		
			
				
					|  |  |  | 		sql_print_information( | 
			
		
	
		
			
				
					|  |  |  | 				"InnoDB: innodb_empty_free_list_algorithm " | 
			
		
	
		
			
				
					|  |  |  | 				"has been changed to legacy " | 
			
		
	
		
			
				
					|  |  |  | 				"because of small buffer pool size. " | 
			
		
	
		
			
				
					|  |  |  | 				"In order to use backoff, " | 
			
		
	
		
			
				
					|  |  |  | 				"increase buffer pool at least up to 20MB.\n"); | 
			
		
	
		
			
				
					|  |  |  | 			srv_empty_free_list_algorithm | 
			
		
	
		
			
				
					|  |  |  | 				= SRV_EMPTY_FREE_LIST_LEGACY; | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	srv_use_atomic_writes = (ibool) innobase_use_atomic_writes; | 
			
		
	
		
			
				
					|  |  |  | 	if (innobase_use_atomic_writes) { | 
			
		
	
		
			
				
					|  |  |  | 		ib_logf(IB_LOG_LEVEL_INFO, "using atomic writes."); | 
			
		
	
	
		
			
				
					|  |  | @ -5145,7 +5321,7 @@ building based on the assumption that there is no concurrent | 
			
		
	
		
			
				
					|  |  |  | index creation/drop and DMLs that requires index lookup. All table | 
			
		
	
		
			
				
					|  |  |  | handle will be closed before the index creation/drop. | 
			
		
	
		
			
				
					|  |  |  | @return TRUE if index translation table built successfully */ | 
			
		
	
		
			
				
					|  |  |  | static | 
			
		
	
		
			
				
					|  |  |  | UNIV_INTERN | 
			
		
	
		
			
				
					|  |  |  | ibool | 
			
		
	
		
			
				
					|  |  |  | innobase_build_index_translation( | 
			
		
	
		
			
				
					|  |  |  | /*=============================*/ | 
			
		
	
	
		
			
				
					|  |  | @ -16539,8 +16715,6 @@ innobase_fts_close_ranking( | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  | 	fts_result_t*	result; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	((NEW_FT_INFO*) fts_hdl)->ft_prebuilt->in_fts_query = false; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	result = ((NEW_FT_INFO*) fts_hdl)->ft_result; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	fts_query_free_result(result); | 
			
		
	
	
		
			
				
					|  |  | @ -16892,6 +17066,87 @@ innodb_status_output_update( | 
			
		
	
		
			
				
					|  |  |  | 	os_event_set(lock_sys->timeout_event); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | /*************************************************************//**
 | 
			
		
	
		
			
				
					|  |  |  | Empty free list algorithm. | 
			
		
	
		
			
				
					|  |  |  | Checks if buffer pool is big enough to enable backoff algorithm. | 
			
		
	
		
			
				
					|  |  |  | InnoDB empty free list algorithm backoff requires free pages | 
			
		
	
		
			
				
					|  |  |  | from LRU for the best performance. | 
			
		
	
		
			
				
					|  |  |  | buf_LRU_buf_pool_running_out cancels query if 1/4 of  | 
			
		
	
		
			
				
					|  |  |  | buffer pool belongs to LRU or freelist. | 
			
		
	
		
			
				
					|  |  |  | At the same time buf_flush_LRU_list_batch | 
			
		
	
		
			
				
					|  |  |  | keeps up to BUF_LRU_MIN_LEN in LRU. | 
			
		
	
		
			
				
					|  |  |  | In order to avoid deadlock baclkoff requires buffer pool | 
			
		
	
		
			
				
					|  |  |  | to be at least 4*BUF_LRU_MIN_LEN, | 
			
		
	
		
			
				
					|  |  |  | but flush peformance is bad because of trashing | 
			
		
	
		
			
				
					|  |  |  | and additional BUF_LRU_MIN_LEN pages are requested. | 
			
		
	
		
			
				
					|  |  |  | @return	true if it's possible to enable backoff. */ | 
			
		
	
		
			
				
					|  |  |  | static | 
			
		
	
		
			
				
					|  |  |  | bool | 
			
		
	
		
			
				
					|  |  |  | innodb_empty_free_list_algorithm_backoff_allowed( | 
			
		
	
		
			
				
					|  |  |  | 	srv_empty_free_list_t	algorithm,	/*!< in: desired algorithm
 | 
			
		
	
		
			
				
					|  |  |  | 						from srv_empty_free_list_t */ | 
			
		
	
		
			
				
					|  |  |  | 	long long		buf_pool_pages)	/*!< in: total number
 | 
			
		
	
		
			
				
					|  |  |  | 						of pages inside buffer pool */ | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  | 	return(buf_pool_pages >= BUF_LRU_MIN_LEN * (4 + 1) | 
			
		
	
		
			
				
					|  |  |  | 			|| algorithm != SRV_EMPTY_FREE_LIST_BACKOFF); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | /*************************************************************//**
 | 
			
		
	
		
			
				
					|  |  |  | Empty free list algorithm. This function is registered as | 
			
		
	
		
			
				
					|  |  |  | a callback with MySQL.  | 
			
		
	
		
			
				
					|  |  |  | @return	0 for valid algorithm */ | 
			
		
	
		
			
				
					|  |  |  | static | 
			
		
	
		
			
				
					|  |  |  | int | 
			
		
	
		
			
				
					|  |  |  | innodb_srv_empty_free_list_algorithm_validate( | 
			
		
	
		
			
				
					|  |  |  | /*===========================*/ | 
			
		
	
		
			
				
					|  |  |  | 	THD*				thd,	/*!< in: thread handle */ | 
			
		
	
		
			
				
					|  |  |  | 	struct st_mysql_sys_var*	var,	/*!< in: pointer to system
 | 
			
		
	
		
			
				
					|  |  |  | 						variable */ | 
			
		
	
		
			
				
					|  |  |  | 	void*				save,	/*!< out: immediate result
 | 
			
		
	
		
			
				
					|  |  |  | 						for update function */ | 
			
		
	
		
			
				
					|  |  |  | 	struct st_mysql_value*		value)	/*!< in: incoming string */ | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  | 	const char*	algorithm_name; | 
			
		
	
		
			
				
					|  |  |  | 	char		buff[STRING_BUFFER_USUAL_SIZE]; | 
			
		
	
		
			
				
					|  |  |  | 	int		len = sizeof(buff); | 
			
		
	
		
			
				
					|  |  |  | 	ulint	algo; | 
			
		
	
		
			
				
					|  |  |  | 	srv_empty_free_list_t 		algorithm; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	algorithm_name = value->val_str(value, buff, &len); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	if (!algorithm_name) { | 
			
		
	
		
			
				
					|  |  |  | 		return(1); | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	for (algo = 0; algo < array_elements( | 
			
		
	
		
			
				
					|  |  |  | 				innodb_empty_free_list_algorithm_names | 
			
		
	
		
			
				
					|  |  |  | 				) - 1; | 
			
		
	
		
			
				
					|  |  |  | 			algo++) { | 
			
		
	
		
			
				
					|  |  |  | 		if (!innobase_strcasecmp( | 
			
		
	
		
			
				
					|  |  |  | 				algorithm_name, | 
			
		
	
		
			
				
					|  |  |  | 				innodb_empty_free_list_algorithm_names[algo])) | 
			
		
	
		
			
				
					|  |  |  | 			break; | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	if (algo == array_elements( innodb_empty_free_list_algorithm_names) - 1) | 
			
		
	
		
			
				
					|  |  |  | 		return(1); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	algorithm = static_cast<srv_empty_free_list_t>(algo); | 
			
		
	
		
			
				
					|  |  |  | 	if (!innodb_empty_free_list_algorithm_backoff_allowed( | 
			
		
	
		
			
				
					|  |  |  | 				algorithm, | 
			
		
	
		
			
				
					|  |  |  | 				innobase_buffer_pool_size / srv_page_size)) { | 
			
		
	
		
			
				
					|  |  |  | 		sql_print_warning( | 
			
		
	
		
			
				
					|  |  |  | 				"InnoDB: innodb_empty_free_list_algorithm " | 
			
		
	
		
			
				
					|  |  |  | 				"= 'backoff' requires at least" | 
			
		
	
		
			
				
					|  |  |  | 				" 20MB buffer pool.\n"); | 
			
		
	
		
			
				
					|  |  |  | 		return(1); | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	*reinterpret_cast<ulong*>(save) = static_cast<ulong>(algorithm); | 
			
		
	
		
			
				
					|  |  |  | 	return(0); | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | static SHOW_VAR innodb_status_variables_export[]= { | 
			
		
	
		
			
				
					|  |  |  | 	{"Innodb", (char*) &show_innodb_vars, SHOW_FUNC}, | 
			
		
	
		
			
				
					|  |  |  | 	{NullS, NullS, SHOW_LONG} | 
			
		
	
	
		
			
				
					|  |  | @ -17436,7 +17691,7 @@ static MYSQL_SYSVAR_ENUM(empty_free_list_algorithm, | 
			
		
	
		
			
				
					|  |  |  |   "The algorithm to use for empty free list handling.  Allowed values: " | 
			
		
	
		
			
				
					|  |  |  |   "LEGACY: Original Oracle MySQL 5.6 handling with single page flushes; " | 
			
		
	
		
			
				
					|  |  |  |   "BACKOFF: (default) Wait until cleaner produces a free page.", | 
			
		
	
		
			
				
					|  |  |  |   NULL, NULL, SRV_EMPTY_FREE_LIST_BACKOFF, | 
			
		
	
		
			
				
					|  |  |  |   innodb_srv_empty_free_list_algorithm_validate, NULL, SRV_EMPTY_FREE_LIST_BACKOFF, | 
			
		
	
		
			
				
					|  |  |  |   &innodb_empty_free_list_algorithm_typelib); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | static MYSQL_SYSVAR_LONG(buffer_pool_instances, innobase_buffer_pool_instances, | 
			
		
	
	
		
			
				
					|  |  | @ -18177,6 +18432,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { | 
			
		
	
		
			
				
					|  |  |  |   MYSQL_SYSVAR(corrupt_table_action), | 
			
		
	
		
			
				
					|  |  |  |   MYSQL_SYSVAR(fake_changes), | 
			
		
	
		
			
				
					|  |  |  |   MYSQL_SYSVAR(locking_fake_changes), | 
			
		
	
		
			
				
					|  |  |  |   MYSQL_SYSVAR(tmpdir), | 
			
		
	
		
			
				
					|  |  |  |   NULL | 
			
		
	
		
			
				
					|  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | 
 |