Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
jormaster3k opened this issue Apr 17, 2023 · 0 comments

Comments

@jormaster3k
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant