-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmt-convert-all-myisam.pl
executable file
·132 lines (119 loc) · 5.29 KB
/
mt-convert-all-myisam.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/perl
use strict;
use Data::Dumper;
use Getopt::Long;
#innodb_stats_on_metadata=0
#http://www.mysqlperformanceblog.com/2011/12/23/solving-information_schema-slowness/
my $mysql_exe=`which mysql`;
chomp($mysql_exe);
my $mysql_user='root';
my $mysql_passwd="";
my $mysql_host='localhost';
my $mysql_port='3306';
#data size limit in mb
my $data_size_limit = 100;
#number of rows where we start using pt-osc
my $num_rows_limit = 500000;
my $execute=0;
my $report=0;
my @ptosc;
my @alter;
my @fulltext;
my @report_ptosc;
my @report_ft;
my @report_alter;
GetOptions ("user=s" => \$mysql_user,
"password=s" => \$mysql_passwd,
"host=s" => \$mysql_host,
"port=i" => \$mysql_port,
"data\-size\-limit=i" => \$data_size_limit,
"num\-rows\-limit=i" => \$num_rows_limit,
"execute" => sub { $execute = 1 },
"report" => sub { $report = 1 }
)
or die("Error in command line arguments\n");
if ($execute == 0) {
print <<EOF;
The script *prints* the commands necessary to convert all of your MyISAM tables(except mysql,information_schema) to InnoDB. It lists all MyISAM tables with FULLTEXT indexes as well.
options:
--user MySQL username [default: root]
--password MySQL password [default: none]
--host MySQL host [default: localhost]
--port MySQL port [default: 3306]
--data-size-limit if data+index size of the table exceeds this value in MB the script will advise using pt-online-schema-change [default:100]
--num-rows-limit if table size exceeds this value the script will advise using pt-online-schema-change [default:500000]
--execute without this the script only print this help screen
--report instead of printing the commands it generate a csv available for making reports
IMPACT: It WON'T MAKE ANY CHANGES just print hints however accessing table statistics require opening the tables
example:
./mt-convert-all-myisam.pl --execute --user=review --passwd=xxx --host=127.0.0.1 --port=3336
EOF
exit 1;
}
my $table_stats_sql = <<END;
SELECT table_schema,
table_name,
table_rows,
ROUND( ( data_length / ( 1024 * 1024 ) ),2),
ROUND( ( index_length / ( 1024 * 1024 ) ),2),
ROUND( ( ( data_length + index_length ) / ( 1024 * 1024 ) ),2)
FROM information_schema.tables
WHERE engine = 'MyISAM'
AND table_schema != 'information_schema'
AND table_schema != 'mysql'
AND Concat(table_schema, '.', table_name) NOT IN
(SELECT
Concat(table_schema, '.', table_name)
FROM
information_schema.statistics
WHERE
index_type = 'fulltext')
ORDER BY data_length + index_length DESC;
END
my $myisam_fulltext_sql="
SELECT table_schema, table_name
FROM information_schema.tables
WHERE engine = 'MyISAM'
AND table_schema <> 'mysql'
AND table_schema <> 'information_schema'
AND Concat(table_schema, '.', table_name) IN (SELECT
Concat(table_schema, '.', table_name)
FROM
information_schema.statistics
WHERE
index_type = 'fulltext');
";
my @table_stats_raw=`$mysql_exe --user $mysql_user --password=\"$mysql_passwd\" --host $mysql_host --port $mysql_port --skip-column-names -e "$table_stats_sql" `;
foreach my $line (@table_stats_raw) {
my ($db, $table, $num_rows, $data_size,$index_size,$total_size) = split(/\t/, $line);
chomp ($db, $table, $num_rows, $data_size,$index_size,$total_size);
if ( ($data_size >= $data_size_limit) or ($num_rows >= $num_rows_limit) ){
#push @report, "$db,$table,$num_rows,$data_size,\"pt-online-schema-change --dry-run --alter 'ENGINE=InnoDB' D=$db,t=$table,h=$mysql_host\"\n";
push @report_ptosc, "$db,$table,$num_rows,${data_size}MB,${index_size}MB,${total_size}M,PT-OSC\n";
push @ptosc, "#Table size: $data_size [limit: $data_size_limit]\n#Number of rows: $num_rows [limit:$num_rows_limit]\n#using pt-osc is recommended\n";
push @ptosc, "pt-online-schema-change --execute --alter 'ENGINE=InnoDB' D=$db,t=$table,h=$mysql_host\n\n";
}
else{
push @report_alter, "$db,$table,$num_rows,${data_size}MB,${index_size}MB,${total_size}MB,ALTER\n";
push @alter, "ALTER TABLE $db.$table ENGINE=InnoDB;\n";
}
}
my @fulltext_tables=`$mysql_exe --user $mysql_user --password=\"$mysql_passwd\" --host $mysql_host --port $mysql_port --skip-column-names -e "$myisam_fulltext_sql" `;
push @fulltext, "\n###Tables with FULLTEXT INDEXES";
push @report_ft, "---,---,---,---,---\n";
foreach my $line (@fulltext_tables) {
my ($db, $table) = split(/\t/, $line);
chomp($db,$table);
push @fulltext, "# $db.$table\n";
push @report_ft, "$db,$table,n/a,n/a,FULLTEXT index on table. Direct conversion is not possible\n";
}
if ( $report == 1 ){
print "DB,TABLE,ROWS,DATA SIZE,INDEX SIZE,TOTAL SIZE,RECOMMENDED METHOD\n";
print @report_ptosc;
print @report_alter;
print @report_ft;
}else{
print @ptosc;
print @alter;
print @fulltext;
}