Внимание! Если выполняется установка версии 5.1.0 поверх уже имеющейся прежней версии 5.0.1 и выше, то
необходимо выполнить следующие действия:
1 Заменить Ora2PgSyncX.jar
2 Заменить содержимое папки lib
3 Если Ваша лицензия включается в себя GUI, то необходимо выполнить скрипт Ora2PgSyncX_LUI.sql пользователем lui в обслуживающей БД Postgres.

Журнал изменений
----------------
Изменения в версии 5.1.0
1 Исправлена ошибка, возникающая при проверке условий репликации
Cannot invoke "oracle.sql.Datum.stringValue()" because the return value of "oracle.streams.ColumnValue.getColumnData()" is null
2 Исправлена ошибка формирования оператора update для таблиц с LOB
  update table set clob_field= where id=?
3 Исправлены ошибки 
  java.io.EOFException at java.base/java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
  и
  java.lang.NullPointerException: Cannot invoke "java.io.ObjectInputStream.readObject()" because "this.ois" is null,
  возникающие при чтении данных из временного файла транзакции при обработке правила игнорирования ошибки
4 Исправлена ошибка
  MESSAGE:Cannot read the array length because "<local22>" is null
  StackTrace:java.lang.NullPointerException: Cannot read the array length because "<local22>" is null,
  возникающая при подготовке к выполнению запроса фильтрации
5 Исправлена ошибка формирования текста оператора SQL вызвавшего SQLException в целевой БД
  Проблема состояла в том, что сжатые lz4 данные LOB-столбца ошибочно преобразовывались к строке
6 Решена проблема некорректной передачи данных со стороны XStream операций LOB WRITE
  Согласно документации от XStream должны поступать атрибуты offset и size для ChunkColumnValue, но они равны null.
  Потому возможность получения целостного значения поля на стороне целевой БД отсутствует.
  В связи с этим, принято решение читать из Oracle полный LOB дополнительным оператором SELECT.
7 Приняты меры по устранению проблемы связанной с неверной реакцией на решение пользователя по обработке ошибки.
8 Приняты меры по устранению проблемы связанной с неверным вычислением количества Out_bytes и Out_dmls в процессах слотов.
9 Усилена устойчивость к потере соединения с целевой БД за счёт выполнения переподключений и idle_session_timeout=0
10 Добавлена возможность выполнять запросы фильтрации не только в Postgres, но и в Oracle. 
  Это настраивается для каждого запроса фильтрации. По умолчанию запросы фильтрации выполняются в Postgres.
  Внесены соответствующие изменения в документацию.
11 При экспорте и импорте настроек добавлена выгрузка и загрузка правил обработки ошибок

 
Изменения в версии 5.0.1
1 Исправлена ошибка
java.lang.NullPointerException: Cannot invoke "java.lang.Long.toString()" because "DML.exedur" is null
at ora2pgsyncx.slotInstance.add2history(slotInstance.java:508)
2 Исправлена ошибка 
java.lang.IndexOutOfBoundsException: Index 1 out of bounds for length 1
...
at ora2pgsyncx.slotInstance.procBatch(slotInstance.java:1072)
Ошибка была связана с тем, что возникала потребность игнорировать ошибки 2-х и более DML, которые произошли в рамках одной транзакции.
3 Исправлена ошибка формирования Insert и Update для таблиц с CLOB и XML. Формировался текст оператора с некорректным синтаксисом для PostgreSQL.
4 Добавлена возможность репликации не только через Oracle XStream, но и через OLR (Oracle Logical Replicator (C)ФОРС Телеком) 
  В связи с этим, внесены изменения в документацию.
5 Добавлены функции экспорта настроек в текстовый файл и импорта настроек из текстового файла.
  Эти функции описаны в "Руководство пользователя" (описание GUI) см. главу 11.

Изменения в версии 4.2.2
1 Исправлена ошибка, связанная с недостоверностью данных в столбце nullable представления SYS.DBA_TAB_COLUMNS.
  В некоторых ситуациях, в этом столбце 'Y', в то время как системный check constraint, ответственный за NOT NULL находится в состоянии ENABLED.
  Проблема выявлена на Oracle 19.
2 Исправлена ошибка Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.util.Set.iterator()" because "Schemas" is null
        at ora2pgsyncx.Prepare.sqlSL2(Prepare.java:2864),
  возникающая при подготовке репликации, если все таблицы имеют те или иные выявленные утилитой проблемы.

Изменения в версии 4.2.1
1 Исправлена ошибка java.lang.NullPointerException: Cannot invoke "java.lang.Long.toString()" because "DML.exedur" is null
        at ora2pgsyncx.slotInstance.add2history(slotInstance.java:532)
2 Исправлена ошибка Exception in thread "main" org.postgresql.util.PSQLException: ОШИБКА: таблица "c3" отсутствует в предложении FROM
  Позиция: 1187
        at ora2pgsyncx.Prepare.sqlSL(Prepare.java:3034)
3 Приняты меры по недопущению наличия необработанных исключений в процессах слотов
4 Теперь при повторном выполнении prepare.sh  если  XStreamRuleType = tables, 
  в случае выявления новых таблиц генерируется скрипт prepare_XadmAX.sql. Его следует использовать для добавления новых таблиц в набор правил репликации 
  для ранее созданного сервера XStream out. Это отражено в документации.
5 В документации добавлено описание плановой остановки репликации по команде из внешней системы
6 Исправлены две орфографические ошибки в названиях столбцов служебных таблиц
7 Исправлены две орфографические ошибки в GUI в экранной форме настройки запроса фильтрации

Изменения в версии 4.2.0
1 Для увеличения производительности добавлена возможность кэширования запросов фильтрации
2 Добавлена возможность хранения паролей в конфигурационных файлах в зашифрованном виде
3 Изменения отражены в документации

Изменения в версии 4.1.3
1 Исправлена ошибка мониторинга доступной памяти JVM
2 Исправлена ошибка генерации оператора alter table ...  add supplemental log group 
  для таблиц с условиями репликации
3 Исправлена ошибка обработки ошибок в главном процессе replicator, которая приводила к зависанию.
4 Теперь для повышения уровня контроля ошибок правило перезаписи должно увеличивать на 1 значение переменной сеанса ORA2PG.DISCARD, а ora2Pg_tab.ignore_updcnt0 должен быть равен “С”.
  Утилита будет считывать переменную и добавлять её значение к общему количеству изменённых строк оператором DML или их пачкой.
5 Добавлена возможность применения "запросов фильтации" для условной репликации таблицы с зависимостью от данных в других таблицах.
6 Изменения отражены в документации

Изменения в версии 3.0.1
1 Исправлен ряд ошибок связанных с неправильной генерации имён служебных таблиц в запросах к служебной БД. Не подставлялось имя схемы.
2 Отменяются параметры задвавие имена таблиц в служебной БД. Вместо них введён параметр pgschema.
3 Изменён алгоритм генерации имён дополнительных групп журналирования. Теперь имя состоит из префикса (имя XStream out) и порядкового номера.
  При удалении старых групп при переконфигурации удалению подлежат системные группы и группы относящиеся к данному XStream out.
  Тем самым обеспечивается неконфликтность использования двух и более экземпляров утилиты на одной исходной БД Oracle.
4 Добавлены параметры xcapture - имя XStream capture процесса и xqueue - имя AQ очереди. Тем самым обеспечена возможность двух и более экземпляров утилиты использовать собственные
  XStream out, но общий XStream capture.
5 Добавлена обработка постоянно изменяющейся позиции LCR сервера XStream out, даже если он не шлёт сообщений в утилиту (холостой ход).
  Это обеспеивает более быстрый перезапуск, т.к. LogMiner и Сapture не будут заняты лишними чтениями.
6 Изменения отражены в документации

Изменения в версии 2.2.3
1 Исправлена ошибка режима "prepare", которая проявлялась если ни для одной из таблиц нет условий репликации. В этом случае, ошибочно выполнялась попытка закрытия неоткрытого курсора.

Изменения в версии 2.2.2
1 Исправлена ошибка обработки NULL в полях типа XMLTYPE
2 Документация дополнена сведениями о системных схемах Oracle, таблицы которых не реплицируются.
3 Добавлены функции обеспечения репликации XMLTYPE stored as binary. C этой целью введён параметр CharSet4XMLtype.
  Этот параметр задаёт кодировку в терминах java.nio (https://docs.oracle.com/javase/8/docs/technotes/guides/intl/encoding.doc.html). 
  Эта кодировка будет применяться при чтении XMLTYPE. 
  Данные этого типа Oracle XSTream передаёт утилите в бинарном формате и их надо перекодировать в UTF-8. 
  В БД Oracle эти данные хранятся в кодировке БД. 
  Имена кодировок БД не соответствуют именам кодировок java.nio. 
  Если этот параметр не указан, а кодировка БД (SELECT value FROM nls_database_parameters WHERE parameter = 'NLS_CHARACTERSET') 
  содержит строку '1251'. То параметр получит значение “Windows-1251”. В противном случае – “UTF-8”. 
  Таким образом, если этот параметр не задан и кодировка БД Oracle не соответствует Windows-1251 или UTF-8, данные XMLTYPE могут искажаться.
  Новый параметр описан в документации.

Изменения в версии 2.1.2
1 Ошибка дублирования имён Oracle SUPPLEMENTAL LOG GROUP проявилась ещё раз в другом фрагменте кода утилиты. Исправлено.
2 Исправлена проблема внесения пользователем данных в столбец "ident_u". 
  Возникала ситуация, когда в качестве набора столбцов идентифицирующих запись использовались как столбцы с 'Y' в "ident", 
  так и столбцы c 'Y'  в "ident_u". Теперь, если пользователем будут внесены изменения в ident_u хотябы для одного столбца таблицы,
  то при репликации и при генерации команд “ALTER TABLE … add SUPPLEMENTAL LOG GROUP …” в файле prepareXadmSL.sql будут использованы только данные указанные в столбце ident_u, 
  данные сгенерированные утилитой в столбце ident не будут использоваться.
3 Добавлена репликация DDL TRUNCATE TABLE. Если DDL LCR содержит оператор TRUNCATE TABLE, и если он относится к реплицируемой таблице, 
  и если эта таблица реплицируется через один слот и не разделяется между слотами, то TRUNCATE TABLE будет применён к целевой таблице. 
  Все остальные DDL LCR утилита не реплицирует и направляет в слот DUMMY, который не применяет их в целевой БД. 
  Невозможность репликации TRUNCATE TABLE в случае разделения таблицы на параллельные потоки репликации через несколько слотов обусловлена необходимостью 
  соблюдения целостности. Не корректно выполнять TRUNCATE для таблицы, если очереди в нескольких слотах содержат для неё операторы DML. 
  Эти DML могут быть выполнены до или после TRUNCATE в зависимости от длины очередей и скоростей их обработки. 
  Тем самым состояние данных в целевой таблице может в итоге не соответствовать состоянию данных в исходной таблице.
4 В таблицу ora2pg_slots обслуживающего Postgres добавлен столбец seek_scn. В нём отображается SCN последнего DML, полученного когда слот находится в состоянии SEEK (пропускает ранее применённые DML).
  Изменения в этом столбце позволяют наблюдать движение слота к lastcommitscn.
5 Добавлена функция сбора статистики выполнения DML в целевой БД. Статистика отображается в таблице ora2pg_pgdmlstats. Она позволяет выявить наиболее затратные по времени выполнения DML.
6 Теперь версия утилиты выводится в файл журнала утилиты и отображается в столбце version таблицы ora2pg_proc в обслуживающей БД
7 Документация дополнена в связи с доработками

Изменения в версии 2.0.1
1 Исправлена ошибка преобразования Oracle NUMBER в Postgres int4 и int2.
2 Устранена потеря данных больших транзакций (>1000 dml) в случаях ошибки в процессе replicator при взаимодействии с XStream
3 Устранено дублирование имён Oracle SUPPLEMENTAL LOG GROUP при генерации скрипта prepareXadmSL.sql в случае повторной подготовки репликации при добавлении новых реплицируемых таблиц.
4 Добавлена возможность репликации строк по условию на уровне самой утилиты. Для написания условий можно использовать JavaScrpt или EvalEx. 
  Для ссылок на поле новой записи применяется синтаксис ИМЯ_СТОЛБЦА[NEW] в случае insert и update. 
  Для ссылок на поле старой записи применяется синтаксис ИМЯ_СТОЛБЦА[OLD] в случае update и delete. 
  Существует возможность при реплиуации заменить UPDATE на INSERT или DELETE, или оставить UPDATE, или совсем не делать репликацию строки в зависимости от данных старой и новой записей.
  Это особенно полезно когда часть прикладной системы эксплуатируется на Oracle, а другая её часть - уже на Postgres.
5 Ранее можно было настроить автоматическое игнорирование заданных ошибок. 
  Добавлена возможность настройки автоповторения транзакции внутри которой произола ошибка без изъятия ошибочного dml.
  В некоторых ситуациях это позволяет избавиться от ошибок при многопоточной репликации таблицы с уникальными ключами. 
  В связи с этой доработкой таблица ora2pg_errskip заменена таблицей ora2pg_errhndl.
6 В связи с доработками внесены изменения в документацию
7 Документация дополнена описанием рисков многопоточной репликации таблицы с уникальными ключами
8 Исправлена ошибка в документации "Если split_u!=null и slot_u=null, то таблица НЕ будет делиться на несколько потоков."
  Правильно так: "Если split_u!=null и slot_u=null, то таблица будет делиться на несколько потоков."

Изменения в версии 1.2
1 Изменена обработка столбцов Oracle NUMBER. Теперь утилита если на стороне Postgres им соответствуют целочисленные типы выполняется отбрасывание дробной части и явное преобразование к целевому типу.
  Это исключило преобразование в Postgres и увеличило производительность репликации для delete и update.
2 Исправлена оибка потери времени при репликации Oracle Date в Postgres Timestamp
3 Возможны ситуации, когда в Oracle столбец являясь членом перыичного ключа не имеет ограничения NOT NULL. Это бывает в случаях alter table add constraint no valdate.
  Это приводило к тому, что утилита не воспринимала такой столбец как ключевой. Генерировались не оптимальные alter table .... add SUPPLEMENTAL LOG GROUP ...
  Реплицировались избыточные данные.
  Теперь член первичного ключа будет рассматриваться всегда как носитель ограничения NOT NULL 
4 Добавлен параметр StartSCN. 
  Это SCN, начиная с которого данные будут реплицироваться в целевую БД. 
  Все RowLCR, у которых SCN меньше указанного в этом параметре, будут игнорированы.

Изменения в версии 1.1
1 Добавлено измерение времени выполнения операций (BatchDML). В таблицах ora2pg_slots и ora2pg_stats сделаны необходимые изменения.
  Соответствующим образом изменено руководство. Если значение интервала более 1 сек, 
  то это означает, что сейчас в сеансе  Postgres выполняется пачка (batch) операторов SQL 
  и длительность этого выполнения уже более 1 сек. И есть необходимость изучить статистику и планы выполнения операторов SQL 
  на стороне Postgres средствами мониторинга и сбора статистики Postgres.
2 Руководство дополнено описанием проблем репликации, способами их обнаружения и устранения
3 Добавлена команда STOP_AND_RESTART - плановый быстрый перезапуск. Эта команда позволяет:
   - не останавливая репликации выполнить переконфигурацию утилиты
   - выполнить остановку репликации с выровненными позициями всех слотов
   - возобновить репликацию в новой конфигурации с соблюдением целостности начиная точки остановки
   Описание команды отражено в руководстве.
4 Изменилось поведение утилиты при повторном запуске prepare.sh (bat). Теперь при повторном запуске 
  пользователь должен ответить на вопрос, который возникает на экране консоли:
  Table list already consists of nnnn tables.
  Do you want to delete old table definitions? (Y/N)
  Если пользователь ответит “Y”, то все данные из таблиц ora2pg_tab и ora2pg_col будут удалены, включая изменения введённые пользователем.
  Если пользователь ответит “N”,то выполняется обновление данных в этих таблицах.
  Описание алгоритма обновления отражено в руководстве.
5 Помимо проверки совпадения часовых поясов Oracle и Postgres, теперь утилита требует совпадения часовых поясов Oracle, Postgres и JVM.
  Это требование связано с корректностью выполнения команды STOP. Дело в том, что утилита получив служебное сообщение в потоке репликации
  о необходимости остановки, проверяет дату/время генерации этого сообщения в Oracle. И если эта дата/время меньше времени старта утилиты, 
  то сообщение будет игнорировано. Установить часовой пояс JVM можно изменив часовой пояс в ОС. Или применить ключ -Duser.timezone при запуске java.
  Пример:java -Xmx8192m -Dfile.encoding=UTF-8 -Duser.timezone=Europe/Moscow -jar Ora2PgSyncX.jar replication.json
