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