if all the inputs align so its possible.

CommentFileSizeAuthor
#6 mysql-replace.patch11.52 KBdanblack

Comments

danblack’s picture

damien tournoud’s picture

Neither REPLACE nor INSERT ... ON DUPLICATE KEY ... are alternatives for MERGE, as they only consider actual table constraints (primary keys or unique keys), not the keys that you specified.

See #715108: Make Merge queries more consistent and robust for the full discussion.

Also, I saw you wondering why we don't have a FOR UPDATE on the SELECT. This not because we implicitly assume we are running under READ REPEATABLE, but it is because we don't care which concurrent modification will succeed. See #715108-114: Make Merge queries more consistent and robust for the discussion that lead us there.

damien tournoud’s picture

Status: Active » Closed (works as designed)
danblack’s picture

Status: Closed (works as designed) » Active

if all the inputs align so its possible.

means if the keys align and a bunch of other stuff mentioned in the other issues mentioned.

damien tournoud’s picture

How do you expect to detect if things align? By introspecting the schema? This very unlikely to lead to performance improvements, but will certainly increase the complexity of the code.

REPLACE was invented as an atomic operation at one point where MySQL didn't have a transactional storage. It is a thing of the past, not the way of the future.

danblack’s picture

definitely agree with code complexity.

http://www.mysqlperformanceblog.com/2013/12/12/one-more-innodb-gap-lock-... indicated it might help.

I'll write a concurrent test next with a varying percentage of insert vs update and see how the two implementations compare.

damien tournoud’s picture

Status: Active » Needs review

At a glance, this is not remotely equivalent to the current code.

Please see #715108-4: Make Merge queries more consistent and robust for a description of all the cases you need to handle. In a nutshell, you will need to introspect the schema (at runtime), to extract the list of constraints for table, and you will only be able to use a REPLACE or a INSERT ... ON DUPLICATE KEY ... when both of the following are true:

(1) There is only one key (because in case of multiple keys, you are going to trigger an error if *any* key is duplicate, not if *all* key are duplicate)
(2) The key is a constraint of the table (primary key or unique key)

damien tournoud’s picture

I can see that you are starting doing this, but:

+    $schema = drupal_get_schema($table);

This is Drupal's conceptual schema, you cannot use this in the database layer. You will have to introspect the schema from MySQL's really slow information_schema.

Status: Needs review » Needs work

The last submitted patch, 6: mysql-replace.patch, failed testing.

danblack’s picture

> At a glance, this is not remotely equivalent to the current code.
I'm sorry you feel anguished at covering something you believe is right and fixed 4 years ago. Can we let the test cases including performance tests to be decider of the value or not of this patch?

Because of the failures outside of MergeTest there are test case and code deficiencies here still.

> (1) There is only one key (because in case of multiple keys, you are going to trigger an error if *any* key is duplicate, not if *all* key are duplicate)

+        $this->uniqueKeys = array_values($uniquekeys);

I believe I covered this (and its implementation in keys) but I guess more explicit tests are required.

the other criteria:
(3) The insert fields covers all non-serial columns

Note to self: a keys() column that isn't part of a uniqueKey needs to trigger the Query/Merge implementation as otherwise it isn't a distinguisher of insert vs update fields.

While a variation between drupal's conceptual schema and the real database schema can obviously occur due to manipulation outside of Drupal's install/update why isn't this a fair assumption?

I totally agree that introspection of the information schema isn't appropriate.

mikeytown2’s picture

There is a module that checks for schema discrepancies.

In general I would assume that at most people would have added indexes and not written an hook_schema_alter to update the schema. As long as we assume indexes aren't perfect I think we can use the schema provided by Drupal.

damien tournoud’s picture

While a variation between drupal's conceptual schema and the real database schema can obviously occur due to manipulation outside of Drupal's install/update why isn't this a fair assumption?

I totally agree that introspection of the information schema isn't appropriate.

No, you just cannot use the conceptual schema in the database layer. The conceptual schema depends on at least (1) Drupal being bootstrapped, (2) the module system and (3) the cache system. Any of those can (and do) depend on the database layer.

The only option you have in the database layer is runtime introspection, which is what is done in PostgreSQL.

morgantocker’s picture

It's worth pointing out that REPLACE is always semantically a DELETE followed by an INSERT. In the case that a merge doesn't have many rows to actually modify, the REPLACE operation will be more expensive on the MySQL-side.

danblack’s picture

> As long as we assume indexes aren't perfect I think we can use the schema provided by Drupal.

It probably a problem only if a unique index is removed and the schema says its still there.

If the schema returns false/empty then it falls back to the Query/Merge implementation.

It's worth pointing out that REPLACE is always semantically a DELETE followed by an INSERT

obviously, but why is that important?

> In the case that a merge doesn't have many rows to actually modify

Hence #1499738: db_merge does not allow multivalue inserts..

> the REPLACE operation will be more expensive on the MySQL-side.

more expensive than what? Expensive in terms of lock, latency or something else? Do you have a test case that proves this? Because that's my next effort, to see what performs better.

mikeytown2’s picture

The conceptual schema depends on at least (1) Drupal being bootstrapped, (2) the module system

Damien Tournoud is right about this. Using the drupal schema in its current form wouldn't be smart as it has the potential to greatly increase the complexity of the database layer due to interdependencies. The only way around this would be to store the schema in file storage but with this issue #2161591: Change default active config from file storage to DB storage I don't see that happening any time soon.

Is there a way to make this functionality be possible in some contrib code for experimentation purposes in the future?

danblack’s picture

I tried following the code paths there to see when schema was available because a FALSE return from drupal_get_schema is still workable as there is a fallback. Getting a schema that has a unique key before the database does however is a problem.

#1314214-16: MySQL driver does not support full UTF-8 (emojis, asian symbols, mathematical symbols) seems to indicate also striving for independence (not sure why - there's other DB abstraction layers like Doctrine doing the same thing).

danblack’s picture

Assigned: danblack » Unassigned

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

amateescu’s picture

Status: Needs work » Closed (outdated)
amateescu’s picture

Status: Closed (outdated) » Closed (won't fix)
Issue tags: -database cache

Per #7, I think this is a won't fix.