Redshift query timeout in C# - c#

I have an instance of Redshift on AWS.
My application is running as Windows Service on EC2 in the same region as the Redshift Cluster. I have a query wich takes on average ~45 seconds and redshift apparently has a default timeout of 30 seconds. So after ~30 seconds of this query running I get:
ERROR: Query (SOME_NUMBER) cancelled on user's request;
Error while executing the query
The same query runs and finishes fine in the SQL Workbench/J, so the cluster is configured properly. I tried without any luck:
to add "CommandTimeout=9000;ConnectionTimeout=9000;" to the connection string
to set timeout parameter programmaticaly via OdbcConnection -> ConnectionTimeout
to run "set statement_timeout = 900000;" before the query
configure cluster parameters
Anyone know how to remove or change default timeout?

You need to set the keep alive parameter. For the JDBC driver it's tcpKeepAlive. Not sure if it has the same name for ODBC.

This connection string format has worked for me pretty well:
Host={Host};Port={Port};Username={Username};Password={Password};SSL Mode=Require;Server Compatibility Mode=Redshift;Timeout=45;Command Timeout={TimeoutSeconds};Tcp Keepalive=true;
"Timeout" is the connection timeout
"Command Timeout" is, well, the default command timeout
You can also set the command timeout on the command itself:
await using var cmd = new NpgsqlCommand(commandSql, con) { CommandTimeout = 300 };

Another issue that can occur which may be impacting you is MTU size. Redshift supports a max MTU of 1500 (this is the max packet size on the network) and most internet connections are also "chunked up" this much to support all the various switches in the path. However, EC2 instances and AWS networks don't have this limitation and can support larger MTUs and are set to do this by default. So what can happen is that the EC2 sends a long query and Redshift only sees the first 1500 bytes of it and is waiting for the rest. Both sides waiting on the other.
To resolve you need to change the network configuration of the EC2 instance to an MTU of 1500. I've don't this many times on Linux EC2s but never for Windows. So here's a link to the page that looks to describe the process for Windows - https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/network_mtu.html#set_mtu_windows

Related

SQL Server TimeOut in C# After Adjusting timeout

I have a windows form application written in C# that passes a query to a SQL Server database and then displays the results in a dataviewgrid. The query that is passed to the database depends on the option selected in the form.
One particular query takes a little over a minute to run in management studio, but timeouts when it is passed to the database from the program. here are the steps I have done to try to resolve the situation:
Added a 5 minute timeout in the program by setting the connection timeout option to 300 seconds in the sql connection string. Example: Data Source=ab;Initial Catalog=abc;User ID=user; Password =pw; Connection Timeout=300
Setting the remote query timeout in the SQL Server instance to 0 (meaning, no timeout). Example: EXEC sp_configure 'remote query timeout', 0 ; GO
Neither of these options work. Despite implementing both of them, the c# program throws back a sql timeout error after less than a minute.
Is there a workaround for this? I have searched for this topic on stack overflow and so far all of the suggestions have been to do either 1 or 2 (which I have done).
For reference, I am using Visual Studio 17 Community edition and SQL Server 2016 Developer edition.
Any help would be greatly appreciated.
Thanks!
There's a "CommandTimeout" property on the SQL command. Try setting that.
Connection timeout and command timeout are two different things.
A connection timeout occurs when a connection cannot be retrieved from the connection pool within the allotted timeout period.
A command timeout occurs when a connection has been retrieved, but the query being executed against it doesn't return results within the allotted command timeout period. The default command timeout period in ADO.NET is 30 seconds.
If you've set the connection timeout to 300 seconds and you're still getting a timeout, it's likely a command timeout. As walkers01 said, set your command timeout to a suitable number of seconds. 300 seconds should be far more than sufficient; if your query executes in one minute in SSMS, a timeout of 90 seconds should suffice.
Try this for unlimited time of query execution if you are using SqlDataAdapter. I have use this one, solved my problem.
SqlDataAdapter dscmd = new SqlDataAdapter(sql, cnn);
dscmd.SelectCommand.CommandTimeout = 0;

How to prevent connection time out when trying to select big data through looping in C#?

Recently,I have to develop a system which will fetch huge data from SQL Server 2008 R2. And then need to create HL7 messages using these data and send these HL7 messages to another application. I need to fetch data and create HL7 messages within looping also. The problem I am facing is that connection time out when 1 or 2 minutes after running the application.How can I prevent this problem? What should I do?
Modifying the connection string in the web.config , you could append ;Connection Timeout=30. The timeout value set in the Connection Timeout property is a time expressed in seconds.
Please Refer Connection Time out
setting the timeout value to 0, you are specifying that your attempt to connect waits an infinite time. As described in the documentation, this is something that you shouldn't set in your connection string.
A value of 0 indicates no limit, and should be avoided in a ConnectionString because an attempt to connect waits indefinitely.

How to avoid DirectoryOperationException: The Server Is Busy when USNChange Poll-Synchronizing an AD LDS directory

We are running a .NET 4.5 console application that performs USNChanged polling on a remote LDAP server and then synchronizes the records into a local AD LDS on Windows Server 2008R2. The DirSync control was not an option on the remote server but getting the records isn't the problem.
The directory is quite large, containing millions of user records. The console app successfully pulls down the records and builds a local cache. It then streams through the cache and does lookup/update/insert as required for each record on the local directory. The various network constraints in the environment had performance running between 8 and 80 records per second. As a result, we used the Task Parallel Library to improve performance:
var totalThreads = Environment.ProcessorCount *2;
var options = new ParallelOptions { MaxDegreeOfParallelism = totalThreads };
Parallel.ForEach(Data.ActiveUsersForSync.Batch(250), options, (batch, loopstate) =>
{
if (!loopstate.IsExceptional
&& !loopstate.IsStopped
&& !loopstate.ShouldExitCurrentIteration)
{
ProcessBatchSync(batch);
}
});
After introducing this block, performance increased to between 1000 and 1500 records per second. Some important notes:
This is running on an eight core machine so it allows up to 16 operations simultaneously Environment.ProcessorCount * 2;
The MoreLinq library batching mechanism is used so each task in the parallel set is processing 250 records on a given connection (from pool) before returning
Each batch is processed synchronously (no additional parallelism)
The implementation relies on System.DirectoryServices.Protocols (Win32), NOT System.DirectoryServices (ADSI)
Whenever a periodic full synchronization is executed, the system will get through about 1.1 million records and then AD LDS returns "The Server Is Busy" and the system throws a DirectoryOperationException. The number it completes before erroring is not constant but it is always near 1.1 million.
According to Microsoft (http://support.microsoft.com/kb/315071) the MaxActiveQueries value in AD LDS is no longer enforced in Windows Server 2008+. I can't change the value anyway, it doesn't show. They also show the "Server is Busy" error coming back only from a violation of that value or from having too many open notification requests per connection. This code only sends simple lookup/update/insert LDAP commands and requests no notifications from the server when something is changed.
As I understand it, I've got at most 16 threads working in tandem to query the LDS. While they are doing it very quickly, that's the max number of queries coming in in a given tick since each of these are processed single-threaded.
Is the Microsoft document incorrect? Am I misunderstanding another component here? Any assistance is appreciated.

Limit ConnectionTimeout for Oracle Database

How can I limit timeout for connecting to Oracle Database? I use devart dotConnect Express Edition on data access layer. I tried add Connection timeout=30; to connection string but it doesn't give right result (even a little weird, first time it really limits to 30 seconds, but not on all connection attempts). Then I find out that
Connection Timeout Time (in seconds) to wait while trying to establish
a connection before terminating the attempt and generating an error. A
value of 0 indicates no limit. The default value is 15 seconds.
Available in Direct mode only.
from Devart site
I can't use direct mode because I use Express Edition. Then I tried to set this parameters in TNSNAMES.ORA
DB1 =
(DESCRIPTION =
(CONNECT_TIMEOUT=11)
(TRANSPORT_CONNECT_TIMEOUT=10)
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.10.100.8)(PORT = 1521)
)
)
(CONNECT_DATA =
(SERVICE_NAME = DB1)
)
)
Still works incorrect. OK, going down and try yo set connection timeout in SQLNET.ORA
SQLNET.INBOUND_CONNECT_TIMEOUT = 5
Another one fail! Does anyone know how can I set timeout restricting allowing time to connect to DB1? It now finishes connection (connection fails) for approximately 20 seconds.
I've never used Devart's dotConnect library, but looking at the OracleConnection class it seems that you should be able to close the connection after a certain period of time by calling OracleConnection.Close(). This should take you out of the blocking state while you're trying to Open the connection.
This is not exactly like setting the timeout, but it may work. Furthermore, check the ConnectionTimeout property when you're debugging this code in order to confirm that the timeout is properly set.
OracleConnection.ConnectionTimeout works in Direct mode only. It is ignored when connection is established via Oracle client, which manages connection in this case.

Solving a timeout error for SQL query

I am getting this error:
Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
I know there are already guides out there to help solve this but they are not working for me. What am I missing or where should I add the code to these SQL statements in my C# program:
String sql = project1.Properties.Resources.myQueryData;
SqlDataAdapter sqlClearQuestDefects = new SqlDataAdapter(sql,
"Data Source=ab;Initial Catalog=ac;User ID=ad; Password =aa");
DataSet lPlanViewData = new DataSet();
sqlClearQuestDefects.Fill(lPlanViewData, "PlanViewData");
I am getting the timeout error at this line:
SqlDataAdapter sqlClearQuestDefects = new SqlDataAdapter(sql,
"Data Source=ab;Initial Catalog=ac;User ID=ad; Password =aa");
SqlDataAdapter adp = new SqlDataAdapter();
adp.SelectCommand.CommandTimeout = 0; // Set the Time out on the Command Object
You're trying to connect to a SQL Server, and it is taking longer than ADO.NET is willing to wait.
Try connecting to the same server, using the same username and password, using SQL Server Management Studio. If you get the same error, there is either something wrong with your connection string, the server you specify is not running, or you can't get to the server across the network from where you are (maybe you're on a public IP address trying to get in to an internal server name). I can't think of a scenario in which you'd enter the exact same server and credentials into SSMS and connect, then do the same in ADO.NET and fail.
If you're on a slow network, you can try increasing the timeout value. However, if a connection is going to happen at all, it should happen pretty quickly.
Take a look at both your SQL Native Client settings, and the SQL Server settings on the server. There is a section for allowed protocols; SQL can connect using a variety of protocols. Usually, you want TCP/IP for a server on the network, and Named Pipes for a server running on your own computer.
EDIT FROM YOUR COMMENT: Oh, that's normal; happens all the time. From time to time on a TCP network, packets "collide", or are "lost" in transmission. It's a known weakness of packet-switching technologies, which is managed by the TCP protocol itself in most cases. One case in which it isn't easily detected is when the initial request for a connection is lost in the shuffle. In that case, the server doesn't know there was a request, and the client didn't know their request wasn't received. So, all the client can do is give up.
To make your program more robust, all you have to do is expect a failure or two, and simply re-try your request. Here's a basic algorithm to do that:
SqlDataAdapter sqlClearQuestDefects;
short retries = 0;
while(true)
{
try
{
sqlClearQuestDefects = new SqlDataAdapter(sql, "Data Source=ab;Initial Catalog=ac;User ID=ad; Password =aa");
break;
}
catch(Exception)
{
retries++;
//will try a total of three times before giving up
if(retries >2) throw;
}
}
Since the exact command to increase connection time out wasn't mentioned in the other answers (of yet)- if you do determine a need to increase your connection time out, you would do so in your connection string as follows:
Data Source=ab;Initial Catalog=ac;User ID=ad; Password =aa; Connection Timeout=120
Where 120 = 120 seconds. Default is 20 or 30 as I recall.
This is probably a connection issue with your database, for example if you had the following connection string:
"Data Source=MyDatabaseServer...
Then you need to make sure that:
The machine MyDatabaseServer is connected to the network and is accessible from the machine you are running your application from (under the name "MyDatabaseServer")
The database server is running on MyDatabaseServer
The database server on MyDatabaseServer is configured to accept connections from remote machines
The firewall settings both on the local machine and MyDatabaseServer are correctly set up to allow SQL Server connections through
Your username / password etc... are correct
You can also try connecting to the given database instance using SQL Server Management Studio from the client machine as a diagnosis step.
There are plenty of articles that address SQL Server connectivity issues - do a Google search for the specific error message that comes up or failing that as a specific question on Server Fault
Faced this problem recently and found the resolution that worked for me.
By the way, setting Timeout = 0 helped to avoid the exception, but the execution time was unreasonable, while manual execution of the store procedure took a few seconds.
Bottom line:
I added SET IMPLICIT_TRANSACTIONS OFF to the stored procedure that is used to fill the data set.
From MSDN:
The SQL Server Native Client OLE DB Provider for SQL Server and the
SQL Server Native Client ODBC driver automatically set
IMPLICIT_TRANSACTIONS to OFF when connecting. SET
IMPLICIT_TRANSACTIONS defaults to OFF for connections with the
SQLClient managed provider, and for SOAP requests received through
HTTP endpoints.
[...]
When SET ANSI_DEFAULTS is ON, SET IMPLICIT_TRANSACTIONS is ON.
So I believe that in my case defaults weren't as required. (I couldn't check that. Don't have enough privileges on SQL server). But adding this line to my SP solved the problem.
IMPORTANT: In my case I didn't need the transaction, so I had no problem to cancel the implicit transaction setting. If in your case transaction is a must you, probably, shouldn't use this solution.

Categories

Resources