4. Проверка Компонента

4.1. Проверка Компонента «Витрина данных» конфигурации Стандарт

Процесс установки Компонента описан в разделе Установка Компонента «Витрина данных» конфигурации Стандарт.

4.1.1. Проверка ПО Prostore

Проверка ПО Prostore осуществляется путем отправки SQL-запросов к Prostore через клиентское JDBC-подключение и сопоставления ожидаемого эталонного и полученного результатов.

Проверка осуществляется согласно следующим этапам:

  1. Создайте Витрину в Prostore с помощью SQL-запроса:

CREATE DATABASE <имя несуществующей логической базы>, например,
CREATE DATABASE testdb;
  1. Создайте таблицу в Prostore со всеми типами колонок с помощью SQL-запроса:

CREATE TABLE <имя логической базы из п.1>.all_types (

- id int not null,
- double_col double,
- float_col float,
- char_col varchar(36),
- boolean_col boolean,
- int_col int not null,
- bigint_col bigint,
- date_col date,
- timestamp_col timestamp,
- primary key (id)
- )
- distributed by (id)
  1. Проверьте существование и структуру созданной таблицы в Prostore с помощью SQL-запросов:

select \* from <имя логической базы из п.1>.all_types
DATASOURCE_TYPE='ADG'

select \* from <имя логической базы из п.1>.all_types
DATASOURCE_TYPE='ADQM'

select \* from <имя логической базы из п.1>.all_types
DATASOURCE_TYPE='ADB'
  1. Удалите таблицу со всеми типами колонок из Prostore с помощью SQL-запроса:

DROP TABLE <имя логической базы из п.1>.all_types
  1. Удалите Витрину с помощью SQL-запроса:

DROP DATABASE <имя логической базы из п.1>.

Примечание

Наличие сообщений об ошибках, а также отличие получаемых состояний Prostore на различных этапах проверки от ожидаемых состояний является индикатором неуспешного прохождения проверки.

4.1.2. Проверка СМЭВ QL Сервера

4.1.2.1. Проверки и валидации

Валидации запускаются либо на все объекты данного типа (указать all), либо только на указанные, в том числе через запятую.

Доступность источников проверяется командой:

./smevql test source <all | source-name>

Валидность моделей проверяется командой:

./smevql test model <all | model-name>

4.1.3. Проверка СМЭВ3-адаптера

4.1.3.1. Проверка модуля

Для проверки модуля СМЭВ3-адаптер выполните запрос к сервису:

curl -s IP:Port/metrics | grep '^liveness '

где,

  • IP - адрес сервера.

  • Port - адрес сервера.

  • liveness - параметр проверки работоспособности модуля.

Например:

curl -s http://172.16.10.67:9837/metrics | grep '^liveness '

Пример успешного ответа:

liveness 1.0

Ответ 1 означает корректную работу модуля.

4.1.4. Проверка DATA-Uploder – Модуля исполнения асинхронных заданий

4.1.4.1. Проверка модуля

Для проверки модуля DATA-Uploader выполните запрос к сервису:

curl -s IP:Port/metrics | grep '^liveness '

где,

  • IP - адрес сервера.

  • Port - адрес сервера.

  • liveness - параметр проверки работоспособности модуля.

Например:

curl -s http://172.16.10.67:9837/metrics | grep '^liveness '

Пример успешного ответа:

liveness 1.0

Ответ 1 означает корректную работу модуля.

4.1.5. Проверка REST-Uploader – Модуля асинхронной загрузки данных из сторонних источников

4.1.5.1. Проверка модуля

Для проверки модуля REST-uploader выполните запрос к сервису:

curl -s IP:Port/metrics | grep '^liveness '

где,

  • IP - адрес сервера.

  • Port - адрес сервера.

  • liveness - параметр проверки работоспособности модуля.

Например:

curl -s http://172.16.10.67:9837/metrics | grep '^liveness '

Пример успешного ответа:

liveness 1.0

Ответ 1 означает корректную работу модуля.

4.1.6. Проверка BLOB-адаптера

4.1.6.1. Проверка модуля

Для проверки модуля Blob-адаптер выполните запрос к сервису:

curl -s IP:Port/metrics | grep '^liveness '

где,

  • IP - адрес сервера.

  • Port - адрес сервера.

  • liveness - параметр проверки работоспособности модуля.

Например

curl -s http://172.16.10.67:9837/metrics | grep '^liveness '

Пример успешного ответа:

liveness 1.0

Ответ 1 означает корректную работу модуля.

4.1.7. Проверка сервиса формирования документов

4.1.7.1. Проверка модуля

Для проверки модуля «Сервис Формирования документов» выполните запрос к сервису:

curl -s IP:Port/metrics | grep '^liveness '

где,

  • IP - адрес сервера.

  • Port - адрес сервера.

  • liveness - параметр проверки работоспособности модуля.

Например:

curl -s http://172.16.10.67:9837/metrics | grep '^liveness '

Пример успешного ответа:

liveness 1.0

Ответ 1 означает корректную работу модуля.

4.1.8. Проверка стандартного загрузчика

4.1.8.1. Проверка модуля

Для проверки стандартного загрузчика выполните запрос к сервису:

curl -s IP:Port/metrics | grep '^liveness '

где,

  • IP - адрес сервера.

  • Port - адрес сервера.

  • liveness - параметр проверки работоспособности модуля.

Например:

curl -s http://172.16.10.67:9837/metrics | grep '^liveness '

Пример успешного ответа:

liveness 1.0

Ответ 1 означает корректную работу модуля.

4.1.9. Проверка Сервиса генерации уникального номера (Counter-provider)

4.1.9.1. Проверка модуля

Для проверки модуля «Сервис генерации уникального номера» выполните запрос к сервису:

curl -s IP:Port/metrics | grep '^liveness '

где,

  • IP - адрес сервера.

  • Port - адрес сервера.

  • liveness - параметр проверки работоспособности модуля.

Например

curl -s http://172.16.10.67:9837/metrics | grep '^liveness '

Пример успешного ответа

liveness 1.0

Ответ 1 означает корректную работу модуля.

4.1.10. Проверка Агента проверок

4.1.10.1. Проверка модуля

Для проверки модуля «Агент проверок» выполните запрос к сервису:

curl -s IP:Port/metrics | grep '^liveness '

где,

  • IP - адрес сервера.

  • Port - адрес сервера.

  • liveness - параметр проверки работоспособности модуля.

Например

curl -s http://172.16.10.67:9837/metrics | grep '^liveness '

Пример успешного ответа:

liveness 1.0

Ответ 1 означает корректную работу модуля.

4.2. Проверка Компонента «Витрина данных» конфигурации Лайт

Процесс установки Компонента описан в разделе Установка Компонента «Витрина данных» конфигурации лайт.

Для проверки установки Компонента следует выполнить следующие действия:

  1. Откройте в браузере веб-интерфейс Portainer для управления docker-контейнерами по адресу IP:9000, где

  • IP - адрес сервера.

  • 9000 - порт сервера.

  1. Введите логин и пароль администратора Portainer. По умолчанию - admin/ LongPassword (Рисунок - 4.1).

Авторизация в Portainer

Рисунок - 4.1 Авторизация в Portainer

  1. Чтобы определить и автоматически настроить локальную среду нажмите значок Get Started (Рисунок - 4.2).

Окно «Quick Setup»

Рисунок - 4.2 Окно «Quick Setup»

  1. На главной странице нажмите ссылку local (Рисунок - 4.3).

Окно «Home»

Рисунок - 4.3 Окно «Home»

  1. Нажмите значок Containers (Рисунок - 4.4).

Окно «Containers»

Рисунок - 4.4 Окно «Containers»

  1. В разделе Container list сверьте наличие компонентов со списком компонентов дистрибутива Компонента, приведенных в Состав модулей в дистрибутиве документа «Техническое описание Компонента «Витрина данных»».

  2. Подключитесь к Компоненту по SSH (например, через Putty). Выполните запрос, согласно приведенному примеру ниже.

Пример запроса:

curl -X 'GET' \
  'http://localhost:9090/api/v1/versions' \
  -H 'x-request-id: 52a68e46-c062-45d7-bf3a-3fe77d0e14d3'

Пример успешного ответа (Рисунок - 4.5).

Проверка подключения к базе данных Prostore

Рисунок - 4.5 Проверка подключения к базе данных Prostore

  1. Подключитесь к Grafana.

Для этого следует перейти по адресу: http://<имя сервера>:3000 и выполнить авторизацию (указаны значения по умолчанию):

  • логин: admin;

  • пароль: admin.

Проверьте, что показатели Healthcheck Leaviness и Readiness (дашборд Lite) работают (индикатор зеленого цвета).

  1. Просмотрите лог-файл установки (ansible/ansible.log). Лог-файл не должен содержать записей с ошибками установки.

5. Обновление Компонента

5.1. Обновление Компонента конфигурации «Стандарт» с версии 1.х до версии 2.х

Для обновления Компонента с версии 1.х на 2.х реализованы варианты, приведенные в Таблица 5.1.

Таблица 5.1 Варианты обновления Компонента

Вариант

Описание

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

Время простоя на запись

Время простоя на чтение

С переиспользованием прикладной БД

Метаданные Prostore мигрируют из Zookeeper в Postgres,

прикладные данные остаются в единственном экземпляре,

с ними поочередно работают Prostore разных версий.

Требуется минимальное число дополнительных

ресурсов на время переходного процесса.

Весь процесс обновления

Время миграции метаданных Prostore + время перезапуска приложений

С поднятием 2 копий витрины

Метаданные Prostore мигрируют из Zookeeper в Postgres,

создается копия прикладных данных.

Требуются дополнительные ресурсы для

создания копии прикладных данных и для

поднятия второй копии витрины.

Весь процесс обновления

Перезапуск Агента СМЭВ4, или 0 если Агентов более 1

5.1.1. Обновление Компонента с переиспользованием прикладной БД

При использовании данного варианта обновления Компонента необходимо выполнить шаги, приведенные ниже.

5.1.1.1. Проверка резервной копии

Проверить наличие свежей резервной копии витрины: если отсутствует, создать резервную копию текущими средствами.

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

5.1.1.2. Подготовка служебной БД нового Prostore

Подготовить служебную БД нового Prostore (dtm-query-execution-core).

Запустить Prostore для инициализации и подготовки служебной БД Prostore.

Перед запуском нового Prostore нужно определить его конфигурацию. В частности разделы servicedb, raft, failover, временно нужно отключить публикацию компонент componentinfo.enabled: ${COMPONENT_INFO_ENABLED:false}.

Ниже приводятся примеры конфигурации старого и нового Prostore.

В случае запуска обоих Prostore на одном сервере, для нового Prostore указываются обособленные порты (в примерах порты метрик меняются так 8080 -> 8081, а порты API меняются так 9090 -> 9091 (в разделах raft и core.http)).

Пример конфигурации старого Prostore.
logging:
  level:
   ru.datamart.prostore: ${DTM_LOGGING_LEVEL:DEBUG}

server:
  port: ${DTM_METRICS_PORT:8080}

pnode:
  host: ${PNODE_HOST:}
  httpPort: ${PNODE_HTTP_PORT:}
  leaderlessEnabled: ${PNODE_LEADERLESS_ENABLED:false}

springdoc:
  api-docs:
   enabled: false
  swagger-ui:
   url: /openapi.yml
   path: /swagger-ui

management:
  endpoints:
    enabled-by-default: ${DTM_METRICS_ENABLED:true}
    web:
      exposure:
        include: ${DTM_METRICS_SCOPE:info, health}
endpoint:
  health:
    show-components: always
     probes:
       enabled: true
     group:
       readiness:
        showDetails: always
        include:
          - readinessState
          - dtmState
       startup:
        showDetails: always
        include:
           - dtmState
core:
  plugins:
    active: ${CORE_PLUGINS_ACTIVE:ADP}
    category:
      mapping:
        RELATIONAL: ${DTM_CORE_PLUGINS_RELATIONAL:ADB, ADP, ADQM, ADG}
        ANALYTICAL: ${DTM_CORE_PLUGINS_ANALYTICAL:ADQM, ADB, ADP, ADG}
        DICTIONARY: ${DTM_CORE_PLUGINS_DICTIONARY:ADG, ADB, ADP, ADQM}
        UNDEFINED: ${DTM_CORE_PLUGINS_UNDEFINED:ADB, ADP, ADQM, ADG}
        WITHOUT_FROM: ${DTM_CORE_PLUGINS_WITHOUT_FROM:ADP, ADB, ADQM, ADG}

http:
  port: ${DTM_CORE_HTTP_PORT:9090}
  tcpNoDelay: ${DTM_CORE_HTTP_TCP_NO_DELAY:true}
  tcpFastOpen: ${DTM_CORE_HTTP_TCP_FAST_OPEN:true}
  tcpQuickAck: ${DTM_CORE_HTTP_TCP_QUICK_ACK:true}
  http2WindowSize: ${DTM_CORE_HTTP2_WINDOW_SIZE:1048576}

webclient:
  tcpNoDelay: ${DTM_CORE_WEBCLIENT_TCP_NO_DELAY:true}
  tcpFastOpen: ${DTM_CORE_WEBCLIENT_TCP_FAST_OPEN:true}
  tcpQuickAck: ${DTM_CORE_WEBCLIENT_TCP_QUICK_ACK:true}
  connectionTimeoutMs: ${DTM_CORE_WEBCLIENT_CONNECTION_TIMEOUT_MS:30000}
  poolSize: ${DTM_CORE_WEBCLIENT_POOL_SIZE:20}
  http2PoolSize: ${DTM_CORE_WEBCLIENT_HTTP2_POOL_SIZE:20}
  http2KeepAliveSec: ${DTM_CORE_WEBCLIENT_HTTP2_KEEP_ALIVE_SEC:0}

privateapiwebclient:
  tcpNoDelay: ${DTM_CORE_WEBCLIENT_LEADER_TCP_NO_DELAY:true}
  tcpFastOpen: ${DTM_CORE_WEBCLIENT_LEADER_TCP_FAST_OPEN:true}
  tcpQuickAck: ${DTM_CORE_WEBCLIENT_LEADER_TCP_QUICK_ACK:true}
  connectionTimeoutMs: ${DTM_CORE_WEBCLIENT_LEADER_CONNECTION_TIMEOUT_MS:2000}
  poolSize: ${DTM_CORE_WEBCLIENT_LEADER_POOL_SIZE:20}
  http2PoolSize: ${DTM_CORE_WEBCLIENT_LEADER_HTTP2_POOL_SIZE:20}
  http2KeepAliveSec: ${DTM_CORE_WEBCLIENT_LEADER_HTTP2_KEEP_ALIVE_SEC:0}

env:
  name: ${DTM_NAME:test}

prometheus:
  enabled: ${PROMETHEUS_ENABLED:true}

auth:
  jwksUri: ${AUTH_JWKS_URI:}
  defaultRoles: ${CORE_DEFAULT_ROLES:env_owner}

restoration:
  autoRestoreState: ${AUTO_RESTORE_STATE:true}

matviewsync:
  periodMs: ${MATERIALIZED_VIEWS_SYNC_PERIOD_MS:5000}
  retryCount: ${MATERIALIZED_VIEWS_RETRY_COUNT:10}
  maxConcurrent: ${MATERIALIZED_VIEWS_CONCURRENT:2}

datacooling:
  periodMs: ${DATA_COOLING_RUN_PERIOD_MS:600000}
  maxConcurrent: ${DATA_COOLING_CONCURRENT:2}
  checkQueriesPeriodMs: ${DATA_COOLING_CHECK_QUERIES_PERIOD_MS:30000}
  checkTrimPeriodMs: ${DATA_COOLING_CHECK_TRIM_PERIOD_MS:30000}

ddlqueue:
  enabled: ${CORE_DDL_QUEUE_ENABLED:true}

tslog:
  maxDepth: ${TSLOG_MAX_DEPTH:2}
  pageSize: ${TSLOG_PAGE_SIZE:1600}

jet:
  connectionString: ${KAFKA_JET_WRITERS:}
  consumerGroup: ${KAFKA_JET_CONSUMER_GROUP:jet-load}
  pollDurationMs: ${KAFKA_JET_POLL_DURATION_MS:1000}
  pollBufferSize: ${KAFKA_JET_POLL_BUFFER_SIZE:1000}
  dbBufferSize: ${KAFKA_JET_DB_BUFFER_SIZE:10000}
  getTimeoutMs: ${KAFKA_JET_GET_TIMEOUT_MS:5000}
  checkTimeoutMs: ${KAFKA_JET_CHECK_TIMEOUT_MS:2000}
  retryCount: ${KAFKA_JET_RETRY_COUNT:1}

datasource:
  edml:
    defaultChunkSize: ${EDML_DEFAULT_CHUNK_SIZE:1000}
    pluginStatusCheckPeriodMs: ${EDML_STATUS_CHECK_PERIOD_MS:1000}
    firstOffsetTimeoutMs: ${EDML_FIRST_OFFSET_TIMEOUT_MS:15000}
    changeOffsetTimeoutMs: ${EDML_CHANGE_OFFSET_TIMEOUT_MS:10000}
  zookeeper:
    connection-string: ${ZOOKEEPER_DS_ADDRESS:localhost}
    connection-timeout-ms: ${ZOOKEEPER_DS_CONNECTION_TIMEOUT_MS:30000}
    session-timeout-ms: ${ZOOKEEPER_DS_SESSION_TIMEOUT_MS:86400000}
    chroot: ${ZOOKEEPER_DS_CHROOT:/adtm}
    connectionRetryCount: ${ZOOKEEPER_DS_CONNECTION_RETRY_COUNT:0}
    optimisticRetryCount: ${ZOOKEEPER_DS_OPTIMISTIC_RETRY_COUNT:20}
    writeOptimisticRetryCount: ${ZOOKEEPER_DS_WRITE_OPTIMISTIC_RETRY_COUNT:1000}
    maxSequenceSize: ${ZOOKEEPER_DS_MAX_SEQUENCE_SIZE:2000000000}

streaming:
  upload:
    dbBatchSize: ${STREAMING_UPLOAD_DB_BATCH_SIZE:1000}
    dbBufferSize: ${STREAMING_UPLOAD_DB_BUFFER_SIZE:10000}
    inputBufferSizeMb: ${STREAMING_UPLOAD_INPUT_BUFFER_SIZE_MB:10}

csvparser:
  separator: ${CSV_PARSER_SEPARATOR:;}
  quoteChar: ${CSV_PARSER_QUOTE_CHAR:"}
  escapeChar: ${CSV_PARSER_ESCAPE_CHAR:'}
  fieldAsNull: ${CSV_PARSER_FIELD_AS_NULL:EMPTY_SEPARATORS}

kafka:
  getOffsetsRetryCount: ${ZOOKEEPER_KAFKA_GET_OFFSETS_RETRY_COUNT:3}
  getOffsetsRetryTimeoutMs: ${ZOOKEEPER_KAFKA_GET_OFFSETS_RETRY_TIMEOUT_MS:1000}
  producer:
    property:
      key.serializer: org.apache.kafka.common.serialization.StringSerializer
      value.serializer: org.apache.kafka.common.serialization.StringSerializer
  consumer:
    property:
      key.deserializer: org.apache.kafka.common.serialization.ByteArrayDeserializer
      value.deserializer: org.apache.kafka.common.serialization.ByteArrayDeserializer
  cluster:
    zookeeper:
      connection-string: ${ZOOKEEPER_KAFKA_ADDRESS:localhost}
      connection-timeout-ms: ${ZOOKEEPER_KAFKA_CONNECTION_TIMEOUT_MS:30000}
      session-timeout-ms: ${ZOOKEEPER_KAFKA_SESSION_TIMEOUT_MS:86400000}
      chroot: ${ZOOKEEPER_KAFKA_CHROOT:}
      connectionRetryCount: ${ZOOKEEPER_KAFKA_CONNECTION_RETRY_COUNT:1}
  admin:
    inputStreamTimeoutMs: ${KAFKA_INPUT_STREAM_TIMEOUT_MS:2000}
  status.event.publish:
    topic: ${KAFKA_STATUS_EVENT_TOPIC:status.event.topic}
    enabled: ${KAFKA_STATUS_EVENT_ENABLED:false}
    writeOperationsEnabled: ${KAFKA_STATUS_EVENT_WRITE_OPERATIONS_ENABLED:false}
    externalDDLEnabled: ${KAFKA_STATUS_EVENT_EXTERNAL_DDL_ENABLED:false}

vertx:
  blocking-stacktrace-time: ${DTM_VERTX_BLOCKING_STACKTRACE_TIME:1}
  pool:
    worker-pool: ${DTM_CORE_WORKER_POOL_SIZE:20}
    event-loop-pool: ${DTM_CORE_EVENT_LOOP_POOL_SIZE:20}
    task-pool: ${DTM_CORE_TASK_POOL_SIZE:20}
    task-timeout: ${DTM_CORE_TASK_TIMEOUT:86400000}

cache:
  initialCapacity: ${CACHE_INITIAL_CAPACITY:100000}
  maximumSize: ${CACHE_MAXIMUM_SIZE:100000}
  expireAfterAccessMinutes: ${CACHE_EXPIRE_AFTER_ACCESS_MINUTES:99960}

delta:
  rollback-status-calls-ms: ${DELTA_ROLLBACK_STATUS_CALLS_MS:2000}
  rollbackRetryCount: ${DELTA_ROLLBACK_RETRY_COUNT:3}
  rollbackRetryTimeoutMs: ${DELTA_ROLLBACK_RETRY_TIMEOUT_MS:1000}
  rollbackOperationsTimeoutMs: ${DELTA_ROLLBACK_OPERATIONS_TIMEOUT_MS:29000}

writeoperation:
  rollbackRetryCount: ${WRITE_OPERATION_ROLLBACK_RETRY_COUNT:3}
  rollbackRetryTimeoutMs: ${WRITE_OPERATION_ROLLBACK_RETRY_TIMEOUT_MS:1000}

statistics:
  enabled: ${CORE_STATISTICS_ENABLED:true}
  threadsCount: ${CORE_STATISTICS_THREADS_COUNT:2}
  dataCountEnabled: ${CORE_STATISTICS_DATA_COUNT_ENABLED:true}
  dataCountPeriodMs: ${CORE_STATISTICS_DATA_COUNT_PERIOD_MS:0}

poststatusevent:
  subscriberGroup:
    - endpointUrl: ${POST_STATUS_EVENT_SUBSCRIBER_GROUP_ENDPOINT_URL:}
      endpointTimeoutMs: ${POST_STATUS_EVENT_SUBSCRIBER_GROUP_ENDPOINT_TIMEOUT_MS:5000}
      endpointRetryTimeoutMs: ${POST_STATUS_EVENT_SUBSCRIBER_GROUP_ENDPOINT_RETRY_TIMEOUT_MS:5000}
      bufferingPeriodMs: ${POST_STATUS_EVENT_SUBSCRIBER_GROUP_BUFFERING_PERIOD_MS:0}
      bufferSize: ${POST_STATUS_EVENT_SUBSCRIBER_GROUP_BUFFER_SIZE:1000}
      writeOperationsEnabled: ${POST_STATUS_EVENT_SUBSCRIBER_GROUP_WRITE_OPERATIONS_ENABLED:false}
      externalDDLEnabled: ${POST_STATUS_EVENT_SUBSCRIBER_GROUP_EXTERNAL_DDL_ENABLED:false}

adp:
  datasource:
    - name: ADP
      env: ${ADP_ENV_NAME:${DTM_NAME:test}}
      user: ${ADP_USERNAME:postgres}
      password: ${ADP_PASS:postgres}
      host: ${ADP_HOST:localhost}
      port: ${ADP_PORT:5432}
      poolSize: ${ADP_MAX_POOL_SIZE:3}
      executorsCount: ${ADP_EXECUTORS_COUNT:3}
      poolRequestTimeout: ${ADP_POOL_REQUEST_TIMEOUT:0}
      preparedStatementsCacheMaxSize: ${ADP_PREPARED_CACHE_MAX_SIZE:256}
      preparedStatementsCacheSqlLimit: ${ADP_PREPARED_CACHE_SQL_LIMIT:2048}
      preparedStatementsCache: ${ADP_PREPARED_CACHE:true}
      idleTimeoutMs: ${ADP_IDLE_TIMEOUT_MS:60000}
      maxLifetimeTimeoutMs: ${ADP_MAX_LIFETIME_TIMEOUT_MS:0}
      mppw:
        restStartLoadUrl: ${ADP_REST_START_LOAD_URL:http://localhost:8096/newdata/start}
        restStopLoadUrl: ${ADP_REST_STOP_LOAD_URL:http://localhost:8096/newdata/stop}
        restVersionUrl: ${ADP_MPPW_CONNECTOR_VERSION_URL:http://localhost:8096/versions}
        restGetEndpoint: ${ADP_MPPW_GET_ENDPOINT:/newdata/get}
        kafkaConsumerGroup: ${ADP_KAFKA_CONSUMER_GROUP:adp-load}
        restGetTimeoutMs: ${ADP_REST_GET_TIMEOUT_MS:5000}
        checkTimeoutMs: ${ADP_MPPW_CONNECTOR_CHECK_TIMEOUT_MS:2000}
        retryCount: ${ADP_MPPW_CONNECTOR_RETRY_COUNT:1}
      mppr:
        restLoadUrl: ${ADP_MPPR_QUERY_URL:http://localhost:8094/query}
        restVersionUrl: ${ADP_MPPR_CONNECTOR_VERSION_URL:http://localhost:8094/versions}
        checkTimeoutMs: ${ADP_MPPR_CONNECTOR_CHECK_TIMEOUT_MS:2000}
        retryCount: ${ADP_MPPR_CONNECTOR_RETRY_COUNT:1}
Пример конфигурации нового Prostore.
logging:
  level:
   ru.datamart.prostore: ${DTM_LOGGING_LEVEL:DEBUG}

server:
  port: ${DTM_METRICS_PORT:8081}

springdoc.swagger-ui:
  url: /openapi.yml
  path: /swagger-ui

management:
  endpoints:
    enabled-by-default: ${DTM_METRICS_ENABLED:true}
    web:
      exposure:
        include: ${DTM_METRICS_SCOPE:info}
core:
  plugins:
   active: ${CORE_PLUGINS_ACTIVE:ADP}
   category:
     mapping:
       RELATIONAL: ${DTM_CORE_PLUGINS_RELATIONAL:ADB, ADP, ADQM, ADG}
       ANALYTICAL: ${DTM_CORE_PLUGINS_ANALYTICAL:ADQM, ADB, ADP, ADG}
       DICTIONARY: ${DTM_CORE_PLUGINS_DICTIONARY:ADG, ADB, ADP, ADQM}
       UNDEFINED: ${DTM_CORE_PLUGINS_UNDEFINED:ADB, ADP, ADQM, ADG}
       WITHOUT_FROM: ${DTM_CORE_PLUGINS_WITHOUT_FROM:ADP, ADB, ADQM, ADG}

http:
  port: ${DTM_CORE_HTTP_PORT:9091}
  tcpNoDelay: ${DTM_CORE_HTTP_TCP_NO_DELAY:true}
  tcpFastOpen: ${DTM_CORE_HTTP_TCP_FAST_OPEN:true}
  tcpQuickAck: ${DTM_CORE_HTTP_TCP_QUICK_ACK:true}
  http2WindowSize: ${DTM_CORE_HTTP2_WINDOW_SIZE:1048576}
  maxRequestSize: ${DTM_CORE_HTTP_MAX_REQUEST_SIZE:-1}

webclient:
  tcpNoDelay: ${DTM_CORE_WEBCLIENT_TCP_NO_DELAY:true}
  tcpFastOpen: ${DTM_CORE_WEBCLIENT_TCP_FAST_OPEN:true}
  tcpQuickAck: ${DTM_CORE_WEBCLIENT_TCP_QUICK_ACK:true}
  priorKnowledgeHttp2: ${DTM_CORE_WEBCLIENT_PRIOR_KNOWLEDGE:true}
  connectionTimeoutMs: ${DTM_CORE_WEBCLIENT_CONNECTION_TIMEOUT_MS:30000}
  poolSize: ${DTM_CORE_WEBCLIENT_POOL_SIZE:20}
  http2PoolSize: ${DTM_CORE_WEBCLIENT_HTTP2_POOL_SIZE:20}
  http2KeepAliveSec: ${DTM_CORE_WEBCLIENT_HTTP2_KEEP_ALIVE_SEC:0}

privateapiwebclient:
  tcpNoDelay: ${DTM_CORE_WEBCLIENT_LEADER_TCP_NO_DELAY:true}
  tcpFastOpen: ${DTM_CORE_WEBCLIENT_LEADER_TCP_FAST_OPEN:true}
  tcpQuickAck: ${DTM_CORE_WEBCLIENT_LEADER_TCP_QUICK_ACK:true}
  priorKnowledgeHttp2: ${DTM_CORE_WEBCLIENT_LEADER_PRIOR_KNOWLEDGE:true}
  connectionTimeoutMs: ${DTM_CORE_WEBCLIENT_LEADER_CONNECTION_TIMEOUT_MS:2000}
  poolSize: ${DTM_CORE_WEBCLIENT_LEADER_POOL_SIZE:20}
  http2PoolSize: ${DTM_CORE_WEBCLIENT_LEADER_HTTP2_POOL_SIZE:20}
  http2KeepAliveSec: ${DTM_CORE_WEBCLIENT_LEADER_HTTP2_KEEP_ALIVE_SEC:0}

env:
name: ${DTM_NAME:test}

prometheus:
 enabled: ${PROMETHEUS_ENABLED:true}

auth:
  jwksUri: ${AUTH_JWKS_URI:}
  defaultRoles: ${CORE_DEFAULT_ROLES:env_owner}

matviewsync:
  enabled: ${MATERIALIZED_VIEWS_SYNC_ENABLED:true}
  periodMs: ${MATERIALIZED_VIEWS_SYNC_PERIOD_MS:900000}
  maxConcurrent: ${MATERIALIZED_VIEWS_CONCURRENT:20}

datacooling:
  periodMs: ${DATA_COOLING_RUN_PERIOD_MS:600000}
  maxConcurrent: ${DATA_COOLING_CONCURRENT:2}

raft:
  myId: ${RAFT_ID:1}
  servers:
    pnode.1: ${RAFT_SERVER_1:127.0.0.1:9091}
  minTimeout: ${RAFT_MIN_TIMEOUT_MS:5000}
  maxTimeout: ${RAFT_MAX_TIMEOUT_MS:7000}
  heartbeatPeriod: ${RAFT_HEARTBEAT_PERIOD_MS:100}
  appendLogsBatchSize: ${APPEND_LOGS_BATCH_SIZE:1000}
  appendLogsBatchSizeBytes: ${APPEND_LOGS_BATCH_SIZE_BYTES:1048576}
  appendEntriesResendDelay: ${RAFT_APPEND_ENTRIES_RESEND_DELAY_MS:0}
  appendEntriesRetryDelay: ${RAFT_APPEND_ENTRIES_RETRY_DELAY_MS:10}
  snapshotPeriod: ${RAFT_SNAPSHOT_PERIOD_MS:600000}
  optimisticRetryCount: ${RAFT_OPTIMISTIC_RETRY_COUNT:40}
  writeOptimisticRetryCount: ${RAFT_WRITE_OPTIMISTIC_RETRY_COUNT:1000}
  callRetryCount: ${DTM_CORE_WEBCLIENT_LEADER_CALL_RETRY_COUNT:100}
  callRetryTimeoutMs: ${DTM_CORE_WEBCLIENT_LEADER_CALL_RETRY_TIMEOUT_MS:1000}
  logsCachingLimit: ${LOGS_CACHING_LIMIT:1000}

   servicedb:
     db: ${RAFT_SERVICEDB_DATABASE:test}
     schema: ${RAFT_SERVICEDB_SCHEMA:sys1}
     user: ${RAFT_SERVICEDB_USER:postgres}
     password: ${RAFT_SERVICEDB_PASS:postgres}
     host: ${RAFT_SERVICEDB_HOST:localhost}
     port: ${RAFT_SERVICEDB_PORT:5432}
     poolSize: ${RAFT_SERVICEDB_MAX_POOL_SIZE:3}
     executorsCount: ${RAFT_SERVICEDB_EXECUTORS_COUNT:3}
     poolRequestTimeout: ${RAFT_SERVICEDB_POOL_REQUEST_TIMEOUT:0}
     preparedStatementsCacheMaxSize: ${RAFT_SERVICEDB_PREPARED_CACHE_MAX_SIZE:256}
     preparedStatementsCacheSqlLimit: ${RAFT_SERVICEDB_PREPARED_CACHE_SQL_LIMIT:2048}
     preparedStatementsCache: ${RAFT_SERVICEDB_PREPARED_CACHE:true}
     idleTimeoutMs: ${RAFT_SERVICEDB_IDLE_TIMEOUT_MS:60000}
     maxLifetimeTimeoutMs: ${RAFT_SERVICEDB_MAX_LIFETIME_TIMEOUT_MS:0}
     fetchSize: ${RAFT_SERVICEDB_FETCH_SIZE:100}

   entityttl:
     checkPeriodMs: ${ENTITY_TTL_CHECK_PERIOD_MS:30000}

datasource:
  edml:
    defaultChunkSize: ${EDML_DEFAULT_CHUNK_SIZE:1000}
    pluginStatusCheckPeriodMs: ${EDML_STATUS_CHECK_PERIOD_MS:1000}
    firstOffsetTimeoutMs: ${EDML_FIRST_OFFSET_TIMEOUT_MS:15000}
    changeOffsetTimeoutMs: ${EDML_CHANGE_OFFSET_TIMEOUT_MS:10000}

streaming:
  upload:
    dbBatchSize: ${STREAMING_UPLOAD_DB_BATCH_SIZE:1000}
    dbBufferSize: ${STREAMING_UPLOAD_DB_BUFFER_SIZE:10000}
    inputBufferSizeMb: ${STREAMING_UPLOAD_INPUT_BUFFER_SIZE_MB:10}

csvparser:
  separator: ${CSV_PARSER_SEPARATOR:;}
  quoteChar: ${CSV_PARSER_QUOTE_CHAR:"}
  escapeChar: ${CSV_PARSER_ESCAPE_CHAR:'}
  fieldAsNull: ${CSV_PARSER_FIELD_AS_NULL:EMPTY_SEPARATORS}

kafka:
  getOffsetsRetryCount: ${ZOOKEEPER_KAFKA_GET_OFFSETS_RETRY_COUNT:3}
  getOffsetsRetryTimeoutMs: ${ZOOKEEPER_KAFKA_GET_OFFSETS_RETRY_TIMEOUT_MS:1000}
  producer:
    property:
      key.serializer: org.apache.kafka.common.serialization.StringSerializer
      value.serializer: org.apache.kafka.common.serialization.StringSerializer
  consumer:
    property:
      key.deserializer: org.apache.kafka.common.serialization.ByteArrayDeserializer
      value.deserializer: org.apache.kafka.common.serialization.ByteArrayDeserializer
  cluster:
    zookeeper:
      connection-string: ${ZOOKEEPER_KAFKA_ADDRESS:}
      connection-timeout-ms: ${ZOOKEEPER_KAFKA_CONNECTION_TIMEOUT_MS:30000}
      session-timeout-ms: ${ZOOKEEPER_KAFKA_SESSION_TIMEOUT_MS:86400000}
      chroot: ${ZOOKEEPER_KAFKA_CHROOT:}
      connectionRetryCount: ${ZOOKEEPER_KAFKA_CONNECTION_RETRY_COUNT:1}
  admin:
    inputStreamTimeoutMs: ${KAFKA_INPUT_STREAM_TIMEOUT_MS:2000}
  status.event.publish:
    topic: ${KAFKA_STATUS_EVENT_TOPIC:status.event.topic}
    enabled: ${KAFKA_STATUS_EVENT_ENABLED:false}
    writeOperationsEnabled: ${KAFKA_STATUS_EVENT_WRITE_OPERATIONS_ENABLED:false}
    externalDDLEnabled: ${KAFKA_STATUS_EVENT_EXTERNAL_DDL_ENABLED:false}

vertx:
  blocking-stacktrace-time: ${DTM_VERTX_BLOCKING_STACKTRACE_TIME:1}
  pool:
    worker-pool: ${DTM_CORE_WORKER_POOL_SIZE:20}
    event-loop-pool: ${DTM_CORE_EVENT_LOOP_POOL_SIZE:20}

cache:
  initialCapacity: ${CACHE_INITIAL_CAPACITY:100000}
  maximumSize: ${CACHE_MAXIMUM_SIZE:100000}
  expireAfterAccessMinutes: ${CACHE_EXPIRE_AFTER_ACCESS_MINUTES:99960}

delta:
  rollback-status-calls-ms: ${DELTA_ROLLBACK_STATUS_CALLS_MS:2000}
  rollbackRetryCount: ${DELTA_ROLLBACK_RETRY_COUNT:0}
  rollbackRetryTimeoutMs: ${DELTA_ROLLBACK_RETRY_TIMEOUT_MS:1000}
  rollbackOperationsTimeoutMs: ${DELTA_ROLLBACK_OPERATIONS_TIMEOUT_MS:29000}

writeoperation:
  rollbackRetryCount: ${WRITE_OPERATION_ROLLBACK_RETRY_COUNT:0}
  rollbackRetryTimeoutMs: ${WRITE_OPERATION_ROLLBACK_RETRY_TIMEOUT_MS:1000}
  activityCheckPeriodMs: ${WRITE_OPERATION_ACTIVITY_CHECK_PERIOD_MS:10000}
  activityCheckTimeoutMs: ${WRITE_OPERATION_ACTIVITY_CHECK_TIMEOUT_MS:120000}

recover:
  loopTimeoutMs: ${RECOVER_LOOP_TIMEOUT_MS:60000}

statistics:
  enabled: ${CORE_STATISTICS_ENABLED:true}
  threadsCount: ${CORE_STATISTICS_THREADS_COUNT:2}
  dataCountEnabled: ${CORE_STATISTICS_DATA_COUNT_ENABLED:true}
  dataCountCheckPeriodMs: ${CORE_STATISTICS_DATA_COUNT_CHECK_PERIOD_MS:10000}

poststatusevent:
  subscriberGroup:
    - endpointUrl: ${POST_STATUS_EVENT_SUBSCRIBER_GROUP_ENDPOINT_URL:}
      endpointTimeoutMs: ${POST_STATUS_EVENT_SUBSCRIBER_GROUP_ENDPOINT_TIMEOUT_MS:5000}
      endpointRetryTimeoutMs: ${POST_STATUS_EVENT_SUBSCRIBER_GROUP_ENDPOINT_RETRY_TIMEOUT_MS:5000}
      bufferingPeriodMs: ${POST_STATUS_EVENT_SUBSCRIBER_GROUP_BUFFERING_PERIOD_MS:0}
      bufferSize: ${POST_STATUS_EVENT_SUBSCRIBER_GROUP_BUFFER_SIZE:1000}
      writeOperationsEnabled: ${POST_STATUS_EVENT_SUBSCRIBER_GROUP_WRITE_OPERATIONS_ENABLED:false}
      externalDDLEnabled: ${POST_STATUS_EVENT_SUBSCRIBER_GROUP_EXTERNAL_DDL_ENABLED:false}

agent:
  endpointUrl: ${AGENT_ENDPOINT_URL:}
  endpointGetCnTimeoutMs: ${AGENT_ENDPOINT_GET_CN_TIMEOUT_MS:60000}
  endpointQueryTimeoutMs: ${AGENT_ENDPOINT_QUERY_TIMEOUT_MS:3600000}
  dbBatchSize: ${AGENT_DB_BATCH_SIZE:1000}
  dbBufferSize: ${AGENT_DB_BUFFER_SIZE:10000}
  inputBufferSizeMb: ${AGENT_INPUT_BUFFER_SIZE_MB:10}

componentinfo:
  enabled: ${COMPONENT_INFO_ENABLED:false}
  datamart: ${COMPONENT_INFO_DATAMART:component_info}
  tableComponents: ${COMPONENT_INFO_TABLE_COMPONENTS:component_info}
  publishPeriodMs: ${COMPONENT_INFO_PUBLISH_PERIOD_MS:60000}
  timeoutActiveMs: ${COMPONENT_INFO_TIMEOUT_ACTIVE_MS:300000}

secrets:
  core:
    raft:
      servicedb:
      user:
      password:
  adb:
    datasource:
      user:
      password:
  adg:
    datasource:
      user:
      password:
  adqm:
    datasource:
      user:
      password:
  adp:
    datasource:
      user:
      password:

autofailover:
  enabled: ${AUTOFAILOVER_ENABLED:false}
  checkPeriodMs: ${AUTOFAILOVER_CHECK_PERIOD_MS:10000}
  waitTimeoutMs: ${AUTOFAILOVER_WAIT_TIMEOUT_MS:2000}
  failsLimit: ${AUTOFAILOVER_FAILS_LIMIT:3}
  healingConfirm: ${AUTOFAILOVER_HEALING_CONFIRM:3}
  startupDelayMs: ${AUTOFAILOVER_STARTUP_DELAY_MS:120000}
  execPeriodMs: ${AUTOFAILOVER_EXEC_PERIOD_MS:2000}
  minSyncReplicas: ${AUTOFAILOVER_MIN_SYNC_REPLICAS:1}
  recoverBatchPeriodMs: ${AUTOFAILOVER_RECOVER_BATCH_PERIOD_MS:10000}
  failedRetryTimeoutMs: ${AUTOFAILOVER_FAILED_RETRY_TIMEOUT_MS:60000}

adp:
  datasource:
    - name: ADP
      env: ${ADP_ENV_NAME:${DTM_NAME:test}}
      user: ${ADP_USERNAME:postgres}
      password: ${ADP_PASS:postgres}
      host: ${ADP_HOST:localhost}
      port: ${ADP_PORT:5432}
      poolSize: ${ADP_MAX_POOL_SIZE:3}
      executorsCount: ${ADP_EXECUTORS_COUNT:3}
      poolRequestTimeout: ${ADP_POOL_REQUEST_TIMEOUT:0}
      preparedStatementsCacheMaxSize: ${ADP_PREPARED_CACHE_MAX_SIZE:256}
      preparedStatementsCacheSqlLimit: ${ADP_PREPARED_CACHE_SQL_LIMIT:2048}
      preparedStatementsCache: ${ADP_PREPARED_CACHE:true}
      idleTimeoutMs: ${ADP_IDLE_TIMEOUT_MS:60000}
      maxLifetimeTimeoutMs: ${ADP_MAX_LIFETIME_TIMEOUT_MS:0}
      autofailoverPriority: ${ADP_AUTOFAILOVER_PRIORITY:}

Запустить новый Postore для иницализации служебной БД. Новому Postore (7.1+) нужна Java 17, в то время как старому Postore нужна Java 8:

java --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.time=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED -jar dtm-query-execution-core-7.4.0.jar

Внимание

В этот момент данном примере два экземпляра Postore разных версий имеют общую прикладную базу, но различные служебные базы, любые действия в новом Postore недопустимы, поскольку это приведет к рассинхронизации метаданных с данными в старом Postore!

Необходимо проверить, что создана схема для служебной БД, для кофигурации из примера база test, схема sys1, если не создана, нужно изучить настройки нового Postore и лог на предмет ошибок, повторить запуск после устранения проблем.

Выключить новый Postore.

5.1.1.3. Остановка Компонента версии 1.х

  1. Запомнить настройки модулей адаптера.

В CSV-Uploader:

  • открыть веб интерфейс;

  • перейти на вкладку «Настройки»;

  • сохранить значения параметров: «Запуск по расписанию», «Забирать CSV из каталога», «Включить».

  1. Снять резервную копию конфигурации Агента СМЭВ4.

  2. Остановить загрузку данных:

  • отключить доступ всем пользователям к инструментам загрузки;

  • периодически проверять длину очереди на загрузку (когда длина очереди на згрузку будет равна 0, перейти к следующему пункту);

  1. Выключить Агент СМЭВ4.

  2. Выключить модули Компонента:

  • blob-adapter;

  • check-adapter;

  • counter-provider;

  • csv-uploader;

  • data-uploader;

  • dtm-uploader;

  • podd-adapter-group-repl;

  • podd-adapter-group-tp;

  • podd-adapter-import-tp;

  • podd-adapter-mppr;

  • podd-adapter-mppw;

  • podd-adapter-mppr;

  • podd-adapter-query;

  • podd-adapter-replicator;

  • podd-adapter-avro-defragmentator;

  • printable-form-service;

  • rest-adapter;

  • rest-uploader;

  • smev3-adapter;

  • smevql-server.

5.1.1.4. Миграция метаданных Postore

1. Выполнить перенос метаданных (Серисной БД) из Zookeeper в Postgres-совместимые СУБД для обновления кластера Prostore с версии 6.х на версию 7.х согласно инструкции, в том числе:

  • Выключить старый Postore (новый выключен ранее);

  • Снять резервную копию прикладной БД средствами БД (нет в документации Postore!).

Внимание

Резервную копию снять обязательно! Данный бекап может потребоваться если понадобится откатываться на предыдущую версию витрины.

Пример команды бэкапирования:

sudo -u postgres pg_dump test > test.sql

Можно воспользоваться командой pg_dumpall для дампа вместе с ролями, правами и т.д. Пример команды pg_dumpall:

sudo pg_dumpall -u postgres > test.sql
  • Выполнить миграцию метаданных Postore. Пример команды миграции метаданных приведен для настроек Postore, приведенных выше:

java -jar dtm-tools-1.23.0.jar zk2pg --zk localhost:2181/adtm/test --datamarts foo --pg 'localhost:5432/tests?user=postgres&password=postgres' --schema sys1

Внимание

Перед выполнением команды запрос get_delta_ok() должен возвращать ответ. Если ответ не возвращается, необходимо открыть и закрыть дельту. Также необходимо проверить наличие горячих дельт get_delta_hot(), и активных операций записи get_write_operations().

Команда выполняется из директории где расположен dtm-tools. Сервис dtm-tools необходимо брать из нового дистрибутива!

При успешной миграции вывод завершается строкой «Transfer from zookeeper to pg successfully finished».

В случае ошибок, необходимо выполнить анализ, устранить и повторить миграцию в соответствии с пунктом 7 инструкции.

  1. Обновить PostgreSQL. Для Postore 6.x используется PostgreSQL 13.14, для Postore 7.х нужен PostgreSQL 16.8.

5.1.1.5. Включение Компонента версии 2.х

  1. Переключить новый Postore на прежние порты (в примере 8081-> 8080 и 9091 -> 9090( в разделах raft и core.http)), новый Postore остается нацелен на прикладную базу данных, общую со старым Простором, чтобы не тратить время на переезд самих прикладных данных.

  2. Включить публикации данных о компонентах, в секции componentinfo.

Пример конфигурации с восстановленными портами
logging:
  level:
    ru.datamart.prostore: ${DTM_LOGGING_LEVEL:DEBUG}

server:
  port: ${DTM_METRICS_PORT:8080}

springdoc.swagger-ui:
  url: /openapi.yml
  path: /swagger-ui

management:
  endpoints:
    enabled-by-default: ${DTM_METRICS_ENABLED:true}
    web:
      exposure:
      include: ${DTM_METRICS_SCOPE:info}
core:
  plugins:
    active: ${CORE_PLUGINS_ACTIVE:ADP}
    category:
      mapping:
        RELATIONAL: ${DTM_CORE_PLUGINS_RELATIONAL:ADB, ADP, ADQM, ADG}
        ANALYTICAL: ${DTM_CORE_PLUGINS_ANALYTICAL:ADQM, ADB, ADP, ADG}
        DICTIONARY: ${DTM_CORE_PLUGINS_DICTIONARY:ADG, ADB, ADP, ADQM}
        UNDEFINED: ${DTM_CORE_PLUGINS_UNDEFINED:ADB, ADP, ADQM, ADG}
        WITHOUT_FROM: ${DTM_CORE_PLUGINS_WITHOUT_FROM:ADP, ADB, ADQM, ADG}

http:
  port: ${DTM_CORE_HTTP_PORT:9090}
  tcpNoDelay: ${DTM_CORE_HTTP_TCP_NO_DELAY:true}
  tcpFastOpen: ${DTM_CORE_HTTP_TCP_FAST_OPEN:true}
  tcpQuickAck: ${DTM_CORE_HTTP_TCP_QUICK_ACK:true}
  http2WindowSize: ${DTM_CORE_HTTP2_WINDOW_SIZE:1048576}
  maxRequestSize: ${DTM_CORE_HTTP_MAX_REQUEST_SIZE:-1}

webclient:
  tcpNoDelay: ${DTM_CORE_WEBCLIENT_TCP_NO_DELAY:true}
  tcpFastOpen: ${DTM_CORE_WEBCLIENT_TCP_FAST_OPEN:true}
  tcpQuickAck: ${DTM_CORE_WEBCLIENT_TCP_QUICK_ACK:true}
  priorKnowledgeHttp2: ${DTM_CORE_WEBCLIENT_PRIOR_KNOWLEDGE:true}
  connectionTimeoutMs: ${DTM_CORE_WEBCLIENT_CONNECTION_TIMEOUT_MS:30000}
  poolSize: ${DTM_CORE_WEBCLIENT_POOL_SIZE:20}
  http2PoolSize: ${DTM_CORE_WEBCLIENT_HTTP2_POOL_SIZE:20}
  http2KeepAliveSec: ${DTM_CORE_WEBCLIENT_HTTP2_KEEP_ALIVE_SEC:0}

privateapiwebclient:
  tcpNoDelay: ${DTM_CORE_WEBCLIENT_LEADER_TCP_NO_DELAY:true}
  tcpFastOpen: ${DTM_CORE_WEBCLIENT_LEADER_TCP_FAST_OPEN:true}
  tcpQuickAck: ${DTM_CORE_WEBCLIENT_LEADER_TCP_QUICK_ACK:true}
  priorKnowledgeHttp2: ${DTM_CORE_WEBCLIENT_LEADER_PRIOR_KNOWLEDGE:true}
  connectionTimeoutMs: ${DTM_CORE_WEBCLIENT_LEADER_CONNECTION_TIMEOUT_MS:2000}
  poolSize: ${DTM_CORE_WEBCLIENT_LEADER_POOL_SIZE:20}
  http2PoolSize: ${DTM_CORE_WEBCLIENT_LEADER_HTTP2_POOL_SIZE:20}
  http2KeepAliveSec: ${DTM_CORE_WEBCLIENT_LEADER_HTTP2_KEEP_ALIVE_SEC:0}

env:
  name: ${DTM_NAME:test}

prometheus:
  enabled: ${PROMETHEUS_ENABLED:true}

auth:
  jwksUri: ${AUTH_JWKS_URI:}
  defaultRoles: ${CORE_DEFAULT_ROLES:env_owner}

matviewsync:
  enabled: ${MATERIALIZED_VIEWS_SYNC_ENABLED:true}
  periodMs: ${MATERIALIZED_VIEWS_SYNC_PERIOD_MS:900000}
  maxConcurrent: ${MATERIALIZED_VIEWS_CONCURRENT:20}

datacooling:
  periodMs: ${DATA_COOLING_RUN_PERIOD_MS:600000}
  maxConcurrent: ${DATA_COOLING_CONCURRENT:2}

raft:
  myId: ${RAFT_ID:1}
    servers:
      pnode.1: ${RAFT_SERVER_1:127.0.0.1:9090}
    minTimeout: ${RAFT_MIN_TIMEOUT_MS:5000}
    maxTimeout: ${RAFT_MAX_TIMEOUT_MS:7000}
    heartbeatPeriod: ${RAFT_HEARTBEAT_PERIOD_MS:100}
    appendLogsBatchSize: ${APPEND_LOGS_BATCH_SIZE:1000}
    appendLogsBatchSizeBytes: ${APPEND_LOGS_BATCH_SIZE_BYTES:1048576}
    appendEntriesResendDelay: ${RAFT_APPEND_ENTRIES_RESEND_DELAY_MS:0}
    appendEntriesRetryDelay: ${RAFT_APPEND_ENTRIES_RETRY_DELAY_MS:10}
    snapshotPeriod: ${RAFT_SNAPSHOT_PERIOD_MS:600000}
    optimisticRetryCount: ${RAFT_OPTIMISTIC_RETRY_COUNT:40}
    writeOptimisticRetryCount: ${RAFT_WRITE_OPTIMISTIC_RETRY_COUNT:1000}
    callRetryCount: ${DTM_CORE_WEBCLIENT_LEADER_CALL_RETRY_COUNT:100}
    callRetryTimeoutMs: ${DTM_CORE_WEBCLIENT_LEADER_CALL_RETRY_TIMEOUT_MS:1000}
    logsCachingLimit: ${LOGS_CACHING_LIMIT:1000}

   servicedb:
     db: ${RAFT_SERVICEDB_DATABASE:tests}
     schema: ${RAFT_SERVICEDB_SCHEMA:sys1}
     user: ${RAFT_SERVICEDB_USER:postgres}
     password: ${RAFT_SERVICEDB_PASS:postgres}
     host: ${RAFT_SERVICEDB_HOST:localhost}
     port: ${RAFT_SERVICEDB_PORT:5432}
     poolSize: ${RAFT_SERVICEDB_MAX_POOL_SIZE:3}
     executorsCount: ${RAFT_SERVICEDB_EXECUTORS_COUNT:3}
     poolRequestTimeout: ${RAFT_SERVICEDB_POOL_REQUEST_TIMEOUT:0}
     preparedStatementsCacheMaxSize: ${RAFT_SERVICEDB_PREPARED_CACHE_MAX_SIZE:256}
     preparedStatementsCacheSqlLimit: ${RAFT_SERVICEDB_PREPARED_CACHE_SQL_LIMIT:2048}
     preparedStatementsCache: ${RAFT_SERVICEDB_PREPARED_CACHE:true}
     idleTimeoutMs: ${RAFT_SERVICEDB_IDLE_TIMEOUT_MS:60000}
     maxLifetimeTimeoutMs: ${RAFT_SERVICEDB_MAX_LIFETIME_TIMEOUT_MS:0}
     fetchSize: ${RAFT_SERVICEDB_FETCH_SIZE:100}

   entityttl:
     checkPeriodMs: ${ENTITY_TTL_CHECK_PERIOD_MS:30000}

datasource:
  edml:
     defaultChunkSize: ${EDML_DEFAULT_CHUNK_SIZE:1000}
     pluginStatusCheckPeriodMs: ${EDML_STATUS_CHECK_PERIOD_MS:1000}
     firstOffsetTimeoutMs: ${EDML_FIRST_OFFSET_TIMEOUT_MS:15000}
     changeOffsetTimeoutMs: ${EDML_CHANGE_OFFSET_TIMEOUT_MS:10000}

streaming:
  upload:
    dbBatchSize: ${STREAMING_UPLOAD_DB_BATCH_SIZE:1000}
    dbBufferSize: ${STREAMING_UPLOAD_DB_BUFFER_SIZE:10000}
    inputBufferSizeMb: ${STREAMING_UPLOAD_INPUT_BUFFER_SIZE_MB:10}

csvparser:
  separator: ${CSV_PARSER_SEPARATOR:;}
  quoteChar: ${CSV_PARSER_QUOTE_CHAR:"}
  escapeChar: ${CSV_PARSER_ESCAPE_CHAR:'}
  fieldAsNull: ${CSV_PARSER_FIELD_AS_NULL:EMPTY_SEPARATORS}

kafka:
  getOffsetsRetryCount: ${ZOOKEEPER_KAFKA_GET_OFFSETS_RETRY_COUNT:3}
  getOffsetsRetryTimeoutMs: ${ZOOKEEPER_KAFKA_GET_OFFSETS_RETRY_TIMEOUT_MS:1000}
  producer:
    property:
      key.serializer: org.apache.kafka.common.serialization.StringSerializer
      value.serializer: org.apache.kafka.common.serialization.StringSerializer
    consumer:
      property:
        key.deserializer: org.apache.kafka.common.serialization.ByteArrayDeserializer
        value.deserializer: org.apache.kafka.common.serialization.ByteArrayDeserializer
   cluster:
      zookeeper:
        connection-string: ${ZOOKEEPER_KAFKA_ADDRESS:}
        connection-timeout-ms: ${ZOOKEEPER_KAFKA_CONNECTION_TIMEOUT_MS:30000}
        session-timeout-ms: ${ZOOKEEPER_KAFKA_SESSION_TIMEOUT_MS:86400000}
        chroot: ${ZOOKEEPER_KAFKA_CHROOT:}
        connectionRetryCount: ${ZOOKEEPER_KAFKA_CONNECTION_RETRY_COUNT:1}
   admin:
     inputStreamTimeoutMs: ${KAFKA_INPUT_STREAM_TIMEOUT_MS:2000}
   status.event.publish:
     topic: ${KAFKA_STATUS_EVENT_TOPIC:status.event.topic}
     enabled: ${KAFKA_STATUS_EVENT_ENABLED:false}
     writeOperationsEnabled: ${KAFKA_STATUS_EVENT_WRITE_OPERATIONS_ENABLED:false}
     externalDDLEnabled: ${KAFKA_STATUS_EVENT_EXTERNAL_DDL_ENABLED:false}

vertx:
  blocking-stacktrace-time: ${DTM_VERTX_BLOCKING_STACKTRACE_TIME:1}
  pool:
    worker-pool: ${DTM_CORE_WORKER_POOL_SIZE:20}
    event-loop-pool: ${DTM_CORE_EVENT_LOOP_POOL_SIZE:20}

cache:
  initialCapacity: ${CACHE_INITIAL_CAPACITY:100000}
  maximumSize: ${CACHE_MAXIMUM_SIZE:100000}
  expireAfterAccessMinutes: ${CACHE_EXPIRE_AFTER_ACCESS_MINUTES:99960}

delta:
  rollback-status-calls-ms: ${DELTA_ROLLBACK_STATUS_CALLS_MS:2000}
  rollbackRetryCount: ${DELTA_ROLLBACK_RETRY_COUNT:0}
  rollbackRetryTimeoutMs: ${DELTA_ROLLBACK_RETRY_TIMEOUT_MS:1000}
  rollbackOperationsTimeoutMs: ${DELTA_ROLLBACK_OPERATIONS_TIMEOUT_MS:29000}

writeoperation:
  rollbackRetryCount: ${WRITE_OPERATION_ROLLBACK_RETRY_COUNT:0}
  rollbackRetryTimeoutMs: ${WRITE_OPERATION_ROLLBACK_RETRY_TIMEOUT_MS:1000}
  activityCheckPeriodMs: ${WRITE_OPERATION_ACTIVITY_CHECK_PERIOD_MS:10000}
  activityCheckTimeoutMs: ${WRITE_OPERATION_ACTIVITY_CHECK_TIMEOUT_MS:120000}

recover:
  loopTimeoutMs: ${RECOVER_LOOP_TIMEOUT_MS:60000}

statistics:
  enabled: ${CORE_STATISTICS_ENABLED:true}
  threadsCount: ${CORE_STATISTICS_THREADS_COUNT:2}
  dataCountEnabled: ${CORE_STATISTICS_DATA_COUNT_ENABLED:true}
  dataCountCheckPeriodMs: ${CORE_STATISTICS_DATA_COUNT_CHECK_PERIOD_MS:10000}

poststatusevent:
  subscriberGroup:
    - endpointUrl: ${POST_STATUS_EVENT_SUBSCRIBER_GROUP_ENDPOINT_URL:}
      endpointTimeoutMs: ${POST_STATUS_EVENT_SUBSCRIBER_GROUP_ENDPOINT_TIMEOUT_MS:5000}
      endpointRetryTimeoutMs: ${POST_STATUS_EVENT_SUBSCRIBER_GROUP_ENDPOINT_RETRY_TIMEOUT_MS:5000}
      bufferingPeriodMs: ${POST_STATUS_EVENT_SUBSCRIBER_GROUP_BUFFERING_PERIOD_MS:0}
      bufferSize: ${POST_STATUS_EVENT_SUBSCRIBER_GROUP_BUFFER_SIZE:1000}
      writeOperationsEnabled: ${POST_STATUS_EVENT_SUBSCRIBER_GROUP_WRITE_OPERATIONS_ENABLED:false}
      externalDDLEnabled: ${POST_STATUS_EVENT_SUBSCRIBER_GROUP_EXTERNAL_DDL_ENABLED:false}

agent:
  endpointUrl: ${AGENT_ENDPOINT_URL:}
  endpointGetCnTimeoutMs: ${AGENT_ENDPOINT_GET_CN_TIMEOUT_MS:60000}
  endpointQueryTimeoutMs: ${AGENT_ENDPOINT_QUERY_TIMEOUT_MS:3600000}
  dbBatchSize: ${AGENT_DB_BATCH_SIZE:1000}
  dbBufferSize: ${AGENT_DB_BUFFER_SIZE:10000}
  inputBufferSizeMb: ${AGENT_INPUT_BUFFER_SIZE_MB:10}

componentinfo:
  enabled: ${COMPONENT_INFO_ENABLED:true}
  datamart: ${COMPONENT_INFO_DATAMART:component_info}
  tableComponents: ${COMPONENT_INFO_TABLE_COMPONENTS:component_info}
  publishPeriodMs: ${COMPONENT_INFO_PUBLISH_PERIOD_MS:60000}
  timeoutActiveMs: ${COMPONENT_INFO_TIMEOUT_ACTIVE_MS:300000}

secrets:
  core:
    raft:
      servicedb:
      user:
      password:
  adb:
    datasource:
      user:
      password:
  adg:
    datasource:
      user:
      password:
  adqm:
    datasource:
      user:
      password:
  adp:
    datasource:
      user:
      password:

autofailover:
  enabled: ${AUTOFAILOVER_ENABLED:false}
  checkPeriodMs: ${AUTOFAILOVER_CHECK_PERIOD_MS:10000}
  waitTimeoutMs: ${AUTOFAILOVER_WAIT_TIMEOUT_MS:2000}
  failsLimit: ${AUTOFAILOVER_FAILS_LIMIT:3}
  healingConfirm: ${AUTOFAILOVER_HEALING_CONFIRM:3}
  startupDelayMs: ${AUTOFAILOVER_STARTUP_DELAY_MS:120000}
  execPeriodMs: ${AUTOFAILOVER_EXEC_PERIOD_MS:2000}
  minSyncReplicas: ${AUTOFAILOVER_MIN_SYNC_REPLICAS:1}
  recoverBatchPeriodMs: ${AUTOFAILOVER_RECOVER_BATCH_PERIOD_MS:10000}
  failedRetryTimeoutMs: ${AUTOFAILOVER_FAILED_RETRY_TIMEOUT_MS:60000}

adp:
  datasource:
    - name: ADP
      env: ${ADP_ENV_NAME:${DTM_NAME:test}}
      user: ${ADP_USERNAME:postgres}
      password: ${ADP_PASS:postgres}
      host: ${ADP_HOST:localhost}
      port: ${ADP_PORT:5432}
      poolSize: ${ADP_MAX_POOL_SIZE:3}
      executorsCount: ${ADP_EXECUTORS_COUNT:3}
      poolRequestTimeout: ${ADP_POOL_REQUEST_TIMEOUT:0}
      preparedStatementsCacheMaxSize: ${ADP_PREPARED_CACHE_MAX_SIZE:256}
      preparedStatementsCacheSqlLimit: ${ADP_PREPARED_CACHE_SQL_LIMIT:2048}
      preparedStatementsCache: ${ADP_PREPARED_CACHE:true}
      idleTimeoutMs: ${ADP_IDLE_TIMEOUT_MS:60000}
      maxLifetimeTimeoutMs: ${ADP_MAX_LIFETIME_TIMEOUT_MS:0}
      autofailoverPriority: ${ADP_AUTOFAILOVER_PRIORITY:}
  1. В конфигурации нового Prostore указать адрес СМЭВ QL сервера при работе Витрины в режиме источника пуш-уведомлений СМЭВ QL (при необходимости через балансировщик).

  2. Указать адрес агента для matview в конфигурации нового Prostore.

  3. Запустить новый Prostore.

  4. Подключиться к новому Prostore, например с помощью DBeaver:

  • Использовать новый драйвер Prostore, который поставляется в к комплекте дистрибутива Компонента;

  • Проверить версию Простора запросом check_versions();

  • Проверить данные запросом к прикладным данным, убедиться, что прежние прикладные данные имеются в новом Prostore.

  1. Обновить конфигурации модулей (Обязательно сохранить прежние конфигурации модулей для возможности отката на предыдущую версию!):

  • blob-adapter;

  • check-adapter;

  • counter-provider;

  • csv-uploader;

  • printable-form-service;

  • rest-adapter;

  • rest-uploader;

  • data-uploader;

  • smev3-adapter;

  • smevql-server;

  1. Определить конфигурацию для нового модуля «Стандартный загрузчик» (standard-loader).

  2. Запустить модули Компонента (необходима Java 17):

  • blob-adapter;

  • check-adapter;

  • counter-provider;

  • csv-uploader;

  • printable-form-service;

  • rest-adapter;

  • smev3-adapter;

  • smevql-server;

  • standard-loader;

  • rest-uploader.

Первый запуск rest-uploader рекомендуется выполнить с настройкой migration.enabled=true (отвечает за миграцию метаданных rest-uploader из zookeeper в PostgreSQL).

При запуске rest-uploader важно, чтобы зукипер еще продолжал работать и его адрес был прописан в конфигурации приложения. Проверить успешность миграции правил ФЛК для нужных таблиц запросом (проверяются только таблицы с правилами):

curl -X 'GET' \
  'http://[host]:[port]/v2/conditions/[datamart]/[table]' \
  -H 'accept: text/yaml'

После миграции перезапустить rest-uploader с настройкой migration.enabled=false

«Стандартный загрузчик» (standard-loader)конфигрурируется для поднятия необходимых сервисов. Состав сервисов определяется внедрением, за типовую основу можно принять:

  • manager;

  • deployer;

  • flk;

  • buffer;

  • uploader;

  • reader-rest-push;

  • dtm-fasade нужен для замещения dtm-uploader в части загрузки табличных данных, загрузка бинарных данных в новой версии витрины выполняется через blob-adapter.

  1. Внести данные справочников и конфигураций.

В CSV-Uploader:

  • открыть веб-интерфейс;

  • перейти на вкладку «Настройки»;

  • внести значения параметров «Запуск по расписанию», «Забирать CSV из каталога», «Включить», полученные из старой версии модуля.

В standard-loader:

  • настроить правила ФЛК

curl -X 'POST' \
  'https://[host]:[port]/api/v3/conditions/[datamart]/[table]' \
  -H 'accept: */*' \
  -H 'Content-Type: application/yaml' \
  -d 'fields:
  id:
    uniq: true   '
  • проверить успешность внесения правил ФЛК для нужных таблиц

curl -X 'GET' \
  'https://[host]:[port]/api/v3/conditions/[datamart]/[table]' \
  -H 'accept: text/yaml'

5.1.1.6. Включение взаимодействий Компонента

  1. Запустить загрузку данных:

  • открыть доступ всем пользователям к стандартному загрузчику;

  • настроить всех клиентов, которые загружают данные, в том числе через dtm-uploader, на загрузку данных чере стандартный загрузчик (standard-loader).

  1. Сконфигурировать Агента СМЭВ4 на работу по протоколу HTTP (необходимость балансировщика в зависимости от высокодоступности внедрения):

  • с Prostore в рамках SQL РЗ (JDBC не использует, обновление драйвера не требуется);

  • с printable-form-service;

  • с blob-adapter.

Пример конфигурации Агента СМЭВ4

# Общие настройки витрины
datamart:
  integration:
   type: HTTP
   http:
     client:
       protocolVersion: HTTP_2
       # для h2 раскомментировать
       # ssl: true
       # useAlpn: true
       # trustAll: true
       retryCount: 3
       retryTimeout: 3s

   prostore:
     host: 127.0.0.1
     port: 9090
   blobAdapter:
     host: 127.0.0.1
     port: 1234
   printableFormsService:
     host: 127.0.0.1
     port: 1235
  1. Запустить Агент СМЭВ4

  2. Вместо каждой подписки версии 1.х, для которой эта Витрина является получателем (рекомендуется предварительно остановить каждую из подписок 1.х в АРМ ПОДД, до выключения модулей витрины, не важно является ли Витрина потребителем или получателем):

  • после обновления Витрины поставщика данных до версии 2.х;

  • создаются РЗ с признаком «подписка 2.х»;

  • запросом на Prostore потребителе формируется matview.

5.1.1.7. Заключительные действия

Остановить Zookeeper и Kafka, удалять данные можно, когда будет подтверждена работоспособность и стабильность новой версии витрины, когда возврат на прежнюю версию уже точно не понадобится.

Настроить резервное копирование на уровне PostgeSQL вместо backup-manager. Для приведенного выше примера нужно останавливать загрузку данных и выполнять резервное копирование базы данных test, в ней для нового Prostore (в приведенном примере) размещаются и прикладные и метаданные.

5.1.1.8. Восстановление прежней версии Компонента

Для восстановление прежней версии Компонента (обновления с 2.х на 1.х) необходимо выполнить шаги:

  1. Остановить Агент СМЭВ4.

  2. Остановить модули новой витрины.

  3. Остановить новый Prostore.

  4. Восстановить PostgreSQL 13.14. Восстановить прикладную базу данных из резевной копии, снятой при обновлении.

  5. Запустить Zookeeper и Kafka, которые были остановлены при обновлении витрины. Zookeeper не должен быть модифицирован или очищен со времени обновления витрины.

  6. Запусить старый Prostore.

  7. Восстановить конфигурации модулей витрины.

  8. Запустить набор модулей версии 1.х.

  9. Восстановить конфигурацию Агента СМЭВ4.

  10. Запустить Агент СМЭВ4.

  11. Отключить бекапирование средствами PostgreSQL, вернуть использование backup-manager.

5.1.2. Обновление Компонента с поднятием второй копии витрины

Данный вариант отличается от предыдущего тем, что в случае недопустимо долгой миграции метаданных выполняется остановка старого Prostore, снятие резервной копии Zookeeper, затем старый Prostore поднимается и старая витрина продолжает работать на чтение.

Параллельно выполняется миграция метаданных с копии Zookeeper, выполняется создание копии прикладной БД и рядом поднимается версия витрины 2.х.

Агент СМЭВ4 перенаправляется на новую версию витрины.

5.1.3. Ограничения

  1. Агент СМЭВ4 обновляется заранее, процесс обновления Агента СМЭВ4 приведен в документе «Руководство администратора Агента СМЭВ4».

  2. Приведенные выше примеры соответствуют одному экземпляру Простора с одним датасортом ADP

5.2. Обновление Компонента конфигурации Лайт

Примечание

Перед началом обновления выполните резервное копирование!

5.2.1. Обновление с версии 1.0.0 до версии 1.0.1

Примечание

Данное обновление предусмотрено только для перехода с версии Компонента 1.0.0 до версии 1.0.1.

Чтобы обновить Компонент необходимо выполнить следующие действия (подробная инструкция по обновлению ниже):

  1. Выполнить резервное копирование.

  2. Скопировать архив с обновлением Компонента на сервер.

  3. Распаковать архив с обновлением.

  4. Запустить процесс обновления.

  5. Проверить, что обновление прошло успешно.

5.2.1.1. Резервное копирование

Примечание

Действия этого раздела необходимо выполнять под созданной учетной записью datamart (Раздел 2.1.2).

Для того чтобы выполнить резервное копирование создайте архив текущей версии с указанием актуальной даты копирования.

Например:

tar -czvf dtm-lite-2022-01-17.tgz ansible/ images/ jdbc/ rpms/

5.2.1.2. Копирование архива с обновлением Компонента на сервер

Для загрузки на сервер архива с файлами обновления Компонента используйте SFTP-клиент (например, WinSCP или Filezilla).

Для авторизации используйте логин и пароль учетной записи администратора datamart созданной при установке ОС (Раздел 2.1.2).

  1. Подключитесь по SSH к серверу (ssh_connect), используя логин и пароль учетной записи администратора.

  2. Загрузите файл с архивом в домашнюю директорию пользователя datamart командой:

mv ~/dtm-lite-1.0.1.tgz /home/datamart/

где,

  • dtm-lite-1.0.1.tgz - название архива Компонента.

  • datamart - имя пользователя.

5.2.1.3. Распаковка архива с обновлением

Примечание

Перед тем как выполнить разархивирование, рекомендуется просмотреть/скопировать значения переменных (IP-адрес сервера, префикс и т.д.), которые использовались в предыдущей версии Компонента в файле ansible/group_vars/all/main.yml. После распаковки архива с обновлением Компонента данные из этого файла будут удалены.

Чтобы распаковать архив, выполните команду:

tar -xzvf dtm-lite-1.0.1.tgz

5.2.1.4. Процесс обновления Компонента

Чтобы запустить процесс обновления Компонента с помощью Ansible, необходимо выполнить следующие действия:

  1. Переименуйте файл custom.example.yml расположенный в папке ansible/group_vars/ в custom.yml командой:

cp -n ansible/group_vars/custom.example.yml ansible/group_vars/custom.yml
  1. В файле custom.yml укажите корректные значения для следующих переменных:

  • server_ip - адреса сервера. Укажите IP-адрес сервера, на который будет установлено обновление Компонента. Например:

server_ip: "172.16.10.59"
  • server_user_name - имя пользователя операционной системы. Укажите имя пользователя операционной системы сервера, под которым устанавливается обновление (Раздел 2.1.2), например:

server_user_name: datamart
  • agentTopicPrefix - префикс перед именем топиков для СМЭВ4-агента (указывается опционально). Например:

agentTopicPrefix: "user_prefix."

Примечание

В качестве префикса рекомендуется использовать мнемонику витрины. После определения параметра префикса следует обязательно ставить символ . (точка)! Пример: agentTopicPrefix: "prod_vitrina98."

Чтобы запустить процесс обновления Компонента выполните команду:

docker-ansible-cmd ansible-playbook -i hosts install.yml

Начнется процесс обновления Компонента (см. рис. ниже):

Обновление Компонента

Рисунок - 5.1 Обновление Компонента

Установка обновления завершена.

После завершения обновления убедитесь, что обновление Компонента прошло успешно.

5.2.1.5. Проверка обновления Компонента до версии 1.0.1

Для проверки обновления Компонента необходимо выполнить следующие действия:

  1. Убедиться, что после установки обновления нет ошибок в работе Компонента.

  2. Убедиться, что параметр failed (см. рис. выше) после установки обновления имеет значение - 0. Это значит, что все необходимые компоненты Компонента были обновлены, а необходимые взаимосвязи между ними настроены корректно.

  3. Открыть Portainer и проверить, что версии модулей соответствуют указанным ниже:

    csv-uploader:1.0.12 podd-adapter:5.0.7 query-execution:5.2.2

5.2.2. Обновление до версии 2.5.0 и выше

Чтобы обновить Компонента необходимо выполнить следующие действия:

  1. Выполнить резервное копирование.

  2. Скопировать архив с обновлением Компонента на сервер.

  3. Распаковать архив с обновлением.

  4. Запустить процесс обновления.

  5. Проверить, что обновление прошло успешно.

5.2.2.1. Резервное копирование

Примечание

Действия этого раздела необходимо выполнять под созданной учетной записью datamart (Создание пользователя datamart).

Чтобы выполнить резервное копирование, создайте архив текущей версии с указанием актуальной даты копирования:

tar -czvf dtm-lite-2022-01-17.tgz ansible/ images/ jdbc/ rpms/

5.2.2.2. Копирование архива с обновлением Компонента на сервер

Для загрузки на сервер архива с файлами обновления Компонента используйте SFTP-клиент (например, WinSCP или Filezilla).

Для авторизации используйте логин и пароль учетной записи администратора datamart созданной при установке ОС (Создание пользователя datamart).

  1. Подключитесь по SSH к серверу (ssh_connect), используя логин и пароль учетной записи администратора.

  2. Загрузите файл с архивом в домашнюю директорию пользователя datamart командой:

mv ~/dtm-lite-<номер версии>.tgz /home/datamart/

где,

  • dtm-lite-<номер версии>.tgz - название архива Компонента.

  • datamart - имя пользователя.

5.2.2.3. Распаковка архива с обновлением

Чтобы распаковать архив, выполните команду:

tar -xzvf dtm-lite-<номер версии>.tgz

5.2.2.4. Процесс обновления Компонента

Чтобы запустить процесс обновления Компонента с помощью Ansible, необходимо выполнить следующие действия:

  1. Переименуйте файл custom.example.yml расположенный в папке ansible/group_vars/ в custom.yml командой:

cp -n ansible/group_vars/custom.example.yml ansible/group_vars/custom.yml
  1. В файле custom.yml укажите корректные значения для следующих переменных:

  • server_ip - адреса сервера. Укажите IP-адрес сервера, на который будет установлено обновление Компонента. Например:

server_ip: "172.16.10.59"
  • server_user_name - имя пользователя операционной системы. Укажите имя пользователя операционной системы сервера, под которым устанавливается обновление (Создание пользователя datamart), например:

server_user_name: datamart
  • agentTopicPrefix - префикс перед именем топиков для СМЭВ4-агента (указывается опционально). Например:

agentTopicPrefix: "user_prefix."

Примечание

В качестве префикса рекомендуется использовать мнемонику витрины. После определения параметра префикса следует обязательно ставить символ . (точка)! Пример: agentTopicPrefix: "prod_vitrina98."

Далее необходимо выполнить миграцию PostgreSQL:

  1. Остановить Prostore

docker stop query-execution
  1. Создать дамп данных в PostgreSQL, Заменить «dtm» на своего пользователя, если название отличается:

docker exec postgres pg_dumpall -U dtm > /tmp/pg13_dumpall.sql
  1. Создать бекап данных в PostgreSQL

docker run --rm -v postgres:/var/lib/postgresql/data:ro -v /tmp:/backup registry.gosuslugi.local/proxy-docker.io/library/postgres:13.4 sh -c 'cd /var/lib/postgresql/data && tar czf /backup/pgdata_volume_backup.tgz .'
  1. Остановить PostgreSQL

docker stop postgres
  1. Удалить контейнер PostgreSQL

docker rm postgres
  1. Удалить volume PostgreSQL

docker volume rm postgres
  1. Создать volume PostgreSQL

docker volume create postgres
  1. Загрузить образы PostgreSQL. Зайти в каталог, в котором распаковывали дистрибутив:

docker image load -i images/postgres-16.8.tar
docker image load -i images/postgres-13.4.tar
  1. Запустить контейнер PostgreSQL 16.8

docker run -d --name pg16-migrate -e POSTGRES_PASSWORD=tmp -v postgres:/var/lib/postgresql/data registry.gosuslugi.local/proxy-docker.io/library/postgres:16.8
  1. Восстановить данные в PostgreSQL 16.8

cat /tmp/pg13_dumpall.sql | docker exec -i pg16-migrate psql -U postgres -d postgres
  1. Установитеь пароли для пользователей PostgreSQL.

docker exec -i pg16-migrate psql -U postgres -d postgres -c "ALTER ROLE dtm WITH PASSWORD 'dtm';"

Заменить «dtm» на своего пользователя, если его название отличается

docker exec -i pg16-migrate psql -U postgres -d postgres -c "ALTER ROLE repl WITH PASSWORD 'repl';"

Заменить «repl» на своего пользователя, если его название отличается

  1. Удалить контейнер PostgreSQL 16.8

docker rm -f pg16-migrate
  1. Запустить процесс обновления Компонента:

docker-ansible-cmd ansible-playbook -i hosts install.yml
  1. Остановить Prostore

docker-ansible-cmd ansible -i hosts stand -b -m shell -a "docker stop query-execution"
  1. Создать дамп данных в PostgreSQL 13

docker-ansible-cmd ansible -i hosts stand -b -m shell -a "docker exec postgres pg_dumpall -U dtm > /tmp/pg13_dumpall.sql"
  1. Создать бекап volume с данными PostgreSQL

docker-ansible-cmd ansible -i hosts stand -b -m shell -a "docker run --rm -v postgres:/var/lib/postgresql/data:ro -v /tmp:/backup registry.gosuslugi.local/proxy-docker.io/library/postgres:13.4 sh -c 'cd /var/lib/postgresql/data && tar czf /backup/pgdata_volume_backup.tgz .'"
  1. Остановить PostgreSQL

docker-ansible-cmd ansible -i hosts stand -b -m shell -a "docker stop postgres"
  1. Удалить контейнер PostgreSQL

docker-ansible-cmd ansible -i hosts stand -b -m shell -a "docker rm postgres"
  1. Удалить volume PostgreSQL

docker-ansible-cmd ansible -i hosts stand -b -m shell -a "docker volume rm postgres"
  1. Создать volume PostgreSQL заново

docker-ansible-cmd ansible -i hosts stand -b -m shell -a "docker volume create postgres"
  1. Загрузить образы PostgreSQL. Заменить <DIST_DIR> на папку, куда распаковывали дистрибутив

docker-ansible-cmd ansible -i hosts stand -b -m shell -a "cd <DIST_DIR> && docker image load -i images/postgres-16.8.tar"
docker-ansible-cmd ansible -i hosts stand -b -m shell -a "cd <DIST_DIR> && docker image load -i images/postgres-13.4.tar"
  1. Запустить временный контейнер PostgreSQL 16.8 для миграции

docker-ansible-cmd ansible -i hosts stand -b -m shell -a "docker run -d --name pg16-migrate -e POSTGRES_PASSWORD=tmp -v postgres:/var/lib/postgresql/data registry.gosuslugi.local/proxy-docker.io/library/postgres:16.8"
  1. Восстановить дамп в PostgreSQL 16.8

docker-ansible-cmd ansible -i hosts stand -b -m shell -a "cat /tmp/pg13_dumpall.sql | docker exec -i pg16-migrate psql -U postgres -d postgres"
  1. Установить пароли пользователям PostgreSQL. Заменить dtm, repl на свои, если имена отличаются.

docker-ansible-cmd ansible -i hosts stand -b -m shell -a "docker exec -i pg16-migrate psql -U postgres -d postgres -c \"ALTER ROLE dtm WITH PASSWORD 'dtm';\""
docker-ansible-cmd ansible -i hosts stand -b -m shell -a "docker exec -i pg16-migrate psql -U postgres -d postgres -c \"ALTER ROLE repl WITH PASSWORD 'repl';\""
  1. Удалить временный контейнер PostgreSQL 16.8

docker-ansible-cmd ansible -i hosts stand -b -m shell -a "docker rm -f pg16-migrate"
  1. Запустить процесс обновления Компонента:

docker-ansible-cmd ansible-playbook -i hosts install.yml

Начнется процесс обновления Компонента (см. рис. ниже):

Обновление Компонента

Рисунок - 5.2 Обновление Компонента

Установка обновления завершена.

После завершения обновления убедитесь, что обновление Компонента прошло успешно.

5.2.2.5. Проверка обновления Компонента

Для проверки обновления Компонента выполните следующие действия:

  1. Убедитесь, что после установки обновления нет ошибок в работе Компонента.

  2. Убедитесь, что параметр failed (см. рис. выше) после установки обновления имеет значение - 0. Это значит, что все необходимые части Компонента были обновлены, а необходимые взаимосвязи между ними настроены корректно.

  3. Откройте Portainer и проверьте, что версии компонентов соответствуют указанным модулям для конфигурации Лайт.