2015-07-02 2 views
3

Я разрабатываю мобильное приложение, чей бэкэнд разработан в Java, а база данных - MySQL.Ошибка блокировки ожидания блокировки MySQL и ошибки тупика

У нас есть некоторые операции вставки и обновления в таблицах базы данных с большим количеством строк (между 400 000 и 3.000.000). Каждой операции обычно не нужно касаться каждого регистра таблицы, но, возможно, они вызываются одновременно, чтобы обновить 20% из них.

Иногда я получаю эту ошибку:

Deadlock found when trying to get lock; try restarting transaction

и

Lock wait timeout exceeded; try restarting transaction

Я улучшил свои запросы делая их меньше и быстрее, но у меня есть еще большая проблема, когда некоторые операции могут не выполняться.

Мои решения до сих пор были: производительность сервера

  • Увеличение (AWS Instance от m2.large до c3.2xlarge)
  • SET GLOBAL tx_isolation = 'READ-COMMITTED';
  • Избегайте проверять внешние ключи: SET FOREIGN_KEY_CHECKS = 0; (я знаю это небезопасно, но я не хочу блокировать базу данных)
  • Установите эти значения для переменных времени ожидания (SHOW VARIABLES LIKE '%timeout%';):
    • connect_timeout: 10
    • delayed_insert_timeout: 300
    • innodb_lock_wait_timeout: 50
    • innodb_rollback_on_timeout: ВЫКЛ
    • interactive_timeout: 28800
    • lock_wait_timeout: 31536000
    • net_read_timeout: 30
    • net_write_timeout: 60
    • slave_net_timeout: 3600
    • wait_timeout: 28800

Но я не уверен, что если эти вещи снижение производительности.

Любая идея о том, как уменьшить эти ошибки?

Примечание: эти другие SO ответить мне не помогают:

MySQL Lock wait timeout exceeded

MySQL: "lock wait timeout exceeded"

How can I change the default Mysql connection timeout when connecting through python?

+0

какой двигатель базы данных вы используете? –

+0

Как вы подключаетесь к базе данных? Какой драйвер вы используете? Используете ли вы пул соединений? – Eduard

+0

Я использую InnoDB, и я использую JPA for persistance. –

ответ

0

Попробуйте обновить меньше строк на одну транзакцию.

Вместо обновления 20% или строк в одном обновлении транзакции 1% строк 20 раз.

Это значительно улучшит ваши выступления, и вы избежите таймаута.

Примечание: ORM не является хорошим решением для больших обновлений. Лучше использовать стандартный JDBC. Используйте ORM для извлечения, обновления, удаления нескольких записей каждый раз. Это ускоряет фазу кодирования, а не время выполнения.

+0

Я уверен, что это может мне помочь, но как это фильтровать? Я имею в виду, если мне нужно обновить 50 000 строк таблицы с 110 000, потому что они соответствуют моим критериям, как я могу разделить этот запрос? –

+0

Вы должны выбрать критерии сортировки. Хорошим является идентификатор, но вы можете выбрать любого, кому нравится –

+0

ORDER BY id DESC, например? –

0

В качестве комментария больше, чем ответ, если вы находитесь на ранней стадии разработки, вы можете подумать, действительно ли вам нужны эти конкретные данные в реляционной базе данных. Существуют гораздо более быстрые и большие альтернативы для хранения данных из мобильных приложений в зависимости от планируемого использования данных. [S3 для больших файлов, хранится один раз, часто читается (и может быть кэширован); NoSQL (Mongo и т. Д.) Для неструктурированных больших, однократных, прочитанных и т. Д.]

Смежные вопросы