Размеры индексов БД для logstore_standard_log

Размеры индексов БД для logstore_standard_log

от Виталий Лавров -
Количество ответов: 2
Изображение пользователя Эксперт по Moodle
Имеется жалкие 17 млн. строк
-------------------------------------------------------------
select count(id) from mdl_logstore_standard_log;
count
----------
17987309
(1 row)
-------------------------------------------------------------
Размеры таблиц и индексов:
public.mdl_logstore_standard_log | 4371 MB
public.mdl_logsstanlog_useconconcr_ix | 1328 MB
public.mdl_logsstanlog_couanotim_ix | 931 MB
public.mdl_logsstanlog_con_ix | 434 MB
public.mdl_logsstanlog_tim_ix | 417 MB
public.mdl_logsstanlog_id_pk | 409 MB
-------------------------------------------------------------
Получается, что размер индексов 3519 Мб, что составляет 80% от самой таблицы.
Смотрим на описание индексов в схеме. Мелкие индексы (id_pk,tim_ix,con_ix) - понятно.
----------------------------------------------------------------
<INDEXES>
   <INDEX NAME="timecreated" UNIQUE="false" FIELDS="timecreated"/>
   <INDEX NAME="course-time" UNIQUE="false" FIELDS="courseid, anonymous, timecreated"/>
   <INDEX NAME="user-module" UNIQUE="false" FIELDS="userid, contextlevel, contextinstanceid, crud, edulevel, timecreated
</INDEXES>
----------------------------------------------------------------

Учитывая, что логи пишутся активно, получаем существенные затраты на запись логов.
А когда логи читаются ? Построение отчетов! А оно часто?

Если сделать секционирование лога, то сложные индексы будут явно ухудшать производительность.

Вопрос 1: - нафига нужен user-module  и course-time?

Вопрос 2:  как найти в moodle запросы на выборку данных из logstore_standard_log ? grep не даёт разумных результатов.
Нет ли протоколирования запросов к таблице ?

В ответ на Виталий Лавров

Re: Размеры индексов БД для logstore_standard_log

от Vadim Dvorovenko -
Изображение пользователя Developers Изображение пользователя Майнтейнер перевода
2. Ищите вызовы к get_events_select, get_events_select_iterator, get_events_select_count из admin/tool/log/store/standard/classes/log/store.php. Поищите по «:anonymous», «:contextinstanceid», «'anonymous' =>», «'contextinstanceid' =>»
1. Так, например, в \core_analytics\course: guess_start нужен индекс user-module (используются первые три колонки индекса), делается вызов к get_events_select.
В course/classes/analytics/target/course_dropout.php: is_valid_analysable и \core\analytics\indicator\any_write_action_in_course: calculate_sample используется courseid, anonymous и get_events_select_count.

Могу предложить такой вариант. Создать дополнительную таблицу с аналогичной структурой как у mdl_logstore_standard_log, но без индексов, настроить для неё Журнал событий во внешней базе данных и писать логи в две таблицы одновременно. В logstore_standard_log сделать очистку через 30 дней. Размер и таблицы, и индексов, будет небольшой. Для статистики и аналитики 30 дней должно быть достаточно. А для истории будут храниться во второй таблице.

В ответ на Vadim Dvorovenko

Re: Размеры индексов БД для logstore_standard_log

от Виталий Лавров -
Изображение пользователя Эксперт по Moodle
Спасибо за подсказку про get_events_*
grep -sIR get_events_select|egrep -v '(/tests/|store.php)'  дает более интересный вывод.

Вместо одной таблицы писать две? На продакшене? Тонко улыбаюсь
Я бы просто удалил индексы course-time и user-module, а вместо них добавил бы индекс для courseid и userid

Вся аналитика подождет и там почти все запросы ограничены либо timecreated, либо userid, либо courseid. (lib/classes/analytics/indicator/)
В course/lib.php есть только запрос числа событий в can_delete_course, что не часто вызывается

В dboptions есть параметр "log_all" - это конечно только для разработчиков, но если в log_query добавить 4 строк кода, то можно дешево получить определенные запросы

if(!empty($this->dboptions['logall_re'])) {
  if(preg_match($this->dboptions['logall_re'],$this->last_sql))
     error_log("query_log $logall_re ".$this->last_sql."\n",3,"/tmp/moodle.sql.log"); }
А в config.php добавить 'logall_re'=>'/SELECT.*logstore_standard_log/i'

Проблемы появились, когда пришло одновременно 1200 человек с 6000 запросами в минуту и 8-ми ядер стало нехватать (появилась полочка в загузке cpu).