Ich führe einen Bericht in MySQL aus. Bei einer der Abfragen wird eine große Anzahl von Zeilen in eine temporäre Tabelle eingefügt. Wenn ich versuche, es auszuführen, wird folgende Fehlermeldung angezeigt:
Fehlercode 1206: Die Anzahl der Sperren überschreitet die Größe der Sperrtabelle.
Die fraglichen Fragen sind:
create temporary table SkusBought(
customerNum int(11),
sku int(11),
typedesc char(25),
key `customerNum` (customerNum)
)ENGINE=InnoDB DEFAULT CHARSET=latin1;
insert into skusBought
select t1.* from
(select customer, sku, typedesc from transactiondatatransit
where (cat = 150 or cat = 151)
AND daysfrom07jan1 > 731
group by customer, sku
union
select customer, sku, typedesc from transactiondatadelaware
where (cat = 150 or cat = 151)
AND daysfrom07jan1 > 731
group by customer, sku
union
select customer, sku, typedesc from transactiondataprestige
where (cat = 150 or cat = 151)
AND daysfrom07jan1 > 731
group by customer, sku) t1
join
(select customernum from topThreetransit group by customernum) t2
on t1.customer = t2.customernum;
Ich habe gelesen, dass das Ändern der Konfigurationsdatei zum Erhöhen der Pufferpoolgröße hilfreich ist, aber das bringt nichts. Wie kann dies behoben werden, entweder als vorübergehende Problemumgehung oder als dauerhafte Lösung?
BEARBEITEN: Teil der Abfrage geändert. Sollte es nicht beeinflussen, aber ich habe alles gefunden und ersetzt und nicht bemerkt, dass es das vermasselt hat. Betrifft die Frage nicht.
EDIT 2: Typedesc zu t1 hinzugefügt. Ich habe es in der Abfrage geändert, aber nicht hier.
Antworten:
Dieses Problem kann behoben werden, indem die höheren Werte für die MySQL-Variable festgelegt werden
innodb_buffer_pool_size
. Der Standardwert fürinnodb_buffer_pool_size
ist8,388,608
.Informationen zum Ändern des Einstellungswerts für finden
innodb_buffer_pool_size
Sie im folgenden Satz.my.cnf
vom Server. Bei Linux-Servern ist dies meistens der Fall/etc/my.cnf
innodb_buffer_pool_size=64MB
zu dieser Datei hinzuUm den MySQL-Server neu zu starten, können Sie eine der folgenden 2 Optionen verwenden:
Referenz Die Gesamtzahl der Sperren überschreitet die Größe der Sperrtabelle
quelle
SET GLOBAL innodb_buffer_pool_size=268435456;
ohne die Datei my.cnf zu durchsuchen und mysql neu zu starten. stackoverflow.com/a/38333056/3553564Ich habe einen anderen Weg gefunden, um es zu lösen - benutze Table Lock. Sicher, es kann für Ihre Anwendung ungeeignet sein - wenn Sie die Tabelle gleichzeitig aktualisieren müssen.
Siehe: Versuchen Sie
LOCK TABLES
, die gesamte Tabelle anstelle der Standardaktion der MVCC-Sperre auf Zeilenebene von InnoDB zu sperren. Wenn ich mich nicht irre, bezieht sich die "Sperrtabelle" auf die interne InnoDB-Struktur, in der Zeilen- und Versionskennungen für die MVCC-Implementierung gespeichert sind, wobei ein Bit, das die Zeile identifiziert, in einer Anweisung geändert wird, und eine Tabelle mit 60 Millionen Zeilen. überschreitet wahrscheinlich den ihm zugewiesenen Speicher. DerLOCK TABLES
Befehl sollte dieses Problem beheben, indem anstelle einer Zeilenebene eine Sperre auf Tabellenebene festgelegt wird:SET @@AUTOCOMMIT=0; LOCK TABLES avgvol WRITE, volume READ; INSERT INTO avgvol(date,vol) SELECT date,avg(vol) FROM volume GROUP BY date; UNLOCK TABLES;
Jay Pipes, Community Relations Manager, Nordamerika, MySQL Inc.
quelle
Aus der MySQL-Dokumentation (die Sie bereits gelesen haben, wie ich sehe):
Wenn das Erhöhen von innodb_buffer_pool_size nicht hilft, folgen Sie einfach den Angaben auf dem fettgedruckten Teil und teilen Sie Ihren INSERT in 3 auf. Überspringen Sie die UNIONs und erstellen Sie 3 INSERTs mit jeweils einem JOIN zur topThreetransit- Tabelle.
quelle
Zunächst können Sie den Befehl sql verwenden
show global variables like 'innodb_buffer%';
, um die Puffergröße zu überprüfen.Lösung ist Ihre
my.cnf
Datei zu finden und hinzuzufügen,NICHT vergessen hinzuzufügen
[mysqld]
, sonst wird es nicht funktionieren.In meinem Fall ubuntu 16.04 ,
my.cnf
wird unter dem Ordner befindet/etc/mysql/
.quelle
Ich führe MySQL Windows mit MySQL Workbench aus. Gehen Sie zu Server> Serverstatus. Oben steht die Konfigurationsdatei: "path" (
C:\ProgramData\MySQL\...\my.ini
)Dann drücken Sie in der Datei "my.ini" Strg + F und suchen
buffer_pool_size
. Stellen Sie den Wert höher ein, ich würde 64 MB empfehlen (Standard ist 8 MB).Starten Sie den Server neu, indem Sie zu Instanz> Start / Herunterfahren> Server stoppen gehen (und den Server später erneut starten).
In meinem Fall konnte ich keine Einträge aus meiner Tabelle löschen.
quelle
Wenn Sie Ihre Tabellen so strukturiert haben, dass jede relativ eindeutige Werte enthält, besteht die weniger intensive Methode darin, drei separate Insert-In-Anweisungen auszuführen, eine für jede Tabelle, wobei der Join-Filter für jede Einfügung vorhanden ist.
INSERT INTO SkusBought... SELECT t1.customer, t1.SKU, t1.TypeDesc FROM transactiondatatransit AS T1 LEFT OUTER JOIN topThreetransit AS T2 ON t1.customer = t2.customernum WHERE T2.customernum IS NOT NULL
Wiederholen Sie diesen Vorgang für die beiden anderen Tabellen. Kopieren / Einfügen ist eine gute Methode. Ändern Sie einfach den Namen der FROM-Tabelle. ** Wenn Sie versuchen, doppelte Einträge in Ihrer SkusBought-Tabelle zu verhindern, können Sie vor der WHERE-Klausel in jedem Abschnitt den folgenden Join-Code hinzufügen.
-und dann die letzte Zeile der WHERE-Klausel-
Ihr anfänglicher Code verwendet eine Reihe von Unterabfragen, und die UNION-Anweisung kann teuer sein, da sie zuerst eine eigene temporäre Tabelle erstellt, um die Daten aus den drei separaten Quellen zu füllen, bevor sie in die gewünschte Tabelle eingefügt wird, während eine andere Unterabfrage ausgeführt wird Abfrage zum Filtern der Ergebnisse.
quelle
in Windows: Wenn Sie MySQL Workbench haben. Wechseln Sie zum Serverstatus. Finden Sie den Speicherort der laufenden Serverdatei in meinem Fall:
Öffnen Sie die Datei my.ini und suchen Sie die buffer_pool_size. Stellen Sie den Wert hoch ein. Der Standardwert ist 8M. So habe ich dieses Problem behoben
quelle
Behebung des Fehlercodes 1206: Die Anzahl der Sperren überschreitet die Größe der Sperrtabelle.
In meinem Fall arbeite ich mit MySQL Workbench (5.6.17), das unter Windows mit WampServer 2.5 ausgeführt wird.
Für Windows / WampServer müssen Sie die Datei my.ini bearbeiten (nicht die Datei my.cnf).
Um diese Datei zu finden, gehen Sie zu Menü Server / Server Status (in MySQL Workbench) und suchen Sie unter Serververzeichnisse / Basisverzeichnis
In der Datei my.ini sind Abschnitte für verschiedene Einstellungen definiert. Suchen Sie nach Abschnitt [mysqld] (erstellen Sie ihn, falls er nicht vorhanden ist) und fügen Sie den folgenden Befehl hinzu: innodb_buffer_pool_size = 4G
[mysqld]
innodb_buffer_pool_size = 4G
Die Größe der Datei buffer_pool hängt von Ihrem Computer ab. In den meisten Fällen wird das Problem durch 2G oder 4G behoben.
Denken Sie daran, den Server neu zu starten, damit die neue Konfiguration übernommen wird. Das Problem wurde für mich behoben.
Ich hoffe es hilft!
quelle
Es ist erwähnenswert, dass die für diese Einstellung verwendete Zahl in BYTES angegeben ist - das haben wir auf die harte Tour herausgefunden!
quelle
Diese Antwort unten beantwortet die Frage des OP nicht direkt. Ich füge diese Antwort hier hinzu, da diese Seite das erste Ergebnis ist, wenn Sie Google "Die Gesamtzahl der Sperren überschreitet die Größe der Sperrtabelle".
Wenn die von Ihnen ausgeführte Abfrage eine gesamte Tabelle analysiert, die Millionen von Zeilen umfasst, können Sie eine while-Schleife versuchen, anstatt die Grenzwerte in der Konfiguration zu ändern.
Der while-Look wird es in Stücke zerbrechen. Unten sehen Sie ein Beispiel für eine Schleife über eine indizierte Spalte mit dem Namen DATETIME.
# Drop DROP TABLE IF EXISTS new_table; # Create (we will add keys later) CREATE TABLE new_table ( num INT(11), row_id VARCHAR(255), row_value VARCHAR(255), row_date DATETIME ); # Change the delimimter DELIMITER // # Create procedure CREATE PROCEDURE do_repeat(IN current_loop_date DATETIME) BEGIN # Loops WEEK by WEEK until NOW(). Change WEEK to something shorter like DAY if you still get the lock errors like. WHILE current_loop_date <= NOW() DO # Do something INSERT INTO user_behavior_search_tagged_keyword_statistics_with_type ( num, row_id, row_value, row_date ) SELECT # Do something interesting here num, row_id, row_value, row_date FROM old_table WHERE row_date >= current_loop_date AND row_date < current_loop_date + INTERVAL 1 WEEK; # Increment SET current_loop_date = current_loop_date + INTERVAL 1 WEEK; END WHILE; END// # Run CALL do_repeat('2017-01-01'); # Cleanup DROP PROCEDURE IF EXISTS do_repeat// # Change the delimimter back DELIMITER ; # Add keys ALTER TABLE new_table MODIFY COLUMN num int(11) NOT NULL, ADD PRIMARY KEY (num), ADD KEY row_id (row_id) USING BTREE, ADD KEY row_date (row_date) USING BTREE;
Sie können es auch so anpassen, dass es die Spalte "num" durchläuft, wenn Ihre Tabelle kein Datum verwendet.
Hoffe das hilft jemandem!
quelle
Gleiches Problem, das ich beim Ausführen des SQL-Skripts in meinem MYSQL bekomme. Sehen Sie sich das folgende Bild an. Fehlercode 1206: Die Anzahl der Sperren überschreitet die Größe der Sperrtabelle
Dies ist ein MySQL-Konfigurationsproblem, daher habe ich einige Änderungen vorgenommen
my.ini
und es funktioniert auf meinem System und das Problem wurde behoben.Wir müssen einige Änderungen vornehmen,
my.ini
die unter folgendem Pfad verfügbar sind : -C:\ProgramData\MySQL\MySQL Server 5.7\my.ini
und bitte aktualisieren Sie die folgenden Änderungen in denmy.ini
Feldern der Konfigurationsdatei: -Nach allen oben genannten Änderungen starten Sie bitte den MYSQL-Dienst neu . Bitte beziehen Sie sich auf das Bild: - Microsoft MYSQL Service Picture
quelle