Почему PostgreSQL поглощает все мое драгоценное HD-пространство? - PullRequest
1 голос
/ 03 января 2009

Я только что закончил передавать как можно больше данных о структуре ссылок, касающихся Википедии (англ.). По сути, я скачал кучу дампов SQL из последнего хранилища дампов Википедии . Поскольку я использую PostgreSQL вместо MySQL, я решил загрузить все эти дампы в свою базу данных, используя команды конвейерной оболочки .

В любом случае, в одной из этих таблиц 295 миллионов строк: таблица pagelinks ; он содержит все внутри-вики гиперссылки. С моего ноутбука, используя pgAdmin III, я отправил следующую команду на сервер базы данных (другой компьютер):

SELECT pl_namespace, COUNT(*) FROM pagelinks GROUP BY (pl_namespace);

Это было в течение часа или около того. Дело в том, что почтмейстер, кажется, поглощает все больше и больше моего очень ограниченного пространства HD. Я думаю, что он съел около 20 ГБ на данный момент. Ранее я играл с файлом postgresql.conf, чтобы повысить гибкость его работы (т. Е. Позволить использовать больше ресурсов), поскольку он работает с 12 ГБ ОЗУ. Я думаю, что я в основном увеличил в четыре раза больше байтов и связанных с этим переменных этого файла, думая, что он будет использовать больше оперативной памяти для своей работы.

Однако БД, похоже, не использует много ОЗУ. Используя системный монитор Linux, я вижу, что почтмейстер использует 1,6 ГБ разделяемой памяти (RAM). В любом случае, мне было интересно, если вы, ребята, могли бы помочь мне лучше понять, что он делает, мне кажется, что я действительно не понимаю , как PostgreSQL использует HD-ресурсы .

Что касается метаструктуры баз данных Википедии, они предоставляют хорошую схему , которая может быть полезной или даже интересной для вас.

Не стесняйтесь спрашивать меня о более подробной информации, спасибо.

Ответы [ 3 ]

3 голосов
/ 04 января 2009

Вероятно, проблема связана с GROUP BY. Чтобы выполнить группировку, база данных должна отсортировать строки, чтобы собрать дубликаты. Индекс, вероятно, не поможет. Расчет с обратной стороны:

Если предположить, что каждая строка занимает 100 байт, то это 29 500 000 000 байт или около 30 ГБ дискового пространства. Он не может вместить все это в память, поэтому ваша система работает с перебоями, что замедляет работу в 1000 и более раз. Ваше HD-пространство может исчезать в пространстве подкачки, если оно использует файлы подкачки.

Если вам нужно выполнить этот расчет только один раз, попробуйте разбить его на меньшие подмножества данных. Предполагая, что pl_namespace является числовым и колеблется в пределах 1-295 миллионов, попробуйте что-то вроде этого:

SELECT pl_namespace, COUNT(*)
FROM pagelinks
WHERE pl_namespace between 1 and 50000000
GROUP BY (pl_namespace);

Затем сделайте то же самое для 50000001-100000000 и так далее. Объедините свои ответы вместе с помощью UNION или просто сведите результаты с помощью внешней программы. Забудьте, что я написал об индексе, не помогающем GROUP BY; здесь индекс поможет предложению WHERE.

1 голос
/ 03 января 2009

Что точно утверждает, что занимает всего 9,5 МБ ОЗУ? Для меня это маловероятно - общая память почти наверняка - это RAM, которая распределяется между различными процессами Postgres. (Из того, что я помню, каждый клиент заканчивает как отдельный процесс, хотя это было какое-то время, поэтому я мог быть очень неправ.)

Есть ли у вас индекс по столбцу pl_namespace? Если бы было много отличных результатов, я мог бы представить, что этот запрос довольно тяжел для 295 миллионов строк таблицы без индекса. Сказав это, 10 ГБ - это очень много, чтобы проглотить. Вы знаете, в какие файлы он пишет?

0 голосов
/ 04 января 2009

Хорошо, вот суть этого:

Предложение GROUP BY сделало индекс 'недействительным, поэтому postmaster (серверный процесс postgresql) решил создать группу таблиц (23 ГБ таблиц), которые были бы расположены в каталоге $ PGDATA / base / 16384 / pgsql_tmp.

При изменении файла postgresql.conf я дал разрешение postgreSQL использовать 1,6 ГБ ОЗУ (которое я сейчас удвою, поскольку у него есть доступ к 11,7 ГБ ОЗУ); процесс postmaster действительно использовал 1,6 ГБ ОЗУ, но этого было недостаточно, поэтому каталог pgsql_tmp.

Как отметил Барри Браун, поскольку я выполнял только эту команду SQL, чтобы получить некоторую статистическую информацию о распределении ссылок между pagelinks.namespaces , я мог бы запросить подмножество 296 миллионов ссылок на страницы (это то, что они делают для опросов).

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

Спасибо за вашу помощь, ребята!

...