Изучаем репозиторную базу Qlik Sense

Если вы управляете клиентской средой Qlik Sense среднего или крупного масштаба, вопросы о репозиторной базе данных (QSR) возникают регулярно. А если не возникают — должны бы:

  • Насколько она велика?
  • Какие таблицы растут быстрее всего?
  • Сколько хранится устаревших данных?
  • Сколько пользователей и групп в базе, и какая часть этих данных реально полезна, а какая — шум из AD/LDAP?

QSR — это база PostgreSQL, где Qlik Sense хранит свои метаданные. QMC (Qlik Management Console) даёт некоторое представление о состоянии, но не показывает метрики на уровне самой базы. А между тем детальное понимание важно для производительности. Например, если из AD или LDAP в пользовательский каталог Qlik Sense подтягивается избыточная информация, это напрямую замедляет работу всех пользователей.

Почему? Sense оценивает свои правила безопасности (security rules) против всех пользователей и групп. Даже если в правилах задействована лишь горстка. 500 групп на пользователя, из которых реально нужны 5, — это шум, который тормозит синхронизацию и вычисление правил.

Два новых open-source PowerShell-скрипта — repo-db-overview.ps1 и user-group-memberships.ps1 — подключаются напрямую к QSR и выдают эту информацию в читаемом виде в консоли. Скрипты работают в режиме чтения, не модифицируют среду и запускаются на PowerShell Core 6.0+ — Windows, macOS, Linux.

Оба скрипта входят в репозиторий qs-toolbox-public на GitHub.


Обзор QSR: repo-db-overview.ps1

repo-db-overview.ps1 даёт общую картину состояния базы. В режиме summary (по умолчанию) скрипт работает быстро, используя встроенные статистические таблицы PostgreSQL. Никаких тяжёлых запросов.

Пример вывода:

================================================================================
Qlik Sense Repository Database - Overview
================================================================================

Connection Information:
  Host:       192.168.x.x
  Port:       4432
  Database:   QSR
  User:       postgres

Database Statistics:
  Total Size:    180 MB (188 932 899 bytes)
  Tables:        164
  Users:         16

================================================================================
Qlik Sense Repository Database - Table Statistics
================================================================================

Total Tables: 164

Table Summary (sorted by size, largest first):
--------------------------------------------------------------------------------

Table Name                                               Row Count Table Size Indexes
                                                                               Size
----------                                               --------- ---------- -------
public.FileReferences                                    158 060   41 MB      6 704 kB
public.ExecutionResultDetailExecutionResults             148 824   9 544 kB   20 MB  
public.ExecutionResultDetails                            148 824   21 MB      6 176 kB
public.ExecutionResults                                  49 421    11 MB      3 336 kB
public.AppObjects                                        16 096    10 MB      2 040 kB
public._deletedentitylog                                 3 485     3 616 kB   5 456 kB
public.StaticContentReferences                           5 725     2 112 kB   376 kB 
public.Apps                                              454       168 kB     64 kB  
public.Extensions                                        83        16 kB      64 kB  
public.Users                                             185       40 kB      32 kB  
...

В данном случае основной драйвер размера — FileReferences (41 МБ). История перезагрузок (ExecutionResults и связанные таблицы) занимает ещё ~40 МБ суммарно. 180 МБ для всей базы — немного. Но понимание структуры позволяет планировать обслуживание и предсказывать рост.

Отчёт также выводит все 16 ролей базы и их разрешения. Удобно для аудита учётных записей с правами superuser или replication.

Детальный режим с точным подсчётом строк

Добавьте -DetailLevel details, чтобы выполнить точные запросы COUNT(*) по крупнейшим таблицам. Это дольше и создаёт дополнительную нагрузку. Поэтому лучше запускать в окно обслуживания. Защитный лимит по умолчанию — 10 таблиц (настраивается через -MaxExactCountTables). Таймаут каждого запроса — 60 секунд.

.\script\repo-db-overview.ps1 -DetailLevel details

Анализ членства в группах: user-group-memberships.ps1

user-group-memberships.ps1 отвечает на конкретный операционный вопрос: какие пользователи есть в репозитории, сколько групповых членств у каждого, и насколько данные о группах чистые и полезные?

Данные о группах в QSR обычно поступают из синхронизации с Active Directory или LDAP. Во многих средах синхронизация затягивает значительно больше групп, чем реально используется для контроля доступа. Рядом с горсткой групп, задействованных в security rules, оказываются Domain Users, Denied RODC Password Replication Group и прочие AD-дефолты. Со временем это засоряет репозиторий и усложняет управление пользователями.

Скрипт делает эту картину видимой.

Пример вывода:

================================================================================
Qlik Sense Repository - User Group Memberships
================================================================================

Connection Information:
  Host:       192.168.x.x
  Port:       4432
  Database:   QSR
  User:       postgres

--------------------------------------------------------------------------------
Summary Statistics:
--------------------------------------------------------------------------------

  Total Users:              185
  Users with Groups:        30
  Users without Groups:     155
  Total Group Memberships:  60
  Distinct Groups:          13

  Avg Groups per User:      0.32
  Min Groups per User:      0
  Max Groups per User:      9

--------------------------------------------------------------------------------
Table Storage:
--------------------------------------------------------------------------------

  Users:
    Rows:       185
    Size:       112 kB (114 688 bytes)
  UserAttributes:
    Rows:       62
    Size:       80 kB (81 920 bytes)

--------------------------------------------------------------------------------
Distribution: Users by Number of Group Memberships
--------------------------------------------------------------------------------

  Groups      Users       %  Bar
  -------------------------------------------------------------------
  0 groups      155   83,8%  ########################################
  1 group        24   13,0%  ######
  3 groups        2    1,1%  #
  6 groups        2    1,1%  #
  9 groups        2    1,1%  #


--------------------------------------------------------------------------------
Top 10 Users by Group Count:
--------------------------------------------------------------------------------

User Directory User ID       Name                 Group Count
-------------- -------       ----                 -----------
CORP           jdoe          Jane Doe             9
DEV            jdoe          Jane Doe             9
DEV            administrator Administrator        6
CORP           administrator Administrator        6
DEV            qlikservice   Qlik service account 3
CORP           qlikservice   Qlik service account 3
CORP           testuser_8    Testuser8            1
...


--------------------------------------------------------------------------------
Top 10 Groups by User Count:
--------------------------------------------------------------------------------

Group Name                             User Count
----------                             ----------
sense-demo-ext                         22
Denied RODC Password Replication Group 8
Administrators                         6
Domain Admins                          4
Schema Admins                          4
...

Уже наглядно: 155 из 185 пользователей не имеют ни одного членства в группах. Из 13 уникальных групп лишь одна (sense-demo-ext) содержит больше 8 членов. Гистограмма распределения показывает форму данных сразу.


Обнаружение раздутых групп с -RelevantGroups

Самая полезная с операционной точки зрения фича user-group-memberships.ps1 — параметр -RelevantGroups. Он позволяет классифицировать каждую группу в репозитории как полезную или шум. Классификация идёт по одному или нескольким паттернам подстроки без учёта регистра.

Логика проста: вы знаете, какие группы реально используются в security rules Qlik Sense. Передайте их как список подстрок через запятую. Скрипт покажет, какая доля хранимых данных о группах осмысленна, а какая — AD-шум.

.\script\user-group-memberships.ps1 -RelevantGroups "sense,qlik"

Блок анализа, добавляемый к стандартному summary:

================================================================================
Group Relevance Analysis (bloat detection)
================================================================================

  Filter patterns (case-insensitive substring match):
    - "sense"
    - "qlik"

--------------------------------------------------------------------------------
Summary:
--------------------------------------------------------------------------------

  Groups:
    Total:       13
    Relevant:    1  (7.7%)
    Bloat:       12  (92.3%)

  Membership rows (in UserAttributes):
    Total:       60
    Relevant:    22  (36.7%)
    Bloat:       38  (63.3%)

  Users (185 total):
    With relevant groups:      22
    With bloat groups:         10
    With relevant only:        20
    With bloat only:           8
    With both:                 2
    With no groups at all:     155

--------------------------------------------------------------------------------
Relevant Groups (1):
--------------------------------------------------------------------------------

Group Name     User Count
----------     ----------
sense-demo-ext 22


--------------------------------------------------------------------------------
Bloat Groups (12):
--------------------------------------------------------------------------------

Group Name                             User Count
----------                             ----------
Denied RODC Password Replication Group 8
Administrators                         6
Domain Admins                          4
Schema Admins                          4
Domain Users                           2
Enterprise Admins                      2
Group Policy Creator Owners            2
grp_1_1                                2
grp_1_2                                2
grp_2_1                                2
Guests                                 2
Users                                  2


--------------------------------------------------------------------------------
Membership Row Composition:
--------------------------------------------------------------------------------

  [RRRRRRRRRRRRRRRxxxxxxxxxxxxxxxxxxxxxxxxx]
  R = Relevant (36.7%)    x = Bloat (63.3%)

В этом тестовом окружении 12 из 13 групп — 63,3% всех строк членства — классифицируются как шум по паттернам sense,qlik. Это конкретное число, на которое можно опереться. Если та же картина в продакшене с тысячами пользователей, вы точно знаете, куда направить усилия по очистке. Или к кому из AD-команды идти с просьбой уточнить конфигурацию UDC-синхронизации (User Directory Connector — компонент Qlik Sense для загрузки пользователей из AD/LDAP).

Процент шума считается по строкам членства (парам пользователь–группа), а не просто по количеству групп. Группа с 200 участниками весит куда больше, чем группа с двумя.


Дополнительные режимы: фильтрация, списки, экспорт

Оба скрипта поддерживают несколько полезных режимов:

  • -ListUsers — список всех пользователей с количеством групп (по убыванию)
  • -ListGroups — список всех групп с количеством участников
  • -FilterUser 'DOMAIN\userId' — подробности по группам конкретного пользователя
  • -FilterGroup 'Group Name' — полный список участников конкретной группы
  • -OutputFile report.txt — запись полного отчёта в файл с меткой времени

Удобно при расследованиях. Если нужно разобраться, почему пользователь может или не может получить доступ к конкретному stream (потоку — контейнеру приложений в Qlik Sense), -FilterUser выдаст полный список его групп одним вызовом.


Требования и запуск

Минимальные требования:

  • PowerShell Core 6.0+ — работает на Windows, macOS, Linux
  • psql-клиент (PostgreSQL 12+) — скрипты вызывают psql для всех запросов к базе
  • Сетевой доступ к хосту PostgreSQL на нужном порту (по умолчанию: 4432)

Конфигурация через переменные окружения или параметры командной строки:

$env:QSR_DB_HOST     = 'qlik-sense-server.example.local'
$env:QSR_DB_PORT     = '4432'
$env:QSR_DB_NAME     = 'QSR'
$env:QSR_DB_USER     = 'postgres'
$env:QSR_DB_PASSWORD = 'your-password'

# Обзор базы
.\script\repo-db-overview.ps1

# Анализ пользователей и групп
.\script\user-group-memberships.ps1

# Обнаружение шума
.\script\user-group-memberships.ps1 -RelevantGroups 'sense,admin'

Все скрипты — только для чтения, ничего не пишут и не модифицируют в QSR. Запуск в режиме summary (по умолчанию) даёт минимальную нагрузку. Детальный режим с COUNT(*) лучше оставлять на окна обслуживания.

При запуске скрипты проверяют подключение через psql и корректно завершаются с описательной ошибкой, если база недоступна или у пользователя недостаточно прав.


Где взять скрипты

Скрипты свободны и доступны под лицензией MIT в репозитории qs-toolbox-public на GitHub:

qs-toolbox-public/
└── client-managed/
    └── powershell/
        └── repo-db-optimize/
            ├── README.md
            ├── script/
            │   ├── repo-db-overview.ps1
            │   └── user-group-memberships.ps1
            └── docs/
                ├── repo-db-overview.md
                └── user-group-memberships.md

Полная документация по каждому скрипту — в папке docs/. В README.md описаны переменные окружения, все параметры, пошаговый режим отладки и устранение неполадок.

Если вы управляете клиентской средой Qlik Sense и хотите яснее понимать свою репозиторную базу — клонируйте репозиторий и запустите скрипты. Обратная связь приветствуется через GitHub issues.