引言
上一節介紹了從命令行和配置文件加載配置參數,這一節介紹其它的初始化邏輯。可以學習的數據結構有鏈表和哈希,可以關注的內容有table_def_size/table_cache_size/max_connections/requested_open_files等參數的計算方式,另外有需要可自行深入學習performance_schema。
源碼分析
初始化命令
init_sql_statement_names();
這裏作用是將命令存儲在sql_statement_names全局數組裏,命令種類可以參考my_sqlcommand.h,這裏定義了enum_sql_command枚舉類型,如下:
enum enum_sql_command {
SQLCOM_SELECT,
SQLCOM_CREATE_TABLE,
SQLCOM_CREATE_INDEX,
SQLCOM_ALTER_TABLE,
SQLCOM_UPDATE,
SQLCOM_INSERT,
SQLCOM_INSERT_SELECT,
SQLCOM_DELETE,
SQLCOM_TRUNCATE,
SQLCOM_DROP_TABLE,
SQLCOM_DROP_INDEX,
SQLCOM_SHOW_DATABASES,
SQLCOM_SHOW_TABLES,
SQLCOM_SHOW_FIELDS,
SQLCOM_SHOW_KEYS,
SQLCOM_SHOW_VARIABLES,
SQLCOM_SHOW_STATUS,
SQLCOM_SHOW_ENGINE_LOGS,
SQLCOM_SHOW_ENGINE_STATUS,
SQLCOM_SHOW_ENGINE_MUTEX,
SQLCOM_SHOW_PROCESSLIST,
SQLCOM_SHOW_MASTER_STAT,
SQLCOM_SHOW_SLAVE_STAT,
SQLCOM_SHOW_GRANTS,
SQLCOM_SHOW_CREATE,
SQLCOM_SHOW_CHARSETS,
SQLCOM_SHOW_COLLATIONS,
SQLCOM_SHOW_CREATE_DB,
SQLCOM_SHOW_TABLE_STATUS,
SQLCOM_SHOW_TRIGGERS,
SQLCOM_LOAD,
SQLCOM_SET_OPTION,
SQLCOM_LOCK_TABLES,
SQLCOM_UNLOCK_TABLES,
SQLCOM_GRANT,
SQLCOM_CHANGE_DB,
SQLCOM_CREATE_DB,
SQLCOM_DROP_DB,
SQLCOM_ALTER_DB,
SQLCOM_REPAIR,
SQLCOM_REPLACE,
SQLCOM_REPLACE_SELECT,
SQLCOM_CREATE_FUNCTION,
SQLCOM_DROP_FUNCTION,
SQLCOM_REVOKE,
SQLCOM_OPTIMIZE,
SQLCOM_CHECK,
SQLCOM_ASSIGN_TO_KEYCACHE,
SQLCOM_PRELOAD_KEYS,
SQLCOM_FLUSH,
SQLCOM_KILL,
SQLCOM_ANALYZE,
SQLCOM_ROLLBACK,
SQLCOM_ROLLBACK_TO_SAVEPOINT,
SQLCOM_COMMIT,
SQLCOM_SAVEPOINT,
SQLCOM_RELEASE_SAVEPOINT,
SQLCOM_SLAVE_START,
SQLCOM_SLAVE_STOP,
SQLCOM_START_GROUP_REPLICATION,
SQLCOM_STOP_GROUP_REPLICATION,
SQLCOM_BEGIN,
SQLCOM_CHANGE_MASTER,
SQLCOM_CHANGE_REPLICATION_FILTER,
SQLCOM_RENAME_TABLE,
SQLCOM_RESET,
SQLCOM_PURGE,
SQLCOM_PURGE_BEFORE,
SQLCOM_SHOW_BINLOGS,
SQLCOM_SHOW_OPEN_TABLES,
SQLCOM_HA_OPEN,
SQLCOM_HA_CLOSE,
SQLCOM_HA_READ,
SQLCOM_SHOW_SLAVE_HOSTS,
SQLCOM_DELETE_MULTI,
SQLCOM_UPDATE_MULTI,
SQLCOM_SHOW_BINLOG_EVENTS,
SQLCOM_DO,
SQLCOM_SHOW_WARNS,
SQLCOM_EMPTY_QUERY,
SQLCOM_SHOW_ERRORS,
SQLCOM_SHOW_STORAGE_ENGINES,
SQLCOM_SHOW_PRIVILEGES,
SQLCOM_HELP,
SQLCOM_CREATE_USER,
SQLCOM_DROP_USER,
SQLCOM_RENAME_USER,
SQLCOM_REVOKE_ALL,
SQLCOM_CHECKSUM,
SQLCOM_CREATE_PROCEDURE,
SQLCOM_CREATE_SPFUNCTION,
SQLCOM_CALL,
SQLCOM_DROP_PROCEDURE,
SQLCOM_ALTER_PROCEDURE,
SQLCOM_ALTER_FUNCTION,
SQLCOM_SHOW_CREATE_PROC,
SQLCOM_SHOW_CREATE_FUNC,
SQLCOM_SHOW_STATUS_PROC,
SQLCOM_SHOW_STATUS_FUNC,
SQLCOM_PREPARE,
SQLCOM_EXECUTE,
SQLCOM_DEALLOCATE_PREPARE,
SQLCOM_CREATE_VIEW,
SQLCOM_DROP_VIEW,
SQLCOM_CREATE_TRIGGER,
SQLCOM_DROP_TRIGGER,
SQLCOM_XA_START,
SQLCOM_XA_END,
SQLCOM_XA_PREPARE,
SQLCOM_XA_COMMIT,
SQLCOM_XA_ROLLBACK,
SQLCOM_XA_RECOVER,
SQLCOM_SHOW_PROC_CODE,
SQLCOM_SHOW_FUNC_CODE,
SQLCOM_ALTER_TABLESPACE,
SQLCOM_INSTALL_PLUGIN,
SQLCOM_UNINSTALL_PLUGIN,
SQLCOM_BINLOG_BASE64_EVENT,
SQLCOM_SHOW_PLUGINS,
SQLCOM_CREATE_SERVER,
SQLCOM_DROP_SERVER,
SQLCOM_ALTER_SERVER,
SQLCOM_CREATE_EVENT,
SQLCOM_ALTER_EVENT,
SQLCOM_DROP_EVENT,
SQLCOM_SHOW_CREATE_EVENT,
SQLCOM_SHOW_EVENTS,
SQLCOM_SHOW_CREATE_TRIGGER,
SQLCOM_ALTER_DB_UPGRADE,
SQLCOM_SHOW_PROFILE,
SQLCOM_SHOW_PROFILES,
SQLCOM_SIGNAL,
SQLCOM_RESIGNAL,
SQLCOM_SHOW_RELAYLOG_EVENTS,
SQLCOM_GET_DIAGNOSTICS,
SQLCOM_ALTER_USER,
SQLCOM_EXPLAIN_OTHER,
SQLCOM_SHOW_CREATE_USER,
SQLCOM_SHUTDOWN,
SQLCOM_ALTER_INSTANCE,
SQLCOM_END
};
存到數組裏SQLCOM_SELECT對應"select",SQLCOM_SIGNAL對應"signal",這個映射是在com_status_vars數組中取的,其它同理。只有最後一個SQLCOM_END例外,對應的是"error"。sql_statement_names數組元素的類型如下:
struct st_mysql_const_lex_string
{
const char *str;
size_t length;
};
所以除了存儲命令名稱,還記錄了命令名稱的長度。
初始化系統變量
if (my_hash_init(&system_variable_hash, system_charset_info, 100, 0,
0, (my_hash_get_key) get_sys_var_length, 0, HASH_UNIQUE,
PSI_INSTRUMENT_ME))
goto error;
初始化哈希表system_variable_hash,結構如下:
typedef struct st_hash {
size_t key_offset,key_length;
size_t blength;
ulong records;
uint flags;
DYNAMIC_ARRAY array;
my_hash_get_key get_key;
void (*free)(void *);
CHARSET_INFO *charset;
my_hash_function hash_function;
PSI_memory_key m_psi_key;
} HASH;
size_t其實是long unsigned int類型,ulong是unsigned long int類型,uint是unsigned int uint類型,PSI_memory_key也是unsigned int類型,get_key是hash函數,free是析構函數,CHARSET_INFO *charset用來存儲字符集,
DYNAMIC_ARRAY array是動態數組,結構如下:
typedef struct st_dynamic_array
{
uchar *buffer;
uint elements,max_element;
uint alloc_increment;
uint size_of_element;
PSI_memory_key m_psi_key;
} DYNAMIC_ARRAY;
接下來把all_sys_vars的內容插入哈希表。
if (mysql_add_sys_var_chain(all_sys_vars.first))
goto error;
其中all_sys_vars爲sys_var類型構成的鏈表,頭尾節點初始化爲NULL,如下:
sys_var_chain all_sys_vars = { NULL, NULL };
sys_vars.h中聲明瞭sys_var的子類,有Sys_var_integer/Sys_var_typelib/Sys_var_multi_enum/Sys_var_charptr/Sys_var_proxy_user/Sys_var_dbug/Sys_var_double/Sys_var_plugin/Sys_var_debug_sync/Sys_var_have/Sys_var_struct/Sys_var_tz/Sys_var_gtid_next/Sys_var_gtid_set/Sys_var_charptr_func/Sys_var_gtid_purged等等。它們的構造函數中生成了all_sys_vars鏈表中的數據。如下:
Sys_var_integer(const char *name_arg,
const char *comment, int flag_args, ptrdiff_t off, size_t size,
CMD_LINE getopt,
T min_val, T max_val, T def_val, uint block_size, PolyLock *lock=0,
enum binlog_status_enum binlog_status_arg=VARIABLE_NOT_IN_BINLOG,
on_check_function on_check_func=0,
on_update_function on_update_func=0,
const char *substitute=0,
int parse_flag= PARSE_NORMAL)
: sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id,
getopt.arg_type, SHOWT, def_val, lock, binlog_status_arg,
on_check_func, on_update_func,
substitute, parse_flag)
而系統變量對象來自於sys_vars.cc,截取其中一個,如下:
static Sys_var_mybool Sys_pfs_enabled(
"performance_schema",
"Enable the performance schema.",
READ_ONLY GLOBAL_VAR(pfs_param.m_enabled),
CMD_LINE(OPT_ARG), DEFAULT(TRUE),
PFS_TRAILING_PROPERTIES);
調整參數
adjust_open_files_limit(requested_open_files);
adjust_max_connections(*requested_open_files);
adjust_table_cache_size(*requested_open_files);
adjust_table_def_size();
在adjust_open_files_limit裏,request_open_files由以下3種算式取最大值。而requested_open_files則是取effective_open_files和request_open_files的最小值。effective_open_files默認算出來爲65536,request_open_files默認算出來爲5000。open_files_limit控制着mysqld進程能使用的最大文件描述符數量,使用的是effective_open_files的值。
limit_1= 10 + max_connections + table_cache_size * 2;
limit_2= max_connections * 5;
limit_3= open_files_limit ? open_files_limit : 5000;
接下來adjust_max_connections裏設置max_connections,即最大連接數,取limit和原值的最小值,limit算法如下:
limit= requested_open_files - 10 - TABLE_OPEN_CACHE_MIN * 2;
其中TABLE_OPEN_CACHE_MIN爲400,所以limit默認爲4190,而通常設置的max_connections更小,所以保持不變。
limit= max<ulong>((requested_open_files - 10 - max_connections) / 2, TABLE_OPEN_CACHE_MIN);
adjust_table_cache_size裏設置table_cache_size和table_cache_size_per_instance。table_cache_size規定了內存中可打開表的數量,和max_connections類似,取limit和自身的最小值。table_cache_size_per_instance則是table_cache_size除以實例數得來的。
void adjust_table_def_size()
{
ulong default_value;
sys_var *var;
default_value= min<ulong> (400 + table_cache_size / 2, 2000);
var= intern_find_sys_var(STRING_WITH_LEN("table_definition_cache"));
DBUG_ASSERT(var != NULL);
var->update_default(default_value);
if (! table_definition_cache_specified)
table_def_size= default_value;
}
table_def_size是內存中可打開表結構的數量。這裏從前面介紹的system_variable_hash哈希表裏查找table_definition_cache系統變量,並將default_value更新到option.def_value裏。
初始化pfs
pfs_param.m_hints.m_table_definition_cache= table_def_size;
pfs_param.m_hints.m_table_open_cache= table_cache_size;
pfs_param.m_hints.m_max_connections= max_connections;
pfs_param.m_hints.m_open_files_limit= requested_open_files;
pfs_param.m_hints.m_max_prepared_stmt_count= max_prepared_stmt_count;
PSI_hook= initialize_performance_schema(&pfs_param);
pfs即performance_schema,用於記錄運行過程中的性能、資源、wait事件等信息。前面設置的table_def_size/table_cache_size/max_connections/requested_open_files等參數,也被設置到performance_schema。
關鍵詞
初始化命令;初始化系統變量;調整參數;初始化pfs