Nouvelle publication

Rechercher

Article
· Avr 21 3m de lecture

Considerations when Migrating from Oracle, MSSQL etc to IRIS

Migrating from Oracle, MSSQL, or other purely relational database systems to a multimodel InterSystems IRIS is a strategic decision that requires careful planning and execution. While this transition offers significant benefits, including enhanced performance, scalability, and support for modern architectures, it also comes with challenges. In this article I will highlight some of the considerations connected to coding to ensure a successful migration. I will leave everything connected to an actual migration of structures and data outside the scope of this article.


First, when you're considering migrating to a different database system, you need to understand your business logic, whether it's on the side of the application (application server) or the database server. Basically, where do you have your SQL statements that you will need to potentially rewrite

When your application logic heavily relies on SQL executed directly within the application code (rather than within stored procedures or triggers in the database), migrating from relational DB to InterSystems IRIS requires a careful examination of your SQL statements. Let's look at some of the most important factors you need to think about.

  1. SQL dialect differences. IRIS SQL supports SQL-92 standard. It doesn't mean that some more modern features are not implemented. It just means that you need to check beforehand. For example, the window functions appeared in SQL:2003, but you still can write them in IRIS:
--window function
select id, rating
  from (select a.id, 
               r.rating, 
               avg(r.rating) over () as avg_rating 
          from SQLUSER.Actor a join SQLUser.Review r on a.id = r.Reviews) as sub 
 where rating > avg_rating

At the same time, new complex datatypes, like XML, JSON, Arrays, and Geographic datatypes, are not supported. So the following query

SELECT a.id, 
       a.firstname, 
       ARRAY_AGG(r.rating) AS ratings 
  FROM SQLUSER.Actor a LEFT JOIN SQLUser.Review r ON a.id = r.Reviews 
GROUP BY  a.firstname

will return an error: ERROR #5540: SQLCODE: -359 Message: User defined SQL function 'SQLUSER.ARRAY_AGG' does not exist

But it's not the end of the world. There are a lot of built-in functions that will allow you to rewrite the queries so that you get the expected result.

2. Built-in functions. Different DBMSs have different built-in functions. Thus, you need to understand how they correspond to the ones available in IRIS. Here are several examples of what I'm talking about, functions used in Oracle and their equivalents in IRIS:

Oracle IRIS
NVL ISNULL(field, default_value)
substr $extract(field, start_pos, end_pos)
instr $find(field, text_to_find)
concat {fn CONCAT(string1,string2)}

When your primary SQL logic resides within a database (e.g., stored procedures, triggers, views), migrating to InterSystems IRIS requires a different approach. Here are some of the considerations:

  1. Database Object Migration
    1. All the Stored Procedures have to be rewritten using ObjectScript. This may also be a good time to change to the object model as you will get a table anyway when you create a class. However, working with classes will allow you to write methods (that can be called as stored procedures) and use the full power of the object-oriented paradigm. 
    2. Triggers, Indexes, and Views are all supported by IRIS. You can even leave your Views as they are if the table columns remain the same if they don't use any of the unsupported functions/syntax (see the previous point). 
  2. Migration of Definitions is also significant and may pose some challenges. First, you must carefully match the data types from your previous DB to IRIS, especially if you're using new complex types. Also, having more flexibility with indexes, you may want to redefine them differently.

Here are some things you need to consider when deciding to migrate to InterSystems IRIS from a different relational database. It is a strategic decision that can unlock significant benefits, including improved scalability, performance, and efficiency. However, careful planning is crucial to ensure a seamless transition and to address compatibility, data transformation, and application refactoring needs.

1 Comment
Discussion (1)3
Connectez-vous ou inscrivez-vous pour continuer
Résumé
· Avr 21

Publications des développeurs d'InterSystems, semaine Avril 14 - 20, 2025, Résumé

Articles
#InterSystems IRIS
#InterSystems IRIS for Health
Bulk FHIR, étape par étape
Par Guillaume Rongier
Annonces
#InterSystems IRIS
Avril 14 - 20, 2025Week at a GlanceInterSystems Developer Community
Résumé
· Avr 21
Question
· Avr 21

Tasks to production

Hi guys,

Would like to replace our scheduled Tasks to instead run in a production, so basically the same code running in OnTask () to be instead called in a Business Service (I guess) and use the Interval filed to specify the iteration, so with adapter would be suitable in this case, and I noticed the Schedule filed as well but not sure how to use it? 

Thanks

7 Comments
Discussion (7)2
Connectez-vous ou inscrivez-vous pour continuer
Article
· Avr 21 4m de lecture

Cuándo tener en cuenta useIrisFsGroup en vuestros despliegues con IKO

Si echáis un vistazo al archivo values.yaml del Helm chart de IKO, encontraréis:

useIrisFsGroup: false 

Vamos a desglosar qué es useIrisFsGroup y en qué situaciones puede ser útil activarlo.

FsGroup se refiere al file system group (grupo del sistema de archivos).

Por defecto, los volúmenes en Kubernetes son propiedad del usuario root, pero necesitamos que IRIS sea propietario de sus propios archivos (IRIS en contenedores se instala bajo el usuario irisowner). Para solucionar esto, utilizamos uno de estos dos métodos:

1) initContainers

Los initContainers se ejecutan antes que los contenedores de la aplicación (como IRIS) en un pod. Generalmente preparan el entorno para la aplicación y luego terminan. El initContainer se ejecuta como root antes que IRIS y ejecuta:

chown irisowner:irisowner /irissys/*

El SecurityContext está, por defecto, configurado como:

RunAsUser: 51773
RunAsGroup: 51773
RunAsNonRoot: true

para el pod. Y vemos que 51773 es el ID de usuario y grupo para irisowner:

$ id
uid=51773(irisowner) gid=51773(irisowner) groups=51773(irisowner)

2) Montar volúmenes con una propiedad de grupo específica

Algunos entornos pueden restringir que los contenedores se ejecuten como root, por ejemplo, mediante las Security Context Constraints en OpenShift. En este caso, ni siquiera podemos ejecutar un initContainer como root y necesitaremos que los volúmenes tengan la propiedad del sistema de archivos correcta en el momento de su montaje. Para hacerlo, desplegad el InterSystems Kubernetes Operator con:

useIrisFsGroup: true 

en el archivo /chart/iris-operator/values.yaml.

Ahora, vuestros pods se desplegarán sin initContainers.

Una advertencia: si deseáis configurar sidecars, se requiere un paso adicional. No podréis utilizar el sidecar habitual de Apache/NGINX. Encontraréis este problema:

>> kubectl get pods
NAME                                              READY   STATUS    RESTARTS      AGE
intersystems-iris-operator-amd-76b75f6b48-7lnw2   1/1     Running   0             43m
iris-data-0-0                                     1/2     Error     2 (22s ago)   2m

lo que resultará en un CrashLoopBackOff. Un análisis más profundo nos muestra que cuando el sidecar habitual de Apache/NGINX está presente, el parámetro useIrisFsGroup no se tiene en cuenta. Esto se debe a que estos contenedores de Apache/NGINX, en este caso el sidecar, se ejecutan como root. IRIS no se ejecuta como root y no puede acceder a sus directorios, lo que causa nuestro problema.

irisowner@iris-data-0-0:/irissys$ ls -l
total 16
drwxrwxrwx 3 root root  107 Mar 31 14:28 cpf
drwxr-xr-x 3 root root 4096 Mar 31 14:21 data
drwxr-xr-x 3 root root 4096 Mar 31 14:21 journal1
drwxr-xr-x 3 root root 4096 Mar 31 14:21 journal2
drwxrwxrwt 3 root root  100 Mar 31 14:28 key
drwxr-xr-x 3 root root 4096 Mar 31 14:21 wij

IRIS falla con el error:

[ERROR] Command "iris start IRIS quietly" exited with status 256
03/31/25-14:41:06:870 (795) 3 [Utility.Event] Error while moving data directories ERROR #5001: Cannot create target: /irissys/data/IRIS/

En su lugar, deberíamos utilizar la imagen non-root del web gateway  (ya que suponemos que queremos que todas nuestras imágenes se ejecuten como no root). Esto implicaría un web gateway restringido o locked-down. También debemos asegurarnos de agregar el security context para hacer cumplir esta condición. Necesitamos declarar explícitamente:

securityContext:
  runAsUser: 51773
  runAsGroup: 51773
  runAsNonRoot: true
  fsGroup: 51773

en vuestros nodos de datos/cómputo.

Un ejemplo de YAML para nuestro IrisCluster CRD que integra todo esto se puede ver a continuación.

apiVersion: intersystems.com/v1alpha1
kind: IrisCluster
metadata:
  name: iris
spec:
  licenseKeySecret:
    name: iris-key-secret
  configSource:
    name: iris-cpf
  imagePullSecrets:
    - name: intersystems-pull-secret
  topology:
    data:
      image: containers.intersystems.com/intersystems/irishealth:2025.1
      compatibilityVersion: "2025.1.0"
      mirrored: true
      podTemplate:
        spec:
          resources:
            requests:
              memory: "4Gi"
              cpu: "2"
            limits:
              memory: "4Gi"
              cpu: "2"
          securityContext:
            runAsUser: 51773
            runAsGroup: 51773
            runAsNonRoot: true
            fsGroup: 51773
      webgateway:
        image: containers.intersystems.com/intersystems/webgateway-lockeddown:2025.1
        type: apache-lockeddown
        applicationPaths:
          - /csp/sys
          - /csp/user
          - /csp/broker
          - /api
          - /isc
          - /oauth2
          - /ui
          - /csp/healthshare
        loginSecret:
          name: iris-webgateway-secret
    webgateway:
      replicas: 1
      image: containers.intersystems.com/intersystems/webgateway-lockeddown:2025.1
      type: apache-lockeddown
      podTemplate:
        spec:
          resources:
            requests:
              memory: "2Gi"
              cpu: "1"
            limits:
              memory: "2Gi"
              cpu: "1"
      applicationPaths:
        - /csp/sys
        - /csp/user
        - /csp/broker
        - /api
        - /isc
        - /oauth2
        - /ui
        - /csp/healthshare
      alternativeServers: LoadBalancing
      loginSecret:
        name: iris-webgateway-secret
    arbiter:
      image: containers.intersystems.com/intersystems/arbiter:2025.1
  serviceTemplate:
    spec:
      type: ClusterIP

Feliz YAMLing

Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer