1 /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 // vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
3 /* -*- mode: C; c-basic-offset: 4 -*- */
4 #ident "$Id$"
5 /*======
6 This file is part of TokuDB
7 
8 
9 Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
10 
11     TokuDBis is free software: you can redistribute it and/or modify
12     it under the terms of the GNU General Public License, version 2,
13     as published by the Free Software Foundation.
14 
15     TokuDB is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18     GNU General Public License for more details.
19 
20     You should have received a copy of the GNU General Public License
21     along with TokuDB.  If not, see <http://www.gnu.org/licenses/>.
22 
23 ======= */
24 
25 #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved."
26 
27 #include "hatoku_hton.h"
28 #include "sql_acl.h"
29 #include "tokudb_dir_cmd.h"
30 #include "sql_parse.h"
31 
32 namespace tokudb {
33 namespace sysvars {
34 
35 //******************************************************************************
36 // global variables
37 //******************************************************************************
38 #ifdef TOKUDB_VERSION
39 #define tokudb_stringify_2(x) #x
40 #define tokudb_stringify(x) tokudb_stringify_2(x)
41 #define TOKUDB_VERSION_STR tokudb_stringify(TOKUDB_VERSION)
42 #else
43 #define TOKUDB_VERSION_STR NULL
44 #endif
45 
46 const size_t error_buffer_max_size = 1024;
47 
48 ulonglong   cache_size = 0;
49 uint        cachetable_pool_threads = 0;
50 int         cardinality_scale_percent = 0;
51 my_bool     checkpoint_on_flush_logs = FALSE;
52 uint        checkpoint_pool_threads = 0;
53 uint        checkpointing_period = 0;
54 ulong       cleaner_iterations = 0;
55 ulong       cleaner_period = 0;
56 uint        client_pool_threads = 0;
57 my_bool     compress_buffers_before_eviction = TRUE;
58 char*       data_dir = NULL;
59 ulong       debug = 0;
60 #if defined(TOKUDB_DEBUG) && TOKUDB_DEBUG
61 // used to control background job manager
62 my_bool     debug_pause_background_job_manager = FALSE;
63 #endif  // defined(TOKUDB_DEBUG) && TOKUDB_DEBUG
64 my_bool     directio = FALSE;
65 my_bool     enable_partial_eviction = TRUE;
66 int         fs_reserve_percent = 0;
67 uint        fsync_log_period = 0;
68 char*       log_dir = NULL;
69 ulonglong   max_lock_memory = 0;
70 uint        read_status_frequency = 0;
71 my_bool     strip_frm_data = FALSE;
72 char*       tmp_dir = NULL;
73 uint        write_status_frequency = 0;
74 my_bool     dir_per_db = FALSE;
75 char*       version = (char*) TOKUDB_VERSION_STR;
76 
77 // file system reserve as a percentage of total disk space
78 #if defined(TOKU_INCLUDE_HANDLERTON_HANDLE_FATAL_SIGNAL) && \
79     TOKU_INCLUDE_HANDLERTON_HANDLE_FATAL_SIGNAL
80 char*       gdb_path = NULL;
81 my_bool     gdb_on_fatal = FALSE;
82 #endif  // defined(TOKU_INCLUDE_HANDLERTON_HANDLE_FATAL_SIGNAL) &&
83         // TOKU_INCLUDE_HANDLERTON_HANDLE_FATAL_SIGNAL
84 
85 my_bool        check_jemalloc = TRUE;
86 
87 static MYSQL_SYSVAR_ULONGLONG(
88     cache_size,
89     cache_size,
90     PLUGIN_VAR_READONLY,
91     "cache table size",
92     NULL,
93     NULL,
94     0,
95     0,
96     ~0ULL,
97     0);
98 
99 static MYSQL_SYSVAR_UINT(
100     cachetable_pool_threads,
101     cachetable_pool_threads,
102     PLUGIN_VAR_READONLY,
103     "cachetable ops thread pool size",
104     NULL,
105     NULL,
106     0,
107     0,
108     1024,
109     0);
110 
111 static MYSQL_SYSVAR_INT(
112     cardinality_scale_percent,
113     cardinality_scale_percent,
114     0,
115     "index cardinality scale percentage",
116     NULL,
117     NULL,
118     50,
119     0,
120     100,
121     0);
122 
123 static MYSQL_SYSVAR_BOOL(
124     checkpoint_on_flush_logs,
125     checkpoint_on_flush_logs,
126     0,
127     "checkpoint on flush logs",
128     NULL,
129     NULL,
130     FALSE);
131 
132 static MYSQL_SYSVAR_UINT(
133     checkpoint_pool_threads,
134     checkpoint_pool_threads,
135     PLUGIN_VAR_READONLY,
136     "checkpoint ops thread pool size",
137     NULL,
138     NULL,
139     0,
140     0,
141     1024,
142     0);
143 
checkpointing_period_update(TOKUDB_UNUSED (THD * thd),TOKUDB_UNUSED (st_mysql_sys_var * sys_var),void * var,const void * save)144 static void checkpointing_period_update(
145     TOKUDB_UNUSED(THD* thd),
146     TOKUDB_UNUSED(st_mysql_sys_var* sys_var),
147     void* var,
148     const void* save) {
149     uint* cp = (uint*)var;
150     *cp = *(const uint*)save;
151     int r = db_env->checkpointing_set_period(db_env, *cp);
152     assert(r == 0);
153 }
154 
155 static MYSQL_SYSVAR_UINT(
156     checkpointing_period,
157     checkpointing_period,
158     0,
159     "checkpointing period",
160     NULL,
161     checkpointing_period_update,
162     60,
163     0,
164     ~0U,
165     0);
166 
cleaner_iterations_update(TOKUDB_UNUSED (THD * thd),TOKUDB_UNUSED (st_mysql_sys_var * sys_var),void * var,const void * save)167 static void cleaner_iterations_update(TOKUDB_UNUSED(THD* thd),
168                                       TOKUDB_UNUSED(st_mysql_sys_var* sys_var),
169                                       void* var,
170                                       const void* save) {
171     ulong* ci = (ulong*)var;
172     *ci = *(const ulong*)save;
173     int r = db_env->cleaner_set_iterations(db_env, *ci);
174     assert(r == 0);
175 }
176 
177 static MYSQL_SYSVAR_ULONG(
178     cleaner_iterations,
179     cleaner_iterations,
180     0,
181     "cleaner_iterations",
182     NULL,
183     cleaner_iterations_update,
184     DEFAULT_TOKUDB_CLEANER_ITERATIONS,
185     0,
186     ~0UL,
187     0);
188 
cleaner_period_update(TOKUDB_UNUSED (THD * thd),TOKUDB_UNUSED (st_mysql_sys_var * sys_var),void * var,const void * save)189 static void cleaner_period_update(TOKUDB_UNUSED(THD* thd),
190                                   TOKUDB_UNUSED(st_mysql_sys_var* sys_var),
191                                   void* var,
192                                   const void* save) {
193     ulong* cp = (ulong*)var;
194     *cp = *(const ulong*)save;
195     int r = db_env->cleaner_set_period(db_env, *cp);
196     assert(r == 0);
197 }
198 
199 static MYSQL_SYSVAR_ULONG(
200     cleaner_period,
201     cleaner_period,
202     0,
203     "cleaner_period",
204     NULL,
205     cleaner_period_update,
206     DEFAULT_TOKUDB_CLEANER_PERIOD,
207     0,
208     ~0UL,
209     0);
210 
211 static MYSQL_SYSVAR_UINT(
212     client_pool_threads,
213     client_pool_threads,
214     PLUGIN_VAR_READONLY,
215     "client ops thread pool size",
216     NULL,
217     NULL,
218     0,
219     0,
220     1024,
221     0);
222 
223 static MYSQL_SYSVAR_BOOL(
224     compress_buffers_before_eviction,
225     compress_buffers_before_eviction,
226     PLUGIN_VAR_READONLY,
227     "enable in-memory buffer compression before partial eviction",
228     NULL,
229     NULL,
230     TRUE);
231 
232 static MYSQL_SYSVAR_STR(
233     data_dir,
234     data_dir,
235     PLUGIN_VAR_READONLY,
236     "data directory",
237     NULL,
238     NULL,
239     NULL);
240 
241 static MYSQL_SYSVAR_ULONG(
242     debug,
243     debug,
244     0,
245     "plugin debug mask",
246     NULL,
247     NULL,
248     0,
249     0,
250     ~0UL,
251     0);
252 
253 #if defined(TOKUDB_DEBUG) && TOKUDB_DEBUG
254 static MYSQL_SYSVAR_BOOL(
255     debug_pause_background_job_manager,
256     debug_pause_background_job_manager,
257     0,
258     "debug : pause the background job manager",
259     NULL,
260     NULL,
261     FALSE);
262 #endif  // defined(TOKUDB_DEBUG) && TOKUDB_DEBUG
263 
264 static MYSQL_SYSVAR_BOOL(
265     directio,
266     directio,
267     PLUGIN_VAR_READONLY, "enable direct i/o ",
268     NULL,
269     NULL,
270     FALSE);
271 
enable_partial_eviction_update(TOKUDB_UNUSED (THD * thd),TOKUDB_UNUSED (st_mysql_sys_var * sys_var),void * var,const void * save)272 static void enable_partial_eviction_update(
273     TOKUDB_UNUSED(THD* thd),
274     TOKUDB_UNUSED(st_mysql_sys_var* sys_var),
275     void* var,
276     const void* save) {
277     my_bool* epe = (my_bool*)var;
278     *epe = *(const my_bool*)save;
279     int r = db_env->evictor_set_enable_partial_eviction(db_env, *epe);
280     assert(r == 0);
281 }
282 
283 static MYSQL_SYSVAR_BOOL(
284     enable_partial_eviction,
285     enable_partial_eviction,
286     0,
287     "enable partial node eviction",
288     NULL,
289     enable_partial_eviction_update,
290     TRUE);
291 
292 static MYSQL_SYSVAR_INT(
293     fs_reserve_percent,
294     fs_reserve_percent,
295     PLUGIN_VAR_READONLY,
296     "file system space reserve (percent free required)",
297     NULL,
298     NULL,
299     5,
300     0,
301     100,
302     0);
303 
fsync_log_period_update(TOKUDB_UNUSED (THD * thd),TOKUDB_UNUSED (st_mysql_sys_var * sys_var),void * var,const void * save)304 static void fsync_log_period_update(TOKUDB_UNUSED(THD* thd),
305                                     TOKUDB_UNUSED(st_mysql_sys_var* sys_var),
306                                     void* var,
307                                     const void* save) {
308     uint* flp = (uint*)var;
309     *flp = *(const uint*)save;
310     db_env->change_fsync_log_period(db_env, *flp);
311 }
312 
313 static MYSQL_SYSVAR_UINT(
314     fsync_log_period,
315     fsync_log_period,
316     0,
317     "fsync log period",
318     NULL,
319     fsync_log_period_update,
320     0,
321     0,
322     ~0U,
323     0);
324 
325 static MYSQL_SYSVAR_STR(
326     log_dir,
327     log_dir,
328     PLUGIN_VAR_READONLY,
329     "log directory",
330     NULL,
331     NULL,
332     NULL);
333 
334 static MYSQL_SYSVAR_ULONGLONG(
335     max_lock_memory,
336     max_lock_memory,
337     PLUGIN_VAR_READONLY,
338     "max memory for locks",
339     NULL,
340     NULL,
341     0,
342     0,
343     ~0ULL,
344     0);
345 
346 static MYSQL_SYSVAR_UINT(
347     read_status_frequency,
348     read_status_frequency,
349     0,
350     "frequency that show processlist updates status of reads",
351     NULL,
352     NULL,
353     10000,
354     0,
355     ~0U,
356     0);
357 
358 static MYSQL_SYSVAR_BOOL(
359     strip_frm_data,
360     strip_frm_data,
361     PLUGIN_VAR_READONLY,
362     "strip .frm data from metadata file(s)",
363     NULL,
364     NULL,
365     FALSE);
366 
367 static MYSQL_SYSVAR_STR(
368     tmp_dir,
369     tmp_dir,
370     PLUGIN_VAR_READONLY,
371     "directory to use for temporary files",
372     NULL,
373     NULL,
374     NULL);
375 
376 static MYSQL_SYSVAR_STR(
377     version,
378     version,
379     PLUGIN_VAR_READONLY,
380     "plugin version",
381     NULL,
382     NULL,
383     NULL);
384 
385 static MYSQL_SYSVAR_UINT(
386     write_status_frequency,
387     write_status_frequency,
388     0,
389     "frequency that show processlist updates status of writes",
390     NULL,
391     NULL,
392     1000,
393     0,
394     ~0U,
395     0);
396 
tokudb_dir_per_db_update(TOKUDB_UNUSED (THD * thd),TOKUDB_UNUSED (struct st_mysql_sys_var * sys_var),void * var,const void * save)397 static void tokudb_dir_per_db_update(
398     TOKUDB_UNUSED(THD* thd),
399     TOKUDB_UNUSED(struct st_mysql_sys_var* sys_var),
400     void* var,
401     const void* save) {
402     my_bool *value = (my_bool *) var;
403     *value = *(const my_bool *) save;
404     db_env->set_dir_per_db(db_env, *value);
405 }
406 
407 static MYSQL_SYSVAR_BOOL(dir_per_db, dir_per_db,
408     0, "TokuDB store ft files in db directories",
409     NULL, tokudb_dir_per_db_update, FALSE);
410 
411 #if defined(TOKU_INCLUDE_HANDLERTON_HANDLE_FATAL_SIGNAL) && \
412     TOKU_INCLUDE_HANDLERTON_HANDLE_FATAL_SIGNAL
413 static MYSQL_SYSVAR_STR(
414     gdb_path,
415     gdb_path,
416     PLUGIN_VAR_READONLY|PLUGIN_VAR_RQCMDARG,
417     "path to gdb for extra debug info on fatal signal",
418     NULL,
419     NULL,
420     "/usr/bin/gdb");
421 
422 static MYSQL_SYSVAR_BOOL(
423     gdb_on_fatal,
424     gdb_on_fatal,
425     0,
426     "enable gdb debug info on fatal signal",
427     NULL,
428     NULL,
429     true);
430 #endif  // defined(TOKU_INCLUDE_HANDLERTON_HANDLE_FATAL_SIGNAL) &&
431         // TOKU_INCLUDE_HANDLERTON_HANDLE_FATAL_SIGNAL
432 
433 static MYSQL_SYSVAR_BOOL(
434     check_jemalloc,
435     check_jemalloc,
436     PLUGIN_VAR_READONLY|PLUGIN_VAR_RQCMDARG,
437     "check if jemalloc is linked and transparent huge pages are disabled",
438     NULL,
439     NULL,
440     TRUE);
441 
442 
443 //******************************************************************************
444 // session variables
445 //******************************************************************************
446 static MYSQL_THDVAR_BOOL(
447     alter_print_error,
448     0,
449     "print errors for alter table operations",
450     NULL,
451     NULL,
452     false);
453 
454 static MYSQL_THDVAR_DOUBLE(
455     analyze_delete_fraction,
456     0,
457     "fraction of rows allowed to be deleted",
458     NULL,
459     NULL,
460     1.0,
461     0,
462     1.0,
463     1);
464 
465 static MYSQL_THDVAR_BOOL(
466     analyze_in_background,
467     0,
468     "dispatch ANALYZE TABLE to background job.",
469     NULL,
470     NULL,
471     false);
472 
473 const char* srv_analyze_mode_names[] = {
474     "TOKUDB_ANALYZE_STANDARD",
475     "TOKUDB_ANALYZE_RECOUNT_ROWS",
476     "TOKUDB_ANALYZE_CANCEL",
477     NullS
478 };
479 
480 static TYPELIB tokudb_analyze_mode_typelib = {
481     array_elements(srv_analyze_mode_names) - 1,
482     "tokudb_analyze_mode_typelib",
483     srv_analyze_mode_names,
484     NULL
485 };
486 
487 static MYSQL_THDVAR_ENUM(analyze_mode,
488     PLUGIN_VAR_RQCMDARG,
489     "Controls the function of ANALYZE TABLE. Possible values are: "
490     "TOKUDB_ANALYZE_STANDARD perform standard table analysis (default); "
491     "TOKUDB_ANALYZE_RECOUNT_ROWS perform logical recount of table rows;"
492     "TOKUDB_ANALYZE_CANCEL terminate and cancel all scheduled background jobs "
493     "for a table",
494     NULL,
495     NULL,
496     TOKUDB_ANALYZE_STANDARD,
497     &tokudb_analyze_mode_typelib);
498 
499 static MYSQL_THDVAR_ULONGLONG(
500     analyze_throttle,
501     0,
502     "analyze throttle (keys)",
503     NULL,
504     NULL,
505     0,
506     0,
507     ~0U,
508     1);
509 
510 static MYSQL_THDVAR_UINT(
511     analyze_time,
512     0,
513     "analyze time (seconds)",
514     NULL,
515     NULL,
516     5,
517     0,
518     ~0U,
519     1);
520 
521 static MYSQL_THDVAR_ULONGLONG(
522     auto_analyze,
523     0,
524     "auto analyze threshold (percent)",
525     NULL,
526     NULL,
527     0,
528     0,
529     ~0U,
530     1);
531 
532 static MYSQL_THDVAR_UINT(
533     block_size,
534     0,
535     "fractal tree block size",
536     NULL,
537     NULL,
538     4<<20,
539     4096,
540     ~0U,
541     1);
542 
543 static MYSQL_THDVAR_BOOL(
544     bulk_fetch,
545     PLUGIN_VAR_THDLOCAL,
546     "enable bulk fetch",
547     NULL,
548     NULL,
549     true);
550 
checkpoint_lock_update(TOKUDB_UNUSED (THD * thd),TOKUDB_UNUSED (st_mysql_sys_var * var),void * var_ptr,const void * save)551 static void checkpoint_lock_update(TOKUDB_UNUSED(THD* thd),
552                                    TOKUDB_UNUSED(st_mysql_sys_var* var),
553                                    void* var_ptr,
554                                    const void* save) {
555     my_bool* val = (my_bool*)var_ptr;
556     *val= *(my_bool*)save ? true : false;
557     if (*val) {
558         tokudb_checkpoint_lock(thd);
559     } else {
560         tokudb_checkpoint_unlock(thd);
561     }
562 }
563 
564 static MYSQL_THDVAR_BOOL(
565     checkpoint_lock,
566     0,
567     "checkpoint lock",
568     NULL,
569     checkpoint_lock_update,
570     false);
571 
572 static MYSQL_THDVAR_BOOL(
573     commit_sync,
574     PLUGIN_VAR_THDLOCAL,
575     "sync on txn commit",
576     NULL,
577     NULL,
578     true);
579 
580 static MYSQL_THDVAR_BOOL(
581     create_index_online,
582     0,
583     "if on, create index done online",
584     NULL,
585     NULL,
586     true);
587 
588 static MYSQL_THDVAR_BOOL(
589     disable_hot_alter,
590     0,
591     "if on, hot alter table is disabled",
592     NULL,
593     NULL,
594     false);
595 
596 static MYSQL_THDVAR_BOOL(
597     disable_prefetching,
598     0,
599     "if on, prefetching disabled",
600     NULL,
601     NULL,
602     false);
603 
604 static MYSQL_THDVAR_BOOL(
605     disable_slow_alter,
606     0,
607     "if on, alter tables that require copy are disabled",
608     NULL,
609     NULL,
610     false);
611 
612 static const char *tokudb_empty_scan_names[] = {
613     "disabled",
614     "lr",
615     "rl",
616     NullS
617 };
618 
619 static TYPELIB tokudb_empty_scan_typelib = {
620     array_elements(tokudb_empty_scan_names) - 1,
621     "tokudb_empty_scan_typelib",
622     tokudb_empty_scan_names,
623     NULL
624 };
625 
626 static MYSQL_THDVAR_ENUM(
627     empty_scan,
628     PLUGIN_VAR_OPCMDARG,
629     "algorithm to check if the table is empty when opened",
630     NULL,
631     NULL,
632     TOKUDB_EMPTY_SCAN_RL,
633     &tokudb_empty_scan_typelib);
634 
635 static MYSQL_THDVAR_UINT(
636     fanout,
637     0,
638     "fractal tree fanout",
639     NULL,
640     NULL,
641     16,
642     2,
643     16*1024,
644     1);
645 
646 static MYSQL_THDVAR_BOOL(
647     hide_default_row_format,
648     0,
649     "hide the default row format",
650     NULL,
651     NULL,
652     true);
653 
654 static MYSQL_THDVAR_ULONGLONG(
655     killed_time,
656     0,
657     "killed time",
658     NULL,
659     NULL,
660     DEFAULT_TOKUDB_KILLED_TIME,
661     0,
662     ~0ULL,
663     1);
664 
665 static MYSQL_THDVAR_STR(last_lock_timeout,
666                         PLUGIN_VAR_MEMALLOC | PLUGIN_VAR_NOCMDOPT |
667                             PLUGIN_VAR_READONLY,
668                         "last lock timeout",
669                         NULL,
670                         NULL,
671                         NULL);
672 
673 static MYSQL_THDVAR_BOOL(
674     load_save_space,
675     0,
676     "compress intermediate bulk loader files to save space",
677     NULL,
678     NULL,
679     true);
680 
681 static MYSQL_THDVAR_ULONGLONG(
682     loader_memory_size,
683     0,
684     "loader memory size",
685     NULL,
686     NULL,
687     100*1000*1000,
688     0,
689     ~0ULL,
690     1);
691 
692 static MYSQL_THDVAR_ULONGLONG(
693     lock_timeout,
694     0,
695     "lock timeout",
696     NULL,
697     NULL,
698     DEFAULT_TOKUDB_LOCK_TIMEOUT,
699     0,
700     ~0ULL,
701     1);
702 
703 static MYSQL_THDVAR_UINT(
704     lock_timeout_debug,
705     0,
706     "lock timeout debug",
707     NULL,
708     NULL,
709     1,
710     0,
711     ~0U,
712     1);
713 
714 static MYSQL_THDVAR_DOUBLE(
715     optimize_index_fraction,
716     0,
717     "optimize index fraction (default 1.0 all)",
718     NULL,
719     NULL,
720     1.0,
721     0,
722     1.0,
723     1);
724 
725 static MYSQL_THDVAR_STR(
726     optimize_index_name,
727     PLUGIN_VAR_THDLOCAL + PLUGIN_VAR_MEMALLOC,
728     "optimize index name (default all indexes)",
729     NULL,
730     NULL,
731     NULL);
732 
733 static MYSQL_THDVAR_ULONGLONG(
734     optimize_throttle,
735     0,
736     "optimize throttle (default no throttle)",
737     NULL,
738     NULL,
739     0,
740     0,
741     ~0ULL,
742     1);
743 
744 static const char* deprecated_tokudb_pk_insert_mode =
745     "Using tokudb_pk_insert_mode is deprecated and the "
746     "parameter may be removed in future releases.";
747 static const char* deprecated_tokudb_pk_insert_mode_zero =
748     "Using tokudb_pk_insert_mode=0 is deprecated and the "
749     "parameter may be removed in future releases. "
750     "Only tokudb_pk_insert_mode=1|2 is allowed."
751     "Resettig the value to 1.";
752 
pk_insert_mode_update(THD * thd,st_mysql_sys_var * var,void * var_ptr,const void * save)753 static void pk_insert_mode_update(
754     THD* thd,
755     st_mysql_sys_var* var,
756     void* var_ptr,
757     const void* save) {
758     const uint* new_pk_insert_mode = static_cast<const uint*>(save);
759     uint* pk_insert_mode = static_cast<uint*>(var_ptr);
760     if (*new_pk_insert_mode == 0) {
761         push_warning(
762             thd,
763             Sql_condition::WARN_LEVEL_WARN,
764             HA_ERR_WRONG_COMMAND,
765             deprecated_tokudb_pk_insert_mode_zero);
766         *pk_insert_mode = 1;
767     } else {
768         push_warning(
769             thd,
770             Sql_condition::WARN_LEVEL_WARN,
771             HA_ERR_WRONG_COMMAND,
772             deprecated_tokudb_pk_insert_mode);
773         *pk_insert_mode = *new_pk_insert_mode;
774     }
775 }
776 
777 static MYSQL_THDVAR_UINT(
778     pk_insert_mode,
779     0,
780     "set the primary key insert mode",
781     NULL,
782     pk_insert_mode_update,
783     1,
784     0,
785     2,
786     1);
787 
788 static MYSQL_THDVAR_BOOL(
789     prelock_empty,
790     0,
791     "prelock empty table",
792     NULL,
793     NULL,
794     true);
795 
796 static MYSQL_THDVAR_UINT(
797     read_block_size,
798     0,
799     "fractal tree read block size",
800     NULL,
801     NULL,
802     64*1024,
803     4096,
804     ~0U,
805     1);
806 
807 static MYSQL_THDVAR_UINT(
808     read_buf_size,
809     0,
810     "range query read buffer size",
811     NULL,
812     NULL,
813     128*1024,
814     0,
815     1*1024*1024,
816     1);
817 
818 static const char *tokudb_row_format_names[] = {
819     "tokudb_uncompressed",
820     "tokudb_zlib",
821     "tokudb_snappy",
822     "tokudb_quicklz",
823     "tokudb_lzma",
824     "tokudb_fast",
825     "tokudb_small",
826     "tokudb_default",
827     NullS
828 };
829 
830 static TYPELIB tokudb_row_format_typelib = {
831     array_elements(tokudb_row_format_names) - 1,
832     "tokudb_row_format_typelib",
833     tokudb_row_format_names,
834     NULL
835 };
836 
837 static MYSQL_THDVAR_ENUM(
838     row_format,
839     PLUGIN_VAR_OPCMDARG,
840     "Specifies the compression method for a table created during this session. "
841     "Possible values are TOKUDB_UNCOMPRESSED, TOKUDB_ZLIB, TOKUDB_SNAPPY, "
842     "TOKUDB_QUICKLZ, TOKUDB_LZMA, TOKUDB_FAST, TOKUDB_SMALL and TOKUDB_DEFAULT",
843     NULL,
844     NULL,
845     SRV_ROW_FORMAT_ZLIB,
846     &tokudb_row_format_typelib);
847 
848 #if defined(TOKU_INCLUDE_RFR) && TOKU_INCLUDE_RFR
849 static MYSQL_THDVAR_BOOL(
850     rpl_check_readonly,
851     PLUGIN_VAR_THDLOCAL,
852     "check if the slave is read only",
853     NULL,
854     NULL,
855     true);
856 
857 static MYSQL_THDVAR_BOOL(
858     rpl_lookup_rows,
859     PLUGIN_VAR_THDLOCAL,
860     "lookup a row on rpl slave",
861     NULL,
862     NULL,
863     true);
864 
865 static MYSQL_THDVAR_ULONGLONG(
866     rpl_lookup_rows_delay,
867     PLUGIN_VAR_THDLOCAL,
868     "time in milliseconds to add to lookups on replication slave",
869     NULL,
870     NULL,
871     0,
872     0,
873     ~0ULL,
874     1);
875 
876 static MYSQL_THDVAR_BOOL(
877     rpl_unique_checks,
878     PLUGIN_VAR_THDLOCAL,
879     "enable unique checks on replication slave",
880     NULL,
881     NULL,
882     true);
883 
884 static MYSQL_THDVAR_ULONGLONG(
885     rpl_unique_checks_delay,
886     PLUGIN_VAR_THDLOCAL,
887     "time in milliseconds to add to unique checks test on replication slave",
888     NULL,
889     NULL,
890     0,
891     0,
892     ~0ULL,
893     1);
894 #endif // defined(TOKU_INCLUDE_RFR) && TOKU_INCLUDE_RFR
895 
896 static MYSQL_THDVAR_BOOL(
897     enable_fast_update,
898     PLUGIN_VAR_THDLOCAL,
899     "disable slow update",
900     NULL,
901     NULL,
902     false);
903 
904 static MYSQL_THDVAR_BOOL(
905     enable_fast_upsert,
906     PLUGIN_VAR_THDLOCAL,
907     "disable slow upsert",
908     NULL,
909     NULL,
910     false);
911 
912 #if TOKU_INCLUDE_XA
913 static MYSQL_THDVAR_BOOL(
914     support_xa,
915     PLUGIN_VAR_OPCMDARG,
916     "Enable TokuDB support for the XA two-phase commit",
917     NULL,
918     NULL,
919     true);
920 #endif
921 
922 static int dir_cmd_check(THD* thd, struct st_mysql_sys_var* var,
923                          void* save, struct st_mysql_value* value) ;
924 
925 static MYSQL_THDVAR_INT(dir_cmd_last_error,
926     PLUGIN_VAR_THDLOCAL,
927     "error from the last dir command. 0 is success",
928     NULL, NULL, 0, 0, 0, 1);
929 
930 static MYSQL_THDVAR_STR(dir_cmd_last_error_string,
931     PLUGIN_VAR_THDLOCAL + PLUGIN_VAR_MEMALLOC,
932     "error string from the last dir command",
933     NULL, NULL, NULL);
934 
935 static MYSQL_THDVAR_STR(dir_cmd,
936     PLUGIN_VAR_THDLOCAL + PLUGIN_VAR_MEMALLOC,
937     "name of the directory where the backup is stored",
938     dir_cmd_check, NULL, NULL);
939 
940 static void MY_ATTRIBUTE((format(printf, 3, 4)))
dir_cmd_set_error(THD * thd,int error,const char * error_fmt,...)941     dir_cmd_set_error(THD* thd, int error, const char* error_fmt, ...) {
942     char   buff[error_buffer_max_size];
943     va_list varargs;
944 
945     assert(thd);
946     assert(error_fmt);
947 
948     va_start(varargs, error_fmt);
949     vsnprintf(buff, sizeof(buff), error_fmt, varargs);
950     va_end(varargs);
951 
952     THDVAR_SET(thd, dir_cmd_last_error, &error);
953     THDVAR_SET(thd, dir_cmd_last_error_string, buff);
954 }
955 
dir_cmd_clear_error(THD * thd)956 static void dir_cmd_clear_error(THD* thd) {
957     static constexpr int no_error = 0;
958     static const char* empty_error_str = "";
959     THDVAR_SET(thd, dir_cmd_last_error, &no_error);
960     THDVAR_SET(thd, dir_cmd_last_error_string, empty_error_str);
961 }
962 
dir_cmd_check(THD * thd,TOKUDB_UNUSED (struct st_mysql_sys_var * var),void * save,struct st_mysql_value * value)963 static int dir_cmd_check(THD* thd,
964                          TOKUDB_UNUSED(struct st_mysql_sys_var* var),
965                          void* save,
966                          struct st_mysql_value* value) {
967     int error = 0;
968     dir_cmd_clear_error(thd);
969 
970     if (check_global_access(thd, SUPER_ACL)) {
971         return 1;
972     }
973 
974     char buff[STRING_BUFFER_USUAL_SIZE];
975     int length = sizeof(buff);
976     const char *str = value->val_str(value, buff, &length);
977     if (str) {
978         str = thd->strmake(str, length);
979         *(const char**)save = str;
980     }
981 
982     if (str) {
983         dir_cmd_callbacks callbacks { .set_error = dir_cmd_set_error };
984         process_dir_cmd(thd, str, callbacks);
985 
986         error = THDVAR(thd, dir_cmd_last_error);
987     } else {
988         error = EINVAL;
989     }
990 
991     return error;
992 }
993 
994 //******************************************************************************
995 // all system variables
996 //******************************************************************************
997 st_mysql_sys_var* system_variables[] = {
998     // global vars
999     MYSQL_SYSVAR(cache_size),
1000     MYSQL_SYSVAR(checkpoint_on_flush_logs),
1001     MYSQL_SYSVAR(cachetable_pool_threads),
1002     MYSQL_SYSVAR(cardinality_scale_percent),
1003     MYSQL_SYSVAR(checkpoint_pool_threads),
1004     MYSQL_SYSVAR(checkpointing_period),
1005     MYSQL_SYSVAR(cleaner_iterations),
1006     MYSQL_SYSVAR(cleaner_period),
1007     MYSQL_SYSVAR(client_pool_threads),
1008     MYSQL_SYSVAR(compress_buffers_before_eviction),
1009     MYSQL_SYSVAR(data_dir),
1010     MYSQL_SYSVAR(debug),
1011     MYSQL_SYSVAR(directio),
1012     MYSQL_SYSVAR(enable_partial_eviction),
1013     MYSQL_SYSVAR(fs_reserve_percent),
1014     MYSQL_SYSVAR(fsync_log_period),
1015     MYSQL_SYSVAR(log_dir),
1016     MYSQL_SYSVAR(max_lock_memory),
1017     MYSQL_SYSVAR(read_status_frequency),
1018     MYSQL_SYSVAR(strip_frm_data),
1019     MYSQL_SYSVAR(tmp_dir),
1020     MYSQL_SYSVAR(version),
1021     MYSQL_SYSVAR(write_status_frequency),
1022     MYSQL_SYSVAR(dir_per_db),
1023 #if defined(TOKU_INCLUDE_HANDLERTON_HANDLE_FATAL_SIGNAL) && \
1024     TOKU_INCLUDE_HANDLERTON_HANDLE_FATAL_SIGNAL
1025     MYSQL_SYSVAR(gdb_path),
1026     MYSQL_SYSVAR(gdb_on_fatal),
1027 #endif  // defined(TOKU_INCLUDE_HANDLERTON_HANDLE_FATAL_SIGNAL) &&
1028         // TOKU_INCLUDE_HANDLERTON_HANDLE_FATAL_SIGNAL
1029 
1030     MYSQL_SYSVAR(check_jemalloc),
1031 
1032     // session vars
1033     MYSQL_SYSVAR(alter_print_error),
1034     MYSQL_SYSVAR(analyze_delete_fraction),
1035     MYSQL_SYSVAR(analyze_in_background),
1036     MYSQL_SYSVAR(analyze_mode),
1037     MYSQL_SYSVAR(analyze_throttle),
1038     MYSQL_SYSVAR(analyze_time),
1039     MYSQL_SYSVAR(auto_analyze),
1040     MYSQL_SYSVAR(block_size),
1041     MYSQL_SYSVAR(bulk_fetch),
1042     MYSQL_SYSVAR(checkpoint_lock),
1043     MYSQL_SYSVAR(commit_sync),
1044     MYSQL_SYSVAR(create_index_online),
1045     MYSQL_SYSVAR(disable_hot_alter),
1046     MYSQL_SYSVAR(disable_prefetching),
1047     MYSQL_SYSVAR(disable_slow_alter),
1048     MYSQL_SYSVAR(empty_scan),
1049     MYSQL_SYSVAR(fanout),
1050     MYSQL_SYSVAR(hide_default_row_format),
1051     MYSQL_SYSVAR(killed_time),
1052     MYSQL_SYSVAR(last_lock_timeout),
1053     MYSQL_SYSVAR(load_save_space),
1054     MYSQL_SYSVAR(loader_memory_size),
1055     MYSQL_SYSVAR(lock_timeout),
1056     MYSQL_SYSVAR(lock_timeout_debug),
1057     MYSQL_SYSVAR(optimize_index_fraction),
1058     MYSQL_SYSVAR(optimize_index_name),
1059     MYSQL_SYSVAR(optimize_throttle),
1060     MYSQL_SYSVAR(pk_insert_mode),
1061     MYSQL_SYSVAR(prelock_empty),
1062     MYSQL_SYSVAR(read_block_size),
1063     MYSQL_SYSVAR(read_buf_size),
1064     MYSQL_SYSVAR(row_format),
1065 #if defined(TOKU_INCLUDE_RFR) && TOKU_INCLUDE_RFR
1066     MYSQL_SYSVAR(rpl_check_readonly),
1067     MYSQL_SYSVAR(rpl_lookup_rows),
1068     MYSQL_SYSVAR(rpl_lookup_rows_delay),
1069     MYSQL_SYSVAR(rpl_unique_checks),
1070     MYSQL_SYSVAR(rpl_unique_checks_delay),
1071 #endif // defined(TOKU_INCLUDE_RFR) && TOKU_INCLUDE_RFR
1072     MYSQL_SYSVAR(enable_fast_update),
1073     MYSQL_SYSVAR(enable_fast_upsert),
1074 #if TOKU_INCLUDE_XA
1075     MYSQL_SYSVAR(support_xa),
1076 #endif
1077 
1078 #if defined(TOKUDB_DEBUG) && TOKUDB_DEBUG
1079     MYSQL_SYSVAR(debug_pause_background_job_manager),
1080 #endif  // defined(TOKUDB_DEBUG) && TOKUDB_DEBUG
1081     MYSQL_SYSVAR(dir_cmd_last_error),
1082     MYSQL_SYSVAR(dir_cmd_last_error_string),
1083     MYSQL_SYSVAR(dir_cmd),
1084 
1085     NULL
1086 };
1087 
alter_print_error(THD * thd)1088 my_bool alter_print_error(THD* thd) {
1089     return (THDVAR(thd, alter_print_error) != 0);
1090 }
analyze_delete_fraction(THD * thd)1091 double analyze_delete_fraction(THD* thd) {
1092     return THDVAR(thd, analyze_delete_fraction);
1093 }
analyze_in_background(THD * thd)1094 my_bool analyze_in_background(THD* thd) {
1095     return (THDVAR(thd, analyze_in_background) != 0);
1096 }
analyze_mode(THD * thd)1097 analyze_mode_t analyze_mode(THD* thd) {
1098     return (analyze_mode_t ) THDVAR(thd, analyze_mode);
1099 }
analyze_throttle(THD * thd)1100 ulonglong analyze_throttle(THD* thd) {
1101     return THDVAR(thd, analyze_throttle);
1102 }
analyze_time(THD * thd)1103 ulonglong analyze_time(THD* thd) {
1104     return THDVAR(thd, analyze_time);
1105 }
auto_analyze(THD * thd)1106 ulonglong auto_analyze(THD* thd) {
1107     return THDVAR(thd, auto_analyze);
1108 }
bulk_fetch(THD * thd)1109 my_bool bulk_fetch(THD* thd) {
1110     return (THDVAR(thd, bulk_fetch) != 0);
1111 }
block_size(THD * thd)1112 uint block_size(THD* thd) {
1113     return THDVAR(thd, block_size);
1114 }
commit_sync(THD * thd)1115 my_bool commit_sync(THD* thd) {
1116     return (THDVAR(thd, commit_sync) != 0);
1117 }
create_index_online(THD * thd)1118 my_bool create_index_online(THD* thd) {
1119     return (THDVAR(thd, create_index_online) != 0);
1120 }
disable_hot_alter(THD * thd)1121 my_bool disable_hot_alter(THD* thd) {
1122     return (THDVAR(thd, disable_hot_alter) != 0);
1123 }
disable_prefetching(THD * thd)1124 my_bool disable_prefetching(THD* thd) {
1125     return (THDVAR(thd, disable_prefetching) != 0);
1126 }
disable_slow_alter(THD * thd)1127 my_bool disable_slow_alter(THD* thd) {
1128     return (THDVAR(thd, disable_slow_alter) != 0);
1129 }
enable_fast_update(THD * thd)1130 my_bool enable_fast_update(THD* thd) {
1131     return (THDVAR(thd, enable_fast_update) != 0);
1132 }
enable_fast_upsert(THD * thd)1133 my_bool enable_fast_upsert(THD* thd) {
1134     return (THDVAR(thd, enable_fast_upsert) != 0);
1135 }
empty_scan(THD * thd)1136 empty_scan_mode_t empty_scan(THD* thd) {
1137     return (empty_scan_mode_t)THDVAR(thd, empty_scan);
1138 }
fanout(THD * thd)1139 uint fanout(THD* thd) {
1140     return THDVAR(thd, fanout);
1141 }
hide_default_row_format(THD * thd)1142 my_bool hide_default_row_format(THD* thd) {
1143     return (THDVAR(thd, hide_default_row_format) != 0);
1144 }
killed_time(THD * thd)1145 ulonglong killed_time(THD* thd) {
1146     return THDVAR(thd, killed_time);
1147 }
last_lock_timeout(THD * thd)1148 char* last_lock_timeout(THD* thd) {
1149     return THDVAR(thd, last_lock_timeout);
1150 }
set_last_lock_timeout(THD * thd,char * last)1151 void set_last_lock_timeout(THD* thd, char* last) {
1152     THDVAR(thd, last_lock_timeout) = last;
1153 }
load_save_space(THD * thd)1154 my_bool load_save_space(THD* thd) {
1155     return (THDVAR(thd, load_save_space) != 0);
1156 }
loader_memory_size(THD * thd)1157 ulonglong loader_memory_size(THD* thd) {
1158     return THDVAR(thd, loader_memory_size);
1159 }
lock_timeout(THD * thd)1160 ulonglong lock_timeout(THD* thd) {
1161     return THDVAR(thd, lock_timeout);
1162 }
lock_timeout_debug(THD * thd)1163 uint lock_timeout_debug(THD* thd) {
1164     return THDVAR(thd, lock_timeout_debug);
1165 }
optimize_index_fraction(THD * thd)1166 double optimize_index_fraction(THD* thd) {
1167     return THDVAR(thd, optimize_index_fraction);
1168 }
optimize_index_name(THD * thd)1169 const char* optimize_index_name(THD* thd) {
1170     return THDVAR(thd, optimize_index_name);
1171 }
optimize_throttle(THD * thd)1172 ulonglong optimize_throttle(THD* thd) {
1173     return THDVAR(thd, optimize_throttle);
1174 }
pk_insert_mode(THD * thd)1175 uint pk_insert_mode(THD* thd) {
1176     return THDVAR(thd, pk_insert_mode);
1177 }
set_pk_insert_mode(THD * thd,uint mode)1178 void set_pk_insert_mode(THD* thd, uint mode) {
1179     THDVAR(thd, pk_insert_mode) = mode;
1180 }
prelock_empty(THD * thd)1181 my_bool prelock_empty(THD* thd) {
1182     return (THDVAR(thd, prelock_empty) != 0);
1183 }
read_block_size(THD * thd)1184 uint read_block_size(THD* thd) {
1185     return THDVAR(thd, read_block_size);
1186 }
read_buf_size(THD * thd)1187 uint read_buf_size(THD* thd) {
1188     return THDVAR(thd, read_buf_size);
1189 }
row_format(THD * thd)1190 row_format_t row_format(THD *thd) {
1191     return (row_format_t) THDVAR(thd, row_format);
1192 }
1193 #if defined(TOKU_INCLUDE_RFR) && TOKU_INCLUDE_RFR
rpl_check_readonly(THD * thd)1194 my_bool rpl_check_readonly(THD* thd) {
1195     return (THDVAR(thd, rpl_check_readonly) != 0);
1196 }
rpl_lookup_rows(THD * thd)1197 my_bool rpl_lookup_rows(THD* thd) {
1198     return (THDVAR(thd, rpl_lookup_rows) != 0);
1199 }
rpl_lookup_rows_delay(THD * thd)1200 ulonglong rpl_lookup_rows_delay(THD* thd) {
1201     return THDVAR(thd, rpl_lookup_rows_delay);
1202 }
rpl_unique_checks(THD * thd)1203 my_bool rpl_unique_checks(THD* thd) {
1204     return (THDVAR(thd, rpl_unique_checks) != 0);
1205 }
rpl_unique_checks_delay(THD * thd)1206 ulonglong rpl_unique_checks_delay(THD* thd) {
1207     return THDVAR(thd, rpl_unique_checks_delay);
1208 }
1209 #endif // defined(TOKU_INCLUDE_RFR) && TOKU_INCLUDE_RFR
support_xa(THD * thd)1210 my_bool support_xa(THD* thd) {
1211     return (THDVAR(thd, support_xa) != 0);
1212 }
1213 
1214 } // namespace sysvars
1215 } // namespace tokudb
1216