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   2306 use strict;
  1         2  
  1         33  
3 1     1   5 use warnings;
  1         1  
  1         40  
4 1     1   5 use MySQL::Sandbox;
  1         1  
  1         2360  
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.17};
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             # END UGLY WORKAROUND
1865             VERBOSE_SQL=''
1866             [ -n "$SBDEBUG" ] && VERBOSE_SQL=-v
1867             $MYSQL -u root $VERBOSE_SQL < $SBDIR/grants.mysql
1868             # echo "source $SBDIR/grants.mysql" | $SBDIR/use -u root --password=
1869             # $SBDIR/my sqldump _EVENTS_OPTIONS_ mysql > $SBDIR/rescue_mysql_dump.sql
1870             LOAD_GRANTS_SCRIPT
1871              
1872             'default_connection.json' => <<'END_DEFAULT_CONNECTION_JSON',
1873             {
1874             "host": "127.0.0.1",
1875             "port": "_SERVERPORT_",
1876             "socket": "_GLOBALTMPDIR_/mysql_sandbox_SERVERPORT_.sock",
1877             "username": "_DBUSER_@_REMOTE_ACCESS_",
1878             "password": "_DBPASSWORD_"
1879             }
1880              
1881             END_DEFAULT_CONNECTION_JSON
1882              
1883             'connection.json' => <<'END_CONNECTION_JSON',
1884             {
1885             "origin": {
1886             "mysql_sandbox_version" : "_MSB_VERSION_",
1887             "mysql_version": "_INSTALL_VERSION_",
1888             "binaries": "_BASEDIR_"
1889             },
1890             "connection": {
1891             "host": "127.0.0.1",
1892             "port": "_SERVERPORT_",
1893             "socket": "_GLOBALTMPDIR_/mysql_sandbox_SERVERPORT_.sock",
1894             "bind_address": "_BIND_ADDRESS_"
1895             },
1896             "users": {
1897             "admin": {
1898             "username": "root@localhost",
1899             "password": "_DBPASSWORD_",
1900             "privileges": "all, with grant option"
1901             },
1902             "all_privileges": {
1903             "username": "_DBUSER_@_REMOTE_ACCESS_",
1904             "password": "_DBPASSWORD_",
1905             "privileges": "all, no grant option"
1906             },
1907             "read_write": {
1908             "username": "_DBUSERRW_@_REMOTE_ACCESS_",
1909             "password": "_DBPASSWORD_",
1910             "privileges": "SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,ALTER,SHOW DATABASES,CREATE TEMPORARY TABLES,LOCK TABLES, EXECUTE"
1911             },
1912             "read_only": {
1913             "username": "_DBUSERRO_@_REMOTE_ACCESS_",
1914             "password": "_DBPASSWORD_",
1915             "privileges": "SELECT,EXECUTE"
1916             },
1917             "replication": {
1918             "username": "_DBUSERREPL_@_REMOTE_ACCESS_",
1919             "password": "_DB_REPL_PASSWORD_",
1920             "privileges": "REPLICATION SLAVE"
1921             }
1922             },
1923             "samples": {
1924             "php": {
1925             "mysqli" : "$mysqli = new mysqli('127.0.0.1', '_DBUSER_', '_DBPASSWORD_', 'test', '_SERVERPORT_');",
1926             "pdo" : "$dbh = new PDO('mysql:host=127.0.0.1;port=5531', '_DBUSER_', '_DBPASSWORD_');"
1927             },
1928             "perl" : {
1929             "dbi" : "$dbh=DBI->connect( 'DBI:mysql:host=127.0.0.1;port=_SERVERPORT_', '_DBUSER_', '_DBPASSWORD_')"
1930             },
1931             "python" : {
1932             "mysql.connector" : "cnx = mysql.connector.connect(user='_DBUSER_', password='_DBPASSWORD_', host='127.0.0.1', port=_SERVERPORT_, database='test')"
1933             },
1934             "java" : {
1935             "DriverManager" : "con=DriverManager.getConnection(\\\"jdbc:mysql://127.0.0.1:_SERVERPORT_/test\\\", \\\"_DBUSER_\\\", \\\"_DBPASSWORD_\\\")"
1936             },
1937             "ruby" : {
1938             "mysql" : "connection = Mysql.new '127.0.0.1', '_DBUSER_', '_DBPASSWORD_', 'test', _SERVERPORT_"
1939             },
1940             "shell" : {
1941             "generic": "_BASEDIR_/bin/mysql -h 127.0.0.1 -P _SERVERPORT_ -u _DBUSER_ -p_DBPASSWORD_"
1942             }
1943             }
1944             }
1945             END_CONNECTION_JSON
1946              
1947             'my.sh' => <<'MY_SCRIPT',
1948             #!_BINBASH_
1949             __LICENSE__
1950              
1951             if [ "$1" = "" ]
1952             then
1953             echo "syntax my sql{dump|binlog|admin} arguments"
1954             exit
1955             fi
1956             __SBINSTR_SH__
1957              
1958             SBDIR=_HOME_DIR_/_SANDBOXDIR_
1959             source $SBDIR/sb_include
1960             BASEDIR=_BASEDIR_
1961             export LD_LIBRARY_PATH=$BASEDIR/lib:$BASEDIR/lib/mysql:$LD_LIBRARY_PATH
1962             export DYLD_LIBRARY_PATH=$BASEDIR/lib:$BASEDIR/lib/mysql:$DYLD_LIBRARY_PATH
1963             MYSQL=$BASEDIR/bin/mysql
1964              
1965             SUFFIX=$1
1966             shift
1967              
1968             MYSQLCMD="$BASEDIR/bin/my$SUFFIX"
1969              
1970             NODEFAULT=(myisam_ftdump
1971             myisamlog
1972             mysql_config
1973             mysql_convert_table_format
1974             mysql_find_rows
1975             mysql_fix_extensions
1976             mysql_fix_privilege_tables
1977             mysql_secure_installation
1978             mysql_setpermission
1979             mysql_tzinfo_to_sql
1980             mysql_config_editor
1981             mysql_waitpid
1982             mysql_zap
1983             mysqlaccess
1984             mysqlbinlog
1985             mysqlbug
1986             mysqldumpslow
1987             mysqlhotcopy
1988             mysqltest
1989             mysqltest_embedded)
1990              
1991             DEFAULTSFILE="--defaults-file=$SBDIR/my.sandbox.cnf"
1992              
1993             for NAME in ${NODEFAULT[@]}
1994             do
1995             if [ "my$SUFFIX" = "$NAME" ]
1996             then
1997             DEFAULTSFILE=""
1998             break
1999             fi
2000             done
2001              
2002             if [ -f $MYSQLCMD ]
2003             then
2004             $MYSQLCMD $DEFAULTSFILE "$@"
2005             else
2006             echo "$MYSQLCMD not found "
2007             fi
2008              
2009             MY_SCRIPT
2010             'proxy_start.sh' => <<'PROXY_START_SCRIPT',
2011             #!_BINBASH_
2012             __LICENSE__
2013              
2014             PROXY_BIN=/usr/local/sbin/mysql-proxy
2015             HOST='127.0.0.1'
2016              
2017             $PROXY_BIN --proxy-backend-addresses=$HOST:_SERVERPORT_ "$@"
2018              
2019             PROXY_START_SCRIPT
2020              
2021             'change_ports.sh' => <<'CHANGE_PORTS_SCRIPT',
2022             #!_BINBASH_
2023             __LICENSE__
2024              
2025             cd $(dirname $0)
2026             __SBINSTR_SH__
2027             OLD_PORT=_SERVERPORT_
2028              
2029             if [ "$1" = "" ]
2030             then
2031             echo "New port required as argument."
2032             exit
2033             else
2034             ONLY_DIGITS_REGEX="^[[:digit:]]+$"
2035             if [[ $1 =~ ${ONLY_DIGITS_REGEX} ]]
2036             then
2037             if [[ $1 -ge 1 ]] && [[ $1 -le 65535 ]]
2038             then
2039             NEW_PORT=$1
2040             else
2041             echo "New port must be a valid port number in the 1-65535 range."
2042             exit
2043             fi
2044             else
2045             echo "New port must contain only digits (unsigned integer)."
2046             exit
2047             fi
2048             fi
2049              
2050             if [ $OLD_PORT = $NEW_PORT ]
2051             then
2052             echo Old port and new port must be different.
2053             exit
2054             fi
2055              
2056             PERL_SCRIPT1='BEGIN{$old=shift;$new=shift};'
2057             PERL_SCRIPT2='s/sandbox$old/sandbox$new/g;'
2058             PERL_SCRIPT3='s/\b$old\b/$new/'
2059             PERL_SCRIPT="$PERL_SCRIPT1 $PERL_SCRIPT2 $PERL_SCRIPT3"
2060              
2061             SCRIPTS1="start stop send_kill clear status restart my.sandbox.cnf "
2062             SCRIPTS2="load_grants my use $0"
2063             SCRIPTS="$SCRIPTS1 $SCRIPTS2"
2064             for SCRIPT in $SCRIPTS
2065             do
2066             perl -i.port.bak -pe "$PERL_SCRIPT" $OLD_PORT $NEW_PORT $SCRIPT
2067             done
2068             echo "($PWD) The old scripts have been saved as filename.port.bak"
2069              
2070             CHANGE_PORTS_SCRIPT
2071              
2072             'change_paths.sh' => <<'CHANGE_PATHS_SCRIPT',
2073             #!_BINBASH_
2074             __LICENSE__
2075             if [ "$1" = "" ]
2076             then
2077             OLD_SB_LOCATION=_HOME_DIR_/_SANDBOXDIR_
2078             else
2079             OLD_SB_LOCATION=$1
2080             fi
2081              
2082             __SBINSTR_SH__
2083             if [ "$2" = "" ]
2084             then
2085             NEW_SB_LOCATION=$PWD
2086             else
2087             NEW_SB_LOCATION=$2
2088             fi
2089              
2090             if [ $OLD_SB_LOCATION = $NEW_SB_LOCATION ]
2091             then
2092             echo Old location and new location must be different.
2093             echo Move the sandbox to the new location and then run this script.
2094             exit
2095             fi
2096              
2097             if [ ! -d "$NEW_SB_LOCATION" ]
2098             then
2099             echo "new location must be a directory"
2100             exit
2101             fi
2102              
2103             PERL_SCRIPT1='BEGIN{$old=shift;$new=shift};'
2104             PERL_SCRIPT2='s/$old/$new/g'
2105             PERL_SCRIPT="$PERL_SCRIPT1 $PERL_SCRIPT2"
2106              
2107             SCRIPTS1="start stop send_kill clear status restart my.sandbox.cnf "
2108             SCRIPTS2="load_grants my use $0"
2109             SCRIPTS="$SCRIPTS1 $SCRIPTS2"
2110              
2111             for SCRIPT in $SCRIPTS
2112             do
2113             perl -i.bak -pe "$PERL_SCRIPT" $OLD_SB_LOCATION $NEW_SB_LOCATION $SCRIPT
2114             done
2115             echo "($PWD) The old scripts have been saved as filename.path.bak"
2116             CHANGE_PATHS_SCRIPT
2117             'sandbox_action.pl' => <<'SANDBOX_ACTION_SCRIPT',
2118             #!_BINPERL_
2119             __LICENSE__
2120             use strict;
2121             use warnings;
2122             use MySQL::Sandbox qw(sbinstr);
2123              
2124             my $DEBUG = $MySQL::Sandbox::DEBUG;
2125              
2126             my $action_list = 'use|start|stop|status|clear|restart|send_kill';
2127             my $action = shift
2128             or die "action required {$action_list}\n";
2129             $action =~/^($action_list)$/
2130             or die "action must be one of {$action_list}\n";
2131             my $sandboxdir = $0;
2132             sbinstr($action);
2133             $sandboxdir =~ s{[^/]+$}{};
2134             $sandboxdir =~ s{/$}{};
2135             my $command = $ARGV[0];
2136             if ($action eq 'use' and !$command) {
2137             die "action 'use' requires a command\n";
2138             }
2139              
2140             my @dirs = glob("$sandboxdir/*");
2141              
2142             for my $dir (@dirs) {
2143             if (-d $dir) {
2144             if ($action eq "use") {
2145             if ( -x "$dir/use_all" ) {
2146             print "executing -- $dir/use_all $command\n" if $DEBUG;
2147             system(qq($dir/use_all "$command"));
2148             }
2149             elsif ( -x "$dir/use" ) {
2150             print "executing -- $dir/use $command\n" if $DEBUG;
2151             system(qq(echo "$command" | $dir/use));
2152             }
2153             }
2154             elsif ( -x "$dir/${action}_all") {
2155             print "-- executing $dir/${action}_all\n" if $DEBUG;
2156             system("$dir/${action}_all", @ARGV)
2157             }
2158             elsif ( -x "$dir/$action") {
2159             print "-- executing $dir/$action\n" if $DEBUG;
2160             system("$dir/$action", @ARGV)
2161             }
2162             }
2163             }
2164              
2165             SANDBOX_ACTION_SCRIPT
2166             'plugin.conf' => <<'PLUGIN_CONF',
2167             #
2168             # Plugin configuration file
2169             # To use this template, see
2170             # sbtool -o plugin
2171             #
2172             $plugin_definition =
2173             {
2174             innodb => {
2175             minimum_version => '5.1.45',
2176             all_servers =>
2177             {
2178             operation_sequence => [qw(stop options_file start sql_commands )],
2179             options_file =>
2180             [
2181             'ignore_builtin_innodb',
2182             'plugin-load='
2183             .'innodb=ha_innodb_plugin.so;'
2184             .'innodb_trx=ha_innodb_plugin.so;'
2185             .'innodb_locks=ha_innodb_plugin.so;'
2186             .'innodb_lock_waits=ha_innodb_plugin.so;'
2187             .'innodb_cmp=ha_innodb_plugin.so;'
2188             .'innodb_cmp_reset=ha_innodb_plugin.so;'
2189             .'innodb_cmpmem=ha_innodb_plugin.so;'
2190             .'innodb_cmpmem_reset=ha_innodb_plugin.so',
2191             'default-storage-engine=InnoDB',
2192             'innodb_file_per_table=1',
2193             'innodb_file_format=barracuda',
2194             'innodb_strict_mode=1',
2195             ],
2196             sql_commands =>
2197             [
2198             'select @@innodb_version;',
2199             ],
2200             startup_file => [ ],
2201             },
2202             },
2203             semisynch => {
2204             minimum_version => '5.5.2',
2205              
2206             master =>
2207             {
2208             operation_sequence => [qw(stop options_file start sql_commands )],
2209             options_file =>
2210             [
2211             'plugin-load=rpl_semi_sync_master=semisync_master.so',
2212             'rpl_semi_sync_master_enabled=1'
2213             ],
2214             sql_commands =>
2215             [
2216             'select @@rpl_semi_sync_master_enabled;'
2217             ],
2218             startup_file => []
2219             },
2220             slave =>
2221             {
2222             operation_sequence => [qw(stop options_file start sql_commands )],
2223             options_file =>
2224             [
2225             'plugin-load=rpl_semi_sync_slave=semisync_slave.so',
2226             'rpl_semi_sync_slave_enabled=1'
2227             ],
2228             sql_commands =>
2229             [
2230             'select @@rpl_semi_sync_slave_enabled;'
2231             ],
2232             startup_file => []
2233             },
2234             },
2235             gearman => {
2236             minimum_version => '5.0',
2237             all_servers =>
2238             {
2239             operation_sequence => [qw(start sql_commands options_file
2240             startup_file restart )],
2241             options_file =>
2242             [
2243             'init-file=startup.sql'
2244             ],
2245             sql_commands =>
2246             [
2247             'CREATE FUNCTION gman_do RETURNS STRING
2248             SONAME "libgearman_mysql_udf.so";',
2249             'CREATE FUNCTION gman_do_high RETURNS STRING
2250             SONAME "libgearman_mysql_udf.so";',
2251             'CREATE FUNCTION gman_do_low RETURNS STRING
2252             SONAME "libgearman_mysql_udf.so";',
2253             'CREATE FUNCTION gman_do_background RETURNS STRING
2254             SONAME "libgearman_mysql_udf.so";',
2255             'CREATE FUNCTION gman_do_high_background RETURNS STRING
2256             SONAME "libgearman_mysql_udf.so";',
2257             'CREATE FUNCTION gman_do_low_background RETURNS STRING
2258             SONAME "libgearman_mysql_udf.so";',
2259             'CREATE AGGREGATE FUNCTION gman_sum RETURNS INTEGER
2260             SONAME "libgearman_mysql_udf.so";',
2261             'CREATE FUNCTION gman_servers_set RETURNS STRING
2262             SONAME "libgearman_mysql_udf.so";',
2263             ],
2264             startup_file =>
2265             [
2266             'set @a := (select gman_servers_set("127.0.0.1"));',
2267             'use test ;',
2268             'create table if not exists startup (msg text, ts timestamp);',
2269             'insert into startup (msg) values (@a);',
2270             ]
2271             },
2272             },
2273             };
2274              
2275             PLUGIN_CONF
2276              
2277             'test_replication.sh' => <<'TEST_REPLICATION',
2278             #!_BINBASH_
2279             __LICENSE__
2280             if [ -x ./m ]
2281             then
2282             MASTER=./m
2283             elif [ -x ./n1 ]
2284             then
2285             MASTER=./n1
2286             else
2287             echo "# No master found"
2288             exit 1
2289             fi
2290             $MASTER -e 'create schema if not exists test'
2291             $MASTER test -e 'drop table if exists t1'
2292             $MASTER test -e 'create table t1 (i int not null primary key, msg varchar(50), d date, t time, dt datetime, ts timestamp)'
2293             #$MASTER test -e "insert into t1 values (1, 'test sandbox 1', '2015-07-16', '11:23:40','2015-07-17 12:34:50', null)"
2294             #$MASTER test -e "insert into t1 values (2, 'test sandbox 2', '2015-07-17', '11:23:41','2015-07-17 12:34:51', null)"
2295             for N in $(seq -f '%02.0f' 1 20)
2296             do
2297             #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)\""
2298             $MASTER test -e "insert into t1 values ($N, 'test sandbox $N', '2015-07-$N', '11:23:$N','2015-07-17 12:34:$N', null)"
2299             done
2300             sleep 0.5
2301             MASTER_RECS=$($MASTER -BN -e 'select count(*) from test.t1')
2302              
2303             master_status=master_status$$
2304             slave_status=slave_status$$
2305             $MASTER -e 'show master status\G' > $master_status
2306             master_binlog=$(grep 'File:' $master_status | awk '{print $2}' )
2307             master_pos=$(grep 'Position:' $master_status | awk '{print $2}' )
2308             echo "# Master log: $master_binlog - Position: $master_pos - Rows: $MASTER_RECS"
2309             rm -f $master_status
2310              
2311             FAILED=0
2312             PASSED=0
2313              
2314             function ok_equal
2315             {
2316             fact="$1"
2317             expected="$2"
2318             msg="$3"
2319             if [ "$fact" == "$expected" ]
2320             then
2321             echo -n "ok"
2322             PASSED=$(($PASSED+1))
2323             else
2324             echo -n "not ok - (expected: <$expected> found: <$fact>) "
2325             FAILED=$(($FAILED+1))
2326             fi
2327             echo " - $msg"
2328             }
2329              
2330             function test_summary
2331             {
2332             TESTS=$(($PASSED+$FAILED))
2333             if [ -n "$TAP_TEST" ]
2334             then
2335             echo "1..$TESTS"
2336             else
2337             PERCENT_PASSED=$(($PASSED/$TESTS*100))
2338             PERCENT_FAILED=$(($FAILED/$TESTS*100))
2339             printf "# TESTS : %5d\n" $TESTS
2340             printf "# FAILED: %5d (%5.1f%%)\n" $FAILED $PERCENT_FAILED
2341             printf "# PASSED: %5d (%5.1f%%)\n" $PASSED $PERCENT_PASSED
2342             fi
2343             exit_code=0
2344             if [ "$FAILED" != "0" ]
2345             then
2346             exit_code=1
2347             fi
2348             echo "# exit code: $exit_code"
2349             exit $exit_code
2350             }
2351              
2352             for SLAVE_N in 1 2 3 4 5 6 7 8 9
2353             do
2354             N=$(($SLAVE_N+1))
2355             unset SLAVE
2356             if [ -x ./s$SLAVE_N ]
2357             then
2358             SLAVE=./s$SLAVE_N
2359             elif [ -x ./n$N ]
2360             then
2361             SLAVE=./n$N
2362             fi
2363             if [ -n "$SLAVE" ]
2364             then
2365             echo "# Testing slave #$SLAVE_N"
2366             if [ -f set_circular_replication.sh ]
2367             then
2368             sleep 3
2369             else
2370             S_READY=$($SLAVE -BN -e "select master_pos_wait('$master_binlog', $master_pos,60)")
2371             # master_pos_wait can return 0 or a positive number for successful replication
2372             # Any result that is not NULL or -1 is acceptable
2373             if [ "$S_READY" != "-1" -a "$S_READY" != "NULL" ]
2374             then
2375             S_READY=0
2376             fi
2377             ok_equal $S_READY 0 "Slave #$SLAVE_N acknowledged reception of transactions from master"
2378             fi
2379             $SLAVE -e 'show slave status\G' > $slave_status
2380             IO_RUNNING=$(grep -w Slave_IO_Running $slave_status | awk '{print $2}')
2381             ok_equal $IO_RUNNING Yes "Slave #$SLAVE_N IO thread is running"
2382             SQL_RUNNING=$(grep -w Slave_IO_Running $slave_status | awk '{print $2}')
2383             ok_equal $SQL_RUNNING Yes "Slave #$SLAVE_N SQL thread is running"
2384             rm -f $slave_status
2385              
2386             [ $FAILED == 0 ] || exit 1
2387              
2388             T1_EXISTS=$($SLAVE -BN -e 'show tables from test like "t1"')
2389             ok_equal $T1_EXISTS t1 "Table t1 found on slave #$SLAVE_N"
2390             T1_RECS=$($SLAVE -BN -e 'select count(*) from test.t1')
2391             ok_equal $T1_RECS $MASTER_RECS "Table t1 has $MASTER_RECS rows on #$SLAVE_N"
2392             fi
2393             done
2394             test_summary
2395              
2396             TEST_REPLICATION
2397              
2398             'show_binlog.sh' => <<'SHOW_BINLOG',
2399             #!_BINBASH_
2400             __LICENSE__
2401              
2402             curdir="_HOME_DIR_/_SANDBOXDIR_"
2403             cd $curdir
2404              
2405             if [ ! -d ./data ]
2406             then
2407             echo "$curdir/data not found"
2408             exit 1
2409             fi
2410              
2411             # Checks if the output is a terminal or a pipe
2412             if [ -t 1 ]
2413             then
2414             echo "###################### WARNING ####################################"
2415             echo "# You are not using a pager."
2416             echo "# The output of this script can be quite large."
2417             echo "# Please pipe this script with a pager, such as 'less' or 'vim -'"
2418             echo "# ENTER 'q' to exit or simply RETURN to continue without a pager"
2419             read answer
2420             if [ "$answer" == "q" ]
2421             then
2422             exit
2423             fi
2424             fi
2425              
2426             pattern=$1
2427             [ -z "$pattern" ] && pattern='[0-9]*'
2428             if [ "$pattern" == "-h" -o "$pattern" == "--help" -o "$pattern" == "-help" -o "$pattern" == "help" ]
2429             then
2430             echo "# Usage: $0 [BINLOG_PATTERN] "
2431             echo "# Where BINLOG_PATTERN is a number, or part of a number used after 'mysql-bin'"
2432             echo "# (The default is '[0-9]*]')"
2433             echo "# examples:"
2434             echo "# ./show_binlog 000001 | less "
2435             echo "# ./show_binlog 000012 | vim - "
2436             echo "# ./show_binlog | grep -i 'CREATE TABLE'"
2437             exit 0
2438             fi
2439             # set -x
2440             last_binlog=$(ls -lotr data/mysql-bin.$pattern | tail -n 1 | awk '{print $NF}')
2441              
2442             if [ -z "$last_binlog" ]
2443             then
2444             echo "No binlog found in $curdir/data"
2445             exit 1
2446             fi
2447              
2448             (printf "#\n# Showing $last_binlog\n#\n" ; ./my sqlbinlog --verbose $last_binlog )
2449              
2450             SHOW_BINLOG
2451              
2452             'show_relaylog.sh' => <<'SHOW_RELAYLOG',
2453             #!_BINBASH_
2454             __LICENSE__
2455              
2456             curdir="_HOME_DIR_/_SANDBOXDIR_"
2457             cd $curdir
2458              
2459             if [ ! -d ./data ]
2460             then
2461             echo "$curdir/data not found"
2462             exit 1
2463             fi
2464              
2465             # Checks if the output is a terminal or a pipe
2466             if [ -t 1 ]
2467             then
2468             echo "###################### WARNING ####################################"
2469             echo "# You are not using a pager."
2470             echo "# The output of this script can be quite large."
2471             echo "# Please pipe this script with a pager, such as 'less' or 'vim -'"
2472             echo "# ENTER 'q' to exit or simply RETURN to continue without a pager"
2473             read answer
2474             if [ "$answer" == "q" ]
2475             then
2476             exit
2477             fi
2478             fi
2479              
2480             relay_basename=$1
2481             [ -z "$relay_basename" ] && relay_basename='mysql-relay'
2482             pattern=$2
2483             [ -z "$pattern" ] && pattern='[0-9]*'
2484             if [ "$pattern" == "-h" -o "$pattern" == "--help" -o "$pattern" == "-help" -o "$pattern" == "help" ]
2485             then
2486             echo "# Usage: $0 [ relay-base-name [BINLOG_PATTERN]] "
2487             echo "# Where relay-basename is the initial part of the relay ('$relay_basename')"
2488             echo "# and BINLOG_PATTERN is a number, or part of a number used after '$relay_basename'"
2489             echo "# (The default is '[0-9]*]')"
2490             echo "# examples:"
2491             echo "# ./show_relaylog relay-log-alpha 000001 | less "
2492             echo "# ./show_relaylog relay-log 000012 | vim - "
2493             echo "# ./show_relaylog | grep -i 'CREATE TABLE'"
2494             exit 0
2495             fi
2496             # set -x
2497             last_relaylog=$(ls -lotr data/$relay_basename.$pattern | tail -n 1 | awk '{print $NF}')
2498              
2499             if [ -z "$last_relaylog" ]
2500             then
2501             echo "No relay log found in $curdir/data"
2502             exit 1
2503             fi
2504              
2505             (printf "#\n# Showing $last_relaylog\n#\n" ; ./my sqlbinlog --verbose $last_relaylog )
2506              
2507             SHOW_RELAYLOG
2508              
2509             'add_option.sh' => <<'ADD_OPTION',
2510             #!_BINBASH_
2511             __LICENSE__
2512              
2513             curdir="_HOME_DIR_/_SANDBOXDIR_"
2514             cd $curdir
2515              
2516             if [ -z "$*" ]
2517             then
2518             echo "# Syntax $0 options-for-my.cnf [more options] "
2519             exit
2520             fi
2521              
2522             CHANGED=''
2523             for OPTION in $@
2524             do
2525             option_exists=$(grep $OPTION ./my.sandbox.cnf)
2526             if [ -z "$option_exists" ]
2527             then
2528             echo "$OPTION" >> my.sandbox.cnf
2529             echo "# option '$OPTION' added to configuration file"
2530             CHANGED=1
2531             else
2532             echo "# option '$OPTION' already exists configuration file"
2533             fi
2534             done
2535              
2536             if [ -n "$CHANGED" ]
2537             then
2538             ./restart
2539             fi
2540              
2541             ADD_OPTION
2542              
2543             );
2544              
2545             # --- END SCRIPTS IN CODE ---
2546              
2547             my $license_text = <<'LICENSE';
2548             # The MySQL Sandbox
2549             # Copyright (C) 2006-2018 Giuseppe Maxia
2550             #
2551             # Licensed under the Apache License, Version 2.0 (the "License");
2552             # you may not use this file except in compliance with the License.
2553             # You may obtain a copy of the License at
2554             #
2555             # http://www.apache.org/licenses/LICENSE-2.0
2556             #
2557             # Unless required by applicable law or agreed to in writing, software
2558             # distributed under the License is distributed on an "AS IS" BASIS,
2559             # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2560             # See the License for the specific language governing permissions and
2561             # limitations under the License.
2562              
2563             LICENSE
2564              
2565             sub license_text {
2566 0     0 0   return $license_text;
2567             }
2568              
2569             sub parse_options_low_level_make_sandbox {
2570 0     0 0   return \%parse_options_low_level_make_sandbox;
2571             }
2572              
2573             sub parse_options_replication {
2574 0     0 0   return \%parse_options_replication;
2575             }
2576              
2577             sub parse_options_many {
2578 0     0 0   return \%parse_options_many;
2579             }
2580              
2581             sub parse_options_sbtool {
2582 0     0 0   return \%parse_options_sbtool;
2583             }
2584              
2585             sub parse_options_custom_many {
2586 0     0 0   return \%parse_options_custom_many;
2587             }
2588              
2589             sub scripts_in_code {
2590 0     0 0   return \%scripts_in_code;
2591             }
2592              
2593             my $readme_multiple = <<'END_README_MULTIPLE';
2594             This is a composite sandbox. Each node is independent, without any replication relationship to the others
2595              
2596             To operate each node, use
2597             ./n1 [options] # (= ./node1/use [options])
2598             ./n2 [options] # (= ./node2/use [options])
2599             ...
2600             ./nN [options] # (= ./nodeN/use [options])
2601              
2602             END_README_MULTIPLE
2603              
2604             my $readme_circular = <<'END_README_CIRCULAR';
2605             This is a composite sandbox, where each node is both a master and a slave (in circular replication)
2606              
2607             To operate each node, use
2608             ./n1 [options] # (= ./node1/use [options])
2609             ./n2 [options] # (= ./node2/use [options])
2610             ...
2611             ./nN [options] # (= ./nodeN/use [options])
2612              
2613             END_README_CIRCULAR
2614              
2615              
2616             my $readme_master_slave = <<'END_README_MASTER_SLAVE';
2617             This is a composite replication sandbox, having one master and many slaves.
2618              
2619             To operate the master, use
2620             ./m [options] # (= ./master/use)
2621              
2622             To operate the slaves, use
2623             ./s1 [options] # (= ./node1/use [options])
2624             ./s2 [options] # (= ./node2/use [options])
2625             ...
2626             ./sN [options] # (= ./nodeN/use [options])
2627              
2628             END_README_MASTER_SLAVE
2629              
2630             my $readme_common_replication = <<'END_README_COMMON_REPLICATION';
2631              
2632             ./to check the status of all slaves, use:
2633             ./check_slaves
2634              
2635             END_README_COMMON_REPLICATION
2636              
2637             my $readme_common = <<'END_README_COMMON';
2638             To run a SQL command in all servers, use:
2639             ./use_all {query}
2640              
2641             To connect to this sandbox, use the information stored inside
2642             'connection.json' or 'default_connection.json'.
2643              
2644             Simple administrative tasks can be performed using:
2645             ./start_all [options] : starts all servers
2646             ./stop_all : stops all servers
2647             ./status_all : tells the status of all servers
2648             ./clear_all : stops andremoves the contents from all servers (WARNING: dangerous)
2649             ./restart_all [options] : restarts all servers
2650              
2651             More information is available inside the README file within each directory below.
2652              
2653             The full manual is available using:
2654             perldoc MySQL::Sandbox
2655              
2656             A task-oriented user guide is also available:
2657             perldoc MySQL::Sandbox::Recipes
2658              
2659             END_README_COMMON
2660              
2661             sub get_readme_common_replication {
2662 0     0 0   return $readme_common_replication;
2663             }
2664              
2665             sub get_readme_common {
2666 0     0 0   return $readme_common;
2667             }
2668              
2669             sub get_readme_multiple {
2670 0     0 0   return MySQL::Sandbox::credits() . "\n" . $readme_multiple;
2671             }
2672             sub get_readme_circular {
2673 0     0 0   return MySQL::Sandbox::credits() . "\n" . $readme_circular;
2674             }
2675              
2676             sub get_readme_master_slave {
2677 0     0 0   return MySQL::Sandbox::credits() . "\n" . $readme_master_slave;
2678             }
2679              
2680             1;
2681             __END__