Database server table creations fail if sql_require_primary_key is set

Created on 2 February 2021, almost 4 years ago
Updated 13 July 2024, 5 months ago

Problem/Motivation

I have a managed MySQL database from DigitalOcean. Their configuration has sql_require_primary_key set. The entities cannot be indexed as table creation fails since search_api_db_* does not specify a primary key.

Drupal\search_api\SearchApiException: SQLSTATE[HY000]: General error: 3750 Unable to create or change a table without a primary key, when the system variable 'sql_require_primary_key' is set. Add a primary key to the table or unset this variable to avoid this message. Note that tables without a primary key can cause performance problems in row-based replication, so please consult your DBA before changing this setting.: CREATE TABLE {search_api_db_roasts_roast_level} ( `item_id` VARCHAR(150) NOT NULL COMMENT 'The primary identifier of the item' ) ENGINE = InnoDB DEFAULT CHARACTER SET utf8mb4; Array ( ) in Drupal\search_api_db\Plugin\search_api\backend\Database->fieldsUpdated() (line 1122 of /workspace/web/modules/contrib/search_api/modules/search_api_db/src/Plugin/search_api/backend/Database.php).

Steps to reproduce

Create a database server on MySQL 8 with sql_require_primary_key set. Index values. Indexing fails.

Proposed resolution

Set item_id as a primary key?

Determine if the changes belong in DatabaseCompatibility\MySql

Or here directly https://git.drupalcode.org/project/search_api/-/blob/8.x-1.x/modules/sea...

      // For the denormalized index table, add a primary key right away. For
      // newly created field tables we first need to add the "value" column.
      if ($type === 'index') {
        $table['primary key'] = ['item_id'];
      }

I see that the primary key is set on the table at the end of the process

   // Add a covering index for field tables.
    if ($new_table && $type == 'field') {
      $this->database->schema()->addPrimaryKey($db['table'], ['item_id', $column]);
    }

Maybe we can set the initial primary key as item_id by default, and then at the end of the function drop it and add a new one of item_id and the column name.

Remaining tasks

πŸ› Bug report
Status

Fixed

Version

1.0

Component

Database backend

Created by

πŸ‡ΊπŸ‡ΈUnited States mglaman WI, USA

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡ͺπŸ‡¬Egypt Mohamed.Osama Egypt

    Thanks so much mglaman for the workarount #3 πŸ› Database server table creations fail if sql_require_primary_key is set Needs review

    I've added the below on the settings.php as I don't have access to mysql configuration.

    $databases['default']['default']['init_commands'] = array(
      'primary_key' => "SET SESSION sql_require_primary_key=0"
    );
  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 9.5.x + Environment: PHP 8.1 & sqlite-3.27
    last update over 1 year ago
    Patch Failed to Apply
  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 9.5.x + Environment: PHP 8.1 & sqlite-3.27
    last update over 1 year ago
    Patch Failed to Apply
  • πŸ‡¨πŸ‡¦Canada smulvih2 Canada 🍁

    I am running into a similar issue using MySQL managed database service in Azure. When I try to save my index, or try to index content, I get this error:

    Drupal\search_api\SearchApiException: Cannot add primary key to table 'search_api_db_INDEX_NAME_search_api_datasource_2': primary key already exists. in Drupal\search_api_db\Plugin\search_api\backend\Database->fieldsUpdated() (line 1187 of /var/www/html/modules/contrib/search_api/modules/search_api_db/src/Plugin/search_api/backend/Database.php).

    I notice that it creates the table, but then fails on the primary key part. Then next time I try to index content or save the index, it creates new tables with _X appended (1, 2, 3.. n) like this search_api_db_INDEX_NAME_search_api_datasource_2.

    Then I tried applying the patch in #11. With this I get the following error:

    Drupal\search_api\SearchApiException: SQLSTATE[42000]: Syntax error or access violation: 1235 This version of MySQL doesn't yet support 'existing primary key drop without adding a new primary key. In @@sql_generate_invisible_primary_key=ON mode table should have a primary key. Please add a new primary key to be able to drop existing primary key.': ALTER TABLE "search_api_db_INDEX_NAME_search_api_datasource" DROP PRIMARY KEY; Array
    (
    )
     in Drupal\search_api_db\Plugin\search_api\backend\Database->fieldsUpdated() (line 1188 of /var/www/html/modules/contrib/search_api/modules/search_api_db/src/Plugin/search_api/backend/Database.php).

    So I reverted the patch and tried adding the workaround in settings.php from #8. Then when I try to clear cache with drush cr and I get:

    SQLSTATE[42000]: Syntax error or access violation: 1227 Access denied; you need (at least one of) the SUPER, SYSTEM_VARIABLES_ADMIN or SESSION_VARIABLES_ADMIN privilege(s) for this operation

    I get the same error when I try to run SET SESSION sql_require_primary_key=0 directly in mysql.

  • πŸ‡¦πŸ‡ΉAustria drunken monkey Vienna, Austria

    @smulvih2: Thanks a lot for your feedback!
    Then I guess we really have to make sure to always create tables already with the correct primary key. Created an MR for that, please test/review!

  • πŸ‡¦πŸ‡ΉAustria drunken monkey Vienna, Austria

    Would be great if some of you could test this to make sure this would now finally work reliably.

  • @smulvih2 I had the same issue with Azure service and I managed it thanks to the answer from the following post (configuring Azure instance) https://drupal.stackexchange.com/questions/316995/multiple-primary-key-d...

  • πŸ‡¦πŸ‡ΊAustralia sonnykt Melbourne, Australia

    @FTE
    Confirming that turning sql_generate_invisible_primary_key off on Azure Flexible server fixed the issue on our site.

  • πŸ‡ΈπŸ‡³Senegal ostry.sn

    new version

  • πŸ‡¦πŸ‡ΉAustria drunken monkey Vienna, Austria

    @ostry.sn: Could you please try out the changes in my MR to see if they fix the problem for you, too?

    The same goes for everyone else here. Did you try out the MR before changing the DB server settings? I don’t think it’s a good solution to let users stumble over this and then google until they can resolve it if we might be able to provide code that just works for everyone.

  • πŸ‡§πŸ‡·Brazil cassioalmeida

    Hi everyone,

    I was facing the issue with an Azure instance with the sql_generate_invisible_primpary_key ON. As the client has 300+ websites, turning off the flag was not an option.

    I can confirm the MR worked fine! I was able to run pending tasks, re-index content, and so on.

  • πŸ‡¦πŸ‡ΉAustria drunken monkey Vienna, Austria

    @cassioalmeida: Great to hear, thanks a lot for reporting back!

    Anyone else who wants to still test the MR? Would be optimal to get a second confirmation.

  • Pipeline finished with Failed
    6 months ago
    Total: 241s
    #205547
  • Pipeline finished with Failed
    6 months ago
    Total: 271s
    #205548
  • πŸ‡¦πŸ‡ΉAustria drunken monkey Vienna, Austria

    (I’d also love to run the tests with the other DBMSs, but unfortunately pipelines don’t seem to run correctly in issue forks, at least for this project.)

  • Thanks @ostry.sn. I had an issue with `sql_generate_invisible_primary_key` being set to "On" in my Azure DB - applying patch #19 has resolved this.

  • Status changed to RTBC 6 months ago
  • πŸ‡¨πŸ‡¦Canada smulvih2 Canada 🍁

    Sorry took a while to test this MR as my project switched to a search_api_solr backend. Was able to test the MR and it works for me, no longer seeing unexpected database tables with _n added to the name, and the tables are being created correctly.

  • Status changed to Fixed 6 months ago
  • πŸ‡¦πŸ‡ΉAustria drunken monkey Vienna, Austria

    @smulvih2: Good to hear, thanks a lot for reporting back!
    Merged. Thanks again, everyone!

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024