Running the database update (update.php) after upgrade from release 7.44 to 7.50 gave me the following message. Website stopped responding normaly sometime after that, we had to restore a backup.

-------------------------------
The following updates returned messages

node module

Update #7016
Failed: PDOException: SQLSTATE[42P16]: Invalid table definition: 7 ERROR: multiple primary keys for table "history" are not allowed: ALTER TABLE {history} ADD PRIMARY KEY (uid,nid); Array ( ) in db_add_primary_key() (regel 2927 van /srv/Http_Server/Parkstadveendam-nl/drupal/includes/database/database.inc).
-------------------------------

Log message:

-------------------------------
TYPE update
DATUM dinsdag 12 juli 2016 21:51
GEBRUIKER Redactie A
LOCATIE http://www.parkstadveendam.nl/update.php?op=selection&token=y0HAIYjz1j-z...
DOORVERWIJZER http://www.parkstadveendam.nl/update.php?op=selection&token=y0HAIYjz1j-z...
BERICHT PDOException: SQLSTATE[42P16]: Invalid table definition: 7 ERROR: multiple primary keys for table "history" are not allowed: ALTER TABLE {history} ADD PRIMARY KEY (uid,nid); Array ( ) in db_add_primary_key() (regel 2927 van /srv/Http_Server/Parkstadveendam-nl/drupal/includes/database/database.inc).
ERNST fout
HOSTNAAM 46.244.50.21
BEWERKINGEN
-------------------------------

RDBMS is PostgreSQL 9.5

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

gjk4all created an issue. See original summary.

cilefen’s picture

Component: base system » database system
Priority: Normal » Major
Issue tags: -database error

What database system is this? Everywhere I look 42P16 is a is a PostgreSQL error. If so you should be on 8.3 or higher.

attiks’s picture

Fixing version

attiks’s picture

Same error running PostgreSQL 9.3.13

attiks’s picture

Checking the key and it is created

SELECT a.attname, format_type(a.atttypid, a.atttypmod) AS data_type
FROM   pg_index i
JOIN   pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey)
WHERE  i.indrelid = 'drupal.history'::regclass AND    i.indisprimary;
attname | data_type 
---------+-----------
 uid     | integer
 nid     | bigint
attiks’s picture

If I drop the key ALTER TABLE drupal.history DROP CONSTRAINT history_pkey; I can create it using ALTER TABLE drupal.history ADD PRIMARY KEY (uid,nid);

cilefen’s picture

Component: database system » postgresql db driver
attiks’s picture

Debugged some more, key gets never dropped, dropPrimaryKey checks if the constraint exists, but it fails.

public function dropPrimaryKey($table) {
    if (!$this->constraintExists($table, 'pkey')) {
      return FALSE;
    }

    $this->connection->query('ALTER TABLE {' . $table . '} DROP CONSTRAINT ' . $this->prefixNonTable($table, 'pkey'));
    return TRUE;
  }
}

but executing SELECT 1 FROM pg_constraint WHERE conname = 'history_pkey'; returns

 ?column? 
----------
        1
(1 row)
attiks’s picture

For some reason constraintExists($table, $name) uses {} around the table name, but this doesn't work if your table name is prefixed. So changing $constraint_name = '{' . $table . '}_' . $name; to $constraint_name = $table . '_' . $name;, solves it.

attiks’s picture

PS: Same for the indexes $index_name = '{' . $table . '}_' . $name . '_idx'; to $index_name = $table . '_' . $name . '_idx';

drumm’s picture

Version: 7.5 » 7.x-dev
gjk4all’s picture

@cilefen it is running on a PostgreSQL 9.5 RDBMS.

gjk4all’s picture

Issue summary: View changes
David_Rothstein’s picture

Based on #9 could this be related to #1009828: constraintExists doesn't work with multiple schemas (or is that something else)?

attiks’s picture

Not sure if it's the same, it links to #1008128: Do not use a single underscore as table and index separator on PostgreSQL and SQLite which does not have a real patch, and I'm not really a psql expert.

On this instance there's a prefix defined 'prefix' => 'drupal.',

gjk4all’s picture

#14: I do have multiple schema's, there are 2 drupal instances in the database, one acceptance instance in schema "drupal" and one production instance in schema "drupalprod". prefixes are set in the site configuration file.

Both encountered this problem, production instance stopped functioning within a day after the failed database update, had to restore a backup.

Previous updates (till 7.44, our current version) didn't show this problem.

gjk4all’s picture

I was able to do the upgrade, update 7016 still failed, did the manual drop as suggested:

parkstadveendam=# alter table drupalprod.history drop constraint history_pkey;
ALTER TABLE
parkstadveendam=# drop index drupalprod.history_nid_idx;
DROP INDEX

After that rerun the database update and 7016 did go well, clearing all caches with drush made the site appear again as we know it.

stefan.r’s picture

Issue tags: +PostgreSQL
David_Rothstein’s picture

I guess this belongs in the release notes at https://www.drupal.org/project/drupal/releases/7.50, so I took a stab at adding it to the "Known issues" section although I wasn't sure exactly what to write: https://www.drupal.org/node/2762447/revisions/view/9922761/9923859

attiks’s picture

Priority: Major » Critical

This also happens on 7.44, tried installing the new version of panels and got the following error

Performed update: panelizer_update_7111                                     [ok]
Performed update: panelizer_update_7112                                     [ok]
SQLSTATE[42P16]: Invalid table definition: 7 ERROR:  multiple primary keys for table "panelizer_entity" are not allowed
attiks’s picture

Adding a patch to see what testbot says, it's add the 2 lines of #9 and #10

stephencamilo’s picture

Status: Needs review » Closed (won't fix)
hestenet’s picture

Status: Closed (won't fix) » Active

Reset issue status.

poker10’s picture

Status: Active » Closed (outdated)

This problem was fixed in Drupal 7.89 release by #998898: Make sure that the identifiers are not more the 63 characters on PostgreSQL , where the DatabaseSchema_pgsql::constraintExists() function was changed. I am not able to simulate the problem anymore, even if I prefix the history table. Therefore I am closing this.