@@ -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 );
@@ -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