Skip to content

Commit 71f1509

Browse files
authored
Merge pull request #849 from jmrenouard/issue-784-redo-log-recommendation
feat: Improve innodb_redo_log_capacity recommendation
2 parents 594f83a + 190186f commit 71f1509

File tree

1 file changed

+119
-68
lines changed

1 file changed

+119
-68
lines changed

mysqltuner.pl

Lines changed: 119 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,20 @@ sub hr_bytes {
441441
}
442442
}
443443

444+
# Calculates the parameter passed in bytes, then rounds it to a practical power-of-2 value in GB.
445+
sub hr_bytes_practical_rnd {
446+
my $num = shift;
447+
return "0B" unless defined($num) and $num > 0;
448+
449+
my $gbs = $num / (1024**3); # convert to GB
450+
my $power_of_2_gb = 1;
451+
while ($power_of_2_gb < $gbs) {
452+
$power_of_2_gb *= 2;
453+
}
454+
455+
return $power_of_2_gb . "G";
456+
}
457+
444458
sub hr_raw {
445459
my $num = shift;
446460
return "0" unless defined($num);
@@ -6581,79 +6595,116 @@ sub mysql_innodb {
65816595
}
65826596
}
65836597
}
6584-
if ( $mycalc{'innodb_log_size_pct'} < 20
6585-
or $mycalc{'innodb_log_size_pct'} > 30 )
6586-
{
6587-
if ( defined $myvar{'innodb_redo_log_capacity'} ) {
6588-
badprint
6589-
"Ratio InnoDB redo log capacity / InnoDB Buffer pool size ("
6590-
. $mycalc{'innodb_log_size_pct'} . "%): "
6591-
. hr_bytes( $myvar{'innodb_redo_log_capacity'} ) . " / "
6592-
. hr_bytes( $myvar{'innodb_buffer_pool_size'} )
6593-
. " should be equal to 25%";
6594-
push( @adjvars,
6595-
"innodb_redo_log_capacity should be (="
6596-
. hr_bytes_rnd( $myvar{'innodb_buffer_pool_size'} / 4 )
6597-
. ") if possible, so InnoDB Redo log Capacity equals 25% of buffer pool size."
6598-
);
6599-
push( @generalrec,
6600-
"Be careful, increasing innodb_redo_log_capacity means higher crash recovery mean time"
6601-
);
6602-
}
6603-
else {
6604-
badprint "Ratio InnoDB log file size / InnoDB Buffer pool size ("
6605-
. $mycalc{'innodb_log_size_pct'} . "%): "
6606-
. hr_bytes( $myvar{'innodb_log_file_size'} ) . " * "
6607-
. $myvar{'innodb_log_files_in_group'} . " / "
6608-
. hr_bytes( $myvar{'innodb_buffer_pool_size'} )
6609-
. " should be equal to 25%";
6610-
push(
6611-
@adjvars,
6612-
"innodb_log_file_size should be (="
6613-
. hr_bytes_rnd(
6614-
(
6615-
defined $myvar{'innodb_buffer_pool_size'}
6616-
&& $myvar{'innodb_buffer_pool_size'} ne ''
6617-
? $myvar{'innodb_buffer_pool_size'}
6618-
: 0
6619-
) / (
6620-
defined $myvar{'innodb_log_files_in_group'}
6621-
&& $myvar{'innodb_log_files_in_group'} ne ''
6622-
&& $myvar{'innodb_log_files_in_group'} != 0
6623-
? $myvar{'innodb_log_files_in_group'}
6624-
: 1
6625-
) / 4
6626-
)
6627-
. ") if possible, so InnoDB total log file size equals 25% of buffer pool size."
6628-
);
6629-
push( @generalrec,
6630-
"Be careful, increasing innodb_log_file_size / innodb_log_files_in_group means higher crash recovery mean time"
6631-
);
6632-
}
6633-
if ( mysql_version_le( 5, 6, 2 ) ) {
6634-
push( @generalrec,
6635-
"For MySQL 5.6.2 and lower, total innodb_log_file_size should have a ceiling of (4096MB / log files in group) - 1MB."
6636-
);
6637-
}
6598+
# InnoDB Log File Size / InnoDB Redo Log Capacity Recommendations
6599+
# For MySQL < 8.0.30, the recommendation is based on innodb_log_file_size and innodb_log_files_in_group.
6600+
# For MySQL >= 8.0.30, innodb_redo_log_capacity replaces the old system.
6601+
if ( mysql_version_ge( 8, 0, 30 ) ) {
6602+
# New recommendation logic for MySQL >= 8.0.30
6603+
infoprint "InnoDB Redo Log Capacity is set to " . hr_bytes($myvar{'innodb_redo_log_capacity'});
6604+
6605+
my $innodb_os_log_written = $mystat{'Innodb_os_log_written'} || 0;
6606+
my $uptime = $mystat{'Uptime'} || 1;
6607+
6608+
if ($uptime > 3600) { # Only make a recommendation if server has been up for at least an hour
6609+
my $hourly_rate = $innodb_os_log_written / ( $uptime / 3600 );
6610+
my $suggested_redo_log_capacity_str = hr_bytes_practical_rnd($hourly_rate);
6611+
my $suggested_redo_log_capacity_bytes = hr_raw($suggested_redo_log_capacity_str);
6612+
6613+
infoprint "Hourly InnoDB log write rate: " . hr_bytes_rnd($hourly_rate) . "/hour";
66386614

6615+
if (hr_raw($myvar{'innodb_redo_log_capacity'}) < $hourly_rate) {
6616+
badprint "Your innodb_redo_log_capacity is not large enough to hold at least 1 hour of writes.";
6617+
push( @adjvars, "innodb_redo_log_capacity (>= " . $suggested_redo_log_capacity_str . ")" );
6618+
} else {
6619+
goodprint "Your innodb_redo_log_capacity is sized to handle more than 1 hour of writes.";
6620+
}
6621+
6622+
# Sanity check against total InnoDB data size
6623+
if ( defined $enginestats{'InnoDB'} and $enginestats{'InnoDB'} > 0 ) {
6624+
my $total_innodb_size = $enginestats{'InnoDB'};
6625+
if ( $suggested_redo_log_capacity_bytes > $total_innodb_size * 0.25 ) {
6626+
infoprint "The suggested innodb_redo_log_capacity (" . $suggested_redo_log_capacity_str . ") is more than 25% of your total InnoDB data size. This might be unnecessarily large.";
6627+
}
6628+
}
6629+
} else {
6630+
infoprint "Server uptime is less than 1 hour. Cannot make a reliable recommendation for innodb_redo_log_capacity.";
6631+
}
66396632
}
66406633
else {
6641-
if ( defined $myvar{'innodb_redo_log_capacity'} ) {
6642-
goodprint
6643-
"Ratio InnoDB Redo Log Capacity / InnoDB Buffer pool size: "
6644-
. hr_bytes( $myvar{'innodb_redo_log_capacity'} ) . "/"
6645-
. hr_bytes( $myvar{'innodb_buffer_pool_size'} )
6646-
. " should be equal to 25%";
6634+
# Keep existing logic for older versions
6635+
if ( $mycalc{'innodb_log_size_pct'} < 20
6636+
or $mycalc{'innodb_log_size_pct'} > 30 )
6637+
{
6638+
if ( defined $myvar{'innodb_redo_log_capacity'} ) {
6639+
badprint
6640+
"Ratio InnoDB redo log capacity / InnoDB Buffer pool size ("
6641+
. $mycalc{'innodb_log_size_pct'} . "%): "
6642+
. hr_bytes( $myvar{'innodb_redo_log_capacity'} ) . " / "
6643+
. hr_bytes( $myvar{'innodb_buffer_pool_size'} )
6644+
. " should be equal to 25%";
6645+
push( @adjvars,
6646+
"innodb_redo_log_capacity should be (="
6647+
. hr_bytes_rnd( $myvar{'innodb_buffer_pool_size'} / 4 )
6648+
. ") if possible, so InnoDB Redo log Capacity equals 25% of buffer pool size."
6649+
);
6650+
push( @generalrec,
6651+
"Be careful, increasing innodb_redo_log_capacity means higher crash recovery mean time"
6652+
);
6653+
}
6654+
else {
6655+
badprint "Ratio InnoDB log file size / InnoDB Buffer pool size ("
6656+
. $mycalc{'innodb_log_size_pct'} . "%): "
6657+
. hr_bytes( $myvar{'innodb_log_file_size'} ) . " * "
6658+
. $myvar{'innodb_log_files_in_group'} . " / "
6659+
. hr_bytes( $myvar{'innodb_buffer_pool_size'} )
6660+
. " should be equal to 25%";
6661+
push(
6662+
@adjvars,
6663+
"innodb_log_file_size should be (="
6664+
. hr_bytes_rnd(
6665+
(
6666+
defined $myvar{'innodb_buffer_pool_size'}
6667+
&& $myvar{'innodb_buffer_pool_size'} ne ''
6668+
? $myvar{'innodb_buffer_pool_size'}
6669+
: 0
6670+
) / (
6671+
defined $myvar{'innodb_log_files_in_group'}
6672+
&& $myvar{'innodb_log_files_in_group'} ne ''
6673+
&& $myvar{'innodb_log_files_in_group'} != 0
6674+
? $myvar{'innodb_log_files_in_group'}
6675+
: 1
6676+
) / 4
6677+
)
6678+
. ") if possible, so InnoDB total log file size equals 25% of buffer pool size."
6679+
);
6680+
push( @generalrec,
6681+
"Be careful, increasing innodb_log_file_size / innodb_log_files_in_group means higher crash recovery mean time"
6682+
);
6683+
}
6684+
if ( mysql_version_le( 5, 6, 2 ) ) {
6685+
push( @generalrec,
6686+
"For MySQL 5.6.2 and lower, total innodb_log_file_size should have a ceiling of (4096MB / log files in group) - 1MB."
6687+
);
6688+
}
66476689
}
66486690
else {
6649-
push( @generalrec,
6650-
"Before changing innodb_log_file_size and/or innodb_log_files_in_group read this: https://bit.ly/2TcGgtU"
6651-
);
6652-
goodprint "Ratio InnoDB log file size / InnoDB Buffer pool size: "
6653-
. hr_bytes( $myvar{'innodb_log_file_size'} ) . " * "
6654-
. $myvar{'innodb_log_files_in_group'} . "/"
6655-
. hr_bytes( $myvar{'innodb_buffer_pool_size'} )
6656-
. " should be equal to 25%";
6691+
if ( defined $myvar{'innodb_redo_log_capacity'} ) {
6692+
goodprint
6693+
"Ratio InnoDB Redo Log Capacity / InnoDB Buffer pool size: "
6694+
. hr_bytes( $myvar{'innodb_redo_log_capacity'} ) . "/"
6695+
. hr_bytes( $myvar{'innodb_buffer_pool_size'} )
6696+
. " should be equal to 25%";
6697+
}
6698+
else {
6699+
push( @generalrec,
6700+
"Before changing innodb_log_file_size and/or innodb_log_files_in_group read this: https://bit.ly/2TcGgtU"
6701+
);
6702+
goodprint "Ratio InnoDB log file size / InnoDB Buffer pool size: "
6703+
. hr_bytes( $myvar{'innodb_log_file_size'} ) . " * "
6704+
. $myvar{'innodb_log_files_in_group'} . "/"
6705+
. hr_bytes( $myvar{'innodb_buffer_pool_size'} )
6706+
. " should be equal to 25%";
6707+
}
66576708
}
66586709
}
66596710

0 commit comments

Comments
 (0)