@@ -383,3 +383,70 @@ where tbl.relname = 'cts__cdr'
383383 and ns .nspname = ' public'
384384 and not att .attisdropped ;
385385```
386+ 387+ # Лайвхак по добыванию свободного места в БД
388+ 389+ Имеется таблица
390+ ``` sql
391+ create table v3_person_password_log
392+ (
393+ id integer generated by default as identity
394+ primary key ,
395+ person_id integer not null
396+ references v3_person
397+ on update cascade on delete cascade ,
398+ password_hash varchar (60 ) not null
399+ constraint v3_person_password_log_password_hash_check
400+ check (octet_length((password_hash)::text ) = 60 ),
401+ created_at timestamp (0 ) with time zone default now() not null ,
402+ http_request_headers jsonb,
403+ request_remote_addr inet ,
404+ session_id varchar (128 ),
405+ is_auto_generated boolean
406+ );
407+ 408+ comment on table v3_person_password_log is ' История изменений паролей пользователей' ;
409+ comment on column v3_person_password_log.id is ' ID записи' ;
410+ comment on column v3_person_password_log.person_id is ' ID персоны' ;
411+ comment on column v3_person_password_log.password_hash is ' Соль и хеш от пароля в формате bcrypt' ;
412+ comment on column v3_person_password_log.created_at is ' Дата-время создания' ;
413+ comment on column v3_person_password_log.http_request_headers is ' Заголовки HTTP запроса в формате ключ-значение' ;
414+ comment on column v3_person_password_log.request_remote_addr is ' IP адрес запроса' ;
415+ comment on column v3_person_password_log.session_id is ' ID сессии, значение из session.sid' ;
416+ comment on column v3_person_password_log.is_auto_generated is ' Признак генерации пароля системой' ;
417+ ```
418+ 419+ В таблице есть разные колонки и ещё ` http_request_headers ` , ` request_remote_addr ` , ` session_id ` .
420+ По данным этих колонок можно обнаруживать роботов, спам, делать аналитику и др.
421+ Для этого интересны только "свежие" данные за последние N месяцев.
422+ В таком случае данные старше N месяцев можно очищать (присваивать этим полям NULL).
423+ 424+ Узнаём, сколько примерно места занимают данные:
425+ ``` sql
426+ select count (* ),
427+ sum (pg_column_size(http_request_headers) +
428+ pg_column_size(request_remote_addr) +
429+ pg_column_size(session_id) +
430+ pg_column_size(is_auto_generated)) as size
431+ from public .v3_person_password_log as t
432+ where created_at < now() - interval ' 1 year'
433+ and (http_request_headers is not null
434+ or request_remote_addr is not null
435+ or session_id is not null
436+ or is_auto_generated is not null
437+ );
438+ ```
439+ 440+ Удаляем уже ненужные данные:
441+ ``` sql
442+ update public .v3_person_password_log
443+ set http_request_headers = null ,
444+ request_remote_addr = null ,
445+ session_id = null ,
446+ is_auto_generated = null
447+ where created_at < now() - interval ' 1 year'
448+ and (http_request_headers is not null
449+ or request_remote_addr is not null
450+ or session_id is not null
451+ or is_auto_generated is not null );
452+ ```
0 commit comments