Почему сообщаемый размер базы данных (на диске?) отличается от размера в памяти

Моя база данных содержит три таблицы, имеющие 50 тыс., 50 тыс. и 5 млн строк. Все они InnoDB. (самый большой содержит varchar[256]). Размер моей базы данных составляет 214 МБ, что я получил, запросив information_schema.TABLES (я думаю, это дает размер данных + индекс на диске?)

У меня было 1,5гб ОЗУ и я думал переделать движок всех таблиц в ПАМЯТЬ. Но когда я начал конвертировать самую большую таблицу, я получил ошибку 1114.

После некоторых исследований я обнаружил, что max_heap_table_size занимает всего 16 МБ. Итак, я установил max_heap_table_size и tmp_table_size на 1 ГБ.

Когда я снова попытался выполнить преобразование, я увидел, что использование памяти процессом mysqld.exe превышало 1,2 ГБ, а затем он снова выдал ту же ошибку еще до преобразования половины строк! Я удалил половину строк из самой большой таблицы, и она, наконец, поместилась — в памяти 700 МБ!

Почему база данных размером 214 МБ не может уместиться даже в четырехкратном размере памяти?

Есть ли что-то еще внутри процесса, которое съедает память, кроме данных + индекс?

Машина: Intel P4 – 1,9 ГГц, 1,5 ГБ ОЗУ, Win7 Ultimate.


person Community    schedule 27.09.2012    source источник
comment
@Randy Но не настолько, чтобы полностью остановить загрузку таблиц в ОЗУ. @OP Может быть большой объем ОЗУ, выделенный для кеша или чего-то еще. Посмотрите на top и/или htop, чтобы узнать, что использует вашу оперативную память. Вы используете виртуальный хостинг или VPS?   -  person Bojangles    schedule 28.09.2012
comment
Да, но использование памяти, о котором я сообщил, относится только к процессу mysqld.exe. Все остальное в моей системе прекрасно помещалось в оставшихся нескольких сотнях мегабайт. Даже если бы у меня было 4Гб и как-то все уместилось, мой главный вопрос: почему 214Мб занимает ›1,2Гб в ОЗУ   -  person    schedule 28.09.2012
comment
@JamWaffles На самом деле это происходит на моей временной машине для разработки Win7. Я смотрел в диспетчере задач. Память для mysqld.exe перед началом конвертации была стабильной на уровне 144M. Как только преобразование началось, оно увеличилось до 1,2 ГБ в течение 20 секунд, а затем возникла ошибка.   -  person    schedule 28.09.2012
comment
Вы можете проверить, есть ли у вас подобное поведение, экспортировав данные, создав новые таблицы с помощью механизма MEMORY и импортировав, пытаясь импортировать эти данные. Однако вы должны помнить, что перезапуск процесса mysql удалит все данные из этих таблиц.   -  person Zefiryn    schedule 28.09.2012
comment
@Zefyryn Я пробовал оба способа. 1) Изменение движка в свойствах таблицы, а также 2) создание таблицы MEMORY и вставка в нее из старой таблицы. То же поведение, тот же шаблон использования памяти!. Единственная разница в том, что я получил ту же ошибку в другом диалоговом окне: |   -  person    schedule 28.09.2012
comment
У вас есть какие-то индикаторы, настроенные для этих таблиц, кроме первичного ключа?   -  person Zefiryn    schedule 28.09.2012
comment
@Zefyryn Да, было. Вот и я тоже подумал. Но удаление всех индексов также не имело никакого значения :( НО... кстати, 214M должен давать нам размер данных + индекс, не так ли?   -  person    schedule 28.09.2012
comment
@SenthilKumar, задумывались ли вы, что, возможно, процесс создания таблицы в памяти требует много памяти, а не обязательно самой таблицы?   -  person kurtzbot    schedule 28.09.2012
comment
@kurtzbot Это именно то, о чем я подумал, когда решил попробовать с меньшим столом. Но если бы это было правдой, после успешной загрузки таблицы половинного размера и занимающей в процессе 700 МБ, в идеале она должна была бы выйти из строя. (см. часть моего вопроса, где я упоминаю статистику для таблицы половинного размера). Но он не сошел. Может быть, какая-то очистка не происходит после конвертации?   -  person    schedule 28.09.2012


Ответы (1)


Я нашел этот вопрос dba.se, в котором принятый ответ содержал ссылку на этого разработчика. страница mysql, в которой говорится:

В таблицах MEMORY используется формат хранения строк фиксированной длины. Типы переменной длины, такие как VARCHAR, хранятся с использованием фиксированной длины.

Как я упоминал в вопросе, у меня была таблица с 5 млн строк с одним столбцом varchar[256].

5 000 000 x 256 = 1,19 ГБ (при условии, что 1 байт на символ), поэтому я думаю, что это ответ!

Только этот конкретный столбец занимает 95% пространства, а остальное приходится на другие числовые столбцы. Я предполагаю, что InnoDB не хранил его фиксированной длины на диске. И поскольку поле в основном имело тестовые значения, которые не превышали 10-15 символов, оно занимало такой маленький размер на диске.

person Community    schedule 28.09.2012
comment
Из любопытства, почему вы решили преобразовать InnoDB в MEMORY? Если это из-за производительности, лучше увеличить innodb_buffer_pool_size. - person N.B.; 28.09.2012
comment
На самом деле да! Я отчаянно пытался сделать это, до того, как я получил правильный размер буфера для InnoDB для моей базы данных; Я никогда раньше не имел дело с 5 миллионами записей в таблице. Теперь у меня InnoDB работает нормально, но я все еще хотел знать, почему это происходит :) - person ; 28.09.2012