2016-07-05 10 views
0

Я делаю пакетные операции с MySQL Cluster NDB: вставка 10000 или 5000 строк и удаление в одной транзакции. Вставка работает отлично, но удаление не удается с исключением:Слишком много одновременно запущенных триггеров (увеличение MaxNoOfFiredTriggers) от 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] 

Попытка увеличить MaxNoOfFiredTriggers не приводило к изменению поведения.

Конечно, я мог бы разделить транзакции на более мелкие партии, но 5000 строк не звучат так громко для числа и особенно странно, что вставка действительно работает нормально.

ответ

1

Я думаю, что вы не принимаете триггеры, запускаемые для обеспечения соблюдения ограничений внешнего ключа при установке MaxNoOfFiredTriggers.

Поскольку вставки прекрасны, а удаление не является, я полагаю, что по крайней мере один столбец таблицы, в которую вы делаете DML, передается другим столбцом (из той же или другой таблицы) в качестве части FK.

Для примера рассмотрим следующие таблицы,

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;

Теперь, когда вы делаете вставку в родительской таблицы, триггеры будут уволены в бэкэндом обновить уникальный индекс UK1. Но здесь не нужны триггеры FK, так как проверить нечего.

Но когда вы удаляете из родительской таблицы, принудительное ограничение FK должно выполняться. Удаление должно быть разрешено, если дочерняя таблица не имеет значения, которое удаляется из родителя. Это может измениться, если ограничение FK имеет предложение on update cascade - в этом случае кортежи с тем же значением, которые удаляются из родителя, также должны быть удалены в дочернем элементе.

Все это обеспечивается с помощью триггеров FK. Поэтому во время удаления из родителя в дополнение к триггерам, запускаемым для обновления хеш-индекса, также запускаются триггеры внешнего ключа. В этом случае для каждой строки будут запущены два триггера. Поэтому, если вы удаляете 5000 строк в пакете в этой настройке, вам потребуется по крайней мере 10K maxNoOfFiredTriggers. С несколькими внешними ключами и с несколькими уровнями зависимостей внешнего ключа этот расчет будет отличаться. Поэтому вы должны проверить свою схему для всех зависимостей внешнего ключа и вычислить MaxNoOfFiredTriggers соответственно.

+0

Честно говоря, я больше не помню, что такое значение MaxNoOfFiredTriggers, и я не упоминал об этом в вопросе ... – divanov