Evgenii Legotckoi
19 квітня 2022 р. 03:39

Django - Урок 058. Розростання бази даних через таблицю django_session

Останнім часом я помітив, що наближається той фатальний момент, коли катастрофічно перестане хапати дискового простору для сайту на хостингу. А дамп бази даних стає неймовірно величезним, хоча очевидних передумов для цього жодних немає. Розмір контенту на сайті не зростає так швидко, та й кількість зареєстрованих користувачів також не прибуває так швидко.

Після вивчення бази даних було виявлено, що розмір таблиці django_session просто гігантський майже 7 Гб, а розмір індексу також досягає майже 6.5 Гб, при тому, що розмір самої бази даних 14 Гб.

При цьому розмір другої за величиною таблиці всього 11 Мб і це стороннє додаток зі списком міст. А розмір третьої таблиці, що містить повідомлення на форумі лише 8 Мб.

Відповідно, було вирішено розібратися, чому це відбувається і як виправляти.

Зараз я швидше за все не відкрию нічого нового для тих, хто активно адмініструє бази даних на PostgreSQL, але для новачків і тих, хто в основному займається Django як PET проект, без професійного використання, інформація може бути корисною.


Як перевірити розмір таблиці

https://evileg.com/ru/knowledge/article/add/#
Для цього достатньо виконати наступний запит в інтерфейсі адміністрування PostreSQL. І отримаємо відсортоване виведення інформації по таблицях бази даних.

  1. select table_name, pg_relation_size(quote_ident(table_name)), pg_size_pretty(pg_relation_size(quote_ident(table_name))) from information_schema.tables where table_schema = 'public' order by 2;
  2.  
  3. forum_forumpost | 8290304 | 8096 kB
  4. cities_light_city | 11108352 | 11 MB
  5. django_session | 7225204736 | 6890 MB
  6. (110 rows)

Як бачите, в моєму випадку таблиця djang_session за 6 років існування сайту на движку Django розросла дуже сильно.
Дякуємо DDOS відвідувачам, механізму створення ключів сесії для всіх анонімних користувачів, а також тому, що за замовчуванням PostgreSQL навіть при видаленні записів не зменшує розмір файлу бази даних.

А розмір бази даних можна переглянути так

  1. SELECT pg_size_pretty( pg_database_size('databasename') );
  2. pg_size_pretty
  3. ----------------
  4. 14 GB
  5. (1 row)
  6.  

Ось такий неприємний розмір вийшов - 14 GB.

Видалення сесій із минулим терміном

Коли сайт піддається DDOS або просто напливу користувачів, створюється величезна кількість сесій, які зазвичай в Django не видаляються, а також додатково зростає індекс таблиці.

Тому перше, що потрібно зробити, це видалити застарілі сесії. Для цього у Django є команда clearsessions .

Тому в консолі активуємо python середовище вашого проекту, переходимо до папки з вашим проектом і виконуємо наступну команду.

  1. python manage.py clearsessions

Це видалить усі старі сесії. Ви також можете налаштувати виконання команди за розкладом через cron.
Наприклад, за допомогою батарейки django-session-cleanup , для неї потрібне використання celery .

Запуск збирача сміття

Після того, як ви виконали видалення старих сесій, вам необхідно звільнити простір зайнятий базою даних.
Це необхідно тому, що пріоритет бази даних – це продуктивність, а не економія дискового простору. Таким чином, файл бази даних розростається за рахунок зростання індексу, а даних там вже давно немає. А також за замовчуванням збирач сміття не запускається сам по собі, для цього необхідно налаштовувати його запуск за розкладом, наприклад, за допомогою демона.

Але особисто я поки що зробив це вручну. Складальник сміття в PostgreSQL запускається командою vacuum .

  1. vacuum FULL ANALYZE django_session;

Після виконання цієї операції знову перевіряю розмір бази даних та бачу

  1. SELECT pg_size_pretty( pg_database_size('databasename') );
  2. pg_size_pretty
  3. ----------------
  4. 494 MB
  5. (1 row)
  6.  

Тепер розмір бази даних лише 494 MB, що не може не тішити.

Потрібно буде згодом налаштувати запуск збирача сміття хоча б раз на тиждень, але про це вже в наступній статті.

Рекомендовані статті на цю тему

По статті запитували0питання

3

Вам це подобається? Поділіться в соціальних мережах!

u
  • 15 травня 2022 р. 17:58
  • (відредаговано)

А если хранить сессии в SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' ?
Интересно стало насколько безопасно хранить сессии в печеньках... стоит оно того или нет?)

Evgenii Legotckoi
  • 15 травня 2022 р. 19:27

Думаю, что скорее всего это будет менее безопасно, но на практике я не проверял.

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up
  • Останні коментарі
  • Evgenii Legotckoi
    16 квітня 2025 р. 17:08
    Благодарю за отзыв. И вам желаю всяческих успехов!
  • IscanderChe
    12 квітня 2025 р. 17:12
    Добрый день. Спасибо Вам за этот проект и отдельно за ответы на форуме, которые мне очень помогли в некоммерческих пет-проектах. Профессиональным программистом я так и не стал, но узнал мно…
  • AK
    01 квітня 2025 р. 11:41
    Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
  • Evgenii Legotckoi
    09 березня 2025 р. 21:02
    К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
  • VP
    09 березня 2025 р. 16:14
    Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…