# 4.10. Odstraňování problémů

## 4.10.1. Uzamčení DB

Po aktualizaci se v logu objevuje chyba ``Waiting for changelog lock....``

Chyba znamená, že při posledním startu aplikace se nepodařilo dokončit změnu databáze. Je nutné se ujistit, že nad danou instancí DB běží jen jedna Elza. Pokud jiná Elza neběží, tak je možné databázový zámek uvolnit a znovu aplikaci spustit.

Zámek je v tabulce `db_databasechangeloglock`, odstranění zámku se provede pomocí:

    delete from db_databasechangeloglock;

## 4.10.2. Chybné zobrazení českých znaků

V některých případech jsou v Elza chybně zobrazeny české znaky při vytváření jednotek popisu. V takovém případě je nutné aplikaci spustit s příznakem požadovaného kódování.

    java "-Dfile.encoding=UTF-8" "-Dsun.jnu.encoding=UTF-8" -jar elza.jar

V případě provozu v Linuxu a spouštění přímým voláním `elza.jar` souboru je možné toto nastavení udělat v konfiguračním souboru `elza.conf`. Soubor musí být umístěn vedle souboru `elza.jar`.

Příklad konfiguračního souboru `elza.conf`:

    JAVA_OPTS="-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8"

## 4.10.3. Nekonzistence v DB při přechodu na verzi 2.1.2 a vyšší

Při přechodu na verzi 2.1.2 z nižších verzí může dojít k detekci nekonzistencí pocházejících z předchozích verzí. Problém bude v logu zaznamenán takto:

    Migration failed for change set db/changelog/db.elza-1.5.xml::20210330155924::ppyt:
         Reason: liquibase.exception.DatabaseException: ERROR: could not create unique index "arr_item_object_pidx"
      Detail: Key (desc_item_object_id)=(45647) is duplicated. [Failed SQL: (0) CREATE UNIQUE INDEX arr_item_object_pidx
                                 ON arr_item(desc_item_object_id)
                                 WHERE delete_change_id IS NULL]

Pro odstranění problému je vhodné provést zhodnocení vážnosti zjištěných nekonzistencí. Automatický skript pro jejich odstranění (3 samostatné příkazy):

    delete from arr_cached_node where node_id in( select distinct node_id from arr_desc_item di where item_id in (select distinct i1.item_id from arr_item i1 join arr_item i2 on i1.desc_item_object_id = i2.desc_item_object_id where i1.item_id<i2.item_id and i1.delete_change_id is null and i2.delete_change_id is null));

    delete from arr_desc_item where item_id in ( select distinct item_id from arr_desc_item di where item_id in (select distinct i1.item_id from arr_item i1 join arr_item i2 on i1.desc_item_object_id = i2.desc_item_object_id where i1.item_id<i2.item_id and i1.delete_change_id is null and i2.delete_change_id is null));

    delete from arr_item where item_id in (select distinct i1.item_id from arr_item i1 join arr_item i2 on i1.desc_item_object_id = i2.desc_item_object_id where i1.item_id<i2.item_id and i1.delete_change_id is null and i2.delete_change_id is null);

## 4.10.4. Nekonzistence v DB při přechodu na 2.3.4 a vyšší

Při přechodu na verzi 2.3.4 z nižších verzí může dojít k detekci nekonzistencí pocházejících z předchozích verzí v případě aktivního připojení na CAM (test nebo vývoj). Problém bude v logu zaznamenán takto:

    Migration failed for change set db/changelog/db.elza-1.5.xml::20211105113000::sergey.iryupin:
       Reason: liquibase.exception.DatabaseException: ERROR: could not create unique index "ap_binding_state_access_point_idx"
       Detail: Key (access_point_id, external_system_id)=(40906, 23) is duplicated. [Failed SQL: (0) CREATE UNIQUE INDEX ap_binding_state_access_point_idx
              ON ap_binding_state(access_point_id,external_system_id)
                          WHERE delete_change_id IS NULL]

Skript pro odstranění problému:

    create table tmp_fix_binding (binding_id integer, access_point_id integer);
    insert into tmp_fix_binding(binding_id, access_point_id)
    select bs.binding_id, bs.access_point_id from ap_binding_state bs
    join ap_binding b on b.binding_id = bs.binding_id
    join ap_binding_state bs2 on bs.access_point_id = bs2.access_point_id
    join ap_binding b2 on b2.binding_id = bs2.binding_id
    where bs.delete_change_id is null and bs2.delete_change_id is null
      and b.external_system_id = b2.external_system_id
      and bs.binding_state_id <> bs2.binding_state_id;
    update arr_data_record_ref rr set record_id = src.access_point_id, binding_id = null
    from tmp_fix_binding src where src.binding_id = rr.binding_id;
    delete from ap_binding_item bi where binding_id in (select binding_id from tmp_fix_binding);
    delete from ap_binding_state where binding_id in (select binding_id from tmp_fix_binding);
    delete from ext_syncs_queue_item exi where exi.access_point_id in (select access_point_id from tmp_fix_binding);
    delete from ext_syncs_queue_item exi where exi.binding_id in (select binding_id from tmp_fix_binding);
    delete from ap_binding where binding_id in (select binding_id from tmp_fix_binding);
    drop table tmp_fix_binding;

## 4.10.5. Změna jazyku na kořeni archivního souboru v 2.8.5 a vyšší

Od verze 2.8.5 byl zaveden nový prvek popisu Jazyk archivního souboru. Do té doby byl na kořeni archivního souboru většinou uváděn prvek popisu Jazyk ve smyslu uvedeného nového prvku. Níže jsou uvedeny dva dotazy, které umožňují provedení migrace prvku popisu Jazyk na prvek popisu Jazyk archivního souboru.

Postup spuštěním migračních skriptů:

> 1. Zastavení aplikace

> 2. Provedení zálohy databáze

> 3. Spuštění migračního skriptu

> 4. Spuštění aplikace

Skript pro přesun jazyků na kořeni:

    --
    -- Aktualizace typu prvku popisu u kořenových uzlů fondů
    --
    update arr_item i set item_type_id = (select item_type_id from rul_item_type where code = 'ZP2015_MAJOR_LANG' )
    where i.item_id in (
    select i.item_id from arr_fund f
    join arr_fund_version fv on fv.fund_id = f.fund_id and fv.lock_change_id is null
    join arr_node n on n.node_id = fv.root_node_id
    join arr_desc_item di on di.node_id = n.node_id
    join arr_item i on i.item_id = di.item_id and i.delete_change_id is null
    join rul_item_type t on t.item_type_id = i.item_type_id
    where code = 'ZP2015_LANGUAGE'
    );

    --
    -- Odstranění změněných záznamů z cache
    --
    delete from arr_cached_node where node_id in (
    select fv.root_node_id from arr_fund f
    join arr_fund_version fv on fv.fund_id = f.fund_id and fv.lock_change_id is null
    join arr_node n on n.node_id = fv.root_node_id
    join arr_desc_item di on di.node_id = n.node_id
    join arr_item i on i.item_id = di.item_id and i.delete_change_id is null
    join rul_item_type t on t.item_type_id = i.item_type_id
    where code = 'ZP2015_MAJOR_LANG'
    );

## 4.10.6. Migrace PP měřítko v 2.8.16 a vyšší

Od verze 2.8.16 byla zavedena u prvku popisu Měřítko možnost zápisu pomocí číselné a/nebo textové formy. Do té doby byl možný jen textový zápis. Níže je uveden skript pomocí něhož je možné textovou podobu ve formátu 1:n převést do číselné formy. Pokud hodnota měřítka není v uvedeném formátu, zůstane v původní textové podobě beze změny.

Postup spuštěním migračních skriptů:

> 1. Zastavení aplikace

> 2. Provedení zálohy databáze

> 3. Spuštění migračního skriptu

> 4. Spuštění aplikace

Skript pro migraci měřítka na strukturovanou variantu:

    --
    -- migrace hodnot z text na string
    --
    insert into arr_data_string
    select dtt.data_id, regexp_replace(dtt.value,'\s+','','g') from arr_item it
    join arr_data_text dtt on dtt.data_id = it.data_id
    join rul_item_type rit on rit.item_type_id = it.item_type_id and rit.code = 'ZP2015_SCALE'
    join arr_desc_item di on di.item_id = it.item_id
    where regexp_replace(dtt.value,'\s+','','g') ~ '^\[?(1|10):[0-9]+\]?$' and it.delete_change_id is null;

    -- vymazani zaznamu z cache
    delete from arr_cached_node where node_id in (select node_id from arr_item it
                         join arr_desc_item dit on dit.item_id = it.item_id
                         join arr_data_string ds on ds.data_id = it.data_id
                         join arr_data_text dt on dt.data_id = it.data_id
                         join rul_item_type rit on rit.item_type_id = it.item_type_id and rit.code = 'ZP2015_SCALE' );
    --
    -- migrace typu dat
    --
    update arr_data d set data_type_id = (select data_type_id from rul_item_type where code = 'ZP2015_SCALE_NUMERICAL')
    where data_id in (select it.data_id from arr_item it
                         join arr_data_string ds on ds.data_id = it.data_id
                         join arr_data_text dt on dt.data_id = it.data_id
                         join rul_item_type rit on rit.item_type_id = it.item_type_id and rit.code = 'ZP2015_SCALE' );
    --
    -- migrace typu prvku popisu
    --
    update arr_item it set item_type_id = (select item_type_id from rul_item_type where code = 'ZP2015_SCALE_NUMERICAL')
    where it.item_id in (select it.item_id from arr_item it
                         join arr_data_string ds on ds.data_id = it.data_id
                         join arr_data_text dt on dt.data_id = it.data_id
                         join rul_item_type rit on rit.item_type_id = it.item_type_id and rit.code = 'ZP2015_SCALE' );
    --
    -- odstraneni puvodnich dat
    --
    delete from arr_data_text where data_id in (
        select it.data_id from arr_item it
                         join arr_data_string ds on ds.data_id = it.data_id
                         join arr_data_text dt on dt.data_id = it.data_id
                         join rul_item_type rit on rit.item_type_id = it.item_type_id and rit.code = 'ZP2015_SCALE_NUMERICAL'
    );