天天看點

mysql 源碼學習筆記:配置檔案和指令行參數的裝載

版本 CentOS release 6.7環境下mysql-5.7.16 社群版

概述 mysql可以通過加載配置檔案或者在啟動時輸入指令行參數的方式來完成初始化系統變量、裝載插件等操作。本文主要梳理了裝載配置檔案和指令參數的過程,以及配置檔案内容和指令行參數生效的過程。

源碼分析 配置檔案的讀取 load_defaults mysql在啟動過程中調用函數load_defaults來完成配置檔案和指令行參數的裝載。調用的具體過程如下: mysqld_main | load_defaults(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv)     | my_load_defaults(conf_file, groups, argc, argv, &default_directories)         | init_default_directories                                             初始化配置檔案路徑         |my_search_option_files(conf_file, argc, argv, ......讀取配置檔案内容 | remaining_argc= argc; | remaining_argv= argv; 其中MYSQL_CONFIG_NAME為"my"(該宏的值為編譯時設定,預設為"my")。argc和argv為main函數的參數,argc為指令行參數數量,argv為指令行參數數組。

函數load_defaults執行結束後,配置檔案中所有的參數(所有配置檔案依次讀取,可能出現重複的參數)和指令行的參數全部存放在參數remaining_argc和remaining_argv中,remaining_argv的格式如下: remaining_argv[0] --port=30001                              配置檔案中的參數 ... remaining_argv[n] ----args-separator----               分隔符 ... remaining_argv[k] --server_id=30001                  指令行參數 remaining_argc和remaining_argv為全局變量,供後續初始化變量使用。

init_default_directories 函數init_default_directories為初始化預設配置檔案目錄函數,會依次将目錄加入到數組中。 init_default_directories | errors += add_directory(alloc, "/etc/", dirs); | errors += add_directory(alloc, "/etc/mysql/", dirs); | errors += add_directory(alloc, DEFAULT_SYSCONFDIR, dirs); | if ((env= getenv("MYSQL_HOME")))                   如果設定了環境變量MYSQL_HOME       errors += add_directory(alloc, env, dirs); | errors += add_directory(alloc, "", dirs)                為系統變量--defaults-extra-file預留 | errors += add_directory(alloc, "~/", dirs);

其中DEFAULT_SYSCONFDIR為mysql安裝目錄下的etc目錄,如果設定了環境變量MYSQL_HOME,則加入預設目錄。 該函數會依次将目錄'/etc'、'/etc/mysql'、'/mysql安裝目錄/etc'、'$MYSQL_HOME'、'~/'作為預設的配置檔案路徑。

my_search_option_files 函數my_search_option_files根據啟動時設定的參數--defaults-file、--no-defaults等,或者在指定位置讀取配置檔案,或者在預設目錄中依次讀取配置檔案,并将讀取到的結果依次緩存下來。 my_search_option_files | get_defaults_options 讀取指定的配置檔案參數                 |*defaults= *argv + sizeof("--defaults-file=")-1;     |*extra_defaults= *argv + sizeof("--defaults-extra-file=")-1;           |*group_suffix= *argv + sizeof("--defaults-group-suffix=")-1;     |*login_path= *argv + sizeof("--login-path=")-1; | if (dirname_length(conf_file)) 如果編譯時指定MYSQL_CONFIG_NAME為絕對路徑            search_default_file(func, func_ctx, NullS, conf_file...... | else if (my_defaults_file) 如果設定了參數--defaults-file(未設定--no-defaults)            search_default_file_with_ext(func, func_ctx, "", "",...... | else if (!found_no_defaults) 如果--defaults-file和--no-defaults均為設定            search_default_file(func, func_ctx, *dirs, conf_file ......

配置檔案和指令行參數生效 在mysql啟動過程中,有兩個函數會使配置檔案和指令行中的參數生效。 mysql_main | handle_early_options     | handle_options | init_common_variables    | get_options(&remaining_argc, &remaining_argv)         | handle_options 在初始化變量過程中,讀取到的配置檔案和指令行參數會全部存放在全局變量remaining_argc和remaining_argv中,在上述兩個函數執行過程中,均使用這兩個變量進行變量的初始化。

handle_early_options 有部分系統變量需要在mysqld --initialize時使用,是以越早初始化越好,handle_early_options函數就是為了初始化這部分系統變量。 handle_early_options   | sys_var_add_options(&all_early_options, sys_var::PARSE_EARLY);   | for (my_option *opt= my_long_early_options; opt->name != NULL;opt++)       all_early_options.push_back(*opt);   | handle_options(&remaining_argc, &remaining_argv, &all_early_options[0], mysqld_get_one_option);

get_options 同樣将屬性為NORMAL的系統變量和靜态系統變量裝載全局變量all_options中 get_options | sys_var_add_options(&all_options, sys_var::PARSE_NORMAL); | for (my_option *opt= my_long_options; .....     all_options.push_back(*opt);   | handle_options(argc_ptr, argv_ptr, &all_options[0], mysqld_get_one_option)))

handle_options 根據輸入參數remaining_argc和remaining_argv,更新系統變量的值 handle_options | my_handle_options           | init_variables(longopts, init_one_value);           | for (pos= *argv, pos_end=pos+ *argc; pos != pos_end ; pos++)     | opt_found= findopt(opt_str, length, &optp)           | error= setval(optp, optp->value, argument......           | get_one_option(optp->id, optp, argument)     在對系統變量進行複制後,會根據系統變量的成員變量id,對系統變量做特殊處理,比如-p參數,會在指令行顯示時隐藏真實的值,以x xxx來代替。

繼續閱讀