все доступные ему аппаратные ресурсы для работы.
Условие: дана таблица tableA весом порядка 3ТБ, в ней около десятка столбцов типов integer/text. Индексов кроме как по ID строки (уникальное ограничение) нет.
Цель: очистка таблицы от дубликатов по столбцу columnX (text). По предварительной информации дубликатов порядка 50%.
Выбранное решение: создать таблицу tableB как LIKE tableA, добавить уникальное ограничение по столбцу columnX, и влить в неё данные из tableA посредством запроса (без разделения на пачки по ID):
INSERT INTO tableB (SELECT * FROM tableA) ON CONFLICT DO NOTHING;
Текущие результаты и проблемы:
Сначала всё было "хорошо": диск (обе таблицы на одном диске hdd, который представляет из себя нулевой raid) интенсивно читал данные по 100-200мб/сек (данные на основе iotop), CPU использовалось средне — 20-30% (данные на основе htop). Но где-то через сутки процесс деградировал и теперь читается по 0.6-1мб/сек, что на два порядка меньше чем ожидалось. ОЗУ используется порядка 20% процентов.
Известная информация (спасибо @darthunix за помощь и советы в сборе информации):
cgroups ничего не режет, сам диск физически не деградировал (производились тесты через dd), никакие индексы не мешают. Перед процедурой производился VACUUM ANALYZE (без FULL).
Также был снят strace на текущий момент, его скидываю ниже.
В нём смущает ошибки с fsm аля open("base/16385/1609973_fsm", O_RDWR) = -1 ENOENT (No such file or directory), и то что операции write всегда пушат \0
Метрики файла strace таковы:
Total time: 70,120 sec.
Total operations: 11386
Total lseek time: 1,722 sec (2,456%).
Total lseeks: 5530
Total read time: 68,116 sec (97,143%).
Total reads: 5407
Total write time: 238,160 ms (0,340%).
Total writes: 449
Таким образом, не выявлено, чтобы процесс во что-то "упирался" аппаратное (disk/cpu/etc). У кого есть идеи что ещё проверить и какие могут быть причины?
Вам нужен gdb
А запись-то на диск с какой скоростью была/стала?
> Выбранное решение: > INSERT INTO tableB (SELECT * FROM tableA) ON CONFLICT DO NOTHING; А почему именно такое? Почему было не создать таблицу без индексов и не использовать запрос с DISTINCT ON? Примерно: INSERT INTO tableB SELECT DISTINCT ON (columnX) * FROM tableA; > никакие индексы не мешают. Из чего был сделан этот вывод? > У кого есть идеи что ещё проверить и какие могут быть причины? Логи PostgreSQL, например, на предмет хоть чего-то необычного. А причина, наверное, всё-таки в поиске по индексу (этот strace не очень полезен — не видно, откуда читается и куда пишется, и вообще не понятно, с какого именно процесса он снят). > Таким образом, не выявлено, чтобы процесс во что-то "упирался" аппаратное (disk/cpu/etc). Да неужели? ;) А вот это что: > Total read time: 68,116 sec (97,143%). ?
Обсуждают сегодня