Come eseguire il debug, eccezione di SQL Server, il periodo di timeout trascorso prima del completamento dell'operazione o il server non risponde

sql sqlbulkcopy sql-server

Domanda

Sto caricando un file di grandi dimensioni (~ 25 GB, 400 milioni di righe) in SQL Server 2014 utilizzando SqlBulkCopy .

La dimensione della copia di massa è di 10.000 righe e il timeout è di 1 ora. L'intero file si trova in una singola transazione poiché vorrei memorizzare l'intero file o eseguire il rollback in caso di errori. Ho 3 indici (un indice cluster univoco e altri due sono indici non raggruppati) su questa tabella.

A volte ottengo questa eccezione:

System.Data.SqlClient.SqlException (0x80131904): Timeout scaduto. Il periodo di timeout è trascorso prima del completamento dell'operazione o il server non risponde.

System.ComponentModel.Win32Exception (0x80004005): l'operazione di attesa è scaduta

at System.Data.SqlClient.SqlInternalConnection.OnError (eccezione SqlException, breakConnection booleano, azione 1 wrapCloseInAction) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error) at System.Data.SqlClient.TdsParserStateObject.ReadSniSyncOverAsync() at System.Data.SqlClient.TdsParserStateObject.TryReadNetworkPacket() at System.Data.SqlClient.TdsParserStateObject.TryPrepareBuffer() at System.Data.SqlClient.TdsParserStateObject.TryReadByte(Byte& value) at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) at System.Data.SqlClient.SqlBulkCopy.RunParser(BulkCopySimpleResultSet bulkCopyHandler) at System.Data.SqlClient.SqlBulkCopy.CopyBatchesAsyncContinuedOnSuccess(BulkCopySimpleResultSet internalResults, String updateBulkCommandText, CancellationToken cts, TaskCompletionSource a System.Data.SqlClient 1 fonte). SqlBulkCopy.CopyBatchesAsyncContinued (bulkCopyHandler internalResults, String updateBulkCommandText, CancellationToken cts, TaskCompletionSource 1 source) at System.Data.SqlClient.SqlBulkCopy.CopyBatchesAsync(BulkCopySimpleResultSet internalResults, String updateBulkCommandText, CancellationToken cts, TaskCompletionSource 1 fonte) System.Data.SqlClient.SqlBulkCopy. WriteToServerInternalRestContinuedAsync (BulkCopySimpleResultSet internalResults, CancellationToken cts, origine TaskCompletionSource 1 source) at System.Data.SqlClient.SqlBulkCopy.WriteToServerInternalRestAsync(CancellationToken cts, TaskCompletionSource 1) su Syst em.Data.SqlClient.SqlBulkCopy.WriteToServerInternalAsync (CancellationToken ctoken) su System.Data.SqlClient.SqlBulkCopy.WriteRowSourceToServerAsync (Int32 columnCount, CancellationToken ctoken) su System.Data.SqlClient.SqlBulkCopy.WriteToServer (lettore IDataReader)

In caso di eccezione, eseguo un rollback dell'intera transazione, ma poi vedo un'altra eccezione durante il tentativo di rollback. Non ho capito perché SqlTransaction non è utilizzabile in quanto il mio codice non chiude la connessione / transazione da nessun'altra parte.

System.InvalidOperationException: questo SqlTransaction è stato completato; non è più utilizzabile

Ho eseguito il debug in una certa misura, in SSMS vedo che c'è una transazione aperta

select @@TRANCOUNT  ==> this gives "0" (I didn't understand why)

dbcc opentran ==> this gives me a open transaction

Oldest active transaction:
    SPID (server process ID): 58
    UID (user ID) : -1
    Name          : user_transaction
    LSN           : (159:2843368:1)
    Start time    : Dec 30 2014 11:20:13:903PM
    SID           : 0x0105000000000005150000005d28f57fd53ad8354354e02ae9881a00
DBCC execution completed. If DBCC printed error messages, contact your system administrator.

Quindi usando questo script SQL ho capito che si è bloccato sulla linea

insert bulk dbo.#mytablename#

con stato come in esecuzione, data / ora che corrisponde esattamente all'ora in cui ha generato l'eccezione: 1 ora (timeout della copia di massa). Ma non riuscivo a capire perché SQL Server è rimasto bloccato qui e perché ci vuole più tempo. C'è un modo per eseguire il debug di questo ulteriore?

SELECT 
   r.[session_id],
   c.[client_net_address],
   s.[host_name],
   c.[connect_time],
   [request_start_time] = s.[last_request_start_time],
   [current_time] = CURRENT_TIMESTAMP,
   r.[percent_complete],
   [estimated_finish_time] = DATEADD
       (
           MILLISECOND,
           r.[estimated_completion_time], 
           CURRENT_TIMESTAMP
       ),
   current_command = SUBSTRING
       (
           t.[text],
           r.[statement_start_offset]/2,
           COALESCE(NULLIF(r.[statement_end_offset], -1)/2, 2147483647)
       ),
   module = COALESCE(QUOTENAME(OBJECT_SCHEMA_NAME(t.[objectid], t.[dbid])) 
       + '.' + QUOTENAME(OBJECT_NAME(t.[objectid], t.[dbid])), '<ad hoc>'),
   [status] = UPPER(s.[status])
 FROM
     sys.dm_exec_connections AS c
 INNER JOIN
     sys.dm_exec_sessions AS s
     ON c.session_id = s.session_id
 LEFT OUTER JOIN
     sys.dm_exec_requests AS r
     ON r.[session_id] = s.[session_id]
 OUTER APPLY
     sys.dm_exec_sql_text(r.[sql_handle]) AS t
 WHERE
     c.session_id = 58;

Risposta popolare

È scaduto perché il tuo carico di massa impiegherà più di un'ora per terminare . Come da MSDN , l'impostazione di timeout si riferisce a

Numero di secondi per il completamento dell'operazione prima che scada.

È logico che un file da 25 GB possa impiegare più di un'ora per caricarsi nel database, quindi perché non provare a impostare un valore di timeout più alto in modo che abbia tempo sufficiente per il completamento?



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché