File Coverage

blib/lib/MySQL/Sandbox/Scripts.pm
Criterion Covered Total %
statement 9 22 40.9
branch n/a
condition n/a
subroutine 3 16 18.7
pod 0 13 0.0
total 12 51 23.5


line stmt bran cond sub pod time code
1             package MySQL::Sandbox::Scripts;
2 1     1   1463 use strict;
  1         2  
  1         29  
3 1     1   5 use warnings;
  1         1  
  1         29  
4 1     1   4 use MySQL::Sandbox;
  1         2  
  1         2192  
5              
6             require Exporter;
7              
8             our @ISA = qw/Exporter/;
9              
10             our @EXPORT_OK = qw(
11             scripts_in_code
12             get_readme_master_slave
13             get_readme_circular
14             get_readme_multiple
15             get_readme_common
16             get_readme_common_replication
17             );
18             our @EXPORT = @EXPORT_OK;
19              
20             our $VERSION=q{3.2.15};
21              
22             our @MANIFEST = (
23             'clear.sh',
24             'my.sandbox.cnf',
25             'sb_include.sh',
26             'start.sh',
27             'status.sh',
28             'msb.sh',
29             'restart.sh',
30             'stop.sh',
31             'send_kill.sh',
32             'load_grants.sh',
33             'use.sh',
34             'mycli.sh',
35             'mysqlsh.sh',
36             'proxy_start.sh',
37             'my.sh',
38             'change_paths.sh',
39             'change_ports.sh',
40             'USING',
41             'README',
42             'connection.json',
43             'default_connection.json',
44             'grants.mysql',
45             'grants_5_7_6.mysql',
46             'json_in_db.sh',
47             'show_binlog.sh',
48             'show_relaylog.sh',
49             'add_option.sh',
50             '# INSTALL FILES',
51             'sandbox_action.pl',
52             'test_replication.sh',
53             );
54              
55             #my $SBINSTR_SH_TEXT =<<'SBINSTR_SH_TEXT';
56             #if [ -f "$SBINSTR" ]
57             #then
58             # echo "[`basename $0`] - `date "+%Y-%m-%d %H:%M:%S"` - $@" >> $SBINSTR
59             #fi
60             #SBINSTR_SH_TEXT
61              
62             #sub sbinstr_sh_text {
63             # return $MySQL::Sandbox::SBINSTR_SH_TEXT;
64             #}
65              
66             sub manifest {
67 0     0 0   return @MANIFEST;
68             }
69             my %parse_options_low_level_make_sandbox = (
70             upper_directory => {
71             value => $ENV{'SANDBOX_HOME'} || $ENV{'HOME'},
72             parse => 'upper_directory=s',
73             so => 10,
74             help => [
75             "The directory that will contain the sandbox. (default: \$SANDBOX_HOME ($ENV{SANDBOX_HOME}))"
76             ]
77             },
78            
79             sandbox_directory => {
80             value => 'msb',
81             parse => 'd|sandbox_directory=s',
82             so => 20,
83             export => 1,
84             help => [
85             'Where to install the sandbox, under upper-directory'
86             ]
87             },
88             sandbox_port => {
89             value => 3310,
90             parse => 'P|sandbox_port=i',
91             export => 1,
92             so => 30,
93             help => [
94             'The port number to use for the sandbox server.',
95             '(Default: 3310)',
96             ]
97             },
98             check_port => {
99             value => 0,
100             parse => 'check_port',
101             export => 1,
102             so => 35,
103             help => [
104             'Check whether the provided port is free,',
105             'and determine the next available one if it is not.',
106             '(Default: disabled)',
107             ]
108             },
109             no_check_port => {
110             value => 0,
111             parse => 'no_check_port',
112             so => 36,
113             help => [
114             'Ignores requests of checking ports.',
115             'To be used by group sandbox scripts.',
116             '(Default: disabled)',
117             ]
118             },
119             datadir_from => {
120             value => 'script',
121             parse => 'datadir_from=s' ,
122             so => 40,
123             help => [
124             'Where to get datadir files from. Available options are',
125             'archive will be taken from the archived data',
126             ' provided with the package. They include',
127             ' default username and passwords',
128             ' ( DEPRECATED )',
129             'script the script mysql_install_db is called, with',
130             ' default users, no passwords.',
131             'dir:name will be copied from an existing mysql directory',
132             '(Default: script)',
133             ]
134             },
135             install_version => {
136             value => '',
137             parse => 'i|install_version=s',
138             so => 50,
139             help => [
140             'Which version to install (3.23, 4.0, 4.1, 5.0 or 5.1) default: none'
141             ]
142             },
143             basedir => {
144             value => '/usr/local/mysql',
145             parse => 'b|basedir=s' ,
146             export => 1,
147             so => 60,
148             help => [
149             'Base directory for MySQL (default: /usr/local/mysql)'
150             ]
151             },
152             tmpdir => {
153             value => undef,
154             parse => 'tmpdir=s' ,
155             export => 1,
156             so => 65,
157             help => [
158             'Temporary directory for MySQL (default: Sandbox_directory/tmp)'
159             ]
160             },
161              
162             my_file => {
163             value => q{},
164             parse => 'm|my_file=s',
165             so => 70,
166             export => 1,
167             help => [
168             'which sample my-{small|large|huge}.cnf file should be used',
169             'for additional configuration',
170             'You may enter either the label (small|large|huge) or a full',
171             'file name. (default: none)',
172             ]
173             },
174             conf_file => {
175             value => q{},
176             parse => 'f|conf_file=s',
177             so => 80,
178             help => [
179             'Configuration file containing options like the ones',
180             'you can give on the command line (without dashes)',
181             ]
182             },
183             operating_system_user => {
184             value => $ENV{'USER'},
185             parse => 'U|operating_system_user=s',
186             so => 90,
187             help => [
188             'Operating system user (for mysql installation)',
189             "default: \$USER ($ENV{USER})",
190             ]
191             },
192             db_user => {
193             value => $MySQL::Sandbox::default_users{'db_user'},
194             parse => 'u|db_user=s' ,
195             so => 100,
196             export => 1,
197             help => [
198             'user for global access to mysql (Default: '
199             . $MySQL::Sandbox::default_users{'db_user'} . ')'
200             ]
201             },
202             remote_access => {
203             value => $MySQL::Sandbox::default_users{'remote_access'},
204             parse => 'remote_access=s' ,
205             so => 101,
206             export => 1,
207             help => [
208             'network access for mysql users (Default: '
209             . $MySQL::Sandbox::default_users{'remote_access'} . ')'
210             ]
211             },
212             bind_address => {
213             value => '127.0.0.1',
214             parse => 'bind_address=s' ,
215             so => 102,
216             export => 1,
217             help => [
218             'Bind address for mysql server (Default: 127.0.0.1'
219             ]
220             },
221              
222             ro_user => {
223             value => $MySQL::Sandbox::default_users{'ro_user'},
224             parse => 'ro_user=s' ,
225             so => 103,
226             export => 1,
227             help => [
228             'user for read-only access to mysql (Default: '
229             . $MySQL::Sandbox::default_users{'ro_user'} . ')'
230             ]
231             },
232              
233             rw_user => {
234             value => $MySQL::Sandbox::default_users{'rw_user'},
235             parse => 'rw_user=s' ,
236             so => 105,
237             export => 1,
238             help => [
239             'user for read-write access to mysql (Default: '
240             . $MySQL::Sandbox::default_users{'rw_user'} . ')'
241             ]
242             },
243             repl_user => {
244             value => $MySQL::Sandbox::default_users{'repl_user'},
245             parse => 'repl_user=s' ,
246             so => 106,
247             export => 1,
248             help => [
249             'user for replication access to mysql (Default: '
250             . $MySQL::Sandbox::default_users{'repl_user'} . ')'
251             ]
252             },
253             db_password => {
254             value => $MySQL::Sandbox::default_users{'db_password'},
255             parse => 'p|db_password=s' ,
256             so => 110,
257             export => 1,
258             help => [
259             'password for global access to mysql (Default: '
260             . $MySQL::Sandbox::default_users{'db_password'} . ')'
261             ]
262             },
263             repl_password => {
264             value => $MySQL::Sandbox::default_users{'repl_password'},
265             parse => 'repl_password=s' ,
266             so => 112,
267             export => 1,
268             help => [
269             'password for replication access to mysql (Default: '
270             . $MySQL::Sandbox::default_users{'repl_password'} . ')'
271             ]
272             },
273             my_clause => {
274             value => '',
275             parse => 'c|my_clause=s@',
276             so => 115,
277             export => 1,
278             help => [
279             'option to be inserted in a my.cnf file',
280             'it may be used several times',
281             ]
282             },
283             init_options => {
284             value => $ENV{INIT_OPTIONS} || '',
285             parse => 'init_options=s',
286             so => 118,
287             export => 1,
288             help => [
289             'options to be used during initialization ',
290             '(by either mysql_install_db or mysqld --initialize.)'
291             ]
292             },
293             init_my_cnf => {
294             value => $ENV{INIT_MY_CNF} || '',
295             parse => 'init_my_cnf',
296             so => 120,
297             export => 1,
298             help => [
299             'If set, it uses my.sandbox.cnf at initialization',
300             'instead of --no-defaults.',
301             'WARNING! it may lead to initialization failures'
302             ]
303             },
304             init_use_cnf => {
305             value => $ENV{INIT_USE_CNF} || '',
306             parse => 'init_use_cnf=s',
307             so => 122,
308             export => 1,
309             help => [
310             'Indicates an options file to load during initialization',
311             'instead of --no-defaults.'
312             ]
313             },
314             master => {
315             value => 0,
316             parse => 'master',
317             so => 124,
318             export => 1,
319             help => [
320             'configures the server as a master (enables binlog and sets server ID)'
321             ]
322             },
323             slaveof => {
324             value => undef,
325             parse => 'slaveof=s',
326             so => 125,
327             export => 1,
328             help => [
329             'Configures the server as a slave of another sandbox ',
330             'Requires options for CHANGE MASTER TO, (at least master_port).',
331             'If options other than master_port are provided, they will override the defaults',
332             'and it will be possible to set a slave for a non-sandbox server'
333             ]
334             },
335             high_performance => {
336             value => 0,
337             parse => 'high_performance',
338             so => 126,
339             export => 1,
340             help => [
341             'configures the server for high performance'
342             ]
343             },
344             gtid => {
345             value => 0,
346             parse => 'gtid',
347             so => 130,
348             export => 1,
349             help => [
350             'enables GTID for MySQL 5.6.10+'
351             ]
352             },
353             # general_log => {
354             # value => 0,
355             # parse => 'gl|general_log' ,
356             # so => 140,
357             # help => [
358             # 'Enables the general log for MYSQL 5.1+',
359             # ]
360             # },
361             pre_start_exec => {
362             value => '',
363             parse => 'pre_start_exec=s',
364             so => 140,
365             export => 1,
366             help => [
367             'Shell command to execute after installation, before the server starts',
368             ]
369             },
370             pre_grants_exec => {
371             value => '',
372             parse => 'pre_grants_exec=s',
373             so => 150,
374             export => 1,
375             help => [
376             'Shell command to execute shortly after installation',
377             ]
378             },
379             post_grants_exec => {
380             value => '',
381             parse => 'post_grants_exec=s',
382             so => 152,
383             export => 1,
384             help => [
385             'Shell command to execute shortly after loading grants',
386             ]
387             },
388             pre_grants_sql => {
389             value => '',
390             parse => 'pre_grants_sql=s',
391             so => 155,
392             export => 1,
393             help => [
394             'SQL command to execute shortly after installation ',
395             ]
396             },
397             post_grants_sql => {
398             value => '',
399             parse => 'post_grants_sql=s',
400             so => 160,
401             export => 1,
402             help => [
403             'SQL command to execute shortly after loading grants ',
404             ]
405             },
406             pre_grants_file => {
407             value => '',
408             parse => 'pre_grants_file=s',
409             so => 170,
410             export => 1,
411             help => [
412             'SQL file to execute shortly after installation ',
413             ]
414             },
415             post_grants_file => {
416             value => '',
417             parse => 'post_grants_file=s',
418             so => 180,
419             export => 1,
420             help => [
421             'SQL file to execute shortly after loading grants ',
422             ]
423             },
424             load_plugin => {
425             value => '',
426             parse => 'load_plugin=s',
427             so => 190,
428             export => 1,
429             help => [
430             'Comma separated list of plugins to install ',
431             ]
432             },
433             plugin_mysqlx => {
434             value => undef,
435             parse => 'plugin_mysqlx',
436             so => 195,
437             export => 1,
438             help => [
439             'Installs MySQLx plugin with an automatic port for X-protocol',
440             ]
441             },
442             mysqlx_port => {
443             value => 0,
444             parse => 'mysqlx_port=i',
445             so => 196,
446             export => 1,
447             help => [
448             'Sets port for X-plugin (requires --plugin_mysqlx)',
449             ]
450             },
451             custom_mysqld => {
452             value => $ENV{'CUSTOM_MYSQLD'} || '' ,
453             parse => 'custom_mysqld=s',
454             so => 198,
455             export => 1,
456             help => [
457             'uses alternative mysqld ',
458             '(must be in the same directory as the regular mysqld)'
459             ]
460             },
461             expose_dd_tables => {
462             value => $ENV{'EXPOSE_DD_TABLES'},
463             parse => 'expose_dd_tables',
464             so => 197,
465             export => 1,
466             help => [
467             'Exposed MySQL 8.0.x data dictionary tables',
468             ]
469             },
470            
471             prompt_prefix => {
472             value => 'mysql',
473             parse => 'prompt_prefix=s',
474             so => 200,
475             export => 1,
476             help => [
477             'prefix to use in CLI prompt (default: mysql)',
478             ]
479             },
480              
481             prompt_body => {
482             value => q/ [\h] {\u} (\d) > /,
483             parse => 'prompt_body=s',
484             so => 210,
485             export => 1,
486             help => [
487             'options to use in CLI prompt (default: [\h] {\u} (\d) > )',
488             ]
489             },
490             force => {
491             value => 0,
492             parse => 'force',
493             so => 220,
494             export => 1,
495             help => [
496             'Use this option if you want to overwrite existing directories',
497             'and files during the installation. (Default: disabled)',
498             ]
499             },
500             no_ver_after_name => {
501             value => 0,
502             parse => 'no_ver_after_name',
503             so => 230,
504             help => [
505             'Do not add version number after sandbox directory name (default: disabled)'
506             ]
507             },
508             verbose => {
509             value => 0,
510             parse => 'v|verbose',
511             so => 240,
512             export => 1,
513             help => [
514             'Use this option to see installation progress (default: disabled)'
515             ]
516             },
517             load_grants => {
518             value => 0,
519             parse => 'load_grants',
520             so => 250,
521             export => 1,
522             help => [
523             'Loads the predefined grants from a SQL file.',
524             'Useful when installing from script.',
525             '(default: disabled)'
526             ]
527             },
528             no_load_grants => {
529             value => 0,
530             parse => 'no_load_grants',
531             so => 260,
532             help => [
533             'Does not loads the predefined grants from a SQL file.',
534             '(default: disabled)'
535             ]
536             },
537              
538             no_run => {
539             value => 0,
540             parse => 'no_run',
541             so => 270,
542             help => [
543             'Stops the server if started with "load_grants".',
544             '(default: disabled)'
545             ]
546             },
547              
548             #
549             # This option requires rewriting several installation steps
550             # For now ( April 29, 2014) we are only supporting MySQL 5.7.4 without random password.
551             # More support will come later
552             #
553             # random_password => {
554             # value => 0,
555             # parse => 'random_password',
556             # so => 275,
557             # help => [
558             # 'Enables random password generation with MySQL 5.7.4+'
559             # ]
560             # },
561             interactive => {
562             value => 0,
563             parse => 't|interactive',
564             so => 280,
565             help => [
566             'Use this option to be guided through the installation process (default: disabled)'
567             ]
568             },
569             more_options => {
570             value => q{},
571             parse => undef,
572             so => 20},
573             help => {
574             value => q{},
575             parse => 'help',
576             so => 25},
577             no_confirm => {
578             value => 0,
579             parse => 'no_confirm',
580             export => 1,
581             so => 290,
582             help => [
583             'suppress the confirmation request from user',
584             ],
585             },
586             no_show => {
587             value => 0,
588             parse => 'no_show',
589             so => 300,
590             help => [
591             'does not show options or ask confirmation to the user',
592             ],
593             },
594             keep_uuid => {
595             value => $ENV{KEEP_UUID} || $ENV{keep_uuid} || 0,
596             parse => 'keep_uuid',
597             so => 310,
598             help => [
599             'does not modify server UUID in MySQL 5.6+',
600             ],
601             },
602             history_dir => {
603             value => $ENV{HISTORY_DIR} || $ENV{HISTORYDIR} || '',
604             parse => 'history_dir=s',
605             so => 320,
606             help => [
607             'Sets the history directory for mysql client to a given path',
608             ],
609             },
610              
611             );
612              
613             my %parse_options_replication = (
614             upper_directory => {
615             value => $ENV{'SANDBOX_HOME'} || $ENV{'HOME'},
616             parse => 'upper_directory=s',
617             so => 10,
618             help => [
619             "The directory containing the sandbox. (default: \$SANDBOX_HOME ($ENV{SANDBOX_HOME}))"
620             ]
621             },
622             replication_directory => {
623             value => undef,
624             parse => 'r|replication_directory=s',
625             so => 20,
626             help => [
627             'Where to install the sandbox replication system, under upper-directory',
628             'default: (rsandbox)'
629             ]
630             },
631             server_version => {
632             value => undef,
633             parse => 'server_version=s',
634             so => 30,
635             help => [
636             'which version to install'
637             ]
638             },
639             sandbox_base_port => {
640             value => undef,
641             parse => 'sandbox_base_port=i',
642             so => 40,
643             help => [
644             'The port number to use for the sandbox replication system.',
645             '(Default: 11000 + version )',
646             ]
647             },
648             check_base_port => {
649             value => undef,
650             parse => 'check_base_port',
651             so => 45,
652             help => [
653             'Check that the ports are available ',
654             '(Default: disabled )',
655             ]
656             },
657              
658              
659             how_many_slaves => {
660             value => 2,
661             parse => 'how_many_nodes|how_many_slaves=i',
662             so => 50,
663             help => [
664             'The number of slaves to create.',
665             '(Default: 2)',
666             ]
667             },
668              
669             topology => {
670             value => 'standard',
671             parse => 't|topology=s',
672             so => 60,
673             help => [
674             'Sets a replication topology.',
675             'Available: {standard|circular} (default: standard)'
676             ]
677             },
678             circular => {
679             value => 0,
680             parse => 'circular=i',
681             so => 70,
682             help => [
683             'Sets circular replication with N nodes.',
684             '(default: 0)'
685             ]
686             },
687              
688              
689             master_master => {
690             value => 0,
691             parse => 'master_master',
692             so => 80,
693             help => [
694             'set exactly two nodes in circular replication'
695             ]
696             },
697            
698             repl_user => {
699             value => $MySQL::Sandbox::default_users{'repl_user'},
700             parse => 'repl_user=s',
701             so => 90,
702             help => [
703             'user with replication slave privileges.',
704             '(default: '. $MySQL::Sandbox::default_users{'repl_user'} . ')'
705             ]
706             },
707             master_ip => {
708             value => '127.0.0.1',
709             parse => 'master_ip=s',
710             so => 95,
711             help => [
712             'Which IP is used by slaves to connect to the master',
713             '(default: 127.0.0.1)'
714             ]
715             },
716              
717             repl_password => {
718             value => $MySQL::Sandbox::default_users{'repl_password'},
719             parse => 'repl_password=s',
720             so => 100,
721             help => [
722             'password for user with replication slave privileges.',
723             '(default: '. $MySQL::Sandbox::default_users{'repl_password'} . ')'
724             ]
725             },
726             remote_access => {
727             value => $MySQL::Sandbox::default_users{'remote_access'},
728             parse => 'remote_access=s' ,
729             so => 110,
730             help => [
731             'network access for mysql users (Default: '
732             . $MySQL::Sandbox::default_users{'remote_access'} . ')'
733             ]
734             },
735             master_options => {
736             value => '',
737             parse => 'master_options=s' ,
738             so => 120,
739             help => [
740             'Options passed to the master (Default: "" )'
741             ]
742             },
743             slave_options => {
744             value => '',
745             parse => 'slave_options=s' ,
746             so => 120,
747             help => [
748             'Options passed to each slave (Default: "" )'
749             ]
750             },
751             node_options => {
752             value => '',
753             parse => 'node_options=s' ,
754             so => 130,
755             help => [
756             'Options passed to each node (Default: "" )'
757             ]
758             },
759             one_slave_options => {
760             value => '',
761             parse => 'one_slave_options=s@' ,
762             so => 130,
763             help => [
764             'Options passed to a specific slave with the format "N:options"',
765             '(Default: "" )'
766             ]
767             },
768             gtid => {
769             value => 0,
770             parse => 'gtid' ,
771             so => 140,
772             help => [
773             'Enables GTID for MYSQL 5.6.10+',
774             '(Default: NO )'
775             ]
776             },
777             # general_log => {
778             # value => 0,
779             # parse => 'gl|general_log' ,
780             # so => 145,
781             # help => [
782             # 'Enables the general log for MYSQL 5.1+',
783             # '(Default: NO )'
784             # ]
785             # },
786            
787            
788             interactive => {
789             value => 0,
790             parse => 'interactive',
791             so => 210,
792             help => [
793             'Use this option to ask interactive user ',
794             'confirmation for each node (default: disabled)'
795             ]
796             },
797             verbose => {
798             value => 0,
799             parse => 'v|verbose',
800             so => 220,
801             help => [
802             'Use this option to see installation progress (default: disabled)'
803             ]
804             },
805             help => {
806             value => 0,
807             parse => 'help',
808             so => 230,
809             help => [
810             'show this help (default: disabled)'
811             ]
812             },
813             );
814              
815              
816             my %parse_options_many = (
817             upper_directory => {
818             value => $ENV{'SANDBOX_HOME'} || $ENV{'HOME'},
819             parse => 'upper_directory=s',
820             so => 10,
821             help => [
822             "The directory containing the sandbox. (default: \$SANDBOX_HOME ($ENV{SANDBOX_HOME}))"
823             ]
824             },
825             group_directory => {
826             value => undef,
827             parse => 'r|group_directory=s',
828             so => 20,
829             help => [
830             'Where to install the sandbox group, under home-directory',
831             'default: (multi_msb)'
832             ]
833             },
834             server_version => {
835             value => undef,
836             parse => 'server_version=s',
837             so => 30,
838             help => [
839             'which version to install'
840             ]
841             },
842             sandbox_base_port => {
843             value => undef,
844             parse => 'sandbox_base_port=i',
845             so => 40,
846             help => [
847             'The port number to use for the sandbox multiple system.',
848             '(Default: 7000 + version )',
849             ]
850             },
851             check_base_port => {
852             value => undef,
853             parse => 'check_base_port',
854             so => 45,
855             help => [
856             'Check that the ports are available ',
857             '(Default: disabled )',
858             ]
859             },
860              
861             how_many_nodes => {
862             value => 3,
863             parse => 'how_many_nodes=i',
864             so => 50,
865             help => [
866             'The number of nodes to create.',
867             '(Default: 3)',
868             ]
869             },
870             master_master => {
871             value => 0,
872             parse => 'master_master',
873             so => 60,
874             help => [
875             'set exactly two nodes in circular replication'
876             ]
877             },
878            
879             circular => {
880             value => 0,
881             parse => 'circular',
882             so => 70,
883             help => [
884             'set the nodes in circular replication'
885             ]
886             },
887              
888             repl_user => {
889             value => $MySQL::Sandbox::default_users{'repl_user'},
890             parse => 'repl_user=s',
891             so => 80,
892             help => [
893             'user with replication slave privileges.',
894             '(default: '. $MySQL::Sandbox::default_users{'repl_user'} . ')'
895             ]
896             },
897              
898             repl_password => {
899             value => $MySQL::Sandbox::default_users{'repl_password'},
900             parse => 'repl_password=s',
901             so => 90,
902             help => [
903             'password for user with replication slave privileges.',
904             '(default: '. $MySQL::Sandbox::default_users{'repl_password'} . ')'
905             ]
906             },
907             remote_access => {
908             value => $MySQL::Sandbox::default_users{'remote_access'},
909             parse => 'remote_access=s' ,
910             so => 100,
911             help => [
912             'network access for mysql users (Default: '
913             . $MySQL::Sandbox::default_users{'remote_access'} . ')'
914             ]
915             },
916            
917             node_options => {
918             value => '',
919             parse => 'node_options=s' ,
920             so => 130,
921             help => [
922             'Options passed to each node (Default: "" )'
923             ]
924             },
925            
926             one_node_options => {
927             value => '',
928             parse => 'one_node_options=s@' ,
929             so => 140,
930             help => [
931             'Options passed to a specific node with the format "N:options"',
932             '(Default: "" )'
933             ]
934             },
935             gtid => {
936             value => 0,
937             parse => 'gtid' ,
938             so => 150,
939             help => [
940             'Enables GTID for MYSQL 5.6.10+',
941             '(Default: NO )'
942             ]
943             },
944            
945              
946             interactive => {
947             value => 0,
948             parse => 'interactive',
949             so => 210,
950             help => [
951             'Use this option to ask interactive user ',
952             'confirmation for each node (default: disabled)'
953             ]
954             },
955             verbose => {
956             value => 0,
957             parse => 'v|verbose',
958             so => 220,
959             help => [
960             'Use this option to see installation progress (default: disabled)'
961             ]
962             },
963              
964             help => {
965             value => 0,
966             parse => 'help',
967             so => 230,
968             help => [
969             'show this help (default: disabled)'
970             ]
971             },
972             );
973              
974             my %parse_options_custom_many = (
975             upper_directory => {
976             value => $ENV{'SANDBOX_HOME'} || $ENV{'HOME'},
977             parse => 'upper_directory=s',
978             so => 10,
979             help => [
980             "The directory containing the sandbox. (default: \$SANDBOX_HOME ($ENV{SANDBOX_HOME}))"
981             ]
982             },
983             group_directory => {
984             value => undef,
985             parse => 'r|group_directory=s',
986             so => 20,
987             help => [
988             'Where to install the sandbox group, under home-directory',
989             'default: (multi_msb)'
990             ]
991             },
992             server_version => {
993             value => undef,
994             parse => 'server_version=s',
995             so => 30,
996             help => [
997             'which version to install'
998             ]
999             },
1000             sandbox_base_port => {
1001             value => undef,
1002             parse => 'sandbox_base_port=i',
1003             so => 40,
1004             help => [
1005             'The port number to use for the sandbox custom system.',
1006             '(Default: 5000 + version )',
1007             ]
1008             },
1009             check_base_port => {
1010             value => undef,
1011             parse => 'check_base_port',
1012             so => 45,
1013             help => [
1014             'Check that the ports are available ',
1015             '(Default: disabled )',
1016             ]
1017             },
1018             node_options => {
1019             value => '',
1020             parse => 'node_options=s' ,
1021             so => 130,
1022             help => [
1023             'Options passed to each node (Default: "" )'
1024             ]
1025             },
1026            
1027             one_node_options => {
1028             value => '',
1029             parse => 'one_node_options=s@' ,
1030             so => 140,
1031             help => [
1032             'Options passed to a specific node with the format "N:options"',
1033             '(Default: "" )'
1034             ]
1035             },
1036              
1037              
1038              
1039             interactive => {
1040             value => 0,
1041             parse => 'interactive',
1042             so => 210,
1043             help => [
1044             'Use this option to ask interactive user ',
1045             'confirmation for each node (default: disabled)'
1046             ]
1047             },
1048             verbose => {
1049             value => 0,
1050             parse => 'v|verbose',
1051             so => 220,
1052             help => [
1053             'Use this option to see installation progress (default: disabled)'
1054             ]
1055             },
1056             help => {
1057             value => 0,
1058             parse => 'help',
1059             so => 230,
1060             help => [
1061             'show this help (default: disabled)'
1062             ]
1063             },
1064             );
1065              
1066             our %sbtool_supported_operations = (
1067             ports => 'lists ports used by the Sandbox',
1068             range => 'finds N consecutive ports not yet used by the Sandbox',
1069             info => 'returns configuration options from a Sandbox',
1070             tree => 'creates a replication tree',
1071             copy => 'copies data from one Sandbox to another',
1072             move => 'moves a Sandbox to a different location',
1073             port => 'Changes a Sandbox port',
1074             delete => 'removes a sandbox completely',
1075             preserve => 'makes a sandbox permanent',
1076             unpreserve => 'makes a sandbox NOT permanent',
1077             plugin => 'adds plugin support to a sandbox (innodb,semisynch)',
1078             );
1079              
1080             our %sbtool_supported_formats = (
1081             text => 'plain text dump of requested information',
1082             perl => 'fully structured information in Perl code',
1083             );
1084              
1085             #our %sbtool_supported_plugins = (
1086             # innodb => 'innodb plugin (5.1)',
1087             # semisync => 'semi synchrounus replication (5.5)',
1088             # gearman => 'Gearman UDF',
1089             #);
1090              
1091             my %parse_options_sbtool = (
1092             operation => {
1093             so => 10,
1094             parse => 'o|operation=s',
1095             value => undef,
1096             accepted => \%sbtool_supported_operations,
1097             help => 'what task to perform',
1098             },
1099             source_dir => {
1100             so => 20,
1101             parse => 's|source_dir=s',
1102             value => undef,
1103             help => 'source directory for move, copy, delete',
1104             },
1105             dest_dir => {
1106             so => 30,
1107             parse => 'd|dest_dir=s',
1108             value => undef,
1109             help => 'destination directory for move,copy',
1110             },
1111             new_port => {
1112             so => 40,
1113             parse => 'n|new_port=s',
1114             value => undef,
1115             help => 'new port while moving a sandbox',
1116             },
1117             only_used => {
1118             so => 50,
1119             parse => 'u|only_used',
1120             value => 0,
1121             help => 'for "ports" operation, shows only the used ones',
1122             },
1123             min_range => {
1124             so => 60,
1125             parse => 'i|min_range=i',
1126             value => 5000,
1127             help => 'minimum port when searching for available ranges',
1128             },
1129             max_range => {
1130             so => 70,
1131             parse => 'x|max_range=i',
1132             value => 64000,
1133             help => 'maximum port when searching for available ranges',
1134             },
1135             range_size => {
1136             so => 80,
1137             parse => 'z|range_size=i',
1138             value => 10,
1139             help => 'size of range when searching for available port range',
1140             },
1141             format => {
1142             so => 90,
1143             parse => 'f|format=s',
1144             value => 'text',
1145             accepted => \%sbtool_supported_formats,
1146             help => 'format for "ports" and "info"',
1147             },
1148             search_path => {
1149             so => 100,
1150             parse => 'p|search_path=s',
1151             value => $ENV{SANDBOX_HOME},
1152             help => 'search path for ports and info',
1153             },
1154             all_info => {
1155             so => 110,
1156             parse => 'a|all_info',
1157             value => 0,
1158             help => 'print more info for "ports" operation'
1159             },
1160             master_node => {
1161             so => 115,
1162             parse => 'master_node=i',
1163             value => '1',
1164             help => 'which node should be master (default: 1)',
1165             },
1166             tree_nodes => {
1167             so => 120,
1168             parse => 'tree_nodes=s',
1169             value => '',
1170             help => 'description of the tree (x-x x x-x x|x x x|x x)',
1171             },
1172             mid_nodes => {
1173             so => 130,
1174             parse => 'mid_nodes=s',
1175             value => '',
1176             help => 'description of the middle nodes (x x x)',
1177             },
1178             leaf_nodes => {
1179             so => 140,
1180             parse => 'leaf_nodes=s',
1181             value => '',
1182             help => 'description of the leaf nodes (x x|x x x|x x)',
1183             },
1184             tree_dir => {
1185             so => 150,
1186             parse => 'tree_dir=s',
1187             value => '',
1188             help => 'which directory contains the tree nodes',
1189             },
1190             verbose => {
1191             so => 160,
1192             parse => 'v|verbose',
1193             value => 0,
1194             help => 'prints more info on some operations'
1195             },
1196             plugin => {
1197             so => 170,
1198             parse => 'plugin=s',
1199             value => undef,
1200             help => 'install given plugin in sandbox',
1201             },
1202             plugin_file => {
1203             so => 180,
1204             parse => 'plugin_file=s',
1205             value => undef,
1206             help => 'plugin configuration file to use instead of default plugin.conf',
1207             },
1208             help => {
1209             so => 999,
1210             parse => 'h|help',
1211             value => undef,
1212             help => 'this screen',
1213             },
1214             );
1215              
1216             # --- START SCRIPTS IN CODE ---
1217              
1218             my %scripts_in_code = (
1219             'msb.sh' => <<'MSB_SCRIPT',
1220             #!_BINBASH_
1221             __LICENSE__
1222              
1223             ACCEPTED="{start|stop|restart|clear|send_kill|status}"
1224             if [ "$1" == "" ]
1225             then
1226             echo "argument required $ACCEPTED"
1227             exit 1
1228             fi
1229              
1230             SBDIR="_HOME_DIR_/_SANDBOXDIR_"
1231             CMD=$1
1232             shift
1233              
1234             if [ -x "$SBDIR/$CMD" ]
1235             then
1236             $SBDIR/$CMD "$@"
1237             else
1238             echo "unrecognized command '$CMD'"
1239             echo "accepted: $ACCEPTED"
1240             exit 1
1241             fi
1242              
1243             #case $CMD in
1244             # start) $SBDIR/start "$@" ;;
1245             # restart) $SBDIR/restart "$@" ;;
1246             # stop) $SBDIR/stop "$@" ;;
1247             # clear) $SBDIR/clear "$@" ;;
1248             # send_kill) $SBDIR/send_kill "$@" ;;
1249             # status) $SBDIR/status "$@" ;;
1250             # *)
1251             # echo "unrecognized command '$CMD'"
1252             # echo "accepted: $ACCEPTED"
1253             # exit 1
1254             # ;;
1255             #esac
1256              
1257             MSB_SCRIPT
1258              
1259             'start.sh' => <<'START_SCRIPT',
1260             #!_BINBASH_
1261             __LICENSE__
1262             BASEDIR='_BASEDIR_'
1263             export LD_LIBRARY_PATH=$BASEDIR/lib:$BASEDIR/lib/mysql:$LD_LIBRARY_PATH
1264             export DYLD_LIBRARY_PATH=$BASEDIR_/lib:$BASEDIR/lib/mysql:$DYLD_LIBRARY_PATH
1265             MYSQLD_SAFE="bin/_MYSQLDSAFE_"
1266             SBDIR="_HOME_DIR_/_SANDBOXDIR_"
1267             PIDFILE="$SBDIR/data/mysql_sandbox_SERVERPORT_.pid"
1268             CUSTOM_MYSQLD=_CUSTOM_MYSQLD_
1269             if [ -n "$CUSTOM_MYSQLD" ]
1270             then
1271             CUSTOM_MYSQLD="--mysqld=$CUSTOM_MYSQLD"
1272             fi
1273             __SBINSTR_SH__
1274             if [ ! -f $BASEDIR/$MYSQLD_SAFE ]
1275             then
1276             echo "mysqld_safe not found in $BASEDIR/bin/"
1277             exit 1
1278             fi
1279             MYSQLD_SAFE_OK=`sh -n $BASEDIR/$MYSQLD_SAFE 2>&1`
1280             if [ "$MYSQLD_SAFE_OK" == "" ]
1281             then
1282             if [ "$SBDEBUG" == "2" ]
1283             then
1284             echo "$MYSQLD_SAFE OK"
1285             fi
1286             else
1287             echo "$MYSQLD_SAFE has errors"
1288             echo "((( $MYSQLD_SAFE_OK )))"
1289             exit 1
1290             fi
1291              
1292             function is_running
1293             {
1294             if [ -f $PIDFILE ]
1295             then
1296             MYPID=$(cat $PIDFILE)
1297             ps -p $MYPID | grep $MYPID
1298             fi
1299             }
1300              
1301             TIMEOUT=180
1302             if [ -n "$(is_running)" ]
1303             then
1304             echo "sandbox server already started (found pid file $PIDFILE)"
1305             else
1306             if [ -f $PIDFILE ]
1307             then
1308             # Server is not running. Removing stale pid-file
1309             rm -f $PIDFILE
1310             fi
1311             CURDIR=`pwd`
1312             cd $BASEDIR
1313             if [ "$SBDEBUG" = "" ]
1314             then
1315             $MYSQLD_SAFE --defaults-file=$SBDIR/my.sandbox.cnf $CUSTOM_MYSQLD $@ > /dev/null 2>&1 &
1316             else
1317             $MYSQLD_SAFE --defaults-file=$SBDIR/my.sandbox.cnf $CUSTOM_MYSQLD $@ > "$SBDIR/start.log" 2>&1 &
1318             fi
1319             cd $CURDIR
1320             ATTEMPTS=1
1321             while [ ! -f $PIDFILE ]
1322             do
1323             ATTEMPTS=$(( $ATTEMPTS + 1 ))
1324             echo -n "."
1325             if [ $ATTEMPTS = $TIMEOUT ]
1326             then
1327             break
1328             fi
1329             sleep 1
1330             done
1331             fi
1332              
1333             if [ -f $PIDFILE ]
1334             then
1335             echo " sandbox server started"
1336             #if [ -f $SBDIR/needs_reload ]
1337             #then
1338             # if [ -f $SBDIR/rescue_mysql_dump.sql ]
1339             # then
1340             # $SBDIR/use mysql < $SBDIR/rescue_mysql_dump.sql
1341             # fi
1342             # rm $SBDIR/needs_reload
1343             #fi
1344             else
1345             echo " sandbox server not started yet"
1346             exit 1
1347             fi
1348              
1349             START_SCRIPT
1350             'sb_include.sh' => <<'SB_INCLUDE_SCRIPT',
1351             if [ -r $HOME/.mylogin.cnf ]
1352             then
1353             if [ -z "$IGNORE_MYLOGIN_CNF" ]
1354             then
1355             echo "MySQL Sandbox does not work with \$HOME/.mylogin.cnf,"
1356             echo "which is a file created by mysql_config_editor."
1357             echo "Either remove the file or make it not readable by the current user."
1358             echo "If you know what you are doing, you can skip this check by"
1359             echo "setting the variable IGNORE_MYLOGIN_CNF to a nonzero value."
1360             echo "Be aware that having \$HOME/.mylogin.cnf can disrupt MySQL-Sandbox."
1361             echo "Use it at your own risk.\n"
1362             exit 1
1363             fi
1364             fi
1365              
1366             SB_INCLUDE_SCRIPT
1367              
1368             'status.sh' => <<'STATUS_SCRIPT',
1369             #!_BINBASH_
1370             __LICENSE__
1371             SBDIR="_HOME_DIR_/_SANDBOXDIR_"
1372             PIDFILE="$SBDIR/data/mysql_sandbox_SERVERPORT_.pid"
1373             __SBINSTR_SH__
1374             source $SBDIR/sb_include
1375             node_status=off
1376             exit_code=1
1377             if [ -f $PIDFILE ]
1378             then
1379             MYPID=$(cat $PIDFILE)
1380             running=$(ps -p $MYPID | grep $MYPID)
1381             if [ -n "$running" ]
1382             then
1383             node_status=on
1384             exit_code=0
1385             fi
1386             fi
1387             echo "_SANDBOXDIR_ $node_status"
1388             exit $exit_code
1389              
1390             STATUS_SCRIPT
1391              
1392             'restart.sh' => <<'RESTART_SCRIPT',
1393             #!_BINBASH_
1394             __LICENSE__
1395              
1396             __SBINSTR_SH__
1397             SBDIR="_HOME_DIR_/_SANDBOXDIR_"
1398             $SBDIR/stop
1399             $SBDIR/start $@
1400              
1401             RESTART_SCRIPT
1402             'stop.sh' => <<'STOP_SCRIPT',
1403             #!_BINBASH_
1404             __LICENSE__
1405             SBDIR="_HOME_DIR_/_SANDBOXDIR_"
1406             source $SBDIR/sb_include
1407             BASEDIR=_BASEDIR_
1408             export LD_LIBRARY_PATH=$BASEDIR/lib:$BASEDIR/lib/mysql:$LD_LIBRARY_PATH
1409             export DYLD_LIBRARY_PATH=$BASEDIR/lib:$BASEDIR/lib/mysql:$DYLD_LIBRARY_PATH
1410             MYSQL_ADMIN="$BASEDIR/bin/mysqladmin"
1411             PIDFILE="$SBDIR/data/mysql_sandbox_SERVERPORT_.pid"
1412             __SBINSTR_SH__
1413              
1414             function is_running
1415             {
1416             if [ -f $PIDFILE ]
1417             then
1418             MYPID=$(cat $PIDFILE)
1419             ps -p $MYPID | grep $MYPID
1420             fi
1421             }
1422              
1423             if [ -n "$(is_running)" ]
1424             then
1425             if [ -f $SBDIR/data/master.info ]
1426             then
1427             echo "stop slave" | $SBDIR/use -u root
1428             fi
1429             # echo "$MYSQL_ADMIN --defaults-file=$SBDIR/my.sandbox.cnf $MYCLIENT_OPTIONS shutdown"
1430             $MYSQL_ADMIN --defaults-file=$SBDIR/my.sandbox.cnf $MYCLIENT_OPTIONS shutdown
1431             sleep 1
1432             else
1433             if [ -f $PIDFILE ]
1434             then
1435             rm -f $PIDFILE
1436             fi
1437             fi
1438              
1439             if [ -n "$(is_running)" ]
1440             then
1441             # use the send_kill script if the server is not responsive
1442             $SBDIR/send_kill
1443             fi
1444             STOP_SCRIPT
1445              
1446             'send_kill.sh' => <<'KILL_SCRIPT',
1447             #!_BINBASH_
1448             __LICENSE__
1449             SBDIR="_HOME_DIR_/_SANDBOXDIR_"
1450             #source $SBDIR/sb_include
1451             PIDFILE="$SBDIR/data/mysql_sandbox_SERVERPORT_.pid"
1452             TIMEOUT=30
1453             __SBINSTR_SH__
1454              
1455             function is_running
1456             {
1457             if [ -f $PIDFILE ]
1458             then
1459             MYPID=$(cat $PIDFILE)
1460             ps -p $MYPID | grep $MYPID
1461             fi
1462             }
1463              
1464              
1465             if [ -n "$(is_running)" ]
1466             then
1467             MYPID=`cat $PIDFILE`
1468             echo "Attempting normal termination --- kill -15 $MYPID"
1469             kill -15 $MYPID
1470             # give it a chance to exit peacefully
1471             ATTEMPTS=1
1472             while [ -f $PIDFILE ]
1473             do
1474             ATTEMPTS=$(( $ATTEMPTS + 1 ))
1475             if [ $ATTEMPTS = $TIMEOUT ]
1476             then
1477             break
1478             fi
1479             sleep 1
1480             done
1481             if [ -f $PIDFILE ]
1482             then
1483             echo "SERVER UNRESPONSIVE --- kill -9 $MYPID"
1484             kill -9 $MYPID
1485             rm -f $PIDFILE
1486             fi
1487             else
1488             # server not running - removing stale pid-file
1489             if [ -f $PIDFILE ]
1490             then
1491             rm -f $PIDFILE
1492             fi
1493             fi
1494              
1495             KILL_SCRIPT
1496              
1497             'json_in_db.sh' => <<'JSON_IN_DB_SCRIPT',
1498              
1499             #!_BINBASH_
1500             __LICENSE__
1501             SBDIR="_HOME_DIR_/_SANDBOXDIR_"
1502             cd $SBDIR
1503             ./use -e 'drop table if exists test.connection_json'
1504             ./use -e 'create table test.connection_json(t longtext)'
1505             ./use -e '/*!50708 alter table test.connection_json modify t json */'
1506             #./use -e "insert into test.connection_json values (load_file('$SBDIR/connection.json'))"
1507             ./use -e "insert into test.connection_json values ( /*!50708 convert( */ load_file('$SBDIR/connection.json') /*!50708 using UTF8 ) */ )"
1508             if [ "$?" != "0" ]
1509             then
1510             echo "error loading connection.json to the database"
1511             exit 1
1512             fi
1513             echo "connection.json saved to test.connection_json"
1514              
1515             JSON_IN_DB_SCRIPT
1516              
1517             'use.sh' => <<'USE_SCRIPT',
1518             #!_BINBASH_
1519             __LICENSE__
1520             export LD_LIBRARY_PATH=_BASEDIR_/lib:_BASEDIR_/lib/mysql:$LD_LIBRARY_PATH
1521             export DYLD_LIBRARY_PATH=_BASEDIR_/lib:_BASEDIR_/lib/mysql:$DYLD_LIBRARY_PATH
1522             SBDIR="_HOME_DIR_/_SANDBOXDIR_"
1523             [ -n "$TEST_REPL_DELAY" -a -f $SBDIR/data/mysql-relay.index ] && sleep $TEST_REPL_DELAY
1524             source $SBDIR/sb_include
1525             BASEDIR=_BASEDIR_
1526             [ -z "$MYSQL_EDITOR" ] && MYSQL_EDITOR="$BASEDIR/bin/mysql"
1527             if [ ! -x $MYSQL_EDITOR ]
1528             then
1529             if [ -x $SBDIR/$MYSQL_EDITOR ]
1530             then
1531             MYSQL_EDITOR=$SBDIR/$MYSQL_EDITOR
1532             else
1533             echo "MYSQL_EDITOR '$MYSQL_EDITOR' not found or not executable"
1534             exit 1
1535             fi
1536             fi
1537             HISTDIR=_HISTORY_DIR_
1538             [ -z "$HISTDIR" ] && HISTDIR=$SBDIR
1539             export MYSQL_HISTFILE="$HISTDIR/.mysql_history"
1540             PIDFILE="$SBDIR/data/mysql_sandbox_SERVERPORT_.pid"
1541             __SBINSTR_SH__
1542             MY_CNF=$SBDIR/my.sandbox.cnf
1543             MY_CNF_NO_PASSWORD=$SBDIR/my.sandbox_np.cnf
1544             if [ -n "$NOPASSWORD" ]
1545             then
1546             perl -ne 'print unless /^password/' < $MY_CNF > $MY_CNF_NO_PASSWORD
1547             MY_CNF=$MY_CNF_NO_PASSWORD
1548             fi
1549             if [ -f $PIDFILE ]
1550             then
1551             $MYSQL_EDITOR --defaults-file=$MY_CNF $MYCLIENT_OPTIONS "$@"
1552             #else
1553             # echo "PID file $PIDFILE not found "
1554             fi
1555             USE_SCRIPT
1556              
1557             'mycli.sh' => <<'MYCLI_SCRIPT',
1558             #!_BINBASH_
1559             __LICENSE__
1560             export LD_LIBRARY_PATH=_BASEDIR_/lib:_BASEDIR_/lib/mysql:$LD_LIBRARY_PATH
1561             export DYLD_LIBRARY_PATH=_BASEDIR_/lib:_BASEDIR_/lib/mysql:$DYLD_LIBRARY_PATH
1562             SBDIR="_HOME_DIR_/_SANDBOXDIR_"
1563             source $SBDIR/sb_include
1564             BASEDIR=_BASEDIR_
1565             mycli --user=_DBUSER_ \
1566             --pass=_DBPASSWORD_ \
1567             --port=_SERVERPORT_ \
1568             --socket=_GLOBALTMPDIR_/mysql_sandbox_SERVERPORT_.sock \
1569             --_MYSQL_PROMPT_ "$@"
1570              
1571             MYCLI_SCRIPT
1572              
1573              
1574             'mysqlsh.sh' => <<'MYSQLSH_SCRIPT',
1575             #!_BINBASH_
1576             __LICENSE__
1577             export LD_LIBRARY_PATH=_BASEDIR_/lib:_BASEDIR_/lib/mysql:$LD_LIBRARY_PATH
1578             export DYLD_LIBRARY_PATH=_BASEDIR_/lib:_BASEDIR_/lib/mysql:$DYLD_LIBRARY_PATH
1579             SBDIR="_HOME_DIR_/_SANDBOXDIR_"
1580             source $SBDIR/sb_include
1581             BASEDIR=_BASEDIR_
1582             mode=$1
1583             if [ -n "$mode" ]
1584             then
1585             shift
1586             else
1587             mode=--sql
1588             fi
1589             case $mode in
1590             --sql)
1591             mysqlsh \
1592             --sqlc \
1593             --user=_DBUSER_ \
1594             --password=_DBPASSWORD_ \
1595             --port=_SERVERPORT_ "$@"
1596             ;;
1597             --js)
1598             mysqlsh \
1599             --user=_DBUSER_ \
1600             --password=_DBPASSWORD_ \
1601             --port=_MYSQLXPORT_ "$@"
1602             ;;
1603             *)
1604             echo "Syntax: $0 [--js|--sql]"
1605             exit 1
1606             esac
1607              
1608             MYSQLSH_SCRIPT
1609              
1610              
1611             'clear.sh' => <<'CLEAR_SCRIPT',
1612             #!_BINBASH_
1613             __LICENSE__
1614             SBDIR="_HOME_DIR_/_SANDBOXDIR_"
1615             #source $SBDIR/sb_include
1616             cd $SBDIR
1617             PIDFILE="$SBDIR/data/mysql_sandbox_SERVERPORT_.pid"
1618             __SBINSTR_SH__
1619             #
1620             # attempt to drop databases gracefully
1621             #
1622              
1623             function is_running
1624             {
1625             if [ -f $PIDFILE ]
1626             then
1627             MYPID=$(cat $PIDFILE)
1628             ps -p $MYPID | grep $MYPID
1629             fi
1630             }
1631              
1632             if [ -n "$(is_running)" ]
1633             then
1634             for D in `echo "show databases " | ./use -B -N | grep -v "^mysql$" | grep -iv "^information_schema$" | grep -iv "^performance_schema" | grep -ivw "^sys"`
1635             do
1636             echo "set sql_mode=ansi_quotes;drop database \"$D\"" | ./use
1637             done
1638             VERSION=`./use -N -B -e 'select left(version(),3)'`
1639             #if [ `perl -le 'print $ARGV[0] ge "5.0" ? "1" : "0" ' "$VERSION"` = "1" ]
1640             #then
1641             # ./use -e "truncate mysql.proc"
1642             # ./use -e "truncate mysql.func"
1643             #fi
1644             is_slave=$(ls data | grep relay)
1645             if [ -n "$is_slave" ]
1646             then
1647             ./use -e "stop slave; reset slave;"
1648             fi
1649             if [ `perl -le 'print $ARGV[0] ge "5.1" ? "1" : "0" ' "$VERSION"` = "1" ]
1650             then
1651             for T in general_log slow_log plugin
1652             do
1653             exists_table=$(./use -e "show tables from mysql like '$T'")
1654             if [ -n "$exists_table" ]
1655             then
1656             ./use -e "truncate mysql.$T"
1657             fi
1658             done
1659             fi
1660             fi
1661              
1662             is_master=$(ls data | grep 'mysql-bin')
1663             if [ -n "$is_master" ]
1664             then
1665             ./use -e 'reset master'
1666             fi
1667              
1668             ./stop
1669             #./send_kill
1670             rm -f data/`hostname`*
1671             rm -f data/log.0*
1672             rm -f data/*.log
1673             rm -f data/falcon*
1674             rm -f data/mysql-bin*
1675             rm -f data/*relay-bin*
1676             rm -f data/ib_*
1677             rm -f data/*.info
1678             rm -f data/*.err
1679             rm -f data/*.err-old
1680             #if [ `perl -le 'print $ARGV[0] ge "5.6" ? "1" : "0" ' "$VERSION"` = "1" ]
1681             #then
1682             # rm -f data/mysql/slave_*
1683             # rm -f data/mysql/innodb_*
1684             # touch needs_reload
1685             #fi
1686             # rm -rf data/test/*
1687              
1688             #
1689             # remove all databases if any (up to 8.0)
1690             #
1691             if [ `perl -le 'print $ARGV[0] lt "8.0" ? "1" : "0" ' "$VERSION"` = "1" ]
1692             then
1693             for D in `ls -d data/*/ | grep -w -v mysql | grep -iv performance_schema | grep -ivw sys`
1694             do
1695             rm -rf $D
1696             done
1697             mkdir data/test
1698             fi
1699              
1700             CLEAR_SCRIPT
1701             'my.sandbox.cnf' => <<'MY_SANDBOX_SCRIPT',
1702             __LICENSE__
1703             [mysql]
1704             _MYSQL_PROMPT_
1705             #
1706              
1707             [client]
1708             user = _DBUSER_
1709             password = _DBPASSWORD_
1710             port = _SERVERPORT_
1711             socket = _GLOBALTMPDIR_/mysql_sandbox_SERVERPORT_.sock
1712              
1713             [mysqld]
1714             user = _OSUSER_
1715             port = _SERVERPORT_
1716             socket = _GLOBALTMPDIR_/mysql_sandbox_SERVERPORT_.sock
1717             basedir = _BASEDIR_
1718             datadir = _HOME_DIR_/_SANDBOXDIR_/data
1719             tmpdir = _TMPDIR_
1720             lower_case_table_names = _LOWER_CASE_TABLE_NAMES_
1721             pid-file = _HOME_DIR_/_SANDBOXDIR_/data/mysql_sandbox_SERVERPORT_.pid
1722             bind-address = _BIND_ADDRESS_
1723             # _SLOW_QUERY_LOG_
1724             # _GENERAL_LOG_
1725             _MORE_OPTIONS_
1726              
1727             MY_SANDBOX_SCRIPT
1728              
1729             'USING' => <
1730             Created with MySQL Sandbox _MSB_VERSION_
1731             Currently using _INSTALL_VERSION_ with basedir _BASEDIR_
1732              
1733             USING_SCRIPT
1734              
1735             'README' =>
1736             MySQL::Sandbox::credits()
1737             . "\n" . <
1738             This is a sandbox for MySQL _INSTALL_VERSION_ (from _BASEDIR_)
1739             Created using MySQL Sandbox _MSB_VERSION_
1740              
1741             Default user: "_DBUSER_" (password: "_DBPASSWORD_")
1742             For more connection options, see connection.json
1743             and default_connection.json.
1744              
1745             You can connect to the database with ./use
1746              
1747             Simple administrative tasks can be performed using:
1748             ./start [options] : starts the server
1749             ./restart [options] : restarts the server
1750             ./stop : stops the server
1751             ./status : tells if the server is running
1752             ./clear : stops the server and removes all contents (WARNING!: dangerous)
1753             ./send_kill : stops an unresponsive server
1754             ./my sqldump : calls mysqldump (notice the space after './my')
1755             ./my sqladmin : calls mysqladmin (notice the space after './my')
1756             ./my sqlbinlog : calls mysqlbinlog (notice the space after './my')
1757             ./msb {start restart stop status} : all-purpose start/stop/status/restart command
1758              
1759             The full manual is available using:
1760             perldoc MySQL::Sandbox
1761              
1762             A task-oriented user manual is also available:
1763             perldoc MySQL::Sandbox::Recipes
1764              
1765             README_SCRIPT
1766              
1767              
1768             'grants.mysql' => <<'GRANTS_MYSQL',
1769              
1770             use mysql;
1771             set password=password('_DBPASSWORD_');
1772             grant all on *.* to _DBUSER_@'_REMOTE_ACCESS_' identified by '_DBPASSWORD_';
1773             grant all on *.* to _DBUSER_@'localhost' identified by '_DBPASSWORD_';
1774             grant SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,ALTER,
1775             SHOW DATABASES,CREATE TEMPORARY TABLES,LOCK TABLES, EXECUTE
1776             on *.* to _DBUSERRW_@'localhost' identified by '_DBPASSWORD_';
1777             grant SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,ALTER,
1778             SHOW DATABASES,CREATE TEMPORARY TABLES,LOCK TABLES, EXECUTE
1779             on *.* to _DBUSERRW_@'_REMOTE_ACCESS_' identified by '_DBPASSWORD_';
1780             grant SELECT,EXECUTE on *.* to _DBUSERRO_@'_REMOTE_ACCESS_' identified by '_DBPASSWORD_';
1781             grant SELECT,EXECUTE on *.* to _DBUSERRO_@'localhost' identified by '_DBPASSWORD_';
1782             grant REPLICATION SLAVE on *.* to _DBUSERREPL_@'_REMOTE_ACCESS_' identified by '_DB_REPL_PASSWORD_';
1783             delete from user where password='';
1784             delete from db where user='';
1785             flush privileges;
1786             create database if not exists test;
1787              
1788             GRANTS_MYSQL
1789              
1790              
1791             'grants_5_7_6.mysql' => <<'GRANTS_MYSQL_5_7_6',
1792              
1793             use mysql;
1794             set password='_DBPASSWORD_';
1795             -- delete from tables_priv;
1796             -- delete from columns_priv;
1797             -- delete from db;
1798             delete from user where user not in ('root', 'mysql.sys', 'mysqlxsys', 'mysql.session', 'mysql.infoschema');
1799              
1800             flush privileges;
1801              
1802             create user _DBUSER_@'_REMOTE_ACCESS_' identified by '_DBPASSWORD_';
1803             grant all on *.* to _DBUSER_@'_REMOTE_ACCESS_' ;
1804              
1805             create user _DBUSER_@'localhost' identified by '_DBPASSWORD_';
1806             grant all on *.* to _DBUSER_@'localhost';
1807              
1808             create user _DBUSERRW_@'localhost' identified by '_DBPASSWORD_';
1809             grant SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,ALTER,
1810             SHOW DATABASES,CREATE TEMPORARY TABLES,LOCK TABLES, EXECUTE
1811             on *.* to _DBUSERRW_@'localhost';
1812              
1813             create user _DBUSERRW_@'_REMOTE_ACCESS_' identified by '_DBPASSWORD_';
1814             grant SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,ALTER,
1815             SHOW DATABASES,CREATE TEMPORARY TABLES,LOCK TABLES, EXECUTE
1816             on *.* to _DBUSERRW_@'_REMOTE_ACCESS_';
1817              
1818             create user _DBUSERRO_@'_REMOTE_ACCESS_' identified by '_DBPASSWORD_';
1819             create user _DBUSERRO_@'localhost' identified by '_DBPASSWORD_';
1820             create user _DBUSERREPL_@'_REMOTE_ACCESS_' identified by '_DB_REPL_PASSWORD_';
1821             grant SELECT,EXECUTE on *.* to _DBUSERRO_@'_REMOTE_ACCESS_';
1822             grant SELECT,EXECUTE on *.* to _DBUSERRO_@'localhost';
1823             grant REPLICATION SLAVE on *.* to _DBUSERREPL_@'_REMOTE_ACCESS_';
1824             create schema if not exists test;
1825              
1826             GRANTS_MYSQL_5_7_6
1827              
1828             'load_grants.sh' => << 'LOAD_GRANTS_SCRIPT',
1829             #!_BINBASH_
1830             __LICENSE__
1831             SBDIR=_HOME_DIR_/_SANDBOXDIR_
1832             source $SBDIR/sb_include
1833             BASEDIR='_BASEDIR_'
1834             export LD_LIBRARY_PATH=$BASEDIR/lib:$BASEDIR/lib/mysql:$LD_LIBRARY_PATH
1835             export DYLD_LIBRARY_PATH=$BASEDIR_/lib:$BASEDIR/lib/mysql:$DYLD_LIBRARY_PATH
1836             MYSQL="$BASEDIR/bin/mysql --no-defaults --socket=_GLOBALTMPDIR_/mysql_sandbox_SERVERPORT_.sock --port=_SERVERPORT_"
1837             # START UGLY WORKAROUND for grants syntax changes in 5.7.6
1838             VERSION=`$MYSQL -u root -BN -e 'select version()' | perl -ne 'print $1 if /(\d+\.\d+\.\d+)/'`
1839             MAJOR=$(echo $VERSION | tr '.' ' ' | awk '{print $1}')
1840             MINOR=$(echo $VERSION | tr '.' ' ' | awk '{print $2}')
1841             REV=$(echo $VERSION | tr '.' ' ' | awk '{print $3}')
1842             if [ "$MAJOR" == "5" -a "$MINOR" == "7" -a "$REV" == "8" ]
1843             then
1844             # workaround for Bug#77732.
1845             echo "grant SELECT on performance_schema.global_variables to _DBUSERREPL_@'_REMOTE_ACCESS_';" >> $SBDIR/grants_5_7_6.mysql
1846             echo "grant SELECT on performance_schema.session_variables to _DBUSERREPL_@'_REMOTE_ACCESS_';" >> $SBDIR/grants_5_7_6.mysql
1847             fi
1848             if [ "$MAJOR" == "5" -a "$MINOR" == "7" -a $REV -gt 5 ]
1849             then
1850             cp $SBDIR/grants_5_7_6.mysql $SBDIR/grants.mysql
1851             fi
1852             if [ "$MAJOR" == "8" ]
1853             then
1854             cp $SBDIR/grants_5_7_6.mysql $SBDIR/grants.mysql
1855             fi
1856             # END UGLY WORKAROUND
1857             VERBOSE_SQL=''
1858             [ -n "$SBDEBUG" ] && VERBOSE_SQL=-v
1859             $MYSQL -u root $VERBOSE_SQL < $SBDIR/grants.mysql
1860             # echo "source $SBDIR/grants.mysql" | $SBDIR/use -u root --password=
1861             # $SBDIR/my sqldump _EVENTS_OPTIONS_ mysql > $SBDIR/rescue_mysql_dump.sql
1862             LOAD_GRANTS_SCRIPT
1863              
1864             'default_connection.json' => <<'END_DEFAULT_CONNECTION_JSON',
1865             {
1866             "host": "127.0.0.1",
1867             "port": "_SERVERPORT_",
1868             "socket": "_GLOBALTMPDIR_/mysql_sandbox_SERVERPORT_.sock",
1869             "username": "_DBUSER_@_REMOTE_ACCESS_",
1870             "password": "_DBPASSWORD_"
1871             }
1872              
1873             END_DEFAULT_CONNECTION_JSON
1874              
1875             'connection.json' => <<'END_CONNECTION_JSON',
1876             {
1877             "origin": {
1878             "mysql_sandbox_version" : "_MSB_VERSION_",
1879             "mysql_version": "_INSTALL_VERSION_",
1880             "binaries": "_BASEDIR_"
1881             },
1882             "connection": {
1883             "host": "127.0.0.1",
1884             "port": "_SERVERPORT_",
1885             "socket": "_GLOBALTMPDIR_/mysql_sandbox_SERVERPORT_.sock",
1886             "bind_address": "_BIND_ADDRESS_"
1887             },
1888             "users": {
1889             "admin": {
1890             "username": "root@localhost",
1891             "password": "_DBPASSWORD_",
1892             "privileges": "all, with grant option"
1893             },
1894             "all_privileges": {
1895             "username": "_DBUSER_@_REMOTE_ACCESS_",
1896             "password": "_DBPASSWORD_",
1897             "privileges": "all, no grant option"
1898             },
1899             "read_write": {
1900             "username": "_DBUSERRW_@_REMOTE_ACCESS_",
1901             "password": "_DBPASSWORD_",
1902             "privileges": "SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,ALTER,SHOW DATABASES,CREATE TEMPORARY TABLES,LOCK TABLES, EXECUTE"
1903             },
1904             "read_only": {
1905             "username": "_DBUSERRO_@_REMOTE_ACCESS_",
1906             "password": "_DBPASSWORD_",
1907             "privileges": "SELECT,EXECUTE"
1908             },
1909             "replication": {
1910             "username": "_DBUSERREPL_@_REMOTE_ACCESS_",
1911             "password": "_DB_REPL_PASSWORD_",
1912             "privileges": "REPLICATION SLAVE"
1913             }
1914             },
1915             "samples": {
1916             "php": {
1917             "mysqli" : "$mysqli = new mysqli('127.0.0.1', '_DBUSER_', '_DBPASSWORD_', 'test', '_SERVERPORT_');",
1918             "pdo" : "$dbh = new PDO('mysql:host=127.0.0.1;port=5531', '_DBUSER_', '_DBPASSWORD_');"
1919             },
1920             "perl" : {
1921             "dbi" : "$dbh=DBI->connect( 'DBI:mysql:host=127.0.0.1;port=_SERVERPORT_', '_DBUSER_', '_DBPASSWORD_')"
1922             },
1923             "python" : {
1924             "mysql.connector" : "cnx = mysql.connector.connect(user='_DBUSER_', password='_DBPASSWORD_', host='127.0.0.1', port=_SERVERPORT_, database='test')"
1925             },
1926             "java" : {
1927             "DriverManager" : "con=DriverManager.getConnection(\\\"jdbc:mysql://127.0.0.1:_SERVERPORT_/test\\\", \\\"_DBUSER_\\\", \\\"_DBPASSWORD_\\\")"
1928             },
1929             "ruby" : {
1930             "mysql" : "connection = Mysql.new '127.0.0.1', '_DBUSER_', '_DBPASSWORD_', 'test', _SERVERPORT_"
1931             },
1932             "shell" : {
1933             "generic": "_BASEDIR_/bin/mysql -h 127.0.0.1 -P _SERVERPORT_ -u _DBUSER_ -p_DBPASSWORD_"
1934             }
1935             }
1936             }
1937             END_CONNECTION_JSON
1938              
1939             'my.sh' => <<'MY_SCRIPT',
1940             #!_BINBASH_
1941             __LICENSE__
1942              
1943             if [ "$1" = "" ]
1944             then
1945             echo "syntax my sql{dump|binlog|admin} arguments"
1946             exit
1947             fi
1948             __SBINSTR_SH__
1949              
1950             SBDIR=_HOME_DIR_/_SANDBOXDIR_
1951             source $SBDIR/sb_include
1952             BASEDIR=_BASEDIR_
1953             export LD_LIBRARY_PATH=$BASEDIR/lib:$BASEDIR/lib/mysql:$LD_LIBRARY_PATH
1954             export DYLD_LIBRARY_PATH=$BASEDIR/lib:$BASEDIR/lib/mysql:$DYLD_LIBRARY_PATH
1955             MYSQL=$BASEDIR/bin/mysql
1956              
1957             SUFFIX=$1
1958             shift
1959              
1960             MYSQLCMD="$BASEDIR/bin/my$SUFFIX"
1961              
1962             NODEFAULT=(myisam_ftdump
1963             myisamlog
1964             mysql_config
1965             mysql_convert_table_format
1966             mysql_find_rows
1967             mysql_fix_extensions
1968             mysql_fix_privilege_tables
1969             mysql_secure_installation
1970             mysql_setpermission
1971             mysql_tzinfo_to_sql
1972             mysql_config_editor
1973             mysql_waitpid
1974             mysql_zap
1975             mysqlaccess
1976             mysqlbinlog
1977             mysqlbug
1978             mysqldumpslow
1979             mysqlhotcopy
1980             mysqltest
1981             mysqltest_embedded)
1982              
1983             DEFAULTSFILE="--defaults-file=$SBDIR/my.sandbox.cnf"
1984              
1985             for NAME in ${NODEFAULT[@]}
1986             do
1987             if [ "my$SUFFIX" = "$NAME" ]
1988             then
1989             DEFAULTSFILE=""
1990             break
1991             fi
1992             done
1993              
1994             if [ -f $MYSQLCMD ]
1995             then
1996             $MYSQLCMD $DEFAULTSFILE "$@"
1997             else
1998             echo "$MYSQLCMD not found "
1999             fi
2000              
2001             MY_SCRIPT
2002             'proxy_start.sh' => <<'PROXY_START_SCRIPT',
2003             #!_BINBASH_
2004             __LICENSE__
2005              
2006             PROXY_BIN=/usr/local/sbin/mysql-proxy
2007             HOST='127.0.0.1'
2008              
2009             $PROXY_BIN --proxy-backend-addresses=$HOST:_SERVERPORT_ "$@"
2010              
2011             PROXY_START_SCRIPT
2012              
2013             'change_ports.sh' => <<'CHANGE_PORTS_SCRIPT',
2014             #!_BINBASH_
2015             __LICENSE__
2016              
2017             cd $(dirname $0)
2018             __SBINSTR_SH__
2019             OLD_PORT=_SERVERPORT_
2020              
2021             if [ "$1" = "" ]
2022             then
2023             echo "New port required as argument."
2024             exit
2025             else
2026             ONLY_DIGITS_REGEX="^[[:digit:]]+$"
2027             if [[ $1 =~ ${ONLY_DIGITS_REGEX} ]]
2028             then
2029             if [[ $1 -ge 1 ]] && [[ $1 -le 65535 ]]
2030             then
2031             NEW_PORT=$1
2032             else
2033             echo "New port must be a valid port number in the 1-65535 range."
2034             exit
2035             fi
2036             else
2037             echo "New port must contain only digits (unsigned integer)."
2038             exit
2039             fi
2040             fi
2041              
2042             if [ $OLD_PORT = $NEW_PORT ]
2043             then
2044             echo Old port and new port must be different.
2045             exit
2046             fi
2047              
2048             PERL_SCRIPT1='BEGIN{$old=shift;$new=shift};'
2049             PERL_SCRIPT2='s/sandbox$old/sandbox$new/g;'
2050             PERL_SCRIPT3='s/\b$old\b/$new/'
2051             PERL_SCRIPT="$PERL_SCRIPT1 $PERL_SCRIPT2 $PERL_SCRIPT3"
2052              
2053             SCRIPTS1="start stop send_kill clear status restart my.sandbox.cnf "
2054             SCRIPTS2="load_grants my use $0"
2055             SCRIPTS="$SCRIPTS1 $SCRIPTS2"
2056             for SCRIPT in $SCRIPTS
2057             do
2058             perl -i.port.bak -pe "$PERL_SCRIPT" $OLD_PORT $NEW_PORT $SCRIPT
2059             done
2060             echo "($PWD) The old scripts have been saved as filename.port.bak"
2061              
2062             CHANGE_PORTS_SCRIPT
2063              
2064             'change_paths.sh' => <<'CHANGE_PATHS_SCRIPT',
2065             #!_BINBASH_
2066             __LICENSE__
2067             if [ "$1" = "" ]
2068             then
2069             OLD_SB_LOCATION=_HOME_DIR_/_SANDBOXDIR_
2070             else
2071             OLD_SB_LOCATION=$1
2072             fi
2073              
2074             __SBINSTR_SH__
2075             if [ "$2" = "" ]
2076             then
2077             NEW_SB_LOCATION=$PWD
2078             else
2079             NEW_SB_LOCATION=$2
2080             fi
2081              
2082             if [ $OLD_SB_LOCATION = $NEW_SB_LOCATION ]
2083             then
2084             echo Old location and new location must be different.
2085             echo Move the sandbox to the new location and then run this script.
2086             exit
2087             fi
2088              
2089             if [ ! -d "$NEW_SB_LOCATION" ]
2090             then
2091             echo "new location must be a directory"
2092             exit
2093             fi
2094              
2095             PERL_SCRIPT1='BEGIN{$old=shift;$new=shift};'
2096             PERL_SCRIPT2='s/$old/$new/g'
2097             PERL_SCRIPT="$PERL_SCRIPT1 $PERL_SCRIPT2"
2098              
2099             SCRIPTS1="start stop send_kill clear status restart my.sandbox.cnf "
2100             SCRIPTS2="load_grants my use $0"
2101             SCRIPTS="$SCRIPTS1 $SCRIPTS2"
2102              
2103             for SCRIPT in $SCRIPTS
2104             do
2105             perl -i.bak -pe "$PERL_SCRIPT" $OLD_SB_LOCATION $NEW_SB_LOCATION $SCRIPT
2106             done
2107             echo "($PWD) The old scripts have been saved as filename.path.bak"
2108             CHANGE_PATHS_SCRIPT
2109             'sandbox_action.pl' => <<'SANDBOX_ACTION_SCRIPT',
2110             #!_BINPERL_
2111             __LICENSE__
2112             use strict;
2113             use warnings;
2114             use MySQL::Sandbox qw(sbinstr);
2115              
2116             my $DEBUG = $MySQL::Sandbox::DEBUG;
2117              
2118             my $action_list = 'use|start|stop|status|clear|restart|send_kill';
2119             my $action = shift
2120             or die "action required {$action_list}\n";
2121             $action =~/^($action_list)$/
2122             or die "action must be one of {$action_list}\n";
2123             my $sandboxdir = $0;
2124             sbinstr($action);
2125             $sandboxdir =~ s{[^/]+$}{};
2126             $sandboxdir =~ s{/$}{};
2127             my $command = $ARGV[0];
2128             if ($action eq 'use' and !$command) {
2129             die "action 'use' requires a command\n";
2130             }
2131              
2132             my @dirs = glob("$sandboxdir/*");
2133              
2134             for my $dir (@dirs) {
2135             if (-d $dir) {
2136             if ($action eq "use") {
2137             if ( -x "$dir/use_all" ) {
2138             print "executing -- $dir/use_all $command\n" if $DEBUG;
2139             system(qq($dir/use_all "$command"));
2140             }
2141             elsif ( -x "$dir/use" ) {
2142             print "executing -- $dir/use $command\n" if $DEBUG;
2143             system(qq(echo "$command" | $dir/use));
2144             }
2145             }
2146             elsif ( -x "$dir/${action}_all") {
2147             print "-- executing $dir/${action}_all\n" if $DEBUG;
2148             system("$dir/${action}_all", @ARGV)
2149             }
2150             elsif ( -x "$dir/$action") {
2151             print "-- executing $dir/$action\n" if $DEBUG;
2152             system("$dir/$action", @ARGV)
2153             }
2154             }
2155             }
2156              
2157             SANDBOX_ACTION_SCRIPT
2158             'plugin.conf' => <<'PLUGIN_CONF',
2159             #
2160             # Plugin configuration file
2161             # To use this template, see
2162             # sbtool -o plugin
2163             #
2164             $plugin_definition =
2165             {
2166             innodb => {
2167             minimum_version => '5.1.45',
2168             all_servers =>
2169             {
2170             operation_sequence => [qw(stop options_file start sql_commands )],
2171             options_file =>
2172             [
2173             'ignore_builtin_innodb',
2174             'plugin-load='
2175             .'innodb=ha_innodb_plugin.so;'
2176             .'innodb_trx=ha_innodb_plugin.so;'
2177             .'innodb_locks=ha_innodb_plugin.so;'
2178             .'innodb_lock_waits=ha_innodb_plugin.so;'
2179             .'innodb_cmp=ha_innodb_plugin.so;'
2180             .'innodb_cmp_reset=ha_innodb_plugin.so;'
2181             .'innodb_cmpmem=ha_innodb_plugin.so;'
2182             .'innodb_cmpmem_reset=ha_innodb_plugin.so',
2183             'default-storage-engine=InnoDB',
2184             'innodb_file_per_table=1',
2185             'innodb_file_format=barracuda',
2186             'innodb_strict_mode=1',
2187             ],
2188             sql_commands =>
2189             [
2190             'select @@innodb_version;',
2191             ],
2192             startup_file => [ ],
2193             },
2194             },
2195             semisynch => {
2196             minimum_version => '5.5.2',
2197              
2198             master =>
2199             {
2200             operation_sequence => [qw(stop options_file start sql_commands )],
2201             options_file =>
2202             [
2203             'plugin-load=rpl_semi_sync_master=semisync_master.so',
2204             'rpl_semi_sync_master_enabled=1'
2205             ],
2206             sql_commands =>
2207             [
2208             'select @@rpl_semi_sync_master_enabled;'
2209             ],
2210             startup_file => []
2211             },
2212             slave =>
2213             {
2214             operation_sequence => [qw(stop options_file start sql_commands )],
2215             options_file =>
2216             [
2217             'plugin-load=rpl_semi_sync_slave=semisync_slave.so',
2218             'rpl_semi_sync_slave_enabled=1'
2219             ],
2220             sql_commands =>
2221             [
2222             'select @@rpl_semi_sync_slave_enabled;'
2223             ],
2224             startup_file => []
2225             },
2226             },
2227             gearman => {
2228             minimum_version => '5.0',
2229             all_servers =>
2230             {
2231             operation_sequence => [qw(start sql_commands options_file
2232             startup_file restart )],
2233             options_file =>
2234             [
2235             'init-file=startup.sql'
2236             ],
2237             sql_commands =>
2238             [
2239             'CREATE FUNCTION gman_do RETURNS STRING
2240             SONAME "libgearman_mysql_udf.so";',
2241             'CREATE FUNCTION gman_do_high RETURNS STRING
2242             SONAME "libgearman_mysql_udf.so";',
2243             'CREATE FUNCTION gman_do_low RETURNS STRING
2244             SONAME "libgearman_mysql_udf.so";',
2245             'CREATE FUNCTION gman_do_background RETURNS STRING
2246             SONAME "libgearman_mysql_udf.so";',
2247             'CREATE FUNCTION gman_do_high_background RETURNS STRING
2248             SONAME "libgearman_mysql_udf.so";',
2249             'CREATE FUNCTION gman_do_low_background RETURNS STRING
2250             SONAME "libgearman_mysql_udf.so";',
2251             'CREATE AGGREGATE FUNCTION gman_sum RETURNS INTEGER
2252             SONAME "libgearman_mysql_udf.so";',
2253             'CREATE FUNCTION gman_servers_set RETURNS STRING
2254             SONAME "libgearman_mysql_udf.so";',
2255             ],
2256             startup_file =>
2257             [
2258             'set @a := (select gman_servers_set("127.0.0.1"));',
2259             'use test ;',
2260             'create table if not exists startup (msg text, ts timestamp);',
2261             'insert into startup (msg) values (@a);',
2262             ]
2263             },
2264             },
2265             };
2266              
2267             PLUGIN_CONF
2268              
2269             'test_replication.sh' => <<'TEST_REPLICATION',
2270             #!_BINBASH_
2271             __LICENSE__
2272             if [ -x ./m ]
2273             then
2274             MASTER=./m
2275             elif [ -x ./n1 ]
2276             then
2277             MASTER=./n1
2278             else
2279             echo "# No master found"
2280             exit 1
2281             fi
2282             $MASTER -e 'create schema if not exists test'
2283             $MASTER test -e 'drop table if exists t1'
2284             $MASTER test -e 'create table t1 (i int not null primary key, msg varchar(50), d date, t time, dt datetime, ts timestamp)'
2285             #$MASTER test -e "insert into t1 values (1, 'test sandbox 1', '2015-07-16', '11:23:40','2015-07-17 12:34:50', null)"
2286             #$MASTER test -e "insert into t1 values (2, 'test sandbox 2', '2015-07-17', '11:23:41','2015-07-17 12:34:51', null)"
2287             for N in $(seq -f '%02.0f' 1 20)
2288             do
2289             #echo "$MASTER test -e \"insert into t1 values ($N, 'test sandbox $N', '2015-07-$N', '11:23:$N','2015-07-17 12:34:$N', null)\""
2290             $MASTER test -e "insert into t1 values ($N, 'test sandbox $N', '2015-07-$N', '11:23:$N','2015-07-17 12:34:$N', null)"
2291             done
2292             sleep 0.5
2293             MASTER_RECS=$($MASTER -BN -e 'select count(*) from test.t1')
2294              
2295             master_status=master_status$$
2296             slave_status=slave_status$$
2297             $MASTER -e 'show master status\G' > $master_status
2298             master_binlog=$(grep 'File:' $master_status | awk '{print $2}' )
2299             master_pos=$(grep 'Position:' $master_status | awk '{print $2}' )
2300             echo "# Master log: $master_binlog - Position: $master_pos - Rows: $MASTER_RECS"
2301             rm -f $master_status
2302              
2303             FAILED=0
2304             PASSED=0
2305              
2306             function ok_equal
2307             {
2308             fact="$1"
2309             expected="$2"
2310             msg="$3"
2311             if [ "$fact" == "$expected" ]
2312             then
2313             echo -n "ok"
2314             PASSED=$(($PASSED+1))
2315             else
2316             echo -n "not ok - (expected: <$expected> found: <$fact>) "
2317             FAILED=$(($FAILED+1))
2318             fi
2319             echo " - $msg"
2320             }
2321              
2322             function test_summary
2323             {
2324             TESTS=$(($PASSED+$FAILED))
2325             if [ -n "$TAP_TEST" ]
2326             then
2327             echo "1..$TESTS"
2328             else
2329             PERCENT_PASSED=$(($PASSED/$TESTS*100))
2330             PERCENT_FAILED=$(($FAILED/$TESTS*100))
2331             printf "# TESTS : %5d\n" $TESTS
2332             printf "# FAILED: %5d (%5.1f%%)\n" $FAILED $PERCENT_FAILED
2333             printf "# PASSED: %5d (%5.1f%%)\n" $PASSED $PERCENT_PASSED
2334             fi
2335             exit_code=0
2336             if [ "$FAILED" != "0" ]
2337             then
2338             exit_code=1
2339             fi
2340             echo "# exit code: $exit_code"
2341             exit $exit_code
2342             }
2343              
2344             for SLAVE_N in 1 2 3 4 5 6 7 8 9
2345             do
2346             N=$(($SLAVE_N+1))
2347             unset SLAVE
2348             if [ -x ./s$SLAVE_N ]
2349             then
2350             SLAVE=./s$SLAVE_N
2351             elif [ -x ./n$N ]
2352             then
2353             SLAVE=./n$N
2354             fi
2355             if [ -n "$SLAVE" ]
2356             then
2357             echo "# Testing slave #$SLAVE_N"
2358             if [ -f set_circular_replication.sh ]
2359             then
2360             sleep 3
2361             else
2362             S_READY=$($SLAVE -BN -e "select master_pos_wait('$master_binlog', $master_pos,60)")
2363             # master_pos_wait can return 0 or a positive number for successful replication
2364             # Any result that is not NULL or -1 is acceptable
2365             if [ "$S_READY" != "-1" -a "$S_READY" != "NULL" ]
2366             then
2367             S_READY=0
2368             fi
2369             ok_equal $S_READY 0 "Slave #$SLAVE_N acknowledged reception of transactions from master"
2370             fi
2371             $SLAVE -e 'show slave status\G' > $slave_status
2372             IO_RUNNING=$(grep -w Slave_IO_Running $slave_status | awk '{print $2}')
2373             ok_equal $IO_RUNNING Yes "Slave #$SLAVE_N IO thread is running"
2374             SQL_RUNNING=$(grep -w Slave_IO_Running $slave_status | awk '{print $2}')
2375             ok_equal $SQL_RUNNING Yes "Slave #$SLAVE_N SQL thread is running"
2376             rm -f $slave_status
2377              
2378             [ $FAILED == 0 ] || exit 1
2379              
2380             T1_EXISTS=$($SLAVE -BN -e 'show tables from test like "t1"')
2381             ok_equal $T1_EXISTS t1 "Table t1 found on slave #$SLAVE_N"
2382             T1_RECS=$($SLAVE -BN -e 'select count(*) from test.t1')
2383             ok_equal $T1_RECS $MASTER_RECS "Table t1 has $MASTER_RECS rows on #$SLAVE_N"
2384             fi
2385             done
2386             test_summary
2387              
2388             TEST_REPLICATION
2389              
2390             'show_binlog.sh' => <<'SHOW_BINLOG',
2391             #!_BINBASH_
2392             __LICENSE__
2393              
2394             curdir="_HOME_DIR_/_SANDBOXDIR_"
2395             cd $curdir
2396              
2397             if [ ! -d ./data ]
2398             then
2399             echo "$curdir/data not found"
2400             exit 1
2401             fi
2402              
2403             # Checks if the output is a terminal or a pipe
2404             if [ -t 1 ]
2405             then
2406             echo "###################### WARNING ####################################"
2407             echo "# You are not using a pager."
2408             echo "# The output of this script can be quite large."
2409             echo "# Please pipe this script with a pager, such as 'less' or 'vim -'"
2410             echo "# ENTER 'q' to exit or simply RETURN to continue without a pager"
2411             read answer
2412             if [ "$answer" == "q" ]
2413             then
2414             exit
2415             fi
2416             fi
2417              
2418             pattern=$1
2419             [ -z "$pattern" ] && pattern='[0-9]*'
2420             if [ "$pattern" == "-h" -o "$pattern" == "--help" -o "$pattern" == "-help" -o "$pattern" == "help" ]
2421             then
2422             echo "# Usage: $0 [BINLOG_PATTERN] "
2423             echo "# Where BINLOG_PATTERN is a number, or part of a number used after 'mysql-bin'"
2424             echo "# (The default is '[0-9]*]')"
2425             echo "# examples:"
2426             echo "# ./show_binlog 000001 | less "
2427             echo "# ./show_binlog 000012 | vim - "
2428             echo "# ./show_binlog | grep -i 'CREATE TABLE'"
2429             exit 0
2430             fi
2431             # set -x
2432             last_binlog=$(ls -lotr data/mysql-bin.$pattern | tail -n 1 | awk '{print $NF}')
2433              
2434             if [ -z "$last_binlog" ]
2435             then
2436             echo "No binlog found in $curdir/data"
2437             exit 1
2438             fi
2439              
2440             (printf "#\n# Showing $last_binlog\n#\n" ; ./my sqlbinlog --verbose $last_binlog )
2441              
2442             SHOW_BINLOG
2443              
2444             'show_relaylog.sh' => <<'SHOW_RELAYLOG',
2445             #!_BINBASH_
2446             __LICENSE__
2447              
2448             curdir="_HOME_DIR_/_SANDBOXDIR_"
2449             cd $curdir
2450              
2451             if [ ! -d ./data ]
2452             then
2453             echo "$curdir/data not found"
2454             exit 1
2455             fi
2456              
2457             # Checks if the output is a terminal or a pipe
2458             if [ -t 1 ]
2459             then
2460             echo "###################### WARNING ####################################"
2461             echo "# You are not using a pager."
2462             echo "# The output of this script can be quite large."
2463             echo "# Please pipe this script with a pager, such as 'less' or 'vim -'"
2464             echo "# ENTER 'q' to exit or simply RETURN to continue without a pager"
2465             read answer
2466             if [ "$answer" == "q" ]
2467             then
2468             exit
2469             fi
2470             fi
2471              
2472             relay_basename=$1
2473             [ -z "$relay_basename" ] && relay_basename='mysql-relay'
2474             pattern=$2
2475             [ -z "$pattern" ] && pattern='[0-9]*'
2476             if [ "$pattern" == "-h" -o "$pattern" == "--help" -o "$pattern" == "-help" -o "$pattern" == "help" ]
2477             then
2478             echo "# Usage: $0 [ relay-base-name [BINLOG_PATTERN]] "
2479             echo "# Where relay-basename is the initial part of the relay ('$relay_basename')"
2480             echo "# and BINLOG_PATTERN is a number, or part of a number used after '$relay_basename'"
2481             echo "# (The default is '[0-9]*]')"
2482             echo "# examples:"
2483             echo "# ./show_relaylog relay-log-alpha 000001 | less "
2484             echo "# ./show_relaylog relay-log 000012 | vim - "
2485             echo "# ./show_relaylog | grep -i 'CREATE TABLE'"
2486             exit 0
2487             fi
2488             # set -x
2489             last_relaylog=$(ls -lotr data/$relay_basename.$pattern | tail -n 1 | awk '{print $NF}')
2490              
2491             if [ -z "$last_relaylog" ]
2492             then
2493             echo "No relay log found in $curdir/data"
2494             exit 1
2495             fi
2496              
2497             (printf "#\n# Showing $last_relaylog\n#\n" ; ./my sqlbinlog --verbose $last_relaylog )
2498              
2499             SHOW_RELAYLOG
2500              
2501             'add_option.sh' => <<'ADD_OPTION',
2502             #!_BINBASH_
2503             __LICENSE__
2504              
2505             curdir="_HOME_DIR_/_SANDBOXDIR_"
2506             cd $curdir
2507              
2508             if [ -z "$*" ]
2509             then
2510             echo "# Syntax $0 options-for-my.cnf [more options] "
2511             exit
2512             fi
2513              
2514             CHANGED=''
2515             for OPTION in $@
2516             do
2517             option_exists=$(grep $OPTION ./my.sandbox.cnf)
2518             if [ -z "$option_exists" ]
2519             then
2520             echo "$OPTION" >> my.sandbox.cnf
2521             echo "# option '$OPTION' added to configuration file"
2522             CHANGED=1
2523             else
2524             echo "# option '$OPTION' already exists configuration file"
2525             fi
2526             done
2527              
2528             if [ -n "$CHANGED" ]
2529             then
2530             ./restart
2531             fi
2532              
2533             ADD_OPTION
2534              
2535             );
2536              
2537             # --- END SCRIPTS IN CODE ---
2538              
2539             my $license_text = <<'LICENSE';
2540             # The MySQL Sandbox
2541             # Copyright (C) 2006-2017 Giuseppe Maxia
2542             #
2543             # Licensed under the Apache License, Version 2.0 (the "License");
2544             # you may not use this file except in compliance with the License.
2545             # You may obtain a copy of the License at
2546             #
2547             # http://www.apache.org/licenses/LICENSE-2.0
2548             #
2549             # Unless required by applicable law or agreed to in writing, software
2550             # distributed under the License is distributed on an "AS IS" BASIS,
2551             # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2552             # See the License for the specific language governing permissions and
2553             # limitations under the License.
2554              
2555             LICENSE
2556              
2557             sub license_text {
2558 0     0 0   return $license_text;
2559             }
2560              
2561             sub parse_options_low_level_make_sandbox {
2562 0     0 0   return \%parse_options_low_level_make_sandbox;
2563             }
2564              
2565             sub parse_options_replication {
2566 0     0 0   return \%parse_options_replication;
2567             }
2568              
2569             sub parse_options_many {
2570 0     0 0   return \%parse_options_many;
2571             }
2572              
2573             sub parse_options_sbtool {
2574 0     0 0   return \%parse_options_sbtool;
2575             }
2576              
2577             sub parse_options_custom_many {
2578 0     0 0   return \%parse_options_custom_many;
2579             }
2580              
2581             sub scripts_in_code {
2582 0     0 0   return \%scripts_in_code;
2583             }
2584              
2585             my $readme_multiple = <<'END_README_MULTIPLE';
2586             This is a composite sandbox. Each node is independent, without any replication relationship to the others
2587              
2588             To operate each node, use
2589             ./n1 [options] # (= ./node1/use [options])
2590             ./n2 [options] # (= ./node2/use [options])
2591             ...
2592             ./nN [options] # (= ./nodeN/use [options])
2593              
2594             END_README_MULTIPLE
2595              
2596             my $readme_circular = <<'END_README_CIRCULAR';
2597             This is a composite sandbox, where each node is both a master and a slave (in circular replication)
2598              
2599             To operate each node, use
2600             ./n1 [options] # (= ./node1/use [options])
2601             ./n2 [options] # (= ./node2/use [options])
2602             ...
2603             ./nN [options] # (= ./nodeN/use [options])
2604              
2605             END_README_CIRCULAR
2606              
2607              
2608             my $readme_master_slave = <<'END_README_MASTER_SLAVE';
2609             This is a composite replication sandbox, having one master and many slaves.
2610              
2611             To operate the master, use
2612             ./m [options] # (= ./master/use)
2613              
2614             To operate the slaves, use
2615             ./s1 [options] # (= ./node1/use [options])
2616             ./s2 [options] # (= ./node2/use [options])
2617             ...
2618             ./sN [options] # (= ./nodeN/use [options])
2619              
2620             END_README_MASTER_SLAVE
2621              
2622             my $readme_common_replication = <<'END_README_COMMON_REPLICATION';
2623              
2624             ./to check the status of all slaves, use:
2625             ./check_slaves
2626              
2627             END_README_COMMON_REPLICATION
2628              
2629             my $readme_common = <<'END_README_COMMON';
2630             To run a SQL command in all servers, use:
2631             ./use_all {query}
2632              
2633             To connect to this sandbox, use the information stored inside
2634             'connection.json' or 'default_connection.json'.
2635              
2636             Simple administrative tasks can be performed using:
2637             ./start_all [options] : starts all servers
2638             ./stop_all : stops all servers
2639             ./status_all : tells the status of all servers
2640             ./clear_all : stops andremoves the contents from all servers (WARNING: dangerous)
2641             ./restart_all [options] : restarts all servers
2642              
2643             More information is available inside the README file within each directory below.
2644              
2645             The full manual is available using:
2646             perldoc MySQL::Sandbox
2647              
2648             A task-oriented user guide is also available:
2649             perldoc MySQL::Sandbox::Recipes
2650              
2651             END_README_COMMON
2652              
2653             sub get_readme_common_replication {
2654 0     0 0   return $readme_common_replication;
2655             }
2656              
2657             sub get_readme_common {
2658 0     0 0   return $readme_common;
2659             }
2660              
2661             sub get_readme_multiple {
2662 0     0 0   return MySQL::Sandbox::credits() . "\n" . $readme_multiple;
2663             }
2664             sub get_readme_circular {
2665 0     0 0   return MySQL::Sandbox::credits() . "\n" . $readme_circular;
2666             }
2667              
2668             sub get_readme_master_slave {
2669 0     0 0   return MySQL::Sandbox::credits() . "\n" . $readme_master_slave;
2670             }
2671              
2672             1;
2673             __END__