{"id":19909,"date":"2026-06-11T15:15:29","date_gmt":"2026-06-11T13:15:29","guid":{"rendered":"https:\/\/webhosting.de\/database-row-locking-mysql-concurrency-optimieren-performance-locks\/"},"modified":"2026-06-11T15:15:29","modified_gmt":"2026-06-11T13:15:29","slug":"blocco-delle-righe-del-database-mysql-concorrenza-ottimizzazione-prestazioni-blocchi","status":"publish","type":"post","link":"https:\/\/webhosting.de\/it\/database-row-locking-mysql-concurrency-optimieren-performance-locks\/","title":{"rendered":"Capire il blocco delle righe del database e i problemi di concorrenza in MySQL"},"content":{"rendered":"<p><strong>Riga del database<\/strong> In MySQL, il blocco controlla con precisione quale transazione possa leggere o scrivere quali righe e in quale momento, proteggendo cos\u00ec da aggiornamenti persi e letture non valide. Vi mostrer\u00f2 passo dopo passo come funzionano i blocchi, <strong>MVCC<\/strong> e come interagiscono i livelli di isolamento, dove sorgono i problemi di concorrenza e come posso strutturare query, indici e transazioni in modo da evitare i blocchi.<\/p>\n\n<h2>Punti centrali<\/h2>\n<p>Per aiutarti a capire subito su cosa mi concentrer\u00f2 in questo articolo, riassumo i punti chiave e li metto brevemente a confronto. In questo modo avrai una struttura sintetica che ti servir\u00e0 come base per le successive approfondimenti <strong>Spiegazioni<\/strong>.<\/p>\n<ul>\n  <li><strong>Blocchi per remi<\/strong> limitare i conflitti a singole righe anzich\u00e9 a intere tabelle.<\/li>\n  <li><strong>MVCC<\/strong> consente una lettura veloce senza shared lock permanenti.<\/li>\n  <li><strong>Isolamento<\/strong> stabilisce quali anomalie sono ammesse.<\/li>\n  <li><strong>Tasto Gap\/Next<\/strong> Bloccare le lacune dell'indice contro i fantasmi.<\/li>\n  <li><strong>Migliori pratiche<\/strong> riducono sensibilmente i blocchi e i deadlock.<\/li>\n<\/ul>\n<p>Nel prosieguo tradurr\u00f2 questi punti in misure concrete volte a garantire che le istanze MySQL produttive siano pi\u00f9 sicure e veloci. Ogni raccomandazione mira a ridurre <strong>Blocco<\/strong>, dati coerenti e percorsi diagnostici chiari.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/06\/mysql-serverraum-9081.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Perch\u00e9 \u00e8 necessario il controllo della concorrenza<\/h2>\n<p>Gli accessi simultanei entrano in conflitto non appena pi\u00f9 sessioni cercano di leggere o scrivere le stesse righe, motivo per cui ho optato per una chiara <strong>Limiti delle transazioni<\/strong> 8. Senza regole si rischia di incorrere in \"lost updates\", \"dirty reads\", \"non-repeatable reads\" e \"phantoms\", che alla fine causano decisioni errate nel codice dell'applicazione. Io lo prevengo garantendo la coerenza di lettura e rendendo visibili tempestivamente i conflitti di scrittura, invece di sovrascriverli silenziosamente. Pi\u00f9 utenti paralleli sono attivi, pi\u00f9 diventano importanti piccoli oggetti di blocco e brevi <strong>Tempi di sosta<\/strong>. Chi ignora questo aspetto va incontro a errori nei dati, con lunghe code di attesa e timeout.<\/p>\n\n<h2>Nozioni di base sul blocco delle righe in MySQL<\/h2>\n<p>Il row locking applica blocchi a singole righe, in modo che le altre righe rimangano libere e... <strong>Parallelismo<\/strong> viene creato. Un blocco esclusivo protegge le operazioni di scrittura fino al commit, mentre gli accessi in lettura utilizzano, a seconda del livello di isolamento, blocchi condivisi o snapshot MVCC. I blocchi di intenti fungono da segnali di livello superiore, consentendo al motore di verificare pi\u00f9 rapidamente la compatibilit\u00e0 dei blocchi. Faccio sempre notare che anche piccoli aggiornamenti possono interessare molte righe se le condizioni WHERE sono imprecise e non c'\u00e8 <strong>Indice<\/strong> . La precisione nel filtro evita ampie fasce di esclusione e preserva la concorrenza.<\/p>\n<p>\u00c8 importante anche l'interazione con gli indici, poich\u00e9 InnoDB blocca i dati tramite i percorsi degli indici; chiavi mancanti o inadeguate aumentano notevolmente il numero di righe interessate. Se una query esegue una scansione completa, il campo di blocco si espande, aumentando i tempi di attesa e favorendo i deadlock. Per questo motivo, pianifico fin dall'inizio le chiavi appropriate per i percorsi frequenti e mantengo le clausole WHERE il pi\u00f9 specifiche possibile. In questo modo i miei blocchi rimangono limitati e le altre transazioni vengono elaborate pi\u00f9 rapidamente. <strong>Accesso<\/strong>. \u00c8 la regolazione pi\u00f9 semplice per ottenere un funzionamento fluido del sistema di bloccaggio.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/06\/mysql_datenbank_probleme_4837.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Locking pessimistico vs. ottimistico<\/h2>\n<p>Il \u00ablocking pessimistico\u00bb parte dal presupposto che ci siano conflitti e blocca le operazioni in una fase precoce, il che rafforza l\u2019integrit\u00e0 ma richiede tempo, mentre <strong>ottimista<\/strong> I sistemi in esecuzione verificano solo alla fine se i dati sono stati modificati. Nelle configurazioni MySQL orientate alla pratica, combino entrambe le cose: per gli account critici eseguo il salvataggio con FOR UPDATE, mentre per le entit\u00e0 che raramente entrano in conflitto utilizzo le versioni. Una colonna di versione o un timestamp mi permette, durante l'aggiornamento, di determinare se qualcuno \u00e8 stato pi\u00f9 veloce, senza bloccare la riga in modo permanente. Se si verifica un conflitto, ripeto la transazione in modo mirato o eseguo una logica di business adattata. In questo modo distribuisco il carico in modo pi\u00f9 efficiente, riduco i tempi di attesa e mantengo la <strong>Correttezza<\/strong> alto.<\/p>\n<p>Scelgo la strategia in base al singolo caso d'uso: le operazioni di lettura simultanee in gran numero traggono vantaggio da approcci ottimistici, mentre le registrazioni contabili o di magazzino altamente critiche richiedono blocchi esclusivi brevi ma chiari. L'obiettivo rimane sempre quello di bloccare solo quanto necessario e di individuare tempestivamente i conflitti. Con questo approccio evito lunghe catene di sessioni in attesa. Di conseguenza aumentano la produttivit\u00e0 e <strong>Affidabilit\u00e0<\/strong> nella vita quotidiana.<\/p>\n\n<h2>Comprendere i livelli di isolamento e l'MVCC<\/h2>\n<p>Il livello di isolamento determina il numero di anomalie che si \u00e8 disposti a tollerare e l'intensit\u00e0 con cui MySQL applica i blocchi; per questo motivo, \u00e8 importante scegliere il livello in base al caso d'uso specifico. READ COMMITTED impedisce le letture sporche, REPEATABLE READ mantiene coerenti i valori di una transazione e SERIALIZABLE garantisce la sequenza pi\u00f9 rigorosa. InnoDB utilizza <strong>MVCC<\/strong>, in modo che i lettori possano quasi sempre fare a meno dei blocchi condivisi e vedere comunque istantanee coerenti. Chi lavora con questo meccanismo dovrebbe capire quando entrano in gioco anche i blocchi Gap e Next-Key per evitare i \u00abfantasmi\u00bb. Per approfondire l'argomento, vale la pena dare un'occhiata a <a href=\"https:\/\/webhosting.de\/it\/mysql-livello-di-isolamento-hosting-server-coerenza-transazioni\/\">Dettagli sui livelli di isolamento<\/a>, in modo da poter valutare correttamente gli effetti per ogni livello.<\/p>\n<p>La tabella seguente mette a confronto i livelli pi\u00f9 comuni con le anomalie tipiche e il loro impatto sui blocchi, in modo da poter fare la scelta giusta ed evitare inutili <strong>Blocco<\/strong> evitare.<\/p>\n<table>\n  <thead>\n    <tr>\n      <th>Livello di isolamento<\/th>\n      <th>Anomalie consentite<\/th>\n      <th>Comportamento di blocco (in sintesi)<\/th>\n      <th>Utilizzo tipico<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>LEGGERE SENZA IMPEGNO<\/td>\n      <td>Dirty Reads, Non-Repeatable, Phantoms<\/td>\n      <td>Pochissimi blocchi, elevata <strong>I rischi<\/strong><\/td>\n      <td>Raramente utile<\/td>\n    <\/tr>\n    <tr>\n      <td>READ COMMITTED<\/td>\n      <td>Non ripetibili, fantasmi<\/td>\n      <td>I lettori utilizzano MVCC, gli scrittori <strong>X-Locks<\/strong><\/td>\n      <td>Report, API con un elevato numero di letture<\/td>\n    <\/tr>\n    <tr>\n      <td>LETTURA RIPETIBILE<\/td>\n      <td>Phantoms in offerta speciale su Next-Key<\/td>\n      <td>Elevata coerenza di lettura, mirata <strong>Gap<\/strong>-Blocchi<\/td>\n      <td>Standard in InnoDB<\/td>\n    <\/tr>\n    <tr>\n      <td>SERIALIZZABILE<\/td>\n      <td>Nessuna anomalia<\/td>\n      <td>Barriere pi\u00f9 larghe, minori <strong>Parallelismo<\/strong><\/td>\n      <td>Processi altamente critici<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n<p>Di solito inizio con REPEATABLE READ e apporto correzioni mirate quando le query causano blocchi eccessivi a causa dei blocchi Next-Key. Al contrario, utilizzo SERIALIZABLE solo nei casi in cui \u00e8 tecnicamente inevitabile, poich\u00e9 altrimenti i tempi di attesa aumentano. Con una scelta chiara per ogni carico di lavoro, mantengo i dati coerenti e allo stesso tempo proteggo la <strong>Prestazioni<\/strong>. Questo approccio consente di risparmiare tempo nell'assistenza, poich\u00e9 si verificano meno spesso picchi di carico imprevisti. In questo modo il sistema rimane prevedibile, anche con l'aumentare del numero di utenti.<\/p>\n\n<h2>La concorrenza in MySQL nella pratica<\/h2>\n<p>Una buona concorrenza inizia con query ben formulate, che selezionano solo le righe realmente necessarie, in modo che InnoDB possa <strong>Riga<\/strong>-posso impostare dei blocchi. Mi assicuro che le condizioni di filtro siano eseguibili tramite indici, ovvero che non richiedano l'uso di funzioni sulle colonne. Mantengo gli aggiornamenti mirati: clausola WHERE chiara, indice appropriato, nessun join superfluo nella stessa istruzione. Per i casi di prenotazione, uso FOR UPDATE con parsimonia e solo per i record effettivamente interessati. Inoltre, evito lunghe interazioni dell'utente tra BEGIN e COMMIT, poich\u00e9 ogni secondo aumenta il <strong>tempo di attesa<\/strong> altre sessioni.<\/p>\n<p>Quando si effettuano inserimenti in spazi di indice densamente popolati, tengo conto del fatto che potrebbero attivarsi i blocchi Next-Key, causando un aumento delle transazioni in attesa. Distribuisco gli hotspot sparpagliando gli spazi delle chiavi o alleggerendo il percorso di scrittura in una piccola coda indipendente. In questo modo riduco le collisioni sulla tabella pi\u00f9 trafficata. Questa messa a punto ha un effetto maggiore rispetto all'aumento dei timeout, perch\u00e9 richiede meno <strong>Conflitti<\/strong> si verifichino affatto. Proprio per questo vale la pena misurare gli accessi ai dati prima del lancio.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/06\/mysql-row-locking-concurrency-9835.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Problemi tipici legati alla concorrenza: blocchi, deadlock, ambito dei blocchi<\/h2>\n<p>Il blocking si verifica quando una transazione \u00e8 in attesa di una riga gi\u00e0 bloccata; per questo motivo cerco di mantenere brevi le transazioni e la riga in questione <strong>Quantit\u00e0<\/strong> limito. I deadlock si verificano quando due transazioni si bloccano a vicenda; MySQL lo rileva e ne interrompe una. Rispondo a questo con tentativi mirati e un ordine di accesso coerente in tutti i percorsi di codice. L'escalation dei blocchi \u00e8 meno frequente in InnoDB, ma i limiti interni limitano comunque lo sforzo di gestione; scansioni di grandi dimensioni avvicinano il motore a tali limiti. Chi riscontra deadlock ricorrenti dovrebbe <a href=\"https:\/\/webhosting.de\/it\/rilevamento-di-deadlock-del-database-gestione-dellinfrastruttura-di-hosting\/\">Rilevamento e gestione dei deadlock<\/a> verificare sistematicamente ed eliminare le cause del conflitto, invece di limitarsi ad aumentare i tempi di attesa.<\/p>\n<p>In base alla mia esperienza, ci sono tre fattori che causano tempi di attesa particolarmente lunghi: filtri non indicizzati su tabelle molto attive, l'uso di FOR UPDATE senza una clausola WHERE precisa e una logica di business troppo complessa tra la fase di lettura e quella di scrittura. Li elimino misurando ogni percorso singolarmente, riducendo la durata del blocco e ottimizzando le istruzioni SQL sui percorsi degli indici. Piccole modifiche al filtro o all'ordine degli aggiornamenti spesso risolvono interi colli di bottiglia. Tali correzioni sono pi\u00f9 convenienti rispetto a ulteriori <strong>Hardware<\/strong>, perch\u00e9 hanno un effetto duraturo. Solo allora vale la pena pensare a un'espansione verticale o orizzontale.<\/p>\n\n<h2>Migliori pratiche contro i blocchi e i deadlock<\/h2>\n<p>Concludo le transazioni rapidamente e non lascio aperte le schermate di immissione dati mentre sono in corso i blocchi, perch\u00e9 ogni secondo \u00e8 tempo perso <strong>Code d'attesa<\/strong> . Gestisco sempre le tabelle e le righe nello stesso ordine per evitare dipendenze cicliche. Per le operazioni di sola lettura spesso \u00e8 sufficiente READ COMMITTED, mentre per gli aggiornamenti critici utilizzo REPEATABLE READ o, in casi specifici, FOR UPDATE. La progettazione degli indici rimane fondamentale: senza una chiave adeguata, un'istruzione blocca rapidamente troppe righe. Anche la gestione degli errori fa parte del processo: intercetto gli errori di deadlock, registro tutti i dettagli e cerco una soluzione breve e pulita <strong>Riprova<\/strong>.<\/p>\n<p>Il monitoraggio completa il pacchetto: tengo sotto controllo i tempi di attesa, il numero di deadlock e i piani di query, ottimizzando innanzitutto i picchi pi\u00f9 evidenti. Piccoli miglioramenti negli hotpath danno grandi risultati, perch\u00e9 influiscono su ogni richiesta. In questo modo ottengo meno blocchi, un throughput maggiore e tempi di risposta affidabili. Questo approccio \u00e8 di gran lunga pi\u00f9 efficace nell'attivit\u00e0 quotidiana rispetto a ristrutturazioni su larga scala. Routine pulite battono le soluzioni generiche <strong>Azioni<\/strong> quasi sempre.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/06\/techoffice2976.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Suggerimenti specifici per MySQL per aumentare la concorrenza<\/h2>\n<p>Utilizzo l'autocommit in modo consapevole: le singole istruzioni ne traggono vantaggio, mentre le modifiche correlate vengono raggruppate in un unico, chiaro <strong>Transazione<\/strong> . Utilizzo SELECT \u2026 FOR UPDATE con parsimonia e solo per i record che devo davvero riservare. I report pi\u00f9 lunghi li trasferisco su repliche o sistemi analitici, in modo che i carichi di lavoro OLTP non debbano attendere. Inoltre, controllo regolarmente quali istruzioni mantengono un numero insolitamente elevato di blocchi e perch\u00e9. Chi desidera approfondire l'argomento dovrebbe consultare la <a href=\"https:\/\/webhosting.de\/it\/mysql-motore-di-archiviazione-innodb-myisam-web-hosting-serverflux\/\">Motore di archiviazione InnoDB<\/a> e valutare attentamente i layout degli indici nel contesto del proprio schema prima che la prossima versione venga messa in produzione.<\/p>\n<p>Riduco al minimo i punti di congestione scegliendo le chiavi primarie in modo tale che il carico di scrittura non si concentri costantemente alla fine di un indice che cresce in modo monotono. Suddivido anche le operazioni batch in piccoli blocchi per non generare blocchi esclusivi di lunga durata. Con questi strumenti, i blocchi durano meno e la contesa diminuisce in modo misurabile. Di conseguenza, il tasso di errore si riduce e l'applicazione risponde in modo pi\u00f9 fluido. In questo modo sblocco risorse senza doverne creare immediatamente di nuove <strong>Server<\/strong> costruire.<\/p>\n\n<h2>Monitoraggio e analisi: cosa misuro<\/h2>\n<p>Inizier\u00f2 con le metriche relative ai tempi di attesa dei blocchi, al numero di deadlock, alle transazioni di lunga durata e alle istruzioni principali in base al tempo di esecuzione, in modo da individuare i principali <strong>Leva<\/strong> Riconoscere. Lo schema delle prestazioni, il comando SHOW ENGINE INNODB STATUS e i log delle query lente mi forniscono indicazioni concrete. Successivamente, esamino i piani delle query pi\u00f9 problematiche e verifico se mancano indici o se i filtri non sono ottimizzabili. Non appena elimino i colli di bottiglia, ne osservo l'effetto su diverse fasi di carico. Questo ciclo di misurazione, modifica e verifica consente di <strong>qualit\u00e0<\/strong> la concorrenza aumenta sensibilmente.<\/p>\n<p>Per ottenere risultati attendibili ho bisogno di dati di test realistici e modelli di accesso reali, non solo test sintetici a campionamento singolo. I profili di carico con sessioni simultanee mostrano come funzionano realmente i blocchi. Tali test rivelano punti critici nascosti che nella routine quotidiana si notano solo in un secondo momento. Chi verifica le versioni in questo modo evita sorprese durante il funzionamento live. Ci\u00f2 consente di risparmiare costi, tempo e stress nel lungo periodo <strong>Vista<\/strong>.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/06\/mysql_locking_problem_3021.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Ambiente di hosting e prestazioni del database<\/h2>\n<p>Una buona concorrenza si basa su un hardware veloce, poich\u00e9 ogni ritardo nell'I\/O allunga il <strong>Durata del blocco<\/strong>. Presto attenzione a dischi SSD veloci, a una quantit\u00e0 sufficiente di RAM per i buffer pool e a percorsi brevi tra l'applicazione e il database. Le riserve di CPU aiutano a eseguire query parallele senza intasamenti. Riduco sistematicamente le latenze di rete, in modo che i roundtrip non facciano aumentare il tempo di blocco effettivo. Chi tiene d'occhio queste condizioni generali ottiene un sistema reattivo <strong>Servizi<\/strong> e meno interruzioni.<\/p>\n<p>Anche le strategie di scalabilit\u00e0 efficaci sono importanti: repliche di lettura per i report, sharding per set di dati molto grandi e sistemi separati per i carichi di lavoro di analisi. Scelgo quale opzione sia pi\u00f9 vantaggiosa solo dopo aver effettuato delle misurazioni, evitando decisioni affrettate. L'architettura e la disciplina SQL si completano a vicenda; senza query coerenti, l'hardware compensa solo a breve termine. Con una combinazione equilibrata, riduco significativamente i conflitti di blocco. Il risultato \u00e8 un'esperienza utente affidabile senza evidenti <strong>Tempi di attesa<\/strong>.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/06\/mysql-zeilensperrung-4839.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>I tipi di blocco in InnoDB in dettaglio<\/h2>\n<p>Per prendere decisioni oculate sui percorsi di interrogazione, conosco bene i principali tipi di blocco: i blocchi su record bloccano singole voci dell'indice, i blocchi su intervallo bloccano lo spazio tra due voci dell'indice e i blocchi Next-Key sono una combinazione dei due. Questi ultimi impediscono la comparsa di phantom durante le scansioni per intervallo. I blocchi di intenzione di inserimento segnalano l'intenzione di effettuare inserimenti e consentono inserimenti paralleli in spazi diversi senza ostacolarsi inutilmente. In caso di ricerche univoche tramite un indice unico, InnoDB riduce il blocco a un Record-Lock, minimizzando cos\u00ec i blocchi. Non appena entra in gioco un predicato di intervallo (BETWEEN, &gt;, LIKE con prefisso), spesso interviene un Next-Key-Lock e quindi un'area di blocco pi\u00f9 ampia.<\/p>\n<p>Per questo motivo, progetto le query in modo che, per quanto possibile, ricorrano a indici univoci o altamente selettivi. Non \u00e8 solo il WHERE a essere determinante: anche l'ORDER BY, il LIMIT e l'ordine dei JOIN influenzano il percorso dell'indice scelto \u2013 e quindi l'entit\u00e0 dei blocchi. Una riscrittura mirata, che utilizza un ORDER BY con un indice adeguato, pu\u00f2 evitare i blocchi Next-Key e ridurre significativamente i tempi di attesa.<\/p>\n\n<h2>Utilizzare le letture con blocco in modo mirato<\/h2>\n<p>Le operazioni di lettura con blocco sono utili quando devo riservare righe o coordinare aggiornamenti concorrenti. In MySQL utilizzo:<\/p>\n<ul>\n  <li>SELECT \u2026 FOR UPDATE: blocco esclusivo sulle righe lette, adatto per le prenotazioni prima di un aggiornamento.<\/li>\n  <li>SELECT \u2026 FOR SHARE (o LOCK IN SHARE MODE nelle versioni precedenti): blocco condiviso per garantire letture coerenti con protezione da scrittura.<\/li>\n  <li>NOWAIT e SKIP LOCKED: evitano lunghi tempi di attesa \u2013 NOWAIT interrompe immediatamente l'operazione, SKIP LOCKED salta le righe bloccate.<\/li>\n<\/ul>\n<p>Un modello comune per le code di lavoro:<\/p>\n<pre><code>START TRANSACTION;\nSELECT id, payload\nFROM jobs\nWHERE status = 'ready'\nORDER BY priority, id\nLIMIT 50\nFOR UPDATE SKIP LOCKED;\n-- contrassegna come 'processing' e conferma\nUPDATE jobs SET status = 'processing' WHERE id IN (...);\nCOMMIT;<\/code><\/pre>\n<p>In questo modo gestisco il carico in parallelo senza che le operazioni si blocchino a vicenda. \u00c8 fondamentale utilizzare clausole WHERE precise, un indice adeguato su (status, priority, id) e transazioni brevi.<\/p>\n\n<h2>Comprendere i Metadata Locks (MDL)<\/h2>\n<p>Oltre ai blocchi su riga (row locks), esistono i blocchi sui metadati (metadata locks) che coordinano le operazioni DDL e DML. Ogni query in esecuzione mantiene un blocco di lettura MDL sulle tabelle interessate; le operazioni DDL richiedono blocchi MDL esclusivi. Un ALTER TABLE avviato in modo avventato pu\u00f2 quindi rimanere in attesa fino al termine di transazioni o report di lunga durata; viceversa, un DDL blocca a sua volta i nuovi accessi DML. Pianifico quindi le modifiche allo schema al di fuori dei picchi di carico, riduco la durata delle transazioni e, prima delle implementazioni, verifico se le sessioni mantengono aperte le tabelle per diversi minuti. Le varianti DDL online attenuano molti problemi, ma non sostituiscono la disciplina nei tempi di transazione. Nel monitoraggio osservo in modo mirato le attese MDL, perch\u00e9 segnalano congestioni evitabili.<\/p>\n\n<h2>Chiavi esterne, cascate e obbligo di indicizzazione<\/h2>\n<p>Le chiavi esterne migliorano la qualit\u00e0 dei dati, ma aumentano l'impronta dei blocchi. InnoDB verifica la coerenza tramite gli indici: se questi mancano sulle colonne delle chiavi esterne, si rischia di incorrere in scansioni estese e blocchi prolungati. Per questo motivo mi assicuro che ci siano indici su ogni colonna di riferimento. Gli aggiornamenti\/cancellazioni a cascata possono bloccare pi\u00f9 tabelle in una transazione e favorire cos\u00ec i deadlock. Definisco un ordine di accesso fisso su tutte le tabelle interessate e mantengo le modifiche di piccole dimensioni. Laddove le cascate sono rare dal punto di vista tecnico, valuto delle alternative: passaggi espliciti e brevi con chiare condizioni WHERE, per mantenere prevedibile la durata del blocco.<\/p>\n\n<h2>Autoincremento, hotspot e inserimenti in blocco<\/h2>\n<p>Le chiavi primarie con crescita monotona generano un punto di congestione alla fine dell'indice clusterizzato. Molti inserti paralleli si incontrano in quel punto, aumentando i tempi di attesa. Distribuisco le chiavi (ad es. tramite chiavi di partizione o ID entit\u00e0 anteposti) oppure utilizzo batch di dimensioni ridotte che vengono sottoposti a commit in modo pulito. Controllo il comportamento dell'autoincremento tramite la modalit\u00e0 di blocco: per l'OLTP preferisco impostazioni che consentono inserimenti paralleli e bloccano solo per brevi periodi. In caso di batch di grandi dimensioni, verifico se un percorso simile a COPY o piccoli sottoinsiemi ripetibili siano pi\u00f9 veloci. Resta importante: creare gli indici solo dopo operazioni di caricamento di grandi dimensioni o alleggerire gli indici secondari durante tali operazioni, al fine di ridurre gli hotspot di inserimento.<\/p>\n\n<h2>Replica e letture coerenti<\/h2>\n<p>Quando leggo dai replica, tengo conto dei ritardi: altrimenti un report potrebbe visualizzare dati non aggiornati. Per ottenere snapshot coerenti, avvio le transazioni intenzionalmente con WITH CONSISTENT SNAPSHOT e imposto READ ONLY se si esegue solo la lettura. In questo modo mantengo una visione stabile su pi\u00f9 istruzioni, senza blocchi inutili. Allo stesso tempo, mi assicuro che l'applicazione disponga di percorsi tolleranti in caso di ritardi di replica o, se necessario, che passi al server primario quando l'aggiornamento in tempo reale \u00e8 fondamentale. Questo riduce le sorprese e spiega le apparenti \u201eanomalie\u201c, che in realt\u00e0 sono solo latenze di replica.<\/p>\n\n<h2>Configurazione e strategie di riprova<\/h2>\n<p>Regolo in modo oculato i tempi di attesa dei blocchi e il loro rilevamento: un valore moderato di innodb_lock_wait_timeout impedisce che le sessioni rimangano bloccate per minuti interi. Rilevo i deadlock in modo proattivo e li distinguo chiaramente: recupero rapidamente l'errore 1213 (deadlock) con backoff e jitter; considero l'errore 1205 (timeout di attesa del blocco) come un segnale per ottimizzare il percorso della query. innodb_deadlock_detect \u00e8 utile in presenza di molte transazioni brevi; in caso di parallelismo estremamente elevato, il suo rapporto costi-benefici pu\u00f2 ribaltarsi: in tal caso, l'equalizzazione degli hotspot \u00e8 quasi sempre la soluzione migliore rispetto alla semplice regolazione dei parametri.<\/p>\n<p>I tentativi di ripetizione sono sicuri solo se le operazioni sono idempotenti. Progetto i percorsi di aggiornamento in modo tale che un tentativo di ripetizione raggiunga lo stesso stato finale (ad esempio con colonne di versione, insiemi deterministici anzich\u00e9 incrementi o eventi aziendali chiari). In questo modo evito doppie registrazioni e mantengo il codice robusto contro i conflitti inevitabili.<\/p>\n\n<h2>Esempi: batch senza blocchi estesi<\/h2>\n<p>Suddivido le modifiche di grandi dimensioni in piccole parti supportate dall'indice, in base alla chiave primaria:<\/p>\n<pre><code>-- Esempio: eliminazione in batch\nSET @last_id = 0;\nWHILE 1 DO\n  DELETE FROM events\n  WHERE id &gt; @last_id\n  ORDER BY id\n  LIMIT 1000;\n  SET @rows = ROW_COUNT();\n  IF @rows = 0 THEN LEAVE; END IF;\n  SET @last_id = (SELECT MAX(id) FROM events WHERE id &lt;= @last_id + 1000);\nEND WHILE;<\/code><\/pre>\n<p>Questo modello mantiene brevi le transazioni, riduce i tempi di blocco e lascia spazio ad altri carichi di lavoro. Adotto un approccio simile anche per gli aggiornamenti di massa: seleziono prima gli ID di destinazione in un insieme temporaneo (o tramite una finestra LIMIT), poi eseguo la scrittura in modo mirato e confermo rapidamente.<\/p>\n\n<h2>Guida rapida alla diagnosi<\/h2>\n<p>Quando i tempi di attesa si allungano, procedo seguendo un ordine prestabilito:<\/p>\n<ol>\n  <li>Individuare il sintomo: quali tabelle, quali istruzioni, a che ora?<\/li>\n  <li>Rendere visibili le code di attesa: individuare i data_locks\/data_lock_waits e i PID bloccanti in Performance Schema; verificare inoltre lo stato attuale di InnoDB.<\/li>\n  <li>Verifica del piano di esecuzione: la query utilizza l'indice previsto? I predicati sono raggruppabili?<\/li>\n  <li>Ridurre l'ambito dei blocchi: specificare meglio le condizioni WHERE, aggiungere indici, evitare le scansioni di intervallo, restringere le letture con blocco.<\/li>\n  <li>Ridurre la durata della transazione: eliminare le interazioni e le chiamate esterne dalla transazione, ridurre i set di risultati.<\/li>\n  <li>Ripetere e misurare: dopo aver apportato le modifiche, osservare nuovamente i tempi di picco e confrontarli.<\/li>\n<\/ol>\n<p>Questo approccio evita di agire alla cieca. Anzich\u00e9 aumentare i timeout, elimino le cause alla radice: \u00e8 una soluzione pi\u00f9 sostenibile e, nella maggior parte dei casi, pi\u00f9 rapida.<\/p>\n\n<h2>Come evitare le insidie operative<\/h2>\n<p>Ci sono tre aspetti a cui presto particolare attenzione durante l'esecuzione: in primo luogo, evito di disattivare per sbaglio l'autocommit a livello globale, poich\u00e9 ci\u00f2 prolunga i blocchi senza che me ne accorga. In secondo luogo, impedisco ai pool di connessioni di trasmettere transazioni che mantengono gi\u00e0 dei blocchi aperti. In terzo luogo, utilizzo i savepoint in modo mirato per i rollback parziali, ma non mi aspetto che riducano i tempi di blocco: il blocco rimane attivo fino al commit o al rollback. Una chiara disciplina a livello di applicazione si traduce qui direttamente in tempi di attesa pi\u00f9 brevi.<\/p>\n\n<h2>In breve: i punti chiave<\/h2>\n<p>Il row locking garantisce la coerenza dei dati, ma solo se abbinato a <strong>MVCC<\/strong>, con un livello di isolamento adeguato e una struttura degli indici ben progettata, mostra tutta la sua efficacia. Mantengo le transazioni brevi, applico filtri mirati e utilizzo FOR UPDATE solo nei casi in cui la prenotazione sia effettivamente necessaria dal punto di vista funzionale. Riduco i conflitti attraverso sequenze di accesso coerenti e chiari tentativi di riprova in caso di deadlock. Scelgo i livelli di isolamento in base al caso d'uso e osservo l'impatto dei blocchi Gap e Next-Key. Chi procede con misurazioni e ottimizza regolarmente raggiunge un elevato <strong>Concorrenza<\/strong> senza sorprese.<\/p>\n<p>Alla fine contano tre cose: oggetti di blocco di piccole dimensioni, tempi di permanenza brevi e percorsi di interrogazione tracciabili. Seguendo questi principi, i carichi di lavoro MySQL funzionano in modo affidabile, anche quando sono attivi molti utenti contemporaneamente. Punto su test ripetibili, metriche significative e ottimizzazioni mirate invece che su grandi ristrutturazioni. In questo modo i dati rimangono corretti, i tempi di risposta bassi e i deadlock rari. \u00c8 esattamente ci\u00f2 che ogni team si aspetta da un sistema reattivo <strong>Banca dati<\/strong>.<\/p>","protected":false},"excerpt":{"rendered":"<p>Scoprite come funziona il Row Locking del database e come ottimizzare la concorrenza di MySQL. Evitate il blocco delle transazioni e i deadlock con consigli pratici.<\/p>","protected":false},"author":1,"featured_media":19902,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[781],"tags":[],"class_list":["post-19909","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-datenbanken-administration-anleitungen"],"acf":[],"_wp_attached_file":null,"_wp_attachment_metadata":null,"litespeed-optimize-size":null,"litespeed-optimize-set":null,"_elementor_source_image_hash":null,"_wp_attachment_image_alt":null,"stockpack_author_name":null,"stockpack_author_url":null,"stockpack_provider":null,"stockpack_image_url":null,"stockpack_license":null,"stockpack_license_url":null,"stockpack_modification":null,"color":null,"original_id":null,"original_url":null,"original_link":null,"unsplash_location":null,"unsplash_sponsor":null,"unsplash_exif":null,"unsplash_attachment_metadata":null,"_elementor_is_screenshot":null,"surfer_file_name":null,"surfer_file_original_url":null,"envato_tk_source_kit":null,"envato_tk_source_index":null,"envato_tk_manifest":null,"envato_tk_folder_name":null,"envato_tk_builder":null,"envato_elements_download_event":null,"_menu_item_type":null,"_menu_item_menu_item_parent":null,"_menu_item_object_id":null,"_menu_item_object":null,"_menu_item_target":null,"_menu_item_classes":null,"_menu_item_xfn":null,"_menu_item_url":null,"_trp_menu_languages":null,"rank_math_primary_category":null,"rank_math_title":null,"inline_featured_image":null,"_yoast_wpseo_primary_category":null,"rank_math_schema_blogposting":null,"rank_math_schema_videoobject":null,"_oembed_049c719bc4a9f89deaead66a7da9fddc":null,"_oembed_time_049c719bc4a9f89deaead66a7da9fddc":null,"_yoast_wpseo_focuskw":null,"_yoast_wpseo_linkdex":null,"_oembed_27e3473bf8bec795fbeb3a9d38489348":null,"_oembed_c3b0f6959478faf92a1f343d8f96b19e":null,"_trp_translated_slug_en_us":null,"_wp_desired_post_slug":null,"_yoast_wpseo_title":null,"tldname":null,"tldpreis":null,"tldrubrik":null,"tldpolicylink":null,"tldsize":null,"tldregistrierungsdauer":null,"tldtransfer":null,"tldwhoisprivacy":null,"tldregistrarchange":null,"tldregistrantchange":null,"tldwhoisupdate":null,"tldnameserverupdate":null,"tlddeletesofort":null,"tlddeleteexpire":null,"tldumlaute":null,"tldrestore":null,"tldsubcategory":null,"tldbildname":null,"tldbildurl":null,"tldclean":null,"tldcategory":null,"tldpolicy":null,"tldbesonderheiten":null,"tld_bedeutung":null,"_oembed_d167040d816d8f94c072940c8009f5f8":null,"_oembed_b0a0fa59ef14f8870da2c63f2027d064":null,"_oembed_4792fa4dfb2a8f09ab950a73b7f313ba":null,"_oembed_33ceb1fe54a8ab775d9410abf699878d":null,"_oembed_fd7014d14d919b45ec004937c0db9335":null,"_oembed_21a029d076783ec3e8042698c351bd7e":null,"_oembed_be5ea8a0c7b18e658f08cc571a909452":null,"_oembed_a9ca7a298b19f9b48ec5914e010294d2":null,"_oembed_f8db6b27d08a2bb1f920e7647808899a":null,"_oembed_168ebde5096e77d8a89326519af9e022":null,"_oembed_cdb76f1b345b42743edfe25481b6f98f":null,"_oembed_87b0613611ae54e86e8864265404b0a1":null,"_oembed_27aa0e5cf3f1bb4bc416a4641a5ac273":null,"_oembed_time_27aa0e5cf3f1bb4bc416a4641a5ac273":null,"_tldname":null,"_tldclean":null,"_tldpreis":null,"_tldcategory":null,"_tldsubcategory":null,"_tldpolicy":null,"_tldpolicylink":null,"_tldsize":null,"_tldregistrierungsdauer":null,"_tldtransfer":null,"_tldwhoisprivacy":null,"_tldregistrarchange":null,"_tldregistrantchange":null,"_tldwhoisupdate":null,"_tldnameserverupdate":null,"_tlddeletesofort":null,"_tlddeleteexpire":null,"_tldumlaute":null,"_tldrestore":null,"_tldbildname":null,"_tldbildurl":null,"_tld_bedeutung":null,"_tldbesonderheiten":null,"_oembed_ad96e4112edb9f8ffa35731d4098bc6b":null,"_oembed_8357e2b8a2575c74ed5978f262a10126":null,"_oembed_3d5fea5103dd0d22ec5d6a33eff7f863":null,"_eael_widget_elements":null,"_oembed_0d8a206f09633e3d62b95a15a4dd0487":null,"_oembed_time_0d8a206f09633e3d62b95a15a4dd0487":null,"_aioseo_description":null,"_eb_attr":null,"_eb_data_table":null,"_oembed_819a879e7da16dd629cfd15a97334c8a":null,"_oembed_time_819a879e7da16dd629cfd15a97334c8a":null,"_acf_changed":null,"_wpcode_auto_insert":null,"_edit_last":null,"_edit_lock":null,"_oembed_e7b913c6c84084ed9702cb4feb012ddd":null,"_oembed_bfde9e10f59a17b85fc8917fa7edf782":null,"_oembed_time_bfde9e10f59a17b85fc8917fa7edf782":null,"_oembed_03514b67990db061d7c4672de26dc514":null,"_oembed_time_03514b67990db061d7c4672de26dc514":null,"rank_math_news_sitemap_robots":null,"rank_math_robots":null,"_eael_post_view_count":"363","_trp_automatically_translated_slug_ru_ru":null,"_trp_automatically_translated_slug_et":null,"_trp_automatically_translated_slug_lv":null,"_trp_automatically_translated_slug_fr_fr":null,"_trp_automatically_translated_slug_en_us":null,"_wp_old_slug":null,"_trp_automatically_translated_slug_da_dk":null,"_trp_automatically_translated_slug_pl_pl":null,"_trp_automatically_translated_slug_es_es":null,"_trp_automatically_translated_slug_hu_hu":null,"_trp_automatically_translated_slug_fi":null,"_trp_automatically_translated_slug_ja":null,"_trp_automatically_translated_slug_lt_lt":null,"_elementor_edit_mode":null,"_elementor_template_type":null,"_elementor_version":null,"_elementor_pro_version":null,"_wp_page_template":null,"_elementor_page_settings":null,"_elementor_data":null,"_elementor_css":null,"_elementor_conditions":null,"_happyaddons_elements_cache":null,"_oembed_75446120c39305f0da0ccd147f6de9cb":null,"_oembed_time_75446120c39305f0da0ccd147f6de9cb":null,"_oembed_3efb2c3e76a18143e7207993a2a6939a":null,"_oembed_time_3efb2c3e76a18143e7207993a2a6939a":null,"_oembed_59808117857ddf57e478a31d79f76e4d":null,"_oembed_time_59808117857ddf57e478a31d79f76e4d":null,"_oembed_965c5b49aa8d22ce37dfb3bde0268600":null,"_oembed_time_965c5b49aa8d22ce37dfb3bde0268600":null,"_oembed_81002f7ee3604f645db4ebcfd1912acf":null,"_oembed_time_81002f7ee3604f645db4ebcfd1912acf":null,"_elementor_screenshot":null,"_oembed_7ea3429961cf98fa85da9747683af827":null,"_oembed_time_7ea3429961cf98fa85da9747683af827":null,"_elementor_controls_usage":null,"_elementor_page_assets":null,"_elementor_screenshot_failed":null,"theplus_transient_widgets":null,"_eael_custom_js":null,"_wp_old_date":null,"_trp_automatically_translated_slug_it_it":null,"_trp_automatically_translated_slug_pt_pt":null,"_trp_automatically_translated_slug_zh_cn":null,"_trp_automatically_translated_slug_nl_nl":null,"_trp_automatically_translated_slug_pt_br":null,"_trp_automatically_translated_slug_sv_se":null,"rank_math_analytic_object_id":null,"rank_math_internal_links_processed":"1","_trp_automatically_translated_slug_ro_ro":null,"_trp_automatically_translated_slug_sk_sk":null,"_trp_automatically_translated_slug_bg_bg":null,"_trp_automatically_translated_slug_sl_si":null,"litespeed_vpi_list":null,"litespeed_vpi_list_mobile":null,"rank_math_seo_score":null,"rank_math_contentai_score":null,"ilj_limitincominglinks":null,"ilj_maxincominglinks":null,"ilj_limitoutgoinglinks":null,"ilj_maxoutgoinglinks":null,"ilj_limitlinksperparagraph":null,"ilj_linksperparagraph":null,"ilj_blacklistdefinition":null,"ilj_linkdefinition":null,"_eb_reusable_block_ids":null,"rank_math_focus_keyword":"Database Row","rank_math_og_content_image":null,"_yoast_wpseo_metadesc":null,"_yoast_wpseo_content_score":null,"_yoast_wpseo_focuskeywords":null,"_yoast_wpseo_keywordsynonyms":null,"_yoast_wpseo_estimated-reading-time-minutes":null,"rank_math_description":null,"surfer_last_post_update":null,"surfer_last_post_update_direction":null,"surfer_keywords":null,"surfer_location":null,"surfer_draft_id":null,"surfer_permalink_hash":null,"surfer_scrape_ready":null,"_thumbnail_id":"19902","footnotes":null,"_links":{"self":[{"href":"https:\/\/webhosting.de\/it\/wp-json\/wp\/v2\/posts\/19909","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/webhosting.de\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/webhosting.de\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/webhosting.de\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/webhosting.de\/it\/wp-json\/wp\/v2\/comments?post=19909"}],"version-history":[{"count":0,"href":"https:\/\/webhosting.de\/it\/wp-json\/wp\/v2\/posts\/19909\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/webhosting.de\/it\/wp-json\/wp\/v2\/media\/19902"}],"wp:attachment":[{"href":"https:\/\/webhosting.de\/it\/wp-json\/wp\/v2\/media?parent=19909"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/webhosting.de\/it\/wp-json\/wp\/v2\/categories?post=19909"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/webhosting.de\/it\/wp-json\/wp\/v2\/tags?post=19909"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}