#!/usr/bin/env php 1) { db_switch_remote_to_main(); print_or_log($installer, 'NOTE: Repairing Tables for Main Database' . PHP_EOL); } else { print_or_log($installer, 'NOTE: Repairing Tables for Local Database' . PHP_EOL); } } else { print_or_log($installer, 'NOTE: Repairing Tables for Local Database' . PHP_EOL); } if (cacti_sizeof($skip_tables)) { foreach ($skip_tables as $table) { if (!db_table_exists($table)) { print_or_log($installer, "ERROR: Skip Table $table does not Exist. Can not continue." . PHP_EOL . PHP_EOL); display_help(); exit(1); } } } $convert = $innodb ? 'InnoDB' : ''; if ($utf8) { $convert .= (strlen($convert) ? ' and ' : '') . ' utf8'; } print_or_log($installer, "Converting Database Tables to $convert with less than '$size' Records" . PHP_EOL); if ($innodb) { $engines = db_fetch_assoc('SHOW ENGINES'); if (cacti_sizeof($engines)) { foreach ($engines as $engine) { if (cacti_strtolower($engine['Engine']) == 'innodb' && cacti_strtolower($engine['Support']) == 'off') { print_or_log($installer, 'InnoDB Engine is not enabled' . PHP_EOL); exit(1); } } } $file_per_table = db_fetch_row("SHOW GLOBAL VARIABLES LIKE 'innodb_file_per_table'"); if (cacti_strtolower($file_per_table['Value']) != 'on') { print_or_log($installer, 'innodb_file_per_table not enabled'); exit(1); } } if (strlen($table_name)) { $tables = [$table_name]; } else { $tables = get_cacti_base_tables(); } if (cacti_sizeof($tables)) { foreach ($tables as $table) { $table_data = db_fetch_row_prepared('SELECT * FROM information_schema.TABLES WHERE TABLE_NAME = ? AND TABLE_SCHEMA = ?', [$table, $database_default]); if (!is_array($table_data) || $table_data === []) { $conversion_failed = true; record_log($installer, "FATAL: Table '$table' does not exist in database '$database_default'"); continue; } $canConvert = $rebuild; $canInnoDB = false; if (!$canConvert && $innodb) { if ($table_data['ENGINE'] == 'MyISAM') { $canConvert = true; $canInnoDB = true; } elseif ($table_data['ENGINE'] == 'Aria') { $canConvert = true; $canInnoDB = true; } } if (in_array($table, $skip_tables, true)) { $canInnoDB = false; } if (!$canConvert && $utf8) { $canConvert = $table_data['TABLE_COLLATION'] != 'utf8mb4_unicode_ci'; } if (!$canConvert && $latin) { $canConvert = $table_data['TABLE_COLLATION'] != 'latin1'; } if ($dynamic && $table_data['ROW_FORMAT'] == 'Compact') { $canConvert = true; } if ($dynamic && $table_data['ROW_FORMAT'] == 'Page') { $canConvert = false; } if ($canConvert) { if ($table_data['TABLE_ROWS'] < $size || $force) { print_or_log($installer, "Converting Table > '$table'"); $clauses = []; if ($dynamic) { $clauses[] = 'ROW_FORMAT=Dynamic'; } if ($utf8) { $clauses[] = 'CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci'; } elseif ($latin) { $clauses[] = 'CONVERT TO CHARACTER SET latin1'; } if ($innodb && $canInnoDB) { $clauses[] = 'ENGINE=InnoDB'; } $sql = implode(', ', $clauses); $status = db_execute("ALTER TABLE `$table` $sql"); if ($status === false) { $conversion_failed = true; print_or_log($installer, ' Failed' . PHP_EOL); record_log($installer, "FATAL: Conversion of Table '$table' Failed. Command: 'ALTER TABLE `$table` $sql'"); } else { print_or_log($installer, ' Successful' . PHP_EOL); } } else { print_or_log($installer, "Skipping Table > '$table' too many rows '{$table_data['TABLE_ROWS']}'" . PHP_EOL); } } else { print_or_log($installer, "Skipping Table > '$table'" . PHP_EOL); } } } exit($conversion_failed ? 1 : 0); function print_or_log(bool $installer, string $text) : void { if ($installer) { log_install_and_file(POLLER_VERBOSITY_MEDIUM, rtrim($text), 'CONVERT', true); } else { print $text; } } function record_log(bool $installer, string $text) : void { if ($installer) { log_install_and_file(POLLER_VERBOSITY_MEDIUM, rtrim($text), 'CONVERT', true); } else { cacti_log($text, false, 'CONVERT'); } } /** * display_version - displays version information * * @return void */ function display_version() : void { $version = get_cacti_cli_version(); print "Cacti Database Conversion Utility, Version $version, " . COPYRIGHT_YEARS . PHP_EOL; } /** * display_help - displays the usage of the function * * @return void */ function display_help() : void { display_version(); print PHP_EOL; print ('usage: convert_tables.php [--debug] [--innodb] [--utf8] [--latin1] ' . '[--table=N] [--size=N] [--rebuild] [--dynamic]') . PHP_EOL . PHP_EOL; print 'A utility to convert a Cacti Database from MyISAM to the InnoDB table format.' . PHP_EOL; print 'MEMORY tables are not converted to InnoDB in this process.' . PHP_EOL . PHP_EOL; print 'Required (one or more):' . PHP_EOL; print '-i | --innodb - Convert any MyISAM tables to InnoDB' . PHP_EOL . PHP_EOL; print '-u | --utf8 - Convert any non-UTF8 tables to utf8mb4_unicode_ci' . PHP_EOL; print '-l | --latin1 - Convert any non-latin1 tables to latin1' . PHP_EOL . PHP_EOL; print 'Optional:' . PHP_EOL; print '-t | --table=S - The name of a single table to change' . PHP_EOL; print '-n | --skip-innodb="table1 table2 ..." - Skip converting tables to InnoDB' . PHP_EOL; print '-s | --size=N - The largest table size in records to convert. Default is 1,000,000 rows.' . PHP_EOL; print '-r | --rebuild - Will compress/optimize existing InnoDB tables if found' . PHP_EOL; print ' --dynamic - Convert a table to Dynamic row format if available' . PHP_EOL; print ' --local - Perform the action on the Remote Data Collector if run from there' . PHP_EOL; print '-f | --force - Proceed with conversion regardless of table size' . PHP_EOL; print '-d | --debug - Display verbose output during execution' . PHP_EOL; }