@@ -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+
444458sub hr_raw {
445459 my $num = shift ;
446460 return " 0" unless defined ($num );
@@ -6580,79 +6594,116 @@ sub mysql_innodb {
65806594 }
65816595 }
65826596 }
6583- if ( $mycalc {' innodb_log_size_pct' } < 20
6584- or $mycalc {' innodb_log_size_pct' } > 30 )
6585- {
6586- if ( defined $myvar {' innodb_redo_log_capacity' } ) {
6587- badprint
6588- " Ratio InnoDB redo log capacity / InnoDB Buffer pool size ("
6589- . $mycalc {' innodb_log_size_pct' } . " %): "
6590- . hr_bytes( $myvar {' innodb_redo_log_capacity' } ) . " / "
6591- . hr_bytes( $myvar {' innodb_buffer_pool_size' } )
6592- . " should be equal to 25%" ;
6593- push ( @adjvars ,
6594- " innodb_redo_log_capacity should be (="
6595- . hr_bytes_rnd( $myvar {' innodb_buffer_pool_size' } / 4 )
6596- . " ) if possible, so InnoDB Redo log Capacity equals 25% of buffer pool size."
6597- );
6598- push ( @generalrec ,
6599- " Be careful, increasing innodb_redo_log_capacity means higher crash recovery mean time"
6600- );
6601- }
6602- else {
6603- badprint " Ratio InnoDB log file size / InnoDB Buffer pool size ("
6604- . $mycalc {' innodb_log_size_pct' } . " %): "
6605- . hr_bytes( $myvar {' innodb_log_file_size' } ) . " * "
6606- . $myvar {' innodb_log_files_in_group' } . " / "
6607- . hr_bytes( $myvar {' innodb_buffer_pool_size' } )
6608- . " should be equal to 25%" ;
6609- push (
6610- @adjvars ,
6611- " innodb_log_file_size should be (="
6612- . hr_bytes_rnd(
6613- (
6614- defined $myvar {' innodb_buffer_pool_size' }
6615- && $myvar {' innodb_buffer_pool_size' } ne ' '
6616- ? $myvar {' innodb_buffer_pool_size' }
6617- : 0
6618- ) / (
6619- defined $myvar {' innodb_log_files_in_group' }
6620- && $myvar {' innodb_log_files_in_group' } ne ' '
6621- && $myvar {' innodb_log_files_in_group' } != 0
6622- ? $myvar {' innodb_log_files_in_group' }
6623- : 1
6624- ) / 4
6625- )
6626- . " ) if possible, so InnoDB total log file size equals 25% of buffer pool size."
6627- );
6628- push ( @generalrec ,
6629- " Be careful, increasing innodb_log_file_size / innodb_log_files_in_group means higher crash recovery mean time"
6630- );
6631- }
6632- if ( mysql_version_le( 5, 6, 2 ) ) {
6633- push ( @generalrec ,
6634- " For MySQL 5.6.2 and lower, total innodb_log_file_size should have a ceiling of (4096MB / log files in group) - 1MB."
6635- );
6636- }
6597+ # InnoDB Log File Size / InnoDB Redo Log Capacity Recommendations
6598+ # For MySQL < 8.0.30, the recommendation is based on innodb_log_file_size and innodb_log_files_in_group.
6599+ # For MySQL >= 8.0.30, innodb_redo_log_capacity replaces the old system.
6600+ if ( mysql_version_ge( 8, 0, 30 ) ) {
6601+ # New recommendation logic for MySQL >= 8.0.30
6602+ infoprint " InnoDB Redo Log Capacity is set to " . hr_bytes($myvar {' innodb_redo_log_capacity' });
6603+
6604+ my $innodb_os_log_written = $mystat {' Innodb_os_log_written' } || 0;
6605+ my $uptime = $mystat {' Uptime' } || 1;
6606+
6607+ if ($uptime > 3600) { # Only make a recommendation if server has been up for at least an hour
6608+ my $hourly_rate = $innodb_os_log_written / ( $uptime / 3600 );
6609+ my $suggested_redo_log_capacity_str = hr_bytes_practical_rnd($hourly_rate );
6610+ my $suggested_redo_log_capacity_bytes = hr_raw($suggested_redo_log_capacity_str );
6611+
6612+ infoprint " Hourly InnoDB log write rate: " . hr_bytes_rnd($hourly_rate ) . " /hour" ;
66376613
6614+ if (hr_raw($myvar {' innodb_redo_log_capacity' }) < $hourly_rate ) {
6615+ badprint " Your innodb_redo_log_capacity is not large enough to hold at least 1 hour of writes." ;
6616+ push ( @adjvars , " innodb_redo_log_capacity (>= " . $suggested_redo_log_capacity_str . " )" );
6617+ } else {
6618+ goodprint " Your innodb_redo_log_capacity is sized to handle more than 1 hour of writes." ;
6619+ }
6620+
6621+ # Sanity check against total InnoDB data size
6622+ if ( defined $enginestats {' InnoDB' } and $enginestats {' InnoDB' } > 0 ) {
6623+ my $total_innodb_size = $enginestats {' InnoDB' };
6624+ if ( $suggested_redo_log_capacity_bytes > $total_innodb_size * 0.25 ) {
6625+ 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." ;
6626+ }
6627+ }
6628+ } else {
6629+ infoprint " Server uptime is less than 1 hour. Cannot make a reliable recommendation for innodb_redo_log_capacity." ;
6630+ }
66386631 }
66396632 else {
6640- if ( defined $myvar {' innodb_redo_log_capacity' } ) {
6641- goodprint
6642- " Ratio InnoDB Redo Log Capacity / InnoDB Buffer pool size: "
6643- . hr_bytes( $myvar {' innodb_redo_log_capacity' } ) . " /"
6644- . hr_bytes( $myvar {' innodb_buffer_pool_size' } )
6645- . " should be equal to 25%" ;
6633+ # Keep existing logic for older versions
6634+ if ( $mycalc {' innodb_log_size_pct' } < 20
6635+ or $mycalc {' innodb_log_size_pct' } > 30 )
6636+ {
6637+ if ( defined $myvar {' innodb_redo_log_capacity' } ) {
6638+ badprint
6639+ " Ratio InnoDB redo log capacity / InnoDB Buffer pool size ("
6640+ . $mycalc {' innodb_log_size_pct' } . " %): "
6641+ . hr_bytes( $myvar {' innodb_redo_log_capacity' } ) . " / "
6642+ . hr_bytes( $myvar {' innodb_buffer_pool_size' } )
6643+ . " should be equal to 25%" ;
6644+ push ( @adjvars ,
6645+ " innodb_redo_log_capacity should be (="
6646+ . hr_bytes_rnd( $myvar {' innodb_buffer_pool_size' } / 4 )
6647+ . " ) if possible, so InnoDB Redo log Capacity equals 25% of buffer pool size."
6648+ );
6649+ push ( @generalrec ,
6650+ " Be careful, increasing innodb_redo_log_capacity means higher crash recovery mean time"
6651+ );
6652+ }
6653+ else {
6654+ badprint " Ratio InnoDB log file size / InnoDB Buffer pool size ("
6655+ . $mycalc {' innodb_log_size_pct' } . " %): "
6656+ . hr_bytes( $myvar {' innodb_log_file_size' } ) . " * "
6657+ . $myvar {' innodb_log_files_in_group' } . " / "
6658+ . hr_bytes( $myvar {' innodb_buffer_pool_size' } )
6659+ . " should be equal to 25%" ;
6660+ push (
6661+ @adjvars ,
6662+ " innodb_log_file_size should be (="
6663+ . hr_bytes_rnd(
6664+ (
6665+ defined $myvar {' innodb_buffer_pool_size' }
6666+ && $myvar {' innodb_buffer_pool_size' } ne ' '
6667+ ? $myvar {' innodb_buffer_pool_size' }
6668+ : 0
6669+ ) / (
6670+ defined $myvar {' innodb_log_files_in_group' }
6671+ && $myvar {' innodb_log_files_in_group' } ne ' '
6672+ && $myvar {' innodb_log_files_in_group' } != 0
6673+ ? $myvar {' innodb_log_files_in_group' }
6674+ : 1
6675+ ) / 4
6676+ )
6677+ . " ) if possible, so InnoDB total log file size equals 25% of buffer pool size."
6678+ );
6679+ push ( @generalrec ,
6680+ " Be careful, increasing innodb_log_file_size / innodb_log_files_in_group means higher crash recovery mean time"
6681+ );
6682+ }
6683+ if ( mysql_version_le( 5, 6, 2 ) ) {
6684+ push ( @generalrec ,
6685+ " For MySQL 5.6.2 and lower, total innodb_log_file_size should have a ceiling of (4096MB / log files in group) - 1MB."
6686+ );
6687+ }
66466688 }
66476689 else {
6648- push ( @generalrec ,
6649- " Before changing innodb_log_file_size and/or innodb_log_files_in_group read this: https://bit.ly/2TcGgtU"
6650- );
6651- goodprint " Ratio InnoDB log file size / InnoDB Buffer pool size: "
6652- . hr_bytes( $myvar {' innodb_log_file_size' } ) . " * "
6653- . $myvar {' innodb_log_files_in_group' } . " /"
6654- . hr_bytes( $myvar {' innodb_buffer_pool_size' } )
6655- . " should be equal to 25%" ;
6690+ if ( defined $myvar {' innodb_redo_log_capacity' } ) {
6691+ goodprint
6692+ " Ratio InnoDB Redo Log Capacity / InnoDB Buffer pool size: "
6693+ . hr_bytes( $myvar {' innodb_redo_log_capacity' } ) . " /"
6694+ . hr_bytes( $myvar {' innodb_buffer_pool_size' } )
6695+ . " should be equal to 25%" ;
6696+ }
6697+ else {
6698+ push ( @generalrec ,
6699+ " Before changing innodb_log_file_size and/or innodb_log_files_in_group read this: https://bit.ly/2TcGgtU"
6700+ );
6701+ goodprint " Ratio InnoDB log file size / InnoDB Buffer pool size: "
6702+ . hr_bytes( $myvar {' innodb_log_file_size' } ) . " * "
6703+ . $myvar {' innodb_log_files_in_group' } . " /"
6704+ . hr_bytes( $myvar {' innodb_buffer_pool_size' } )
6705+ . " should be equal to 25%" ;
6706+ }
66566707 }
66576708 }
66586709
0 commit comments