L'aumento della latenza di rete causerà blocchi della tabella in MS SQL Server?


16

Se sto effettuando una singola chiamata a un database SQL Server su una rete ad alta latenza, si verificheranno blocchi della tabella dovuti a tale latenza? Supponiamo che esegua una query nella tabella A per alcuni record e che SQL Server debba restituire quei dati su una rete lenta - ci sarà un blocco di lettura sulla tabella A mentre il server invia la risposta sulla rete o SQL Server rilascia il blocco prima di inviare la risposta?

Inoltre, la risposta potrebbe variare in base alla dimensione della risposta? Se dovesse restituire solo pochi KB contro diverse centinaia di MB, ciò farebbe la differenza?

La creazione di una transazione esplicita, l'esecuzione di query e la chiusura della transazione causerebbero ovviamente il blocco delle tabelle, poiché la durata della transazione è correlata alla mia latenza.


A meno che non specifichi un nolocksuggerimento, ci sarà sempre un lucchetto . La latenza determina solo per quanto tempo verrà trattenuto il blocco.
Brandon,

3
E anche con nolock, riceverai comunque i blocchi
billinkc

@brandon È documentato da Microsoft da qualche parte? Le mie ricerche sono risultate vuote.
Evan M,

1
@Brandon NOLOCK non significa ciò che pensi significhi.
Aaron Bertrand

3
@Brandon Unless you specify a nolock hint, there will always be a lock.<- questo implica che se si utilizza nolock potrebbero non esserci blocchi. Stavo semplicemente chiarendo.
Aaron Bertrand

Risposte:


15

Se il client impiega molto tempo a ricevere i dati e, a sua volta, invia il riconoscimento a SQL Server di aver ricevuto i dati che SQL Server deve attendere, a causa di questa attesa SQL Server non rilascerà i blocchi conservati dalla query a meno che non venga ricevuto il riconoscimento dal client.

Questo non è accurato, dipende dal livello di isolamento.

Ai READ COMMITTEDblocchi predefiniti non vengono mantenuti per la durata dell'esecuzione delle istruzioni. READ COMMITTEDnon fornisce coerenza di lettura a livello di istruzione, l'unica garanzia è che non è possibile leggere dati non confermati. Un blocco condiviso viene acquisito e trattenuto per leggere la riga e quindi rilasciato.

A meno che non si disponga di tipi LOB.

I tipi di LOB, essendo potenzialmente molto grandi, non possono essere bufferizzati. Un blocco condiviso deve essere acquisito e trattenuto fino al completamento dell'istruzione, in sostanza dandoti un REPEATABLE READcomportamento in READ COMMITTED.

Se sto effettuando una singola chiamata a un database MSSQL su una rete ad alta latenza, si verificheranno blocchi della tabella dovuti a tale latenza?

La latenza non sta causando il blocco della tabella, no. Tuttavia, se è stato acquisito un blocco tabella, la latenza lo prolungherà.

Per citare qualcuno che conosce la meccanica di questo meglio di me ( @RemusRusanu ):

I risultati vengono restituiti al programma client man mano che procede l'esecuzione. Quando le righe "riempiono" l'albero delle esecuzioni, all'operatore principale viene solitamente assegnato il compito di scrivere queste righe nei buffer di rete e di inviarle al client. Il risultato non viene creato prima in un archivio intermedio (memoria o disco) e quindi rispedito al client, ma viene rispedito mentre viene creato (durante l'esecuzione della query). L'invio del risultato al client è ovviamente soggetto al protocollo di controllo del flusso di rete. Se il client non sta attivamente consumando il risultato (ad es. Chiamando SqlDataReader.Read ()), alla fine il controllo di flusso dovrà bloccare il lato di invio (la query che viene eseguita) e questo a sua volta sospenderà l'esecuzione del query.[fonte]

Laddove i risultati non vengono consumati con la stessa rapidità con cui SQL Server è in grado di fornirli, a causa del client o della rete, vediamo ASYNC_NETWORK_IOaccumularsi le attese. Per ribadire, ciò non influenzerà i blocchi acquisiti, ma solo la durata in cui vengono mantenuti.


9

La risposta di Mark ha chiarito molta della mia confusione, ma volevo pubblicare le mie scoperte dopo averle testate usando NetBalancer per emulare la latenza.

Il mio computer locale chiamava un server SQL remoto ed eseguiva SELECT e INSERT su una tabella all'interno di una piccola transazione. Sul computer remoto, mi sono collegato all'istanza SQL locale e ho usato un ciclo WHILE per scorrere ripetutamente la tabella sys.dm_tran_locks, cercando eventuali blocchi sulla tabella da cui stavo modificando e leggendo. Ho installato NetBalancer sul server e l'ho usato per emulare la latenza della rete sulla connessione di rete del server.

Ecco cosa ho trovato:

  • Per le dichiarazioni che non restituiscono molti dati al client, la latenza non ha alcun effetto sul blocco. Stavo restituendo solo poche centinaia di byte di dati. La transazione sulla mia macchina aveva un WAITFOR da 250 ms che manteneva i blocchi e quando ho aumentato la latenza della rete a 5000 ms la durata del blocco è rimasta vicina a 250 ms.
  • Per le dichiarazioni che restituiscono molti dati, la latenza influisce sicuramente sul blocco. Ho restituito al client decine di migliaia di righe e, senza latenza, la durata del blocco è stata breve. Quando ho aumentato la latenza, i blocchi sono continuati fino a quando non ho ricevuto tutti i dati.

Da questo, sto concludendo che la latenza non ha importanza finché i dati si adattano al buffer di rete. Se SQL deve inserire molti dati nel buffer di rete, la latenza farà sì che il buffer esegua il backup e SQL manterrà i blocchi della tabella fino a quando non potrà inserire tutti i risultati della query nel buffer.


Risultati interessanti Con quale programma / libreria client si tratta?
James L

Roba buona. Qualche possibilità che tu possa dedicare un po 'più di tempo a questo e vedere se riesci a determinare la dimensione del risultato in cui ciò si verifica?
Mark Storey-Smith,

@ MarkStorey-Smith Non credo di poter ottenere un valore preciso e varierebbe senza dubbio a seconda della macchina. Da vircom.com/security/improve-sql-nic-performance , sembra che sia un'impostazione sulla tua scheda di rete locale, e quella sul mio server di database è stata impostata su "auto"
Evan M

@James Ho appena usato SSMS su entrambe le macchine
Evan M

0

Se sto effettuando una singola chiamata a un database MSSQL su una rete ad alta latenza, si verificheranno blocchi della tabella dovuti a tale latenza?

Quando una query viene generata e completata da SQL Server, produce i risultati, inserirla nel buffer di output e inviarla al client che quindi recupera il risultato dal buffer di output. SQL Server non rilascerà i blocchi conservati dalla query se non viene ricevuto il riconoscimento dal client. Ciò potrebbe causare il blocco.

Modifica: Evan puoi fare riferimento a questo articolo di supporto di MS

Nella sezione 3

Il blocco causato da uno SPID di cui l'applicazione client corrispondente non ha recuperato tutte le righe dei risultati fino al completamento

Dopo aver inviato una query al server, tutte le applicazioni devono immediatamente recuperare tutte le righe dei risultati per il completamento. Se un'applicazione non recupera tutte le righe dei risultati, i blocchi possono essere lasciati sui tavoli, bloccando altri utenti. Se si utilizza un'applicazione che invia in modo trasparente istruzioni SQL al server, l'applicazione deve recuperare tutte le righe dei risultati. In caso contrario (e se non può essere configurato per farlo), potresti non essere in grado di risolvere il problema di blocco. Per evitare il problema, è possibile limitare le applicazioni mal gestite a un database o un database di supporto decisionale.


Grazie per la tua risposta Shanky! Ti capita di sapere se questo è documentato ovunque?
Evan M,


5
Questo non è corretto
Mark Storey-Smith,

Questo è corretto sembra che l'applicazione non recuperi tutte le righe dei risultati, i blocchi possono essere lasciati sui tavoli, bloccando altri utenti. Se si utilizza un'applicazione che invia in modo trasparente istruzioni SQL al server, l'applicazione deve recuperare tutte le righe dei risultati. In caso contrario (e se non può essere configurato per farlo), potresti non essere in grado di risolvere il problema di blocco. Per evitare il problema, è possibile limitare le applicazioni mal educate a un database o a un database di supporto decisionale. " Più oltre stavo parlando in termini generali. Puoi leggere da qui support2.microsoft.com/kb/224453
Shanky,

4
@Grazie Crea una grande tabella. SELECT *da esso in a READ COMMITTEDin una connessione SSMS, monitora i blocchi da un'altra. In qualsiasi momento, quante serrature vedi in possesso?
Mark Storey-Smith,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.