Visitar URL original
spanner-client: Retry PDML on "Received unexpected EOS on DATA frame from server" · Issue #3258 · googleapis/google-cloud-php · GitHub
Skip to content

spanner-client: Retry PDML on "Received unexpected EOS on DATA frame from server"  #3258

Closed

Description

@thiagotnunes

This bug is related to the Spanner client library.

For long lived transactions (>= 30 minutes), in the case of large PDML changes, it is possible that the gRPC connection is terminated with an error "Received unexpected EOS on DATA frame from server".

In this case, we need to retry the transaction either with the received resume token obtained on reading the stream or from scratch. This will ensure that the PDML transaction continues to execute until it is successful or a hard timeout is reached.

We have already implemented such change in the Java client library, for more information see this PR: googleapis/java-spanner#360.

In order to test the fix, we can use a large spanner database. Please speak to @thiagotnunes for more details.

Activity

  1. added
    priority: p2Moderately-important priority. Fix may not be included in next release.
    type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.
    and removed
    triage meI really want to be triaged.
    on Jul 30, 2020
  2. ava12 commented on Aug 4, 2020

    @ava12
    Contributor

    Not sure, but looks like this case is already handled and transaction is retried. Is there an easy way to check it? Maybe some server emulator that can be instructed to close connection in a few seconds?

  3. self-assigned this
    on Aug 5, 2020
  4. ava12 commented on Aug 5, 2020

    @ava12
    Contributor

    I've tried PDML updates on a table with one milloin rows using custom port forwarder that breaks connections before update operation is complete. In this case gRPC library throws Google\Cloud\Core\Exception\ServiceException with message "Socket closed", code 14, status "UNAVAILABLE". This exception is caught by Google\Cloud\Spanner\Result, and operation is retried using obtained resume token. To me it looks like everything works as needed. But I cannot test it in real conditions.

  5. thiagotnunes commented on Aug 5, 2020

    @thiagotnunes
    Author

    @ava12 thanks for testing this. I can help you testing this next week with a larger database if you share with me some of the code. This will make sure that the problem does not occur in long running PDMLs.

  6. ava12 commented on Aug 6, 2020

    @ava12
    Contributor

    Sample code is like this:

    <?php
    
    require_once __DIR__ . '/vendor/autoload.php';
    use Google\Cloud\Spanner\SpannerClient;
    
    const INSTANCE_NAME = 'my-instance';
    const DATABASE_NAME = 'my-database';
    const QUERY = "UPDATE my_table SET my_col = 'updated' WHERE true";
    $config = [
    //    'keyFilePath' => '/path/to/keyfile.json', // default: GOOGLE_APPLICATION_CREDENTIALS env var
    //    'projectId' => 'my-project', // default: obtain from key file
    ];
    
    $client = new SpannerClient($config);
    $database = $client->instance(INSTANCE_NAME)->database(DATABASE_NAME);
    echo 'updating' . PHP_EOL;
    $rowCount = $db->executePartitionedUpdate(QUERY);
    echo "done, $rowCount rows updated" . PHP_EOL;
  7. thiagotnunes commented on Aug 10, 2020

    @thiagotnunes
    Author

    @ava12 thanks for the sample code!

    I am not being able to successfully run the operation, I keep getting the following error after ~10 minutes of the PDML running:

    Fatal error: Uncaught Google\Cloud\Core\Exception\ServiceException: {
        "message": "The operation was cancelled.",
        "code": 1,
        "status": "CANCELLED",
        "details": [
            {
                "@type": "grpc-server-stats-bin",
                "data": "<Unknown Binary Data>"
            }
        ]
    } in /home/spanner/vendor/google/cloud-core/src/GrpcRequestWrapper.php:257
    

    Could you try and see if you get the same error for a long running PDML?

  8. ava12 commented on Aug 11, 2020

    @ava12
    Contributor

    I cannot get this error because I cannot initiate a request that is long enough.
    I guess connection is broken by client, but don't know where and why.
    Could you please run

    composer show -i | grep grpc

    in the sample code directory and show its output?

  9. thiagotnunes commented on Aug 11, 2020

    @thiagotnunes
    Author

    The output of the command is the following:

    google/grpc-gcp         0.1.5   gRPC GCP library for channel management
    grpc/grpc               1.30.0  gRPC library for PHP
    

    We will try to investigate the issue. It seems this is happening in the python library as well.

  10. thiagotnunes commented on Aug 14, 2020

    @thiagotnunes
    Author

    @ava12 sorry, we will probably not have the resources to investigate this further, could you continue with the investigation?
    In order to run a long running PDML you can use the "thiagotnunes-test-instance" and the "thiagotnunes-pdml-testing" (assuming you have credentials to the staging project we use).

    The PDML that takes a long time to execute is the following:

    <?php
    require './vendor/autoload.php';
    
    use Google\Cloud\Spanner\SpannerClient;
    
    $spanner = new SpannerClient(array(
      'projectId' => '' // staging project
    ));
    $instance = $spanner->instance('thagotnunes-test-instance');
    $database = $instance->database('thiagotnunes-pdml-testing');
    
    printf("Running PDML started at " . date("Y-m-d H:i:s") . "\n");
    $rowCount = $database->executePartitionedUpdate(
      "UPDATE ChildTable c SET c.name=CONCAT('315',c.name) WHERE c.ChildId < 1000000 AND NOT c.name LIKE '315%'"
    );
    printf("Running PDML finished at " . date("Y-m-d H:i:s") . "\n");
    
    ?>
  11. ava12 commented on Aug 14, 2020

    @ava12
    Contributor

    @thiagotnunes, I don't know the name of staging project and I don't think I have credentials to access it.

    Your sample query is quite simple and updates only one million rows. I've tried similar query on dev project and my table with one million rows, and it took less than 30 seconds to complete. How come your query takes more than 10 minutes? Complex schema? Huge table rows?

  12. thiagotnunes commented on Aug 15, 2020

    @thiagotnunes
    Author

    @ava12 oh I thought you had access to it. That would be the app-soda staging project. Let me talk to my peers to see how to get you access to it.

    In terms of the time to update, the schema has a parent / child relationship with interleaving. There are about 500 parents with 1M children, so 500M updates.

  13. ava12 commented on Aug 15, 2020

    @ava12
    Contributor

    Ah, the project is appdev-soda-spanner-staging. I can access it and I see thiagotnunes-test-instance in instance list.

  14. ava12 commented on Aug 19, 2020

    @ava12
    Contributor

    Cannot reproduce. I never see neither "Socket closed", nor "The operation was cancelled". I always get "Timeout Exceeded". Even when I set timeout to 3 hours, I get "Timeout Exceeded" in 3 hours, no other errors, no retries.

  15. thiagotnunes commented on Aug 19, 2020

    @thiagotnunes
    Author

    @ava12 thanks for trying it out. I will see if this still happens on my end and get back to you.

  16. thiagotnunes commented on Aug 20, 2020

    @thiagotnunes
    Author

    @ava12 you are correct, this problem does not seem to occur any longer. I was running my tests in a different environment, which might had been the culprit of the problem.

    Thanks for verifying this. I will close the issue.

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

Metadata

Metadata

Assignees

Labels

api: spannerIssues related to the Spanner API.priority: p2Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions