Visualizzazione dei risultati da 1 a 2 su 2

Discussione: deadlock con innodb

  1. #1

    deadlock con innodb

    Salve a tutti,
    Ho un problemino che mi sta facendo impazzire riguardo una tabella sessioni di un forum.

    Ho da poco convertito tutto il database a InnoDB (del quale premetto di non conoscere molto) per un passaggio ad un sistema multi-server basato su galera (un plug-in wsrep che sincronizza le tabelle su più server)

    Il mio grosso problema ora è che su un singolo server ho ogni 2-3 secondi un errore mysql sulla tabella delle sessioni di questo tipo:
    Error Number: 1213
    Error: Deadlock found when trying to get lock; try restarting transaction
    Sulla tabella vengono effettuate le seguenti operazioni principalmente:
    -La prima volta che un utente arriva e non ha un cookie (o tramite get) un codice di sessione, gli viene creato e inserito nel database
    -->Durante la creazione viene eseguita una query delete che cancella le precedenti sessioni dell'utente in base al suo id di membro se è un utente registrato o tramite ip
    -Ogni pagina che l'utente ricarica, a fine esecuzione dello script viene aggiornata la sessione con una query update
    -Ogni ora vengono cancellate tutte le sessioni più vecchie di 1 ora

    A parte i continui errori deadlock sulle query insert e update, quando viene eseguita la query di cancellazione delle vecchie sessioni, a volte si inchioda tutto per diversi minuti (una volta per 15 minuti, poi ho killato io la query)

    A questo punto mi serve riuscire a risolvere questa situazione perché crea veramente tanti problemi (oltre ad un log errori mysql abbastanza considerabile...)

    Leggendo un po a proposito del deadlock ho letto le seguenti informazioni:
    -Si verifica se due query fanno una richiesta su due campi diversi bloccandoli in modo incrociato (le due query si trovano quindi ad aspettare che venga sbloccato il campo che attendono, ma questo non avviene)
    -Si verifica quando è in esecuzione una query delete che và a bloccare un campo, e quindi le query insert e update non posso usarlo (confesso di non aver capito molto questo caso...)

    Il primo caso non dovrebbe centrare con me dato che le query che eseguo usano un solo campo nel where (o l'id della sessione, o lo unixtime salvato come integer oppure l'id dell'utente) e mai più di uno incrociato.

    Il secondo caso potrebbe essere, perchè ci sono più query che usano il campo id della sessioni e magari una blocca il campo e le altre quindi danno errore.

    Mi serve quindi sapere come procedere perché ho letto un po di cose in giro ma non sò quanto giovamento possano darmi e se risolverebbero il problema, e prima ci complicare ulteriormente le query che ho, vorrei essere sicuro di stare capendo il problema che ho. (esempio 1 e esempio 2 di informazioni che ho trovato)

    Riesco a risolvere in qualche modo con InnoDB? (non posso riportare la tabella a myisam)
    Mi consigliate se no qualche altra cosa che potrei usare per salvarmi queste informazioni, o qualche metodo? (Una cosa tipo usare sphinx per le ricerche fulltext)

    Grazie Mille per qualsiasi tipo di aiuto che riuscite a darmi.
    Ciauz Mix


    -------------------------------------------------------------------
    Di seguito un po di informazioni in più per cercare di capire meglio il problema:

    Server Mysql
    Versione del server: 5.5.17
    Versione protocollo: 10

    Struttura della tabella
    codice:
    CREATE TABLE IF NOT EXISTS `ibf_sessions` (
      `id` varchar(60) NOT NULL DEFAULT '0',
      `member_name` varchar(64) DEFAULT NULL,
      `member_id` mediumint(8) NOT NULL DEFAULT '0',
      `ip_address` varchar(16) DEFAULT NULL,
      `browser` varchar(200) NOT NULL DEFAULT '',
      `running_time` int(10) DEFAULT NULL,
      `login_type` char(3) DEFAULT '',
      `location` varchar(40) DEFAULT NULL,
      `member_group` smallint(3) DEFAULT NULL,
      `in_error` tinyint(1) NOT NULL DEFAULT '0',
      `location_1_type` varchar(10) NOT NULL DEFAULT '',
      `location_1_id` int(10) NOT NULL DEFAULT '0',
      `location_2_type` varchar(10) NOT NULL DEFAULT '',
      `location_2_id` int(10) NOT NULL DEFAULT '0',
      `location_3_type` varchar(10) NOT NULL DEFAULT '',
      `location_3_id` int(10) NOT NULL DEFAULT '0',
      `in_game` varchar(32) NOT NULL,
      PRIMARY KEY (`id`),
      KEY `location1` (`location_1_type`,`location_1_id`),
      KEY `location2` (`location_2_type`,`location_2_id`),
      KEY `location3` (`location_3_type`,`location_3_id`),
      KEY `running_time` (`running_time`),
      KEY `mem_id` (`member_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    Query di cancellazione a tempo
    codice:
    DELETE FROM ibf_sessions WHERE running_time < {$date}
    Query di cancellazione sessioni già esistenti
    codice:
    DELETE FROM ibf_sessions WHERE member_id={$id}
    Esempio di log di errore con query insert e update
    codice:
     Date: Wed, 11 Jan 2012 13:02:36 +0000
     Error Number: 1213
     Error: Deadlock found when trying to get lock; try restarting transaction
     mySQL query error: UPDATE ibf_sessions SET member_name='',member_id=0,member_group=2,login_type=0,running_time=1326286955,location='Post,0,02',in_error=0,location_1_type='',location_1_id=0,location_2_type='',location_2_id=0,location_3_type='',location_3_id=0 WHERE id='f8beb6ba9fa9f02df3faedaabe74f123'
    ===================================================
     Date: Wed, 11 Jan 2012 13:02:37 +0000
     Error Number: 1213
     Error: Deadlock found when trying to get lock; try restarting transaction
     mySQL query error: UPDATE ibf_sessions SET member_name='',member_id=0,member_group=2,login_type=0,running_time=1326286956,location='st',in_error=0,location_1_type='topic',location_1_id=94249,location_2_type='forum',location_2_id=8,location_3_type='',location_3_id=0 WHERE id='4453ea78a6296e92e76bb39599fe38a6'
    ===================================================
     Date: Wed, 11 Jan 2012 13:02:38 +0000
     Error Number: 1213
     Error: Deadlock found when trying to get lock; try restarting transaction
     mySQL query error: UPDATE ibf_sessions SET member_name='pick',member_id=193705,member_group=3,login_type=0,running_time=1326286958,location='st',in_error=0,location_1_type='topic',location_1_id=259942,location_2_type='forum',location_2_id=20,location_3_type='',location_3_id=0 WHERE id='f8f52cd4d89f818b86a8be38937d5bf8'
    ===================================================
     Date: Wed, 11 Jan 2012 13:02:37 +0000
     Error Number: 1213
     Error: Deadlock found when trying to get lock; try restarting transaction
     mySQL query error: INSERT INTO ibf_sessions (id,member_name,member_id,member_group,login_type,running_time,ip_address,browser,location,in_error,location_1_type,location_1_id,location_2_type,location_2_id,location_3_type,location_3_id) VALUES('f02777a5f843d746ecc3d8a9de953127','',0,2,0,1326286957,'xx.xx.xxx.xx','Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.26 Safari/535.11','home,0,',0,'',0,'',0,'',0)
    ===================================================
     Date: Wed, 11 Jan 2012 13:02:38 +0000
     Error Number: 1213
     Error: Deadlock found when trying to get lock; try restarting transaction
     mySQL query error: UPDATE ibf_sessions SET member_name='',member_id=0,member_group=2,login_type=0,running_time=1326286958,location='st',in_error=0,location_1_type='topic',location_1_id=94249,location_2_type='forum',location_2_id=8,location_3_type='',location_3_id=0 WHERE id='4453ea78a6296e92e76bb39599fe38a6'

    Errare e' umano, ma per fare veramente casino serve la password di root.
    Coltiva Linux........Tanto windows si impianta da solo!!!!!
    PHP 4 Ever

  2. #2
    Utente di HTML.it L'avatar di Joe Taras
    Registrato dal
    Nov 2003
    residenza
    Taranto
    Messaggi
    955

    Re: deadlock con innodb

    Originariamente inviato da Mix
    Salve a tutti,
    Ho un problemino che mi sta facendo impazzire riguardo una tabella sessioni di un forum.

    Ho da poco convertito tutto il database a InnoDB (del quale premetto di non conoscere molto) per un passaggio ad un sistema multi-server basato su galera (un plug-in wsrep che sincronizza le tabelle su più server)

    Il mio grosso problema ora è che su un singolo server ho ogni 2-3 secondi un errore mysql sulla tabella delle sessioni di questo tipo:


    Sulla tabella vengono effettuate le seguenti operazioni principalmente:
    -La prima volta che un utente arriva e non ha un cookie (o tramite get) un codice di sessione, gli viene creato e inserito nel database
    -->Durante la creazione viene eseguita una query delete che cancella le precedenti sessioni dell'utente in base al suo id di membro se è un utente registrato o tramite ip
    -Ogni pagina che l'utente ricarica, a fine esecuzione dello script viene aggiornata la sessione con una query update
    -Ogni ora vengono cancellate tutte le sessioni più vecchie di 1 ora

    A parte i continui errori deadlock sulle query insert e update, quando viene eseguita la query di cancellazione delle vecchie sessioni, a volte si inchioda tutto per diversi minuti (una volta per 15 minuti, poi ho killato io la query)

    A questo punto mi serve riuscire a risolvere questa situazione perché crea veramente tanti problemi (oltre ad un log errori mysql abbastanza considerabile...)

    Leggendo un po a proposito del deadlock ho letto le seguenti informazioni:
    -Si verifica se due query fanno una richiesta su due campi diversi bloccandoli in modo incrociato (le due query si trovano quindi ad aspettare che venga sbloccato il campo che attendono, ma questo non avviene)
    -Si verifica quando è in esecuzione una query delete che và a bloccare un campo, e quindi le query insert e update non posso usarlo (confesso di non aver capito molto questo caso...)

    Il primo caso non dovrebbe centrare con me dato che le query che eseguo usano un solo campo nel where (o l'id della sessione, o lo unixtime salvato come integer oppure l'id dell'utente) e mai più di uno incrociato.

    Il secondo caso potrebbe essere, perchè ci sono più query che usano il campo id della sessioni e magari una blocca il campo e le altre quindi danno errore.

    Mi serve quindi sapere come procedere perché ho letto un po di cose in giro ma non sò quanto giovamento possano darmi e se risolverebbero il problema, e prima ci complicare ulteriormente le query che ho, vorrei essere sicuro di stare capendo il problema che ho. (esempio 1 e esempio 2 di informazioni che ho trovato)

    Riesco a risolvere in qualche modo con InnoDB? (non posso riportare la tabella a myisam)
    Mi consigliate se no qualche altra cosa che potrei usare per salvarmi queste informazioni, o qualche metodo? (Una cosa tipo usare sphinx per le ricerche fulltext)

    Grazie Mille per qualsiasi tipo di aiuto che riuscite a darmi.
    Ciauz Mix


    -------------------------------------------------------------------
    Di seguito un po di informazioni in più per cercare di capire meglio il problema:

    Server Mysql
    Versione del server: 5.5.17
    Versione protocollo: 10

    Struttura della tabella
    codice:
    CREATE TABLE IF NOT EXISTS `ibf_sessions` (
      `id` varchar(60) NOT NULL DEFAULT '0',
      `member_name` varchar(64) DEFAULT NULL,
      `member_id` mediumint(8) NOT NULL DEFAULT '0',
      `ip_address` varchar(16) DEFAULT NULL,
      `browser` varchar(200) NOT NULL DEFAULT '',
      `running_time` int(10) DEFAULT NULL,
      `login_type` char(3) DEFAULT '',
      `location` varchar(40) DEFAULT NULL,
      `member_group` smallint(3) DEFAULT NULL,
      `in_error` tinyint(1) NOT NULL DEFAULT '0',
      `location_1_type` varchar(10) NOT NULL DEFAULT '',
      `location_1_id` int(10) NOT NULL DEFAULT '0',
      `location_2_type` varchar(10) NOT NULL DEFAULT '',
      `location_2_id` int(10) NOT NULL DEFAULT '0',
      `location_3_type` varchar(10) NOT NULL DEFAULT '',
      `location_3_id` int(10) NOT NULL DEFAULT '0',
      `in_game` varchar(32) NOT NULL,
      PRIMARY KEY (`id`),
      KEY `location1` (`location_1_type`,`location_1_id`),
      KEY `location2` (`location_2_type`,`location_2_id`),
      KEY `location3` (`location_3_type`,`location_3_id`),
      KEY `running_time` (`running_time`),
      KEY `mem_id` (`member_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    Query di cancellazione a tempo
    codice:
    DELETE FROM ibf_sessions WHERE running_time < {$date}
    Query di cancellazione sessioni già esistenti
    codice:
    DELETE FROM ibf_sessions WHERE member_id={$id}
    Esempio di log di errore con query insert e update
    codice:
     Date: Wed, 11 Jan 2012 13:02:36 +0000
     Error Number: 1213
     Error: Deadlock found when trying to get lock; try restarting transaction
     mySQL query error: UPDATE ibf_sessions SET member_name='',member_id=0,member_group=2,login_type=0,running_time=1326286955,location='Post,0,02',in_error=0,location_1_type='',location_1_id=0,location_2_type='',location_2_id=0,location_3_type='',location_3_id=0 WHERE id='f8beb6ba9fa9f02df3faedaabe74f123'
    ===================================================
     Date: Wed, 11 Jan 2012 13:02:37 +0000
     Error Number: 1213
     Error: Deadlock found when trying to get lock; try restarting transaction
     mySQL query error: UPDATE ibf_sessions SET member_name='',member_id=0,member_group=2,login_type=0,running_time=1326286956,location='st',in_error=0,location_1_type='topic',location_1_id=94249,location_2_type='forum',location_2_id=8,location_3_type='',location_3_id=0 WHERE id='4453ea78a6296e92e76bb39599fe38a6'
    ===================================================
     Date: Wed, 11 Jan 2012 13:02:38 +0000
     Error Number: 1213
     Error: Deadlock found when trying to get lock; try restarting transaction
     mySQL query error: UPDATE ibf_sessions SET member_name='pick',member_id=193705,member_group=3,login_type=0,running_time=1326286958,location='st',in_error=0,location_1_type='topic',location_1_id=259942,location_2_type='forum',location_2_id=20,location_3_type='',location_3_id=0 WHERE id='f8f52cd4d89f818b86a8be38937d5bf8'
    ===================================================
     Date: Wed, 11 Jan 2012 13:02:37 +0000
     Error Number: 1213
     Error: Deadlock found when trying to get lock; try restarting transaction
     mySQL query error: INSERT INTO ibf_sessions (id,member_name,member_id,member_group,login_type,running_time,ip_address,browser,location,in_error,location_1_type,location_1_id,location_2_type,location_2_id,location_3_type,location_3_id) VALUES('f02777a5f843d746ecc3d8a9de953127','',0,2,0,1326286957,'xx.xx.xxx.xx','Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.26 Safari/535.11','home,0,',0,'',0,'',0,'',0)
    ===================================================
     Date: Wed, 11 Jan 2012 13:02:38 +0000
     Error Number: 1213
     Error: Deadlock found when trying to get lock; try restarting transaction
     mySQL query error: UPDATE ibf_sessions SET member_name='',member_id=0,member_group=2,login_type=0,running_time=1326286958,location='st',in_error=0,location_1_type='topic',location_1_id=94249,location_2_type='forum',location_2_id=8,location_3_type='',location_3_id=0 WHERE id='4453ea78a6296e92e76bb39599fe38a6'
    Le delete lockano la tabella, così come le update, mentre le insert solo il record che stanno scrivendo.

    Se parte una delete prima di una insert quest'ultima dovrà attendere il completamento della delete per poter scrivere.

    Ti consiglio quindi 2 cose,
    1. Le delete non devono coinvolgere troppe righe (ad esempio la query sul tempo) perché lockano per molto tempo la tabella e quindi mandi in deadlock le query che vengono dopo
    2. Aumenta il tempo di time out delle query (è un parametro che trovi su MySql) in questo modo la query in coda prima di andare in deadlock attendenrà un tempo maggiore.

    Tra le 2 accortezze che devi prendere la 1. è quella più importante.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.