1 | /* Copyright (C) 2009-2013 Codership Oy <info@codership.com> |
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 as published by |
5 | the Free Software Foundation; version 2 of the License. |
6 | |
7 | This program is distributed in the hope that it will be useful, |
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
10 | GNU General Public License for more details. |
11 | |
12 | You should have received a copy of the GNU General Public License along |
13 | with this program; if not, write to the Free Software Foundation, Inc., |
14 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
15 | */ |
16 | |
17 | /*! |
18 | @file wsrep API declaration. |
19 | |
20 | HOW TO READ THIS FILE. |
21 | |
22 | Due to C language rules this header layout doesn't lend itself to intuitive |
23 | reading. So here's the scoop: in the end this header declares two main types: |
24 | |
25 | * struct wsrep_init_args |
26 | |
27 | and |
28 | |
29 | * struct wsrep |
30 | |
31 | wsrep_init_args contains initialization parameters for wsrep provider like |
32 | names, addresses, etc. and pointers to callbacks. The callbacks will be called |
33 | by provider when it needs to do something application-specific, like log a |
34 | message or apply a writeset. It should be passed to init() call from |
35 | wsrep API. It is an application part of wsrep API contract. |
36 | |
37 | struct wsrep is the interface to wsrep provider. It contains all wsrep API |
38 | calls. It is a provider part of wsrep API contract. |
39 | |
40 | Finally, wsrep_load() method loads (dlopens) wsrep provider library. It is |
41 | defined in wsrep_loader.c unit and is part of libwsrep.a (which is not a |
42 | wsrep provider, but a convenience library). |
43 | |
44 | wsrep_unload() does the reverse. |
45 | |
46 | */ |
47 | #ifndef WSREP_H |
48 | #define WSREP_H |
49 | |
50 | #include <stdint.h> |
51 | #include <stdlib.h> |
52 | #include <unistd.h> |
53 | #include <time.h> |
54 | |
55 | #ifdef __cplusplus |
56 | extern "C" { |
57 | #endif |
58 | |
59 | /************************************************************************** |
60 | * * |
61 | * wsrep replication API * |
62 | * * |
63 | **************************************************************************/ |
64 | |
65 | #define WSREP_INTERFACE_VERSION "25" |
66 | |
67 | /*! Empty backend spec */ |
68 | #define WSREP_NONE "none" |
69 | |
70 | |
71 | /*! |
72 | * @brief log severity levels, passed as first argument to log handler |
73 | */ |
74 | typedef enum wsrep_log_level |
75 | { |
76 | WSREP_LOG_FATAL, //!< Unrecoverable error, application must quit. |
77 | WSREP_LOG_ERROR, //!< Operation failed, must be repeated. |
78 | WSREP_LOG_WARN, //!< Unexpected condition, but no operational failure. |
79 | WSREP_LOG_INFO, //!< Informational message. |
80 | WSREP_LOG_DEBUG //!< Debug message. Shows only of compiled with debug. |
81 | } wsrep_log_level_t; |
82 | |
83 | /*! |
84 | * @brief error log handler |
85 | * |
86 | * All messages from wsrep provider are directed to this |
87 | * handler, if present. |
88 | * |
89 | * @param level log level |
90 | * @param message log message |
91 | */ |
92 | typedef void (*wsrep_log_cb_t)(wsrep_log_level_t, const char *); |
93 | |
94 | |
95 | /*! |
96 | * Certain provider capabilities application may want to know about |
97 | */ |
98 | #define WSREP_CAP_MULTI_MASTER ( 1ULL << 0 ) |
99 | #define WSREP_CAP_CERTIFICATION ( 1ULL << 1 ) |
100 | #define WSREP_CAP_PARALLEL_APPLYING ( 1ULL << 2 ) |
101 | #define WSREP_CAP_TRX_REPLAY ( 1ULL << 3 ) |
102 | #define WSREP_CAP_ISOLATION ( 1ULL << 4 ) |
103 | #define WSREP_CAP_PAUSE ( 1ULL << 5 ) |
104 | #define WSREP_CAP_CAUSAL_READS ( 1ULL << 6 ) |
105 | #define WSREP_CAP_CAUSAL_TRX ( 1ULL << 7 ) |
106 | #define WSREP_CAP_INCREMENTAL_WRITESET ( 1ULL << 8 ) |
107 | #define WSREP_CAP_SESSION_LOCKS ( 1ULL << 9 ) |
108 | #define WSREP_CAP_DISTRIBUTED_LOCKS ( 1ULL << 10 ) |
109 | #define WSREP_CAP_CONSISTENCY_CHECK ( 1ULL << 11 ) |
110 | #define WSREP_CAP_UNORDERED ( 1ULL << 12 ) |
111 | #define WSREP_CAP_ANNOTATION ( 1ULL << 13 ) |
112 | #define WSREP_CAP_PREORDERED ( 1ULL << 14 ) |
113 | |
114 | |
115 | /*! |
116 | * Writeset flags |
117 | * |
118 | * COMMIT the writeset and all preceding writesets must be committed |
119 | * ROLLBACK all preceding writesets in a transaction must be rolled back |
120 | * ISOLATION the writeset must be applied AND committed in isolation |
121 | * PA_UNSAFE the writeset cannot be applied in parallel |
122 | * COMMUTATIVE the order in which the writeset is applied does not matter |
123 | * NATIVE the writeset contains another writeset in this provider format |
124 | * |
125 | * Note that some of the flags are mutually exclusive (e.g. COMMIT and |
126 | * ROLLBACK). |
127 | */ |
128 | #define WSREP_FLAG_COMMIT ( 1ULL << 0 ) |
129 | #define WSREP_FLAG_ROLLBACK ( 1ULL << 1 ) |
130 | #define WSREP_FLAG_ISOLATION ( 1ULL << 2 ) |
131 | #define WSREP_FLAG_PA_UNSAFE ( 1ULL << 3 ) |
132 | #define WSREP_FLAG_COMMUTATIVE ( 1ULL << 4 ) |
133 | #define WSREP_FLAG_NATIVE ( 1ULL << 5 ) |
134 | |
135 | |
136 | typedef uint64_t wsrep_trx_id_t; //!< application transaction ID |
137 | typedef uint64_t wsrep_conn_id_t; //!< application connection ID |
138 | typedef int64_t wsrep_seqno_t; //!< sequence number of a writeset, etc. |
139 | #ifdef __cplusplus |
140 | typedef bool wsrep_bool_t; |
141 | #else |
142 | typedef _Bool wsrep_bool_t; //!< should be the same as standard (C99) bool |
143 | #endif /* __cplusplus */ |
144 | |
145 | /*! undefined seqno */ |
146 | #define WSREP_SEQNO_UNDEFINED (-1) |
147 | |
148 | |
149 | /*! wsrep provider status codes */ |
150 | typedef enum wsrep_status |
151 | { |
152 | WSREP_OK = 0, //!< success |
153 | WSREP_WARNING, //!< minor warning, error logged |
154 | WSREP_TRX_MISSING, //!< transaction is not known by wsrep |
155 | WSREP_TRX_FAIL, //!< transaction aborted, server can continue |
156 | WSREP_BF_ABORT, //!< trx was victim of brute force abort |
157 | WSREP_SIZE_EXCEEDED, //!< data exceeded maximum supported size |
158 | WSREP_CONN_FAIL, //!< error in client connection, must abort |
159 | WSREP_NODE_FAIL, //!< error in node state, wsrep must reinit |
160 | WSREP_FATAL, //!< fatal error, server must abort |
161 | WSREP_NOT_IMPLEMENTED //!< feature not implemented |
162 | } wsrep_status_t; |
163 | |
164 | |
165 | /*! wsrep callbacks status codes */ |
166 | typedef enum wsrep_cb_status |
167 | { |
168 | WSREP_CB_SUCCESS = 0, //!< success (as in "not critical failure") |
169 | WSREP_CB_FAILURE //!< critical failure (consistency violation) |
170 | /* Technically, wsrep provider has no use for specific failure codes since |
171 | * there is nothing it can do about it but abort execution. Therefore any |
172 | * positive number shall indicate a critical failure. Optionally that value |
173 | * may be used by provider to come to a consensus about state consistency |
174 | * in a group of nodes. */ |
175 | } wsrep_cb_status_t; |
176 | |
177 | |
178 | /*! |
179 | * UUID type - for all unique IDs |
180 | */ |
181 | typedef struct wsrep_uuid { |
182 | uint8_t data[16]; |
183 | } wsrep_uuid_t; |
184 | |
185 | /*! Undefined UUID */ |
186 | static const wsrep_uuid_t WSREP_UUID_UNDEFINED = {{0,}}; |
187 | |
188 | /*! UUID string representation length, terminating '\0' not included */ |
189 | #define WSREP_UUID_STR_LEN 36 |
190 | |
191 | /*! |
192 | * Scan UUID from string |
193 | * @return length of UUID string representation or negative error code |
194 | */ |
195 | extern int |
196 | wsrep_uuid_scan (const char* str, size_t str_len, wsrep_uuid_t* uuid); |
197 | |
198 | /*! |
199 | * Print UUID to string |
200 | * @return length of UUID string representation or negative error code |
201 | */ |
202 | extern int |
203 | wsrep_uuid_print (const wsrep_uuid_t* uuid, char* str, size_t str_len); |
204 | |
205 | #define WSREP_MEMBER_NAME_LEN 32 //!< maximum logical member name length |
206 | #define WSREP_INCOMING_LEN 256 //!< max Domain Name length + 0x00 |
207 | |
208 | |
209 | /*! |
210 | * Global transaction identifier |
211 | */ |
212 | typedef struct wsrep_gtid |
213 | { |
214 | wsrep_uuid_t uuid; /*!< History UUID */ |
215 | wsrep_seqno_t seqno; /*!< Sequence number */ |
216 | } wsrep_gtid_t; |
217 | |
218 | /*! Undefined GTID */ |
219 | static const wsrep_gtid_t WSREP_GTID_UNDEFINED = {{{0, }}, -1}; |
220 | |
221 | /*! Minimum number of bytes guaranteed to store GTID string representation, |
222 | * terminating '\0' not included (36 + 1 + 20) */ |
223 | #define WSREP_GTID_STR_LEN 57 |
224 | |
225 | |
226 | /*! |
227 | * Scan GTID from string |
228 | * @return length of GTID string representation or negative error code |
229 | */ |
230 | extern int |
231 | wsrep_gtid_scan(const char* str, size_t str_len, wsrep_gtid_t* gtid); |
232 | |
233 | /*! |
234 | * Print GTID to string |
235 | * @return length of GTID string representation or negative error code |
236 | */ |
237 | extern int |
238 | wsrep_gtid_print(const wsrep_gtid_t* gtid, char* str, size_t str_len); |
239 | |
240 | |
241 | /*! |
242 | * Transaction meta data |
243 | */ |
244 | typedef struct wsrep_trx_meta |
245 | { |
246 | wsrep_gtid_t gtid; /*!< Global transaction identifier */ |
247 | wsrep_seqno_t depends_on; /*!< Sequence number part of the last transaction |
248 | this transaction depends on */ |
249 | } wsrep_trx_meta_t; |
250 | |
251 | |
252 | /*! |
253 | * member status |
254 | */ |
255 | typedef enum wsrep_member_status { |
256 | WSREP_MEMBER_UNDEFINED, //!< undefined state |
257 | WSREP_MEMBER_JOINER, //!< incomplete state, requested state transfer |
258 | WSREP_MEMBER_DONOR, //!< complete state, donates state transfer |
259 | WSREP_MEMBER_JOINED, //!< complete state |
260 | WSREP_MEMBER_SYNCED, //!< complete state, synchronized with group |
261 | WSREP_MEMBER_ERROR, //!< this and above is provider-specific error code |
262 | WSREP_MEMBER_MAX |
263 | } wsrep_member_status_t; |
264 | |
265 | /*! |
266 | * static information about a group member (some fields are tentative yet) |
267 | */ |
268 | typedef struct wsrep_member_info { |
269 | wsrep_uuid_t id; //!< group-wide unique member ID |
270 | char name[WSREP_MEMBER_NAME_LEN]; //!< human-readable name |
271 | char incoming[WSREP_INCOMING_LEN]; //!< address for client requests |
272 | } wsrep_member_info_t; |
273 | |
274 | /*! |
275 | * group status |
276 | */ |
277 | typedef enum wsrep_view_status { |
278 | WSREP_VIEW_PRIMARY, //!< primary group configuration (quorum present) |
279 | WSREP_VIEW_NON_PRIMARY, //!< non-primary group configuration (quorum lost) |
280 | WSREP_VIEW_DISCONNECTED, //!< not connected to group, retrying. |
281 | WSREP_VIEW_MAX |
282 | } wsrep_view_status_t; |
283 | |
284 | /*! |
285 | * view of the group |
286 | */ |
287 | typedef struct wsrep_view_info { |
288 | wsrep_gtid_t state_id; //!< global state ID |
289 | wsrep_seqno_t view; //!< global view number |
290 | wsrep_view_status_t status; //!< view status |
291 | wsrep_bool_t state_gap; //!< gap between global and local states |
292 | int my_idx; //!< index of this member in the view |
293 | int memb_num; //!< number of members in the view |
294 | int proto_ver; //!< application protocol agreed on the view |
295 | wsrep_member_info_t members[1];//!< array of member information |
296 | } wsrep_view_info_t; |
297 | |
298 | /*! |
299 | * Magic string to tell provider to engage into trivial (empty) state transfer. |
300 | * No data will be passed, but the node shall be considered JOINED. |
301 | * Should be passed in sst_req parameter of wsrep_view_cb_t. |
302 | */ |
303 | #define WSREP_STATE_TRANSFER_TRIVIAL "trivial" |
304 | |
305 | /*! |
306 | * Magic string to tell provider not to engage in state transfer at all. |
307 | * The member will stay in WSREP_MEMBER_UNDEFINED state but will keep on |
308 | * receiving all writesets. |
309 | * Should be passed in sst_req parameter of wsrep_view_cb_t. |
310 | */ |
311 | #define WSREP_STATE_TRANSFER_NONE "none" |
312 | |
313 | /*! |
314 | * @brief group view handler |
315 | * |
316 | * This handler is called in total order corresponding to the group |
317 | * configuration change. It is to provide a vital information about |
318 | * new group view. If view info indicates existence of discontinuity |
319 | * between group and member states, state transfer request message |
320 | * should be filled in by the callback implementation. |
321 | * |
322 | * @note Currently it is assumed that sst_req is allocated using |
323 | * malloc()/calloc()/realloc() and it will be freed by |
324 | * wsrep implementation. |
325 | * |
326 | * @param app_ctx application context |
327 | * @param recv_ctx receiver context |
328 | * @param view new view on the group |
329 | * @param state current state |
330 | * @param state_len lenght of current state |
331 | * @param sst_req location to store SST request |
332 | * @param sst_req_len location to store SST request length or error code, |
333 | * value of 0 means no SST. |
334 | */ |
335 | typedef enum wsrep_cb_status (*wsrep_view_cb_t) ( |
336 | void* app_ctx, |
337 | void* recv_ctx, |
338 | const wsrep_view_info_t* view, |
339 | const char* state, |
340 | size_t state_len, |
341 | void** sst_req, |
342 | size_t* sst_req_len |
343 | ); |
344 | |
345 | |
346 | /*! |
347 | * @brief apply callback |
348 | * |
349 | * This handler is called from wsrep library to apply replicated writeset |
350 | * Must support brute force applying for multi-master operation |
351 | * |
352 | * @param recv_ctx receiver context pointer provided by the application |
353 | * @param data data buffer containing the writeset |
354 | * @param size data buffer size |
355 | * @param flags WSREP_FLAG_... flags |
356 | * @param meta transaction meta data of the writeset to be applied |
357 | * |
358 | * @return success code: |
359 | * @retval WSREP_OK |
360 | * @retval WSREP_NOT_IMPLEMENTED appl. does not support the writeset format |
361 | * @retval WSREP_ERROR failed to apply the writeset |
362 | */ |
363 | typedef enum wsrep_cb_status (*wsrep_apply_cb_t) ( |
364 | void* recv_ctx, |
365 | const void* data, |
366 | size_t size, |
367 | uint32_t flags, |
368 | const wsrep_trx_meta_t* meta |
369 | ); |
370 | |
371 | |
372 | /*! |
373 | * @brief commit callback |
374 | * |
375 | * This handler is called to commit the changes made by apply callback. |
376 | * |
377 | * @param recv_ctx receiver context pointer provided by the application |
378 | * @param flags WSREP_FLAG_... flags |
379 | * @param meta transaction meta data of the writeset to be committed |
380 | * @param exit set to true to exit recv loop |
381 | * @param commit true - commit writeset, false - rollback writeset |
382 | * |
383 | * @return success code: |
384 | * @retval WSREP_OK |
385 | * @retval WSREP_ERROR call failed |
386 | */ |
387 | typedef enum wsrep_cb_status (*wsrep_commit_cb_t) ( |
388 | void* recv_ctx, |
389 | uint32_t flags, |
390 | const wsrep_trx_meta_t* meta, |
391 | wsrep_bool_t* exit, |
392 | wsrep_bool_t commit |
393 | ); |
394 | |
395 | |
396 | /*! |
397 | * @brief unordered callback |
398 | * |
399 | * This handler is called to execute unordered actions (actions that need not |
400 | * to be executed in any particular order) attached to writeset. |
401 | * |
402 | * @param recv_ctx receiver context pointer provided by the application |
403 | * @param data data buffer containing the writeset |
404 | * @param size data buffer size |
405 | */ |
406 | typedef enum wsrep_cb_status (*wsrep_unordered_cb_t) ( |
407 | void* recv_ctx, |
408 | const void* data, |
409 | size_t size |
410 | ); |
411 | |
412 | |
413 | /*! |
414 | * @brief a callback to donate state snapshot |
415 | * |
416 | * This handler is called from wsrep library when it needs this node |
417 | * to deliver state to a new cluster member. |
418 | * No state changes will be committed for the duration of this call. |
419 | * Wsrep implementation may provide internal state to be transmitted |
420 | * to new cluster member for initial state. |
421 | * |
422 | * @param app_ctx application context |
423 | * @param recv_ctx receiver context |
424 | * @param msg state transfer request message |
425 | * @param msg_len state transfer request message length |
426 | * @param gtid current state ID on this node |
427 | * @param state current wsrep internal state buffer |
428 | * @param state_len current wsrep internal state buffer len |
429 | * @param bypass bypass snapshot transfer, only transfer uuid:seqno pair |
430 | */ |
431 | typedef enum wsrep_cb_status (*wsrep_sst_donate_cb_t) ( |
432 | void* app_ctx, |
433 | void* recv_ctx, |
434 | const void* msg, |
435 | size_t msg_len, |
436 | const wsrep_gtid_t* state_id, |
437 | const char* state, |
438 | size_t state_len, |
439 | wsrep_bool_t bypass |
440 | ); |
441 | |
442 | |
443 | /*! |
444 | * @brief a callback to signal application that wsrep state is synced |
445 | * with cluster |
446 | * |
447 | * This callback is called after wsrep library has got in sync with |
448 | * rest of the cluster. |
449 | * |
450 | * @param app_ctx application context |
451 | */ |
452 | typedef void (*wsrep_synced_cb_t) (void* app_ctx); |
453 | |
454 | |
455 | /*! |
456 | * Initialization parameters for wsrep provider. |
457 | */ |
458 | struct wsrep_init_args |
459 | { |
460 | void* app_ctx; //!< Application context for callbacks |
461 | |
462 | /* Configuration parameters */ |
463 | const char* node_name; //!< Symbolic name of this node (e.g. hostname) |
464 | const char* node_address; //!< Address to be used by wsrep provider |
465 | const char* node_incoming; //!< Address for incoming client connections |
466 | const char* data_dir; //!< Directory where wsrep files are kept if any |
467 | const char* options; //!< Provider-specific configuration string |
468 | int proto_ver; //!< Max supported application protocol version |
469 | |
470 | /* Application initial state information. */ |
471 | const wsrep_gtid_t* state_id; //!< Application state GTID |
472 | const char* state; //!< Initial state for wsrep provider |
473 | size_t state_len; //!< Length of state buffer |
474 | |
475 | /* Application callbacks */ |
476 | wsrep_log_cb_t logger_cb; //!< logging handler |
477 | wsrep_view_cb_t view_handler_cb; //!< group view change handler |
478 | |
479 | /* Applier callbacks */ |
480 | wsrep_apply_cb_t apply_cb; //!< apply callback |
481 | wsrep_commit_cb_t commit_cb; //!< commit callback |
482 | wsrep_unordered_cb_t unordered_cb; //!< callback for unordered actions |
483 | |
484 | /* State Snapshot Transfer callbacks */ |
485 | wsrep_sst_donate_cb_t sst_donate_cb; //!< starting to donate |
486 | wsrep_synced_cb_t synced_cb; //!< synced with group |
487 | }; |
488 | |
489 | |
490 | /*! Type of the stats variable value in struct wsrep_status_var */ |
491 | typedef enum wsrep_var_type |
492 | { |
493 | WSREP_VAR_STRING, //!< pointer to null-terminated string |
494 | WSREP_VAR_INT64, //!< int64_t |
495 | WSREP_VAR_DOUBLE //!< double |
496 | } |
497 | wsrep_var_type_t; |
498 | |
499 | /*! Generalized stats variable representation */ |
500 | struct wsrep_stats_var |
501 | { |
502 | const char* name; //!< variable name |
503 | wsrep_var_type_t type; //!< variable value type |
504 | union { |
505 | int64_t _integer64; |
506 | double _double; |
507 | const char* _string; |
508 | } value; //!< variable value |
509 | }; |
510 | |
511 | |
512 | /*! Abstract data buffer structure */ |
513 | typedef struct wsrep_buf |
514 | { |
515 | const void* ptr; /*!< Pointer to data buffer */ |
516 | size_t len; /*!< Length of buffer */ |
517 | } wsrep_buf_t; |
518 | |
519 | /*! Key struct used to pass certification keys for transaction handling calls. |
520 | * A key consists of zero or more key parts. */ |
521 | typedef struct wsrep_key |
522 | { |
523 | const wsrep_buf_t* key_parts; /*!< Array of key parts */ |
524 | size_t key_parts_num; /*!< Number of key parts */ |
525 | } wsrep_key_t; |
526 | |
527 | /*! Key type: |
528 | * EXCLUSIVE conflicts with any key type |
529 | * SEMI reserved. If not supported, should be interpeted as EXCLUSIVE |
530 | * SHARED conflicts only with EXCLUSIVE keys */ |
531 | typedef enum wsrep_key_type |
532 | { |
533 | WSREP_KEY_SHARED = 0, |
534 | WSREP_KEY_SEMI, |
535 | WSREP_KEY_EXCLUSIVE |
536 | } wsrep_key_type_t; |
537 | |
538 | /*! Data type: |
539 | * ORDERED state modification event that should be applied and committed |
540 | * in order. |
541 | * UNORDERED some action that does not modify state and execution of which is |
542 | * optional and does not need to happen in order. |
543 | * ANNOTATION (human readable) writeset annotation. */ |
544 | typedef enum wsrep_data_type |
545 | { |
546 | WSREP_DATA_ORDERED = 0, |
547 | WSREP_DATA_UNORDERED, |
548 | WSREP_DATA_ANNOTATION |
549 | } wsrep_data_type_t; |
550 | |
551 | |
552 | /*! Transaction handle struct passed for wsrep transaction handling calls */ |
553 | typedef struct wsrep_ws_handle |
554 | { |
555 | wsrep_trx_id_t trx_id; //!< transaction ID |
556 | void* opaque; //!< opaque provider transaction context data |
557 | } wsrep_ws_handle_t; |
558 | |
559 | /*! |
560 | * @brief Helper method to reset trx writeset handle state when trx id changes |
561 | * |
562 | * Instead of passing wsrep_ws_handle_t directly to wsrep calls, |
563 | * wrapping handle with this call offloads bookkeeping from |
564 | * application. |
565 | */ |
566 | static inline wsrep_ws_handle_t* wsrep_ws_handle_for_trx( |
567 | wsrep_ws_handle_t* ws_handle, |
568 | wsrep_trx_id_t trx_id) |
569 | { |
570 | if (ws_handle->trx_id != trx_id) |
571 | { |
572 | ws_handle->trx_id = trx_id; |
573 | ws_handle->opaque = NULL; |
574 | } |
575 | return ws_handle; |
576 | } |
577 | |
578 | |
579 | /*! |
580 | * A handle for processing preordered actions. |
581 | * Must be initialized to WSREP_PO_INITIALIZER before use. |
582 | */ |
583 | typedef struct wsrep_po_handle { void* opaque; } wsrep_po_handle_t; |
584 | |
585 | static const wsrep_po_handle_t WSREP_PO_INITIALIZER = { NULL }; |
586 | |
587 | |
588 | typedef struct wsrep wsrep_t; |
589 | /*! |
590 | * wsrep interface for dynamically loadable libraries |
591 | */ |
592 | struct wsrep { |
593 | |
594 | const char *version; //!< interface version string |
595 | |
596 | /*! |
597 | * @brief Initializes wsrep provider |
598 | * |
599 | * @param wsrep provider handle |
600 | * @param args wsrep initialization parameters |
601 | */ |
602 | wsrep_status_t (*init) (wsrep_t* wsrep, |
603 | const struct wsrep_init_args* args); |
604 | |
605 | /*! |
606 | * @brief Returns provider capabilities flag bitmap |
607 | * |
608 | * @param wsrep provider handle |
609 | */ |
610 | uint64_t (*capabilities) (wsrep_t* wsrep); |
611 | |
612 | /*! |
613 | * @brief Passes provider-specific configuration string to provider. |
614 | * |
615 | * @param wsrep provider handle |
616 | * @param conf configuration string |
617 | * |
618 | * @retval WSREP_OK configuration string was parsed successfully |
619 | * @retval WSREP_WARNING could't not parse conf string, no action taken |
620 | */ |
621 | wsrep_status_t (*options_set) (wsrep_t* wsrep, const char* conf); |
622 | |
623 | /*! |
624 | * @brief Returns provider-specific string with current configuration values. |
625 | * |
626 | * @param wsrep provider handle |
627 | * |
628 | * @return a dynamically allocated string with current configuration |
629 | * parameter values |
630 | */ |
631 | char* (*options_get) (wsrep_t* wsrep); |
632 | |
633 | /*! |
634 | * @brief Opens connection to cluster |
635 | * |
636 | * Returns when either node is ready to operate as a part of the clsuter |
637 | * or fails to reach operating status. |
638 | * |
639 | * @param wsrep provider handle |
640 | * @param cluster_name unique symbolic cluster name |
641 | * @param cluster_url URL-like cluster address (backend://address) |
642 | * @param state_donor name of the node to be asked for state transfer. |
643 | * @param bootstrap a flag to request initialization of a new wsrep |
644 | * service rather then a connection to the existing one. |
645 | * clister_url may still carry important initialization |
646 | * parameters, like backend spec and/or listen address. |
647 | */ |
648 | wsrep_status_t (*connect) (wsrep_t* wsrep, |
649 | const char* cluster_name, |
650 | const char* cluster_url, |
651 | const char* state_donor, |
652 | wsrep_bool_t bootstrap); |
653 | |
654 | /*! |
655 | * @brief Closes connection to cluster. |
656 | * |
657 | * If state_uuid and/or state_seqno is not NULL, will store final state |
658 | * in there. |
659 | * |
660 | * @param wsrep this wsrep handler |
661 | */ |
662 | wsrep_status_t (*disconnect)(wsrep_t* wsrep); |
663 | |
664 | /*! |
665 | * @brief start receiving replication events |
666 | * |
667 | * This function never returns |
668 | * |
669 | * @param wsrep provider handle |
670 | * @param recv_ctx receiver context |
671 | */ |
672 | wsrep_status_t (*recv)(wsrep_t* wsrep, void* recv_ctx); |
673 | |
674 | /*! |
675 | * @brief Replicates/logs result of transaction to other nodes and allocates |
676 | * required resources. |
677 | * |
678 | * Must be called before transaction commit. Returns success code, which |
679 | * caller must check. |
680 | * In case of WSREP_OK, starts commit critical section, transaction can |
681 | * commit. Otherwise transaction must rollback. |
682 | * |
683 | * @param wsrep provider handle |
684 | * @param ws_handle writeset of committing transaction |
685 | * @param conn_id connection ID |
686 | * @param flags fine tuning the replication WSREP_FLAG_* |
687 | * @param meta transaction meta data |
688 | * |
689 | * @retval WSREP_OK cluster-wide commit succeeded |
690 | * @retval WSREP_TRX_FAIL must rollback transaction |
691 | * @retval WSREP_CONN_FAIL must close client connection |
692 | * @retval WSREP_NODE_FAIL must close all connections and reinit |
693 | */ |
694 | wsrep_status_t (*pre_commit)(wsrep_t* wsrep, |
695 | wsrep_conn_id_t conn_id, |
696 | wsrep_ws_handle_t* ws_handle, |
697 | uint32_t flags, |
698 | wsrep_trx_meta_t* meta); |
699 | |
700 | /*! |
701 | * @brief Releases resources after transaction commit. |
702 | * |
703 | * Ends commit critical section. |
704 | * |
705 | * @param wsrep provider handle |
706 | * @param ws_handle writeset of committing transaction |
707 | * @retval WSREP_OK post_commit succeeded |
708 | */ |
709 | wsrep_status_t (*post_commit) (wsrep_t* wsrep, |
710 | wsrep_ws_handle_t* ws_handle); |
711 | |
712 | /*! |
713 | * @brief Releases resources after transaction rollback. |
714 | * |
715 | * @param wsrep provider handle |
716 | * @param ws_handle writeset of committing transaction |
717 | * @retval WSREP_OK post_rollback succeeded |
718 | */ |
719 | wsrep_status_t (*post_rollback)(wsrep_t* wsrep, |
720 | wsrep_ws_handle_t* ws_handle); |
721 | |
722 | /*! |
723 | * @brief Replay trx as a slave writeset |
724 | * |
725 | * If local trx has been aborted by brute force, and it has already |
726 | * replicated before this abort, we must try if we can apply it as |
727 | * slave trx. Note that slave nodes see only trx writesets and certification |
728 | * test based on write set content can be different to DBMS lock conflicts. |
729 | * |
730 | * @param wsrep provider handle |
731 | * @param ws_handle writeset of committing transaction |
732 | * @param trx_ctx transaction context |
733 | * |
734 | * @retval WSREP_OK cluster commit succeeded |
735 | * @retval WSREP_TRX_FAIL must rollback transaction |
736 | * @retval WSREP_BF_ABORT brute force abort happened after trx replicated |
737 | * must rollback transaction and try to replay |
738 | * @retval WSREP_CONN_FAIL must close client connection |
739 | * @retval WSREP_NODE_FAIL must close all connections and reinit |
740 | */ |
741 | wsrep_status_t (*replay_trx)(wsrep_t* wsrep, |
742 | wsrep_ws_handle_t* ws_handle, |
743 | void* trx_ctx); |
744 | |
745 | /*! |
746 | * @brief Abort pre_commit() call of another thread. |
747 | * |
748 | * It is possible, that some high-priority transaction needs to abort |
749 | * another transaction which is in pre_commit() call waiting for resources. |
750 | * |
751 | * The kill routine checks that abort is not attmpted against a transaction |
752 | * which is front of the caller (in total order). |
753 | * |
754 | * @param wsrep provider handle |
755 | * @param bf_seqno seqno of brute force trx, running this cancel |
756 | * @param victim_trx transaction to be aborted, and which is committing |
757 | * |
758 | * @retval WSREP_OK abort secceded |
759 | * @retval WSREP_WARNING abort failed |
760 | */ |
761 | wsrep_status_t (*abort_pre_commit)(wsrep_t* wsrep, |
762 | wsrep_seqno_t bf_seqno, |
763 | wsrep_trx_id_t victim_trx); |
764 | |
765 | /*! |
766 | * @brief Appends a row reference to transaction writeset |
767 | * |
768 | * Both copy flag and key_type can be ignored by provider (key type |
769 | * interpreted as WSREP_KEY_EXCLUSIVE). |
770 | * |
771 | * @param wsrep provider handle |
772 | * @param ws_handle writeset handle |
773 | * @param keys array of keys |
774 | * @param count length of the array of keys |
775 | * @param type type ot the key |
776 | * @param copy can be set to FALSE if keys persist through commit. |
777 | */ |
778 | wsrep_status_t (*append_key)(wsrep_t* wsrep, |
779 | wsrep_ws_handle_t* ws_handle, |
780 | const wsrep_key_t* keys, |
781 | size_t count, |
782 | enum wsrep_key_type type, |
783 | wsrep_bool_t copy); |
784 | |
785 | /*! |
786 | * @brief Appends data to transaction writeset |
787 | * |
788 | * This method can be called any time before commit and it |
789 | * appends a number of data buffers to transaction writeset. |
790 | * |
791 | * Both copy and unordered flags can be ignored by provider. |
792 | * |
793 | * @param wsrep provider handle |
794 | * @param ws_handle writeset handle |
795 | * @param data array of data buffers |
796 | * @param count buffer count |
797 | * @param type type of data |
798 | * @param copy can be set to FALSE if data persists through commit. |
799 | */ |
800 | wsrep_status_t (*append_data)(wsrep_t* wsrep, |
801 | wsrep_ws_handle_t* ws_handle, |
802 | const struct wsrep_buf* data, |
803 | size_t count, |
804 | enum wsrep_data_type type, |
805 | wsrep_bool_t copy); |
806 | |
807 | /*! |
808 | * @brief Get causal ordering for read operation |
809 | * |
810 | * This call will block until causal ordering with all possible |
811 | * preceding writes in the cluster is guaranteed. If pointer to |
812 | * gtid is non-null, the call stores the global transaction ID |
813 | * of the last transaction which is guaranteed to be ordered |
814 | * causally before this call. |
815 | * |
816 | * @param wsrep provider handle |
817 | * @param gtid location to store GTID |
818 | */ |
819 | wsrep_status_t (*causal_read)(wsrep_t* wsrep, wsrep_gtid_t* gtid); |
820 | |
821 | /*! |
822 | * @brief Clears allocated connection context. |
823 | * |
824 | * Whenever a new connection ID is passed to wsrep provider through |
825 | * any of the API calls, a connection context is allocated for this |
826 | * connection. This call is to explicitly notify provider fo connection |
827 | * closing. |
828 | * |
829 | * @param wsrep provider handle |
830 | * @param conn_id connection ID |
831 | * @param query the 'set database' query |
832 | * @param query_len length of query (does not end with 0) |
833 | */ |
834 | wsrep_status_t (*free_connection)(wsrep_t* wsrep, |
835 | wsrep_conn_id_t conn_id); |
836 | |
837 | /*! |
838 | * @brief Replicates a query and starts "total order isolation" section. |
839 | * |
840 | * Replicates the action spec and returns success code, which caller must |
841 | * check. Total order isolation continues until to_execute_end() is called. |
842 | * |
843 | * @param wsrep provider handle |
844 | * @param conn_id connection ID |
845 | * @param keys array of keys |
846 | * @param keys_num lenght of the array of keys |
847 | * @param action action buffer array to be executed |
848 | * @param count action buffer count |
849 | * @param meta transaction meta data |
850 | * |
851 | * @retval WSREP_OK cluster commit succeeded |
852 | * @retval WSREP_CONN_FAIL must close client connection |
853 | * @retval WSREP_NODE_FAIL must close all connections and reinit |
854 | */ |
855 | wsrep_status_t (*to_execute_start)(wsrep_t* wsrep, |
856 | wsrep_conn_id_t conn_id, |
857 | const wsrep_key_t* keys, |
858 | size_t keys_num, |
859 | const struct wsrep_buf* action, |
860 | size_t count, |
861 | wsrep_trx_meta_t* meta); |
862 | |
863 | /*! |
864 | * @brief Ends the total order isolation section. |
865 | * |
866 | * Marks the end of total order isolation. TO locks are freed |
867 | * and other transactions are free to commit from this point on. |
868 | * |
869 | * @param wsrep provider handle |
870 | * @param conn_id connection ID |
871 | * |
872 | * @retval WSREP_OK cluster commit succeeded |
873 | * @retval WSREP_CONN_FAIL must close client connection |
874 | * @retval WSREP_NODE_FAIL must close all connections and reinit |
875 | */ |
876 | wsrep_status_t (*to_execute_end)(wsrep_t* wsrep, wsrep_conn_id_t conn_id); |
877 | |
878 | /*! |
879 | * @brief Collects preordered replication events into a writeset. |
880 | * |
881 | * @param wsrep wsrep provider handle |
882 | * @param handle a handle associated with a given writeset |
883 | * @param data an array of data buffers. |
884 | * @param count length of data buffer array. |
885 | * @param copy whether provider needs to make a copy of events. |
886 | * |
887 | * @retval WSREP_OK cluster-wide commit succeeded |
888 | * @retval WSREP_TRX_FAIL operation failed (e.g. trx size exceeded limit) |
889 | * @retval WSREP_NODE_FAIL must close all connections and reinit |
890 | */ |
891 | wsrep_status_t (*preordered_collect) (wsrep_t* wsrep, |
892 | wsrep_po_handle_t* handle, |
893 | const struct wsrep_buf* data, |
894 | size_t count, |
895 | wsrep_bool_t copy); |
896 | |
897 | /*! |
898 | * @brief "Commits" preordered writeset to cluster. |
899 | * |
900 | * The contract is that the writeset will be committed in the same (partial) |
901 | * order this method was called. Frees resources associated with the writeset |
902 | * handle and reinitializes the handle. |
903 | * |
904 | * @param wsrep wsrep provider handle |
905 | * @param po_handle a handle associated with a given writeset |
906 | * @param source_id ID of the event producer, also serves as the partial order |
907 | * or stream ID - events with different source_ids won't be |
908 | * ordered with respect to each other. |
909 | * @param flags WSREP_FLAG_... flags |
910 | * @param pa_range the number of preceding events this event can be processed |
911 | * in parallel with. A value of 0 means strict serial |
912 | * processing. Note: commits always happen in wsrep order. |
913 | * @param commit 'true' to commit writeset to cluster (replicate) or |
914 | * 'false' to rollback (cancel) the writeset. |
915 | * |
916 | * @retval WSREP_OK cluster-wide commit succeeded |
917 | * @retval WSREP_TRX_FAIL operation failed (e.g. NON-PRIMARY component) |
918 | * @retval WSREP_NODE_FAIL must close all connections and reinit |
919 | */ |
920 | wsrep_status_t (*preordered_commit) (wsrep_t* wsrep, |
921 | wsrep_po_handle_t* handle, |
922 | const wsrep_uuid_t* source_id, |
923 | uint32_t flags, |
924 | int pa_range, |
925 | wsrep_bool_t commit); |
926 | |
927 | /*! |
928 | * @brief Signals to wsrep provider that state snapshot has been sent to |
929 | * joiner. |
930 | * |
931 | * @param wsrep provider handle |
932 | * @param state_id state ID |
933 | * @param rcode 0 or negative error code of the operation. |
934 | */ |
935 | wsrep_status_t (*sst_sent)(wsrep_t* wsrep, |
936 | const wsrep_gtid_t* state_id, |
937 | int rcode); |
938 | |
939 | /*! |
940 | * @brief Signals to wsrep provider that new state snapshot has been received. |
941 | * May deadlock if called from sst_prepare_cb. |
942 | * |
943 | * @param wsrep provider handle |
944 | * @param state_id state ID |
945 | * @param state initial state provided by SST donor |
946 | * @param state_len length of state buffer |
947 | * @param rcode 0 or negative error code of the operation. |
948 | */ |
949 | wsrep_status_t (*sst_received)(wsrep_t* wsrep, |
950 | const wsrep_gtid_t* state_id, |
951 | const void* state, |
952 | size_t state_len, |
953 | int rcode); |
954 | |
955 | |
956 | /*! |
957 | * @brief Generate request for consistent snapshot. |
958 | * |
959 | * If successfull, this call will generate internally SST request |
960 | * which in turn triggers calling SST donate callback on the nodes |
961 | * specified in donor_spec. If donor_spec is null, callback is |
962 | * called only locally. This call will block until sst_sent is called |
963 | * from callback. |
964 | * |
965 | * @param wsrep provider handle |
966 | * @param msg context message for SST donate callback |
967 | * @param msg_len length of context message |
968 | * @param donor_spec list of snapshot donors |
969 | */ |
970 | wsrep_status_t (*snapshot)(wsrep_t* wsrep, |
971 | const void* msg, |
972 | size_t msg_len, |
973 | const char* donor_spec); |
974 | |
975 | /*! |
976 | * @brief Returns an array fo status variables. |
977 | * Array is terminated by Null variable name. |
978 | * |
979 | * @param wsrep provider handle |
980 | * @return array of struct wsrep_status_var. |
981 | */ |
982 | struct wsrep_stats_var* (*stats_get) (wsrep_t* wsrep); |
983 | |
984 | /*! |
985 | * @brief Release resources that might be associated with the array. |
986 | * |
987 | * @param wsrep provider handle. |
988 | * @param var_array array returned by stats_get(). |
989 | */ |
990 | void (*stats_free) (wsrep_t* wsrep, struct wsrep_stats_var* var_array); |
991 | |
992 | /*! |
993 | * @brief Reset some stats variables to inital value, provider-dependent. |
994 | * |
995 | * @param wsrep provider handle. |
996 | */ |
997 | void (*stats_reset) (wsrep_t* wsrep); |
998 | |
999 | /*! |
1000 | * @brief Pauses writeset applying/committing. |
1001 | * |
1002 | * @return global sequence number of the paused state or negative error code. |
1003 | */ |
1004 | wsrep_seqno_t (*pause) (wsrep_t* wsrep); |
1005 | |
1006 | /*! |
1007 | * @brief Resumes writeset applying/committing. |
1008 | */ |
1009 | wsrep_status_t (*resume) (wsrep_t* wsrep); |
1010 | |
1011 | /*! |
1012 | * @brief Desynchronize from cluster |
1013 | * |
1014 | * Effectively turns off flow control for this node, allowing it |
1015 | * to fall behind the cluster. |
1016 | */ |
1017 | wsrep_status_t (*desync) (wsrep_t* wsrep); |
1018 | |
1019 | /*! |
1020 | * @brief Request to resynchronize with cluster. |
1021 | * |
1022 | * Effectively turns on flow control. Asynchronous - actual synchronization |
1023 | * event to be deliverred via sync_cb. |
1024 | */ |
1025 | wsrep_status_t (*resync) (wsrep_t* wsrep); |
1026 | |
1027 | /*! |
1028 | * @brief Acquire global named lock |
1029 | * |
1030 | * @param wsrep wsrep provider handle |
1031 | * @param name lock name |
1032 | * @param shared shared or exclusive lock |
1033 | * @param owner 64-bit owner ID |
1034 | * @param tout timeout in nanoseconds. |
1035 | * 0 - return immediately, -1 wait forever. |
1036 | * @return wsrep status or negative error code |
1037 | * @retval -EDEADLK lock was already acquired by this thread |
1038 | * @retval -EBUSY lock was busy |
1039 | */ |
1040 | wsrep_status_t (*lock) (wsrep_t* wsrep, |
1041 | const char* name, wsrep_bool_t shared, |
1042 | uint64_t owner, int64_t tout); |
1043 | |
1044 | /*! |
1045 | * @brief Release global named lock |
1046 | * |
1047 | * @param wsrep wsrep provider handle |
1048 | * @param name lock name |
1049 | * @param owner 64-bit owner ID |
1050 | * @return wsrep status or negative error code |
1051 | * @retval -EPERM lock does not belong to this owner |
1052 | */ |
1053 | wsrep_status_t (*unlock) (wsrep_t* wsrep, const char* name, uint64_t owner); |
1054 | |
1055 | /*! |
1056 | * @brief Check if global named lock is locked |
1057 | * |
1058 | * @param wsrep wsrep provider handle |
1059 | * @param name lock name |
1060 | * @param owner if not NULL will contain 64-bit owner ID |
1061 | * @param node if not NULL will contain owner's node UUID |
1062 | * @return true if lock is locked |
1063 | */ |
1064 | wsrep_bool_t (*is_locked) (wsrep_t* wsrep, const char* name, uint64_t* conn, |
1065 | wsrep_uuid_t* node); |
1066 | |
1067 | /*! |
1068 | * wsrep provider name |
1069 | */ |
1070 | const char* provider_name; |
1071 | |
1072 | /*! |
1073 | * wsrep provider version |
1074 | */ |
1075 | const char* provider_version; |
1076 | |
1077 | /*! |
1078 | * wsrep provider vendor name |
1079 | */ |
1080 | const char* provider_vendor; |
1081 | |
1082 | /*! |
1083 | * @brief Frees allocated resources before unloading the library. |
1084 | * @param wsrep provider handle |
1085 | */ |
1086 | void (*free)(wsrep_t* wsrep); |
1087 | |
1088 | void *dlh; //!< reserved for future use |
1089 | void *ctx; //!< reserved for implemetation private context |
1090 | }; |
1091 | |
1092 | |
1093 | /*! |
1094 | * |
1095 | * @brief Loads wsrep library |
1096 | * |
1097 | * @param spec path to wsrep library. If NULL or WSREP_NONE initialises dummy |
1098 | * pass-through implementation. |
1099 | * @param hptr wsrep handle |
1100 | * @param log_cb callback to handle loader messages. Otherwise writes to stderr. |
1101 | * |
1102 | * @return zero on success, errno on failure |
1103 | */ |
1104 | int wsrep_load(const char* spec, wsrep_t** hptr, wsrep_log_cb_t log_cb); |
1105 | |
1106 | /*! |
1107 | * @brief Unloads wsrep library and frees associated resources |
1108 | * |
1109 | * @param hptr wsrep handler pointer |
1110 | */ |
1111 | void wsrep_unload(wsrep_t* hptr); |
1112 | |
1113 | #ifdef __cplusplus |
1114 | } |
1115 | #endif |
1116 | |
1117 | #endif /* WSREP_H */ |
1118 | |