Skip to content

SaveAccountsTableData repair step destroys whole accounts table  #6406

Description

@LukasReschke

This basically makes the instance inaccessible as for example /index.php/settings/user doesn't load anymore.

Steps to reproduce:

  1. Install master
  2. Increase version of any app such as the files app to 1.8.1
  3. Open /index.php/settings/user
Type: Doctrine\DBAL\Exception\TableNotFoundException
Code: 0
Message: An exception occurred while executing 'SELECT "data" FROM "oc_accounts" WHERE "uid" = ?' with params ["admin"]: SQLSTATE[HY000]: General error: 1 no such table: oc_accounts
File: /media/psf/stable9/3rdparty/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractSQLiteDriver.php
Line: 58

Trace
#0 /media/psf/stable9/3rdparty/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php(128): Doctrine\DBAL\Driver\AbstractSQLiteDriver->convertException('An exception oc...', Object(Doctrine\DBAL\Driver\PDOException))
#1 /media/psf/stable9/3rdparty/doctrine/dbal/lib/Doctrine/DBAL/Connection.php(855): Doctrine\DBAL\DBALException::driverExceptionDuringQuery(Object(Doctrine\DBAL\Driver\PDOSqlite\Driver), Object(Doctrine\DBAL\Driver\PDOException), 'SELECT "data" F...', Array)
#2 /media/psf/stable9/lib/private/DB/Connection.php(193): Doctrine\DBAL\Connection->executeQuery('SELECT "data" F...', Array, Array, NULL)
#3 /media/psf/stable9/3rdparty/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryBuilder.php(206): OC\DB\Connection->executeQuery('SELECT "data" F...', Array, Array)
#4 /media/psf/stable9/lib/private/DB/QueryBuilder/QueryBuilder.php(213): Doctrine\DBAL\Query\QueryBuilder->execute()
#5 /media/psf/stable9/lib/private/Accounts/AccountManager.php(141): OC\DB\QueryBuilder\QueryBuilder->execute()
#6 /media/psf/stable9/lib/private/Settings/Personal/PersonalInfo.php(104): OC\Accounts\AccountManager->getUser(Object(OC\User\User))
#7 /media/psf/stable9/settings/Controller/CommonSettingsTrait.php(110): OC\Settings\Personal\PersonalInfo->getForm()
#8 /media/psf/stable9/settings/Controller/PersonalSettingsController.php(70): OC\Settings\Controller\PersonalSettingsController->formatSettings(Array)
#9 /media/psf/stable9/settings/Controller/CommonSettingsTrait.php(120): OC\Settings\Controller\PersonalSettingsController->getSettings('personal-info')
#10 /media/psf/stable9/settings/Controller/PersonalSettingsController.php(60): OC\Settings\Controller\PersonalSettingsController->getIndexResponse('personal', 'personal-info')
#11 [internal function]: OC\Settings\Controller\PersonalSettingsController->index('personal-info')
#12 /media/psf/stable9/lib/private/AppFramework/Http/Dispatcher.php(160): call_user_func_array(Array, Array)
#13 /media/psf/stable9/lib/private/AppFramework/Http/Dispatcher.php(90): OC\AppFramework\Http\Dispatcher->executeController(Object(OC\Settings\Controller\PersonalSettingsController), 'index')
#14 /media/psf/stable9/lib/private/AppFramework/App.php(114): OC\AppFramework\Http\Dispatcher->dispatch(Object(OC\Settings\Controller\PersonalSettingsController), 'index')
#15 /media/psf/stable9/lib/private/AppFramework/Routing/RouteActionHandler.php(47): OC\AppFramework\App::main('OC\\Settings\\Con...', 'index', Object(OC\AppFramework\DependencyInjection\DIContainer), Array)
#16 [internal function]: OC\AppFramework\Routing\RouteActionHandler->__invoke(Array)
#17 /media/psf/stable9/lib/private/Route/Router.php(297): call_user_func(Object(OC\AppFramework\Routing\RouteActionHandler), Array)
#18 /media/psf/stable9/lib/base.php(1004): OC\Route\Router->match('/settings/user')
#19 /media/psf/stable9/index.php(40): OC::handleRequest()
#20 {main}

As this repair step is also on stable12 we need investigation here if it is also affected.

cc @nickvergessen

Activity

  1. added this to the Nextcloud 12.0.4 milestone on Sep 7, 2017
  2. LukasReschke commented on Sep 7, 2017

    @LukasReschke
    MemberAuthor

    I guess this happens if no data is yet in the accounts table:

    protected function shouldRun() {
    $query = $this->db->getQueryBuilder();
    $query->select('*')
    ->from('accounts')
    ->where($query->expr()->isNotNull('user_id'))
    ->setMaxResults(1);
    try {
    $query->execute();
    return true;
    } catch (InvalidFieldNameException $e) {
    return false;
    } catch (TableNotFoundException $e) {
    return false;
    }
    }

    But this isn't too unlikely … not everyone fills in data 🙈

  3. nickvergessen commented on Sep 8, 2017

    @nickvergessen
    Member

    Ouch, finally an explanation!

    Thanks

  4. self-assigned this
    on Sep 8, 2017
  5. nickvergessen commented on Sep 8, 2017

    @nickvergessen
    Member

    Hmm no, not really. We don't actually use the result, we only check if selecting the (on our side) unexisting field fails or not. For me on mysql it also fails when the table is empty.
    So the job is not run and the accounts table not deleted....

  6. LukasReschke commented on Sep 8, 2017

    @LukasReschke
    MemberAuthor

    @nickvergessen Can you try SQLite? The reproduction steps work reliably for me.

  7. nickvergessen commented on Sep 8, 2017

    @nickvergessen
    Member

    Oh god, SQLite

    Deleting the rows without writing to disk (journal file):

    no such column: user_id: SELECT * FROM oc_accounts WHERE user_id IS NOT NULL;

    Writing to disk and repeat:

    0 Rows returned from: SELECT * FROM "oc_accounts" WHERE "user_id" IS NOT NULL LIMIT 1 (took 1ms)

    ewiugbnhewg hewuioa eawofjenawoifeaw 😢

  8. MorrisJobke commented on Sep 8, 2017

    @MorrisJobke
    Member

    Let's keep it open for 12.0.3 and close once the backport is in.

  9. MorrisJobke commented on Sep 12, 2017

    @MorrisJobke
    Member

    also now in stable12: #6442

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions