Search code examples
load-balancingcitrixnetscaler

MySql NetScaler DataStream Content Switching failing to detect select


We are using the new DataStream feature introduced in NetScaler 9 (we're on v10) to do content switching (described here: http://support.citrix.com/proddocs/topic/netscaler/ns-dbproxy-wrapper-con.html). We have a read-only virtual server that balances across several read-only MySql slaves. We use our Content Switching to send all "Selects" over to the read-only server.

the policy is configured as such:

mysql.req.query.command.contains("select")

our users send multi-part queries to our database server. Most often they are simple, like:

use database;
select col1 from table1;

Sometimes they will put comments at the head of the query. for example:

-- this is my query
select col1 from table1;

What we've found is that if the query simply starts with a select, everything works swimmingly. However, in the cases where there is a use statement or comments preceding the query, the content swticher fails to detect that this is a select query and it bypasses our read-only virtual server.

I am about to tell all of our developers that they must fully alias every table in every query and avoid use statements (yes, this is a good thing anyway), and also that they cannot use comments in their sql (that's just silly).

Does anyone know how I can configure my NetScaler DataStream Content Switching to ignore comments and use statements?


Solution

  • The decision on where to send the query is done on the first line received after successful authentication... so ignoring the comment won't work. You could setup a responder policy which sends back an error message saying "Please don't use SQL Comments in commands sent to the Load Balanced VIP". A bit draconian, but your devs would get the message fairly quick.. but there's no way to ignore the comment, but still base a decision on the select statement. However, I was under the impression that the select statement is up to the first semi colon... so in your example above, it should (in theory) still find the select statement. I'd need to test that to be certain of the behaviour however.

    Also - the USE statement is critical. This is the DB on which all subsequent commands are issued. It would be best practice to NOT use the USE statement, but instead, change the select statement to: select col1 from database.table1;

    Once the USE statement is seen, it prevents any subsequent commands being pipelined down the same connection... So if there are a lot of Use statements, you will not get to enjoy the connection multiplexing functionality that comes with DataStream.