wp-migrate-db icon indicating copy to clipboard operation
wp-migrate-db copied to clipboard

Some exports of databases with large InnoDB tables fail due to row count estimation

Open jormaster3k opened this issue 1 year ago • 0 comments

We encountered a bug while running wp migrated export on one of our databases with many rows in the wp_postmeta table.

wp --allow-root migratedb export exportfile.sql  --path=/path/to/wordpress-site

Error

Initiating migration...
PHP Fatal error:  Uncaught ValueError: str_repeat(): Argument #2 ($times) must be greater than or equal to 0 in phar:///usr/local/bin/wp/vendor/wp-cli/php-cli-tools/lib/cli/progress/Bar.php:64================================] 7:07 / 8:35
Stack trace:
#0 phar:///usr/local/bin/wp/vendor/wp-cli/php-cli-tools/lib/cli/progress/Bar.php(64): str_repeat()
#1 phar:///usr/local/bin/wp/vendor/wp-cli/php-cli-tools/lib/cli/Notify.php(182): cli\progress\Bar->display()
#2 phar:///usr/local/bin/wp/vendor/wp-cli/php-cli-tools/lib/cli/progress/Bar.php(83): cli\Notify->tick()
#3 /path/to/wordpress//wp-content/plugins/wp-migrate-db/class/Common/Cli/Cli.php(573): cli\progress\Bar->tick()
#4 /path/to/wordpress//wp-content/plugins/wp-migrate-db/class/Common/Cli/Cli.php(266): DeliciousBrains\WPMDB\Common\Cli\Cli->migrate_tables()
#5 /path/to/wordpress//wp-content/plugins/wp-migrate-db/class/Common/Cli/Command.php(212): DeliciousBrains\WPMDB\Common\Cli\Cli->cli_migration()
#6 /path/to/wordpress//wp-content/plugins/wp-migrate-db/class/Common/Cli/Command.php(92): DeliciousBrains\WPMDB\Common\Cli\Command->_perform_cli_migration()
#7 [internal function]: DeliciousBrains\WPMDB\Common\Cli\Command->export()
#8 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Dispatcher/CommandFactory.php(100): call_user_func()
#9 [internal function]: WP_CLI\Dispatcher\CommandFactory::WP_CLI\Dispatcher\{closure}()
#10 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Dispatcher/Subcommand.php(491): call_user_func()
#11 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(417): WP_CLI\Dispatcher\Subcommand->invoke()
#12 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(440): WP_CLI\Runner->run_command()
#13 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(1237): WP_CLI\Runner->run_command_and_exit()
#14 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LaunchRunner.php(28): WP_CLI\Runner->start()
#15 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/bootstrap.php(78): WP_CLI\Bootstrap\LaunchRunner->process()
#16 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/wp-cli.php(27): WP_CLI\bootstrap()
#17 phar:///usr/local/bin/wp/php/boot-phar.php(11): include('...')
#18 /usr/local/bin/wp(4): include('...')
#19 {main}
  thrown in phar:///usr/local/bin/wp/vendor/wp-cli/php-cli-tools/lib/cli/progress/Bar.php on line 64

Further research

In DeliciousBrains\WPMDB\Common\Cli\Cli->migrate_tables(), we're updating the progress bar by comparing the rows processed to the total number of rows in the table. The total number of rows in the table is obtained by querying TABLE_ROWS from INFORMATION_SCHEMA.TABLES. The problem is that according to the MySQL INFORMATION_SCHEMA documentation, for InnoDB, the TABLE_ROWS value is estimated.

For tables with a large number of rows, this may cause the actual number of rows processed to exceed the total number of rows in the database, leading to the "must be greater than or equal to 0" error.

Workaround / Fix

As a simple fix, we can check that $increment is greater than or equal to zero before calling tick():

 572                     if (null !== $notify && $increment >=0) {
 573                         $notify->tick($increment);
 574                     }

The progress bar may not be accurate, but at least the entire export will not fail.

A better fix would be to call select count(*) to obtain the precise number of rows in the table, but that may come with performance implications.

Lastly, I think it would make sense to add a flag to disable the progress bar if desired.

jormaster3k avatar Apr 17 '23 19:04 jormaster3k