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. І отримаємо відсортоване виведення інформації по таблицях бази даних.

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;

 forum_forumpost                        |          8290304 | 8096 kB
 cities_light_city                      |         11108352 | 11 MB
 django_session                         |       7225204736 | 6890 MB
(110 rows)

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

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

SELECT pg_size_pretty( pg_database_size('databasename') );
 pg_size_pretty 
----------------
 14 GB
(1 row)

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

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

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

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

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

python manage.py clearsessions

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

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

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

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

vacuum FULL ANALYZE django_session;

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

SELECT pg_size_pretty( pg_database_size('databasename') );
 pg_size_pretty 
----------------
 494 MB
(1 row)

Тепер розмір бази даних лише 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