1 /* Copyright (c) 2017, 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 /**
24 @file clone/include/clone.h
25 Clone Plugin: Common objects and interfaces
26 
27 */
28 
29 #ifndef CLONE_H
30 #define CLONE_H
31 
32 #include "mysqld_error.h"
33 #include "plugin/clone/include/clone_hton.h"
34 
35 #include "mysql/psi/mysql_memory.h"
36 #include "mysql/psi/mysql_statement.h"
37 #include "mysql/psi/mysql_thread.h"
38 
39 #include "mysql/components/services/backup_lock_service.h"
40 #include "mysql/components/services/clone_protocol_service.h"
41 #include "mysql/components/services/log_builtins.h"
42 #include "violite.h"
43 
44 extern SERVICE_TYPE(registry) * mysql_service_registry;
45 extern SERVICE_TYPE(mysql_backup_lock) * mysql_service_mysql_backup_lock;
46 extern SERVICE_TYPE(clone_protocol) * mysql_service_clone_protocol;
47 extern SERVICE_TYPE(log_builtins) * log_bi;
48 extern SERVICE_TYPE(log_builtins_string) * log_bs;
49 
50 /** Clone memory key for performance schema */
51 extern PSI_memory_key clone_mem_key;
52 
53 /** Key for registering clone local worker threads */
54 extern PSI_thread_key clone_local_thd_key;
55 
56 /** Key for registering clone client worker threads */
57 extern PSI_thread_key clone_client_thd_key;
58 
59 /** Clone Local statement */
60 extern PSI_statement_key clone_stmt_local_key;
61 
62 /** Clone Remote client statement */
63 extern PSI_statement_key clone_stmt_client_key;
64 
65 /** Clone Remote server statement */
66 extern PSI_statement_key clone_stmt_server_key;
67 
68 /** Size of intermediate buffer for transferring data from source
69 file to network or destination file. */
70 extern uint clone_buffer_size;
71 
72 /** Clone system variable: timeout for DDL lock */
73 extern uint clone_ddl_timeout;
74 
75 /** Clone system variable: If concurrency is automatically tuned */
76 extern bool clone_autotune_concurrency;
77 
78 /** Clone system variable: Maximum concurrent threads */
79 extern uint clone_max_concurrency;
80 
81 /** Clone system variable: Maximum network bandwidth in MiB/sec */
82 extern uint clone_max_network_bandwidth;
83 
84 /** Clone system variable: Maximum IO bandwidth in MiB/sec */
85 extern uint clone_max_io_bandwidth;
86 
87 /** Clone system variable: If network compression is enabled */
88 extern bool clone_enable_compression;
89 
90 /** Clone system variable: SSL private key */
91 extern char *clone_client_ssl_private_key;
92 
93 /** Clone system variable: SSL Certificate */
94 extern char *clone_client_ssl_certificate;
95 
96 /** Clone system variable: SSL Certificate authority */
97 extern char *clone_client_ssl_certficate_authority;
98 
99 /** Number of storage engines supporting clone. */
100 const uint MAX_CLONE_STORAGE_ENGINE = 16;
101 
102 /** Sleep time in microseconds between multiple failed attempts. */
103 const uint CLONE_CONN_REATTEMPT_INTERVAL = 5 * 1000 * 1000;  // 5 sec
104 
105 /** Maximum number of connection retry during re-connect */
106 const uint CLONE_MAX_CONN_RETRY = 60;  // 60 x 5 sec = 5 minutes
107 
108 /** Maximum number of restart attempts */
109 const uint CLONE_MAX_RESTART = 100;
110 
111 /** Minimum block size of clone data. */
112 const uint CLONE_MIN_BLOCK = 1024 * 1024;
113 
114 /** Minimum network packet. Safe margin for meta information */
115 const uint CLONE_MIN_NET_BLOCK = 2 * CLONE_MIN_BLOCK;
116 
117 /* Namespace for all clone data types */
118 namespace myclone {
119 
120 /**  Clone protocol version */
121 const uint32_t CLONE_PROTOCOL_VERSION = 0x0100;
122 
123 /** Clone protocol commands. Please bump the protocol version before adding
124 new command. */
125 typedef enum Type_Cmmand_RPC : uchar {
126   /** Initialize clone and negotiate version */
127   COM_INIT = 1,
128 
129   /** Attach to current on going clone operation */
130   COM_ATTACH,
131 
132   /** Re-Initialize clone network error */
133   COM_REINIT,
134 
135   /** Execute command to clone remote database */
136   COM_EXECUTE,
137 
138   /** Send Error or ACK data to remote database */
139   COM_ACK,
140 
141   /** Exit clone protocol */
142   COM_EXIT,
143 
144   /** Limit value for clone RPC */
145   COM_MAX
146 } Command_RPC;
147 
148 /** Clone protocol response. Please bump the protocol version before adding
149 new response. */
150 typedef enum Type_Command_Response : uchar {
151   /** Remote Locators */
152   COM_RES_LOCS = 1,
153 
154   /** Remote Data descriptor */
155   COM_RES_DATA_DESC,
156 
157   /** Remote Data */
158   COM_RES_DATA,
159 
160   /** Plugin */
161   COM_RES_PLUGIN,
162 
163   /** Configuration */
164   COM_RES_CONFIG,
165 
166   /** Character set collation */
167   COM_RES_COLLATION,
168 
169   /** End of response data */
170   COM_RES_COMPLETE = 99,
171 
172   /** Error in remote server operation */
173   COM_RES_ERROR = 100,
174 
175   /** Limit value for clone RPC response */
176   COM_RES_MAX
177 } Command_Response;
178 
179 using String_Key = std::string;
180 using String_Keys = std::vector<String_Key>;
181 
182 using Key_Value = std::pair<String_Key, String_Key>;
183 using Key_Values = std::vector<Key_Value>;
184 
185 /** We transfers data between storage handle and external data link.
186 Storage handle is always identified by a set of locators provided by
187 the Storage Engines. External data link could be of type buffer or file
188 in case of local clone and network socket in case of remote clone. */
189 enum Data_Link_Type {
190   CLONE_HANDLE_SOCKET = 1,
191   CLONE_HANDLE_BUFFER,
192   CLONE_HANDLE_FILE
193 };
194 
195 /** Data stored in buffer */
196 struct Buffer {
197   /** Initialize buffer */
initBuffer198   void init() {
199     m_buffer = nullptr;
200     m_length = 0;
201   }
202 
203   /** Allocate or Re-Allocate buffer
204   @param[in]	length	length to allocate or extend to
205   @return error if allocation fails. */
allocateBuffer206   int allocate(size_t length) {
207     if (m_length >= length) {
208       DBUG_ASSERT(m_buffer != nullptr);
209       return (0);
210     }
211 
212     uchar *temp_ptr = nullptr;
213 
214     if (m_buffer == nullptr) {
215       temp_ptr =
216           static_cast<uchar *>(my_malloc(clone_mem_key, length, MYF(MY_WME)));
217 
218     } else {
219       temp_ptr = static_cast<uchar *>(
220           my_realloc(clone_mem_key, m_buffer, length, MYF(MY_WME)));
221     }
222 
223     if (temp_ptr == nullptr) {
224       my_error(ER_OUTOFMEMORY, MYF(0), length);
225       return (ER_OUTOFMEMORY);
226     }
227 
228     m_buffer = temp_ptr;
229     m_length = length;
230 
231     return (0);
232   }
233 
234   /** Free buffer */
freeBuffer235   void free() {
236     my_free(m_buffer);
237     init();
238   }
239 
240   /** Buffer pointer */
241   uchar *m_buffer;
242 
243   /** Buffer length */
244   size_t m_length;
245 };
246 
247 /** Data stored in file */
248 struct File {
249   /** Open file descriptor */
250   Ha_clone_file m_file_desc;
251 
252   /** Data length */
253   uint m_length;
254 };
255 
256 /** External data link for transfer */
257 struct Data_Link {
258   /** Get external handle type.
259   @return handle type */
get_typeData_Link260   Data_Link_Type get_type() { return (m_type); }
261 
262   /** Get external handle of type buffer. Caller must ensure
263   correct handle type.
264   @return clone buffer */
get_bufferData_Link265   Buffer *get_buffer() {
266     DBUG_ASSERT(m_type == CLONE_HANDLE_BUFFER);
267     return (&m_buffer);
268   }
269 
270   /** Set external handle buffer.
271   @param[in]	in_buf	buffer pointer
272   @param[in]	in_len	buffer length */
set_bufferData_Link273   void set_buffer(uchar *in_buf, uint in_len) {
274     m_type = CLONE_HANDLE_BUFFER;
275 
276     m_buffer.m_buffer = in_buf;
277     m_buffer.m_length = in_len;
278   }
279 
280   /** Get external handle of type file. Caller must ensure
281   correct handle type.
282   @return clone file */
get_fileData_Link283   File *get_file() {
284     DBUG_ASSERT(m_type == CLONE_HANDLE_FILE);
285     return (&m_file);
286   }
287 
288   /** Set external handle file.
289   @param[in]	in_file	file descriptor
290   @param[in]	in_len	data length */
set_fileData_Link291   void set_file(Ha_clone_file in_file, uint in_len) {
292     m_type = CLONE_HANDLE_FILE;
293 
294     m_file.m_file_desc = in_file;
295     m_file.m_length = in_len;
296   }
297 
298   /** Set external handle socket.
299   @param[in]	socket	network socket */
set_socketData_Link300   void set_socket(MYSQL_SOCKET socket) {
301     m_type = CLONE_HANDLE_SOCKET;
302     m_socket = socket;
303   }
304 
305  private:
306   /** external handle type */
307   Data_Link_Type m_type;
308 
309   /** external handle data */
310   union {
311     MYSQL_SOCKET m_socket;
312     Buffer m_buffer;
313     File m_file;
314   };
315 };
316 
317 /** Validate all local configuration parameters.
318 @param[in]	thd	current session THD
319 @return error code */
320 int validate_local_params(THD *thd);
321 }  // namespace myclone
322 
323 #endif /* CLONE_H */
324