2016-07-05 8 views
0

Ich mache Batch-Operationen mit MySQL Cluster NDB: Einfügen von 10000 oder 5000 Zeilen und Entfernen in einer einzigen Transaktion. Legen Sie funktioniert gut, aber die Entfernung nicht mit einer Ausnahme:Zu viele gleichzeitig ausgelöste Trigger (erhöhen MaxNoOfFiredTriggers) von NDBCLUSTER

java.sql.SQLException: Got temporary error 221 'Too many concurrently fired triggers (increase MaxNoOfFiredTriggers)' from NDBCLUSTER 
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1086) ~[mysql-connector-java-5.1.29-bin.jar:na] 
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4237) ~[mysql-connector-java-5.1.29-bin.jar:na] 
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4169) ~[mysql-connector-java-5.1.29-bin.jar:na] 
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2617) ~[mysql-connector-java-5.1.29-bin.jar:na] 
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2778) ~[mysql-connector-java-5.1.29-bin.jar:na] 
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2828) ~[mysql-connector-java-5.1.29-bin.jar:na] 
at com.mysql.jdbc.ConnectionImpl.commit(ConnectionImpl.java:1748) ~[mysql-connector-java-5.1.29-bin.jar:na] 
at com.mchange.v2.c3p0.impl.NewProxyConnection.commit(NewProxyConnection.java:981) ~[c3p0-0.9.5.1.jar:0.9.5.1] 
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doCommit(JdbcTransaction.java:112) [hibernate-core-4.1.0.Final.jar:4.1.0.Final] 
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:178) [hibernate-core-4.1.0.Final.jar:4.1.0.Final] 

Versuch MaxNoOfFiredTriggers zu erhöhen in keiner Verhaltensänderung geführt hat.

Sicher könnte ich Transaktionen in kleinere Chargen aufteilen, aber 5000 Zeilen klingt nicht so riesig für eine Nummer und besonders seltsam, dass Einsatz wirklich gut funktioniert.

Antwort

1

Ich denke, Sie nehmen nicht die Auslöser ausgelöst, um die Fremdschlüssel Einschränkungen beim Festlegen der MaxNoOfFiredTriggers zu erzwingen.

Da die Einfügungen in Ordnung sind und der Löschvorgang nicht ausgeführt wird, ist meine Vermutung, dass mindestens eine Spalte der Tabelle, in der Sie DMLs ausführen, von einer anderen Spalte (aus der gleichen oder einer anderen Tabelle) als Teil einer FK Beziehung.

Zum Beispiel die folgenden Tabellen betrachten,

create table parent(id int, unique uk1(id) using hash) engine ndb;

create table child(id_ref int, foreign key fk1(id_ref) references parent(id)) engine ndb;

Nun, wenn Sie eine Einfügung in die übergeordnete Tabelle tun, werden Trigger im Backend abgefeuert werden, um den eindeutigen Index zu aktualisieren uk1. Aber hier werden keine FK-Trigger benötigt, da es nichts zu überprüfen gibt.

Wenn Sie jedoch aus der übergeordneten Tabelle löschen, muss die FK-Einschränkung erzwungen werden. Das Löschen sollte zulässig sein, wenn die untergeordnete Tabelle nicht den Wert enthält, der vom übergeordneten Element gelöscht wird. Dies kann variieren, wenn die FK-Bedingung eine on update cascade-Klausel hat - in diesem Fall müssen die Tupel mit dem gleichen Wert, der aus der übergeordneten Klasse gelöscht wird, ebenfalls im untergeordneten Element gelöscht werden.

All dies wird durch FK-Trigger erzwungen. Beim Löschen von Parent werden also zusätzlich zu den Triggern, die ausgelöst werden, um den Hash-Index zu aktualisieren, Trigger für Fremdschlüssel ausgelöst. In diesem Fall werden für jede Zeile zwei Trigger ausgelöst. Wenn Sie also in diesem Setup 5000 Zeilen im Batch löschen, benötigen Sie mindestens 10K maxNoOfFiredTriggers. Mit mehreren Fremdschlüsseln und mehreren Fremdschlüsselabhängigkeiten kann diese Berechnung variieren. Sie müssen also Ihr Schema auf alle Fremdschlüsselabhängigkeiten prüfen und entsprechend MaxNoOfFiredTriggers berechnen.

+0

Ehrlich, ich erinnere mich nicht mehr was war MaxNoOfFiredTriggers Wert und ich habe dies nicht in der Frage erwähnt ... – divanov

Verwandte Themen