Die direkte Antwort auf den Titel Ihrer Frage lautet Nein.
SELECT-Abfragen können Sperren für den gen_clust_index ausführen , auch bekannt als Clustered Index.
Hier sind drei Fragen zum DBA- Stapelaustausch , die ich mit @RedBlueThing , der Person, die diese Fragen gestellt hat, aggressiv durchgesehen habe . @RedBlueThing hat Workarounds für seine Fragen gefunden.
Nur um Ihre Frage im Blick zu behalten: Wenn Sie sich diese Antworten ansehen (schauen Sie nicht zu tief, auch wenn mir meine eigenen verschlungenen Antworten schwindelig werden), sollte schnell klar sein, dass SELECT-Abfragen Daten sperren können.
Sie haben auch spezielle Fälle von SELECT, in denen Sie bestimmte Zeilen bei Bedarf sperren können .
UPDATE 2011-08-08 16:49 EDT
Sie haben die Variationsfrage gestellt: "Werden InnoDB-Deadlock-Ausnahmen möglicherweise von SELECT ausgelöst?" Die Antwort darauf kann unter bestimmten Bedingungen Ja sein. Was ist das für ein Zustand? Wenn nur eine einzelne SQL-Anweisung aufgrund eines Fehlers zurückgesetzt wird, bleiben möglicherweise einige der von der Anweisung festgelegten Sperren erhalten. Dies liegt daran, dass InnoDB Zeilensperren in einem Format speichert, dass es nicht wissen kann, welche Sperre von welcher Anweisung gesetzt wurde .
Basierend auf dieser Aussage könnten die Ereignissequenzen, die dies verursachen, theoretisch wie folgt sein:
- Ihr SQL-UPDATE erstellt eine einzelne Zeile, generiert jedoch einen Fehler
- Das UPDATE bewirkt ein Rollback der einen Zeile
- Die Reihe hat ein verweilendes Schloss
Persönlich macht mir diese letzte Aussage Angst. Es wäre schön für MySQL gewesen, alle über diese Eigenart zu informieren. Diese Aussage stammt jedoch aus der MySQL-Dokumentation. (Oh ja, Oracle besitzt InnoDB)
UPDATE 2015-09-22 18:40 EST
Anfang des Jahres erfuhr ich, dass Percona einen coolen Nagios-Check hat , um diese lästigen Schlösser zu finden, die sich hinter schlafenden Verbindungen verstecken. Jetzt müssen Sie nur noch den Code über diesen Link ausführen:
SELECT COALESCE(MAX(IF(p.command = 'Sleep', p.time, 0)), 0) AS idle_in_trx
FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS AS w
INNER JOIN INFORMATION_SCHEMA.INNODB_TRX AS b ON b.trx_id = w.blocking_trx_id
INNER JOIN INFORMATION_SCHEMA.INNODB_TRX AS r ON r.trx_id = w.requesting_trx_id
LEFT JOIN INFORMATION_SCHEMA.PROCESSLIST AS p ON p.id = b.trx_mysql_thread_id;
Dies funktioniert nur für MySQL 5.5+. Wenn Sie MySQL 5.1 oder eine frühere Version haben, müssen Sie alle schlafenden Verbindungen beenden, um die Sperren aufzuheben.