1 /* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. 2 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License, version 2.0, 5 as published by the Free Software Foundation. 6 7 This program is also distributed with certain software (including 8 but not limited to OpenSSL) that is licensed under separate terms, 9 as designated in a particular file or component or in included license 10 documentation. The authors of MySQL hereby grant you an additional 11 permission to link the program and your derivative works with the 12 separately licensed software that they have included with MySQL. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License, version 2.0, for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 22 23 #ifndef PERSISTED_VARIABLE_H_INCLUDED 24 #define PERSISTED_VARIABLE_H_INCLUDED 25 26 #include <stddef.h> 27 #include <map> 28 #include <string> 29 #include <vector> 30 31 #include "my_alloc.h" 32 #include "my_inttypes.h" 33 #include "my_psi_config.h" 34 #include "mysql/components/services/mysql_mutex_bits.h" 35 #include "mysql/psi/mysql_mutex.h" 36 #include "mysql/psi/psi_base.h" 37 #include "sql_string.h" 38 39 class Json_dom; 40 class THD; 41 class set_var; 42 class sys_var; 43 struct MYSQL_FILE; 44 45 /** 46 STRUCT st_persist_var 47 48 This structure represents information of a variable which is to 49 be persisted in mysql-auto.cnf file. 50 */ 51 struct st_persist_var { 52 std::string key; 53 std::string value; 54 ulonglong timestamp; 55 std::string user; 56 std::string host; 57 bool is_null; 58 st_persist_var(); 59 st_persist_var(THD *thd); 60 st_persist_var(const std::string key, const std::string value, 61 const ulonglong timestamp, const std::string user, 62 const std::string host, const bool is_null); 63 }; 64 65 /** 66 CLASS Persisted_variables_cache 67 Holds <name,value> pair of all options which needs to be persisted 68 to a file. 69 70 OVERVIEW 71 -------- 72 When first SET PERSIST statement is executed we instantiate 73 Persisted_variables_cache which loads the config file if present into 74 m_persist_variables vector. This is a singleton operation. m_persist_variables 75 is an in-memory copy of config file itself. If the SET statement passes then 76 this in-memory is updated and flushed to file as an atomic operation. 77 78 Next SET PERSIST statement would only update the in-memory copy and sync 79 to config file instead of loading the file again. 80 */ 81 82 #ifdef HAVE_PSI_INTERFACE 83 void my_init_persist_psi_keys(void); 84 #endif /* HAVE_PSI_INTERFACE */ 85 86 class Persisted_variables_cache { 87 public: 88 int init(int *argc, char ***argv); 89 static Persisted_variables_cache *get_instance(); 90 /** 91 Update in-memory copy for every SET PERSIST statement 92 */ 93 bool set_variable(THD *thd, set_var *system_var); 94 /** 95 Flush in-memory copy to persistent file 96 */ 97 bool flush_to_file(); 98 /** 99 Read options from persistent file 100 */ 101 int read_persist_file(); 102 /** 103 Search for persisted config file and if found read persistent options 104 */ 105 bool load_persist_file(); 106 /** 107 Set persisted options 108 */ 109 bool set_persist_options(bool plugin_options = false); 110 /** 111 Reset persisted options 112 */ 113 bool reset_persisted_variables(THD *thd, const char *name, bool if_exists); 114 /** 115 Get persisted variables 116 */ 117 std::vector<st_persist_var> *get_persisted_variables(); 118 /** 119 Get persisted static variables 120 */ 121 std::map<std::string, st_persist_var> *get_persist_ro_variables(); 122 /** 123 append read only persisted variables to command line options with a 124 separator. 125 */ 126 bool append_read_only_variables(int *argc, char ***argv, 127 bool plugin_options = false); 128 void cleanup(); 129 130 /** 131 Acquire lock on m_persist_variables/m_persist_ro_variables 132 */ lock()133 void lock() { mysql_mutex_lock(&m_LOCK_persist_variables); } 134 /** 135 Release lock on m_persist_variables/m_persist_ro_variables 136 */ unlock()137 void unlock() { mysql_mutex_unlock(&m_LOCK_persist_variables); } 138 /** 139 Assert caller that owns lock on m_persist_variables/m_persist_ro_variables 140 */ assert_lock_owner()141 void assert_lock_owner() { 142 mysql_mutex_assert_owner(&m_LOCK_persist_variables); 143 } 144 145 private: 146 /* Helper function to get variable value */ 147 static String *get_variable_value(THD *thd, sys_var *system_var, String *str, 148 bool *is_null); 149 /* Helper function to get variable name */ 150 static const char *get_variable_name(sys_var *system_var); 151 /* Helper function to construct json formatted string */ 152 static String *construct_json_string(std::string name, std::string value, 153 ulonglong timestamp, std::string user, 154 std::string host, bool is_null, 155 String *dest); 156 /* Helper function to extract variables from json formatted string */ 157 bool extract_variables_from_json(const Json_dom *dom, 158 bool is_read_only = false); 159 160 private: 161 /* Helper functions for file IO */ 162 bool open_persist_file(int flag); 163 void close_persist_file(); 164 165 private: 166 /* In memory copy of persistent config file */ 167 std::vector<st_persist_var> m_persist_variables; 168 /* copy of plugin variables whose plugin is not yet installed */ 169 std::vector<st_persist_var> m_persist_plugin_variables; 170 /* In memory copy of read only persistent variables */ 171 std::map<std::string, st_persist_var> m_persist_ro_variables; 172 173 mysql_mutex_t m_LOCK_persist_variables; 174 static Persisted_variables_cache *m_instance; 175 176 /* File handler members */ 177 MYSQL_FILE *m_fd; 178 std::string m_persist_filename; 179 mysql_mutex_t m_LOCK_persist_file; 180 /* Memory for read only persisted options */ 181 MEM_ROOT ro_persisted_argv_alloc{PSI_NOT_INSTRUMENTED, 512}; 182 /* Memory for read only persisted plugin options */ 183 MEM_ROOT ro_persisted_plugin_argv_alloc{PSI_NOT_INSTRUMENTED, 512}; 184 }; 185 186 #endif /* PERSISTED_VARIABLE_H_INCLUDED */ 187