Чёртовы уроки, пожалуйста, используйте вставку в select с осторожностью. После того, как его использовали коллеги, компания потеряла почти 10 Вт и в конечном итоге была уволена.
причина вопроса
Объем транзакций компании относительно велик, используемая база данных - mysql, а ежедневный прирост составляет около 1 млн. У компании нет подбазы данных или подтаблицы, поэтому, если вы хотите поддерживать производительность этой таблицы, вы можете рассматривать только миграцию данных.
Коллега Ли получил это задание, поэтому он придумал эти два плана
- Сначала запросите его через программу, затем вставьте в таблицу истории, а затем удалите исходную таблицу.
- Используйте вставку в выбор, чтобы позволить базе данных IO выполнять все операции
При использовании первой схемы обнаружилось, что все нагрузки грузились одновременно, а система была ООМ напрямую, но делать это пачками требовалось слишком много ио и времени, поэтому я выбрал вторую схему, там было никаких проблем во время теста, и я был счастлив выйти в интернет, а затем быть уволены.
Что случилось, давайте отмотаем назад
- Давайте сначала посмотрим на первую схему, сначала посмотрим на псевдокод
// 1、查询对应需要迁移的数据
List<Object> list = selectData();
// 2、将数据插入历史表
insertData(list);
// 3、删除原表数据
deleteByIds(ids);
Из этого кода видно, что причина OOM очень проста, мы напрямую загружаем все данные в память, и неудивительно, что память не взрывается.
- Давайте посмотрим на второй план, что произошло?
Чтобы поддерживать производительность таблицы и в то же время сохранять действительные данные, после согласования определенного количества, чтобы сохранить данные за 10 дней, в таблице должно быть сохранено почти 1 кВт данных. Итак, мой коллега выполнил операцию фильтрации по времени, напрямую вставив в select... dateTime
Для теста были специально построены данные 1кВт для моделирования.Конечно, в тестовой среде нет проблем, и она прошла гладко. Учитывая, что эта таблица является счетчиком потока платежей, эта задача сделана временной и запланирована на 20:00.
Сумма к вечеру не слишком большая, так что проблем естественно нет, но на следующий день финансовый отдел компании вышел на работу и начал сверку счетов.Выяснилось, что средства не совпадают, и много на склад не подведена водопроводная вода. Окончательное расследование показало, что после 20:00 проблема невозможности вставить платежный поток стала возникать одна за другой, в результате чего было потеряно много данных. Я наконец понял, что проблема была вызвана задачей переноса.Я сначала не знал этого, поэтому днем проблем не было.Потом я подумал, что такая ситуация ночью может быть связана с задачей ночью Наконец, я остановил второй онлайн-запуск задания и обнаружил, что оно пропало.Такая ситуация.
Обзор
- В чем проблема?
Почему все нормально после остановки задачи миграции? Что именно делает эта вставка в операцию выбора? Давайте посмотрим на объяснение этого утверждения.Из рисунка нетрудно увидеть, что этот оператор запроса напрямую проходит полное сканирование таблицы. В это время нам нетрудно угадать небольшую проблему. Если полное сканирование таблицы, наша таблица такая большая, значит ли это, что время миграции будет долгим? Если наше время миграции составляет час, значит ли это, что это объясняет, почему у нас нет таких проблем в течение дня. Но является ли полное сканирование таблицы основной причиной?
С тем же успехом мы могли бы попытаться во время миграции выполнить некоторые операции по восстановлению сцены. В конце концов эта проблема все равно возникнет. В это время мы можем его скорректировать и сделать смелое предположение, если мы не просканируем всю таблицу, не возникнет ли эта проблема? Когда мы изменили условия, мы обнаружили, что полного сканирования таблицы не было. Наконец снова восстановите сцену, проблема решена
Вывод: Полное сканирование таблицы вызвало аварию.
Это решает возникшую проблему, но это нелегко объяснить, так как они начинают выходить из строя один за другим.
- причина
При уровне изоляции транзакций по умолчанию: операция a вставки в a select b означает прямую блокировку таблицы, а таблица b блокируется одна за другой. Это также объясняет, почему происходят последовательные неудачи. При блокировке по одному большинство расходомеров являются составными записями, поэтому конечная часть блокируется при сканировании, а некоторые не могут получить блокировку, что в итоге приводит к таймауту или прямому сбою, и некоторые из них здесь успешно блокируются.
- Почему нет проблем с тестом?
В тесте данные формальной среды полностью используются для тестирования, но не игнорируйте проблему, то есть тестовая среда все-таки тестовая среда Во время теста реальный объем данных не означает, что это реальный бизнес-сценарий. Например, в этом случае одним случаем, когда при миграции вставляется большой объем данных, меньше. в конечном итоге привести к онлайн-ошибкам
Решение
Поскольку мы можем решить эту проблему, избегая полного сканирования таблицы, мы можем просто избежать этого. Чтобы избежать полного сканирования таблицы, проиндексируйте условия позади where и разрешите нашим избранным запросам пройти через индекс.
Может вставить еще работать?
Может
Суммировать
Пожалуйста, будьте осторожны при использовании вставки в выборке, убедитесь, что хорошо проиндексировали