Uploaded image for project: 'MariaDB MaxScale'
  1. MariaDB MaxScale
  2. MXS-323

mysql_client readwritesplit handleError seems using wrong dcb and cause wrong behavior

    XMLWordPrintable

    Details

      Description

      I am doing some experimentation with Maxscale 1.3 develop branch and I ran into a situation which I think is a bug in readwritesplit.handleError. let me describe why I think it is a bug.

      In mysql_client.gw_read_client_event(DCB *dcb), it calls route_by_statement() to route a query stmt in its dcb->session. Let's say that route_by_statement() return a 'rc' that indicates routing failure due to backend failure. In my case, I somehow faked a backend failure.

      At mysql_client.c line 1176, it calls router->handleError(...dcb...), which is readwritesplit.handleError().

      router->handleError(
      router_instance,
      session->router_session,
      errbuf,
      dcb,
      ERRACT_NEW_CONNECTION,
      &succp);

      Note, 'dcb' is actually client_dcb that is passed to gw_read_client_event(dcb). However, in readwritesplit.handleError(), this dcb is thought to be a 'backend_dcb'. In my case, the error action is ERRACT_NEW_CONNECTION, and it is supposed to find a replacement of slave or fail because of master failover.

      At readwritesplit.c line 4851, the equality check of "rses->rses_master_ref->bref_dcb == backend_dcb" would not be true, and it would go to slave case. For my case, I used a single master server in the config, so it is already wrong to go to slave replacement. I think it should set *succp = false so that it would show error to the client.

      if (rses->rses_master_ref->bref_dcb == backend_dcb &&
      !SERVER_IS_MASTER(srv))

      Now, look at slave replacement. It calls handle_error_new_connection().

      At readwritesplit.c line 4970, it checks for the backend_ref_t that points this "backend_dcb" and it would never find it because this dcb is a client_dcb.

      if ((bref = get_bref_from_dcb(myrses, backend_dcb)) == NULL)

      { succp = true; goto return_succp; }

      So it sets succp = true and return. Back in mysql_client.gw_read_client_event(), it seems error handling went fine. The correct action should be close the client_dcb and let client know. Instead, the client session hangs, while maxscale moves on.

      mysql> insert into test.mytest values (4,'test4',4);
      .........

      Well, I know I kind of faked the master backend error, but it actually is something that I want to test with error handling. I hope my description is clear. I am happy to discuss the situation.

        Attachments

          Activity

            People

            Assignee:
            markus makela markus makela
            Reporter:
            liang_guo Leo Guo
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved: