Uploaded image for project: 'eZ Publish / Platform'
  1. eZ Publish / Platform
  2. EZP-29206

MySQL deadlock errors happen when concurrently moving subtree

    XMLWordPrintable

Details

    • [2.2] Sprint 5

    Description

      When executing LocationService::moveSubtree() concurrently, MySQL deadlocks can happen.
      Example of such error:

      StatusCodeError: 500 - {"ErrorMessage":{"_media-type":"application/vnd.ez.api.ErrorMessage+json","errorCode":500,"errorMessage":"Internal Server Error","errorDescription":"Database error","Previous":{"_media-type":"application/vnd.ez.api.ErrorMessage+json","ErrorMessage":{"_media-type":"application/vnd.ez.api.ErrorMessage+json","errorCode":500,"errorMessage":"Internal Server Error","errorDescription":"An exception occurred while executing 'UPDATE `ezcontentobject` SET `section_id` = :placeholder2 WHERE `id` IN ( SELECT `contentobject_id` FROM `ezcontentobject_tree` WHERE `path_string` LIKE :placeholder1 )' with params [\"\\/1\\/2\\/58\\/157\\/%\", 1]:\n\nSQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction","Previous":{"_media-type":"application/vnd.ez.api.ErrorMessage+json","ErrorMessage":{"_media-type":"application/vnd.ez.api.ErrorMessage+json","errorCode":500,"errorMessage":"Internal Server Error","errorDescription":"SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction","Previous":{"_media-type":"application/vnd.ez.api.ErrorMessage+json","ErrorMessage":{"_media-type":"application/vnd.ez.api.ErrorMessage+json","errorCode":500,"errorMessage":"Internal Server Error","errorDescription":"SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction"}}}}}}}}
      

      The issue was reproduced by creating a PublishVersionSignalSlot that uses LocationService::moveSubtree() to move the freshly created Content Object to another location. Then, the script was used that:

      1. Logs in with n sessions (POST /user/sessions)
        THEN
      2. Creates n content items using each session (POST /content/objects)
        THEN
      3. Publishes the n content items created (POST /content/objects/<contentId>/versions/<versionId>)

      Steps to reproduce

      1. Create new eZ Platform installation.
      2. Create and publish new Content Object. Note its Location remote Id.
      3. Create the following files inside AppBundle. You can use the AppBundle attached to this issue (just remember to change the Location remote Id inside LocationTestSlot).
        • src/AppBundle/Slot/LocationTestSlot.php:
          <?php
          
          namespace AppBundle\Slot;
          
          use eZ\Publish\Core\SignalSlot\Slot as BaseSlot;
          use eZ\Publish\API\Repository\Repository;
          use eZ\Publish\Core\SignalSlot\Signal;
          
          class LocationTestSlot extends BaseSlot
          {
              /**
               * @var Repository
               */
              private $repository;
          
              public function __construct(
                  Repository $repository
              ) {
                  $this->repository = $repository;
              }
          
              public function receive(Signal $signal)
              {
                  $content = $this->repository->getContentService()->loadContent($signal->contentId, null, $signal->versionNo);
          
                  $primaryParentLocation = $this->repository->getLocationService()->loadLocationByRemoteId('50f2bd981799c968f07589fa94be245b');
                  $currentMainLocation = $this->repository->getLocationService()->loadLocation($content->contentInfo->mainLocationId);
          
                  $this->repository->getLocationService()->moveSubtree($currentMainLocation, $primaryParentLocation);
              }
          }
          
        • src/AppBundle/Resources/config/signalslot.yml:
          Unable to find source-code formatter for language: yml. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
          services:
              app.slot.locationtest:
                  class: AppBundle\Slot\LocationTestSlot
                  arguments:
                      - @ezpublish.api.repository
                  tags:
                      - { name: ezpublish.api.slot, signal: ContentService\PublishVersionSignal }
          
        • src/AppBundle/DependencyInjection/AppExtension.php:
          <?php
          
          namespace AppBundle\DependencyInjection;
          
          use Symfony\Component\DependencyInjection\ContainerBuilder;
          use Symfony\Component\Config\FileLocator;
          use Symfony\Component\HttpKernel\DependencyInjection\Extension;
          use Symfony\Component\DependencyInjection\Loader;
          
          class AppExtension extends Extension
          {
              /**
               * {@inheritDoc}
               */
              public function load(array $configs, ContainerBuilder $container)
              {
                  $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__."/../Resources/config"));
                  $loader->load('signalslot.yml');
              }
          }
          
      4. Run the script to concurently create and publish multiple Content Objects. Such script written in node.js can be found in the attachment.
      5. Some of the requests should error out with the message mentioned above. Since the issue only happens in concurrency situations, there is no way to reproduce the issue every time. If there was no error, try to run the script again.

      Attachments

        1. test-concurrent-publishing.js
          5 kB
          Jacek Foremski

        Activity

          People

            Unassigned Unassigned
            jacek.foremski-obsolete@ez.no Jacek Foremski (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: