Cet article propose un guide de migration de Sybase Adaptive Server Enterprise (ASE) vers une base de données IQ 12.7.
Une revue de l'architecture IQ 12.7 est proposée en préambule, puis sont abordées les différences entre ASE et IQ pour tout ce qui concerne les types de données, la gestion des contraintes, etc... Connaître ces différences permet d'appréhender efficacement les migrations d'ASE vers IQ. Cette documentation n'aborde pas les différences entre ASE et IQ sur l'administration des serveurs.
Un cas pratique de migration est ensuite proposé (ASE 12.5.3 > IQ 12.7), cas pratique qui inclut les migrations des tables et les chargements avec le binaire bcp et les commandes IQ LOAD TABLE et INSERT LOCATION.
IQ diffère d'un serveur Sybase ASE sur plusieurs points importants. IQ ne contient qu'une seule base de données, ce qui est très différent d'un serveur ASE qui peut contenir plusieurs bases de données. IQ a une philosophie serveur unique/base de données unique.
Une instance IQ est une collection de fichiers et de supports de type "raw device". Chaque fichier a un rôle spécifique.

| Fichier | Description |
|---|---|
| Catalogue de la base de données (catalog) | Le fichier databasename.db contient les tables et vues systèmes ainsi que les procédures stockées, utilisateurs, groupes, évènements et types de données utilisateurs. |
| Journal de transactions (txn log) | Par défaut, le journal de transactions a pour nomenclature databasename.log et contient les transactions d'une base IQ. La nomenclature est modifiable avec la commande CREATE DATABASE. Ce journal gère les transactions dans le catalogue de base de données et est maintenu par le programme utilitaire dblog |
| Fichier de configuration du serveur (config) | Le fichier de configuration contient les paramètres de démarrage d'un serveur IQ. |
| Espace de stockage principal (IQ Main Store) | Cet espace de stockage contient les données de la base IQ. La nomenclature classique de ce fichier est databasename_01.iq, mais celui-ci peut être modifié durant la création de la base de données ou des ajouts de dbspaces. Les bases de données IQ sont composées de plusieurs fichiers, chaque fichier représentant un dbspace. Le dbspace est un support logique dans un serveur IQ et qui pointe vers un support physique. Les supports de type "raw device" sont recommandés. |
| Espace de stockage temporaire (IQ Temporary Store) | L'espace de stockage temporaire permet de résoudre les résultats de jointures, des tris ou des regroupements (group by) mais aussi bien d'autres fonctions d'IQ. Il peut être composé comme l'espace principal de plusieurs dbspace logiques pointant sur des supports physiques séparés. |
| Fichier | Description |
|---|---|
| Fichier de message IQ (iqmsg) | Ce fichier est la sortie principale des messages spécifiques à la base de données IQ. Par défaut ce fichier a pour nomenclature databasename.iqmsg. Toutes les opérations spécifiques à la base de données sont écrites dans ce fichier, opérations incluant les avertissements et messages d'erreur, plans d'exécutions et tags de transactions (checkpoint etc...). |
| Autres fichiers de messages | Par défaut les fichiers <IQservername>_nnn.stderr et <IQservername>_nnn.stdout sont générés pour les messages propres au serveur. Ces fichiers sont nommés et numérotés à chaque démarrage du serveur IQ. Ces fichiers sont créés par l'utilitaire start_asiq. Si le démarrage est réalisé par un utilitaire personnalisé autre que start_asiq, ces fichiers ne sont pas générés. |
| Fichier | Description |
|---|---|
| Fichier SQLLOG | Ce fichier fournit spécifiquement toutes les requêtes exécutées sur une base de données IQ. Le niveau de verbosité et la localisation de ce fichier sont configurables avec les options -zr et -zo dans le fichiers de configuration params.cfg du serveur IQ. |
| Plans d'exécution des requêtes HTML | Ces fichiers contiennent au format HTML les plans d'exécution des requêtes pour toutes les requêtes exécutées dans un serveur ou pour une requête individuelle donnée par une option de la base. Cette fonctionnalité est modifiée avec le paramètre query_plan_as_html dans le serveur. Par défaut, les fichiers de sortie sont écrits dans le répertoire contenant le fichier de message IQ (db_name.iqmsg) mais ils peuvent être écrits dans un répertoire spécifique sur la machine avec l'option de base de données Query_Plan_As_HTML_Directory. |
L'architecture Sybase IQ Multiplex permet une implémentation plus évolutive d'une base de données IQ. Dans cette architecture, plusieurs instances Sybase IQ peuvent partager les mêmes données, ce qui permet de répartir les exécutions des requêtes sur plusieurs instances. Les dégradations de performances sur cette architecture distribuée multiplex sont quasi négligeables.
L'installation Multiplex se compose de plusieurs machines connectées à un disque partagé.

Les instances IQ sur les machines sont désignées comme des serveurs de requêtes (query servers) ou comme un serveur d'écriture (write server). Il ne peut y avoir qu'un seul serveur IQ d'écriture dans une installation multiplex, mais plusieurs serveurs IQ de requête peuvent être présents. La création de ces serveurs est malheureusement accompli uniquement à travers Sybase Central, il n'existe pas de lignes de commandes pour la mise en oeuvre des serveurs IQ de requête.
Les serveurs IQ dans une architecture multiplex ont leurs propres fichiers ( .db, .log, .iqtmp, .iqmsg etc...) à l'exception des fichiers de données de la base de données (IQ Main Store) qui sont partagés par tous les serveurs.
Un serveur de requêtes IQ dans une architecture multiplex peut disposer d'un espace de données local (dbspace local ou local store). Cet espace local n'est pas représenté dans le schéma de l'architecture multiplex plus haut. Ainsi les utilisateurs connectés à un serveur de requête peuvent créer, stocker et maintenir des tables ou objets persistents au serveur de requête.
Comme il n'y a qu'une seule base de données par serveur, l'instance IQ ne peut se présenter comme un serveur ASE contenant de multiples bases de données. Toutefois, il existe des méthodes qui permettent de ségréguer logiquement une base de données IQ en une multitude de schémas (comme Oracle) afin de simuler les bases de données multiples dans ASE.
En manipulant l'appartenance des objets à des utilisateurs spécifiques, des schémas séparés peuvent être créés dans des partitions de données et ainsi des bases de données logiques peuvent être formées.
Par exemple, un schéma créé par l'utilisateur MKTG (table MKTG.customer), est différent d'un schéma créé par l'utilisateur ACCT (table ACCT.customer).
Les colonnes dans IQ doivent être explicitement définies avec l'option NULL ou NOT NULL. Les comportements par défaut d'ASE et d'IQ sont en effet radicalement différent à ce sujet. IQ applique l'option NULL par défaut à une colonne à moins que l'option NOT NULL ne soit explicitement donnée. ASE applique l'inverse : par défaut la colonne a la caractère NOT NULL si rien n'est spécifié explicitement pour la colonne.
Le choix des types de données est critique pour l'optimisation des performances et un stockage efficace. Le tableau ci-dessous illustre comment les types de données sont gérées par ASE et IQ.
| Type | IQ | ASE | Note |
|---|---|---|---|
| bit | √ | √ | |
| tinyint | √ | √ | |
| smallint | √ | √ | |
| integer | √ | √ | ! ASE supporte les entiers non signés (unsigned integer) qu'à partir de la version 15. |
| bigint | √ | √ | ! ASE supporte le type bigint qu'à partir de la version 15. |
| char | √ | √ | ASE char dépend de la taille de page |
| varchar | √ | √ | ASE varchar dépend de la taille de page |
| long varchar | √ | IQ utilise le type de données CLOB et peut avoir une taille illimitée | |
| text | √ | √ | IQ utilise le type de données CLOB et peut avoir une taille illimitée |
| nchar/nvarchar | √ | ||
| unichar | √ | ||
| binary | √ | √ | 255 max pour IQ. Pour ASE, dépendant de la taille de page |
| varbinary | √ | √ | 255 max pour IQ. Pour ASE, dépendant de la taille de page |
| long binary | √ | ||
| image | √ | √ | Image est un synonyme pour long binary dans IQ |
| date | √ | √ | |
| time | √ | √ | |
| datetime | √ | √ | |
| smalldatetime | √ | √ | smalldatetime est un synonyme de datetime dans IQ |
| timestamp | √ | √ | timestamp est un binary(8) dans ASE. Dans IQ, timestamp est un datetime |
| numeric | √ | √ | La précision et l'échelle sont très différents |
| decimal | √ | √ | La précision et l'échelle sont très différents |
| float | √ | √ | Les stockages diffèrent |
| double | √ | √ | |
| java types | √ | √ | IQ stocke les types java dans le dbspace system (catalog) |
| identity | √ | √ | L'implémentation diffère entre ASE et IQ |
Les contraintes d'intégrité référentielle (RI) peuvent être implémentés dans IQ. Les contraintes RI sont bénéfiques pour les performances des requêtes et plus particulièrement lorsqu'une table de fait partitionnée est employée. L'optimiseur utilise les contraintes RI pour déterminer la cardinalité entre les clés d'un parent et celles des tables filles. Les contraintes RI dégradent les performances d'environ 5% (max), mais ces contraintes peuvent être désactivées temporairement lors du chargement en utilisant l'option de base de données Disable_RI_Check.
Les seuls types d'évènements autorisés sont :
BackupEnd | "Connect" || ConnectFailed | DatabaseStart | DBDiskSpace |
"Disconnect" | GlobalAutoincrement | GrowDB | GrowLog | GrowTemp|
LogDiskSpace | "RAISERROR" | ServerIdle | TempDiskSpace
Sybase IQ devient de plus en plus mature et les différences entre ASE et IQ se réduisent petit à petit avec les nouvelles versions. Beaucoup d'options systèmes IQ permettent de forcer IQ à se comporter comme ASE. Les options de compatibilité sont automatiquement appliquées lorsqu'une connection à un serveur IQ est réalisée à travers la couche TDS grâce à la procédure système sp_tsql_environment.
set option public.allow_nulls_by_default = 'off';
set option public.quoted_identifier = 'off';
set option public.string_rtruncation = 'off';
set option public.ansinull = 'off';
set option public.chained = 'on';
set option public.float_as_double = 'off';
Pour transférer les données d'un serveur Sybase Adaptive Server Enterprise
vers un serveur IQ, deux méthodes sont offertes : la méthode "INSERT LOCATION"
et la méthode "LOAD TABLE". La méthode INSERT LOCATION est réservée aux faibles
volumes de données, alors que la méthode LOAD TABLE est plutôt réservée aux
volumes importants.
Dans les cas pratiques de cette documentation, les serveurs IQ sont
installés avec la norme décrite dans l'article "Installation et normalisation de Sybase IQ
12.7 sous Solaris".
La commande INSERT LOCATION permet de charger dans une table IQ depuis une
session dbisql des données contenues dans un serveur Sybase ASE par un ordre
INSERT/SELECT.
La cinématique est la suivante :

| 1. |
Une application cliente se connecte au
serveur IQ et lance la commande INSERT LOCATION. |
| 2. |
Le serveur IQ ouvre une connection Open
Client vers Sybase ASE. |
| 3. |
Le serveur IQ envoie la commande SELECT
de la commande INSERT LOCATION au serveur Sybase ASE. |
| 4. |
Le serveur Sybase ASE exécute la
commande SQL Select et retourne le jeu de résultats au serveur IQ. |
| 5. |
Le serveur IQ charge le jeu de données
retourné par Sybase ASE. |
INSERT [INTO] [owner.]table-name[ |
Paramètres : |
L'ordre SELECT {select-statement} donné au serveur ASE peut contenir des
jointures, des conversions, des clauses CASE et du casting du type de
données.
Exemple :
INSERT INTO dbo.authors ( au_id )
NOTIFY 10000
LOCATION 'ASESERVER.pubs2'
{ select au_id from authors }
Lorsque le serveur IQ se connecte au serveur distant ASE, INSERT..LOCATION
utilise le login distant défini pour l'utilisateur de la connexion courante si
un login distant a été créé avec CREATE EXTERNLOGIN et un serveur distant a été
défini avec la commande CREATE SERVER.
Pour définir un serveur distant ASE :
CREATE SERVER server-name
CLASS 'ASEJDBC|ASEODBC'
USING '{ machine-name:port-number [ /dbname ] | data-source-name }'
[ READ ONLY ]
Pour définir un login externe vers un serveur distant ASE :
CREATE EXTERNLOGIN login-name
TO remote-server
REMOTE LOGIN remote-user
[ IDENTIFIED BY remote-password ]
remote-server est le serveur distant défini dans l'étape précédente avec la commande CREATE SERVER.
Lorsque le serveur distant ou le login distant n'est pas défini, IQ effectue une connexion vers le serveur ASE en utilisant les coordonnées disponibles dans le fichier interfaces ou le fichier sql.ini et en utilisant l'utilisateur et le mot de passe de la connexion courante.
Dans le cas pratique, l'authentification est réalisée avec le contexte de l'utilisateur : le compte et le mot de passe de l'utilisateur sont envoyés au serveur ASE. Cette méthode est adaptée pour les faibles volumes à transférer.
INSERT INTO IDW.PORTFOLIO
(
PORTFOLIO_ID,
PORTFOLIO_NAME,
...
)
LOCATION 'IDB_T1_ASE.investment'
'
SELECT PORTFOLIO_ID,
PORTFOLIO_NAME,
....
FROM PORTFOLIO
'
go
commit
go
La commande LOAD TABLE permet de charger massivement dans une table IQ les
données contenues dans un fichier plat ASCII depuis une session dbisql.
Les données contenues dans les fichiers plats sont exportées en mode caractère
depuis un serveur Sybase Adaptive Server Enterprise avec le binaire bcp : les
données peuvent provenir de la table directement ou d'une vue. L'avantage des
vues est multiple, elles permettent de formater les données, notamment les
colonnes date/datetime etc..., ou encore de réaliser des exports par plages
(plages de dates par exemple) si il s'agit d'une table très volumineuse à
décharger.
La syntaxe de la commande LOAD TABLE est très touffue, toutes les options ne seront pas décrites dans cet article.
LOAD [ INTO ] TABLE [ owner ].table-name
... ( load-specification [, ...] )
... FROM { 'filename-string' | filename-variable } [, ...]
... [ CHECK CONSTRAINTS { ON | OFF } ]
... [ DEFAULTS { ON | OFF } ]
... QUOTES OFF
... ESCAPES OFF
... [ FORMAT { 'ascii' | 'binary' } ]
... [ DELIMITED BY 'string' ]
... [ STRIP { ON | OFF } ]
... [ WITH CHECKPOINT { ON | OFF } ]
... [ { BLOCK FACTOR number | BLOCK SIZE number } ]
... [ BYTE ORDER { NATIVE | HIGH | LOW } ]
... [ LIMIT number-of-rows ]
... [ NOTIFY number-of-rows ]
... [ ON FILE ERROR { ROLLBACK | FINISH | CONTINUE} ]
... [ PREVIEW { ON | OFF } ]
... [ ROW DELIMITED BY 'delimiter-string' ]
... [ SKIP number-of-rows ]
... [ WORD SKIP number ]
... [ START ROW ID number ]
... [ UNLOAD FORMAT ]
... [ IGNORE CONSTRAINT constrainttype [, ...] ]
... [ MESSAGE LOG 'string' ROW LOG 'string' [ ONLY LOG logwhat [, ...] ]
... [ LOG DELIMITED BY 'string' ]
Les permissions requises pour exécuter la commande LOAD TABLE dépendent
initialement de l'option -gl donnée à la ligne de commande du démarrage du
serveur IQ.
| -gl ALL |
La commande LOAD TABLE est autorisée
pour les propriétaires des tables, les utilisateurs ayant le rôle DBA
ou disposant de la permission ALTER TABLE sur la table à charger. |
| -gl DBA |
L'autorité DBA est exclusive pour
exécuter la commande LOAD TABLE. |
| -gl NONE |
La commande LOAD TABLE n'est pas
autorisée. |
Par défaut, lorsque l'option -gl n'est pas donnée au démarrage du serveur IQ, -gl est à ALL pour les serveurs démarrés avec start_asiq et à DBA pour les autres modes de démarrage.
Dans la normalisation adoptée, le serveur IQ est démarré avec l'option -gl
DBA et un utilisateur IQ appelé idwloader dédié aux chargements est créé. Le
droit ALTER TABLE sur une table autorise les chargements massifs pour un
utilisateur donné.
L'utilisateur idwloader est créé avec la commande GRANT CONNECT et le droit
ALTER TABLE est donné à cet utilisateur pour les tables chargées avec ce
compte. Les syntaxes GRANT nécessaires sont rappelées ci-dessous
GRANT CONNECT TO userid IDENTIFIED BY password;
GRANT ALTER ON [owner.]table-name TO userid;
Exemple :
GRANT CONNECT TO idwloader IDENTIFIED BY ********;
GRANT ALTER ON IDW.ADJUSTEMENT_FACTOR TO idwloader;
Dans le cas pratique, la table ADJUSTMENT_FACTOR est exportée du serveur ASE IDB_T1_ASE pour chargement dans la table IDW.ADJUSTMENT_FACTOR dans le serveur IQ IDB_T1_ASQ.
Une vue vIQ_ADJUSTMENT_FACTOR est créée dans le serveur ASE IDB_T1_ASE pour préparer les données et notamment le formatage des dates.
use investment
go
if exists (select 1 from sysobjects where type='V' and name='vIQ_ADJUSTMENT_FACTOR')
begin
drop view vIQ_ADJUSTMENT_FACTOR
end
go
CREATE VIEW vIQ_ADJUSTMENT_FACTOR
as
select
INSTRUMENT_ID,
( case ADJUSTMENT_DATE
when NULL then '0000/00/00' else convert(varchar(10),ADJUSTMENT_DATE,117)
end) as ADJUSTMENT_DATE,
SOURCE_ID,
ADJ_FACTOR_P,
ADJ_FACTOR_GR,
ADJ_FACTOR_NR,
CREATED_BY,
convert(varchar(10),CREATED_ON,117) +' '+ convert(varchar(8),CREATED_ON,108) as CREATED_ON,
UPDATED_BY,
( case UPDATED_ON
when NULL then '0000/00/00 00:00:00' else convert(varchar(10),UPDATED_ON,117)
+' '+ convert(varchar(8),UPDATED_ON,108)
end ) as UPDATED_ON
from ADJUSTMENT_FACTOR
go
Les données de la vue sont exportées sur la machine hébergeant le serveur IQ IDB_T1_ASQ, export réalisé en mode caractère avec le binaire bcp en spécifiant comme délimiteur de colonnes le point-virgule (;) :
sybase@IDB_T1_ASQ > bcp investment..vIQ_ADJUSTMENT_FACTOR out ADJUSTMENT_FACTOR.bcpc -Usa -t";" -SIDB_T1_ASE -P******** -c
La table IDW.ADJUSTMENT_FACTOR est créée avec dbisql :
sybase@IDB_T1_ASQ > cat iq_c_ADJUSTMENT_FACTOR.sql
DROP TABLE IDW.ADJUSTMENT_FACTOR;
CREATE TABLE IDW.ADJUSTMENT_FACTOR
(
INSTRUMENT_ID int NOT NULL IQ UNIQUE(500000),
ADJUSTMENT_DATE date NOT NULL,
SOURCE_ID varchar(12) NOT NULL IQ UNIQUE(500),
ADJ_FACTOR_P float NULL,
ADJ_FACTOR_GR float NULL,
ADJ_FACTOR_NR float NULL,
CREATED_BY varchar(20) NOT NULL,
CREATED_ON datetime NOT NULL,
UPDATED_BY varchar(20) NULL,
UPDATED_ON datetime NULL,
PRIMARY KEY(INSTRUMENT_ID, ADJUSTMENT_DATE, SOURCE_ID)
);
GRANT ALTER ON IDW.ADJUSTEMENT_FACTOR TO idwloader;
dbisql iq_c_ADJUSTMENT_FACTOR.sql
Un fichier SQL iq_l_ADJUSTMENT_FACTOR.sql contenant la commande LOAD TABLE pour la table IDW.ADJUSTMENT_FACTOR est alors créé puis exécuté avec dbisql.
sybase@IDB_T1_ASQ > cat iq_l_ADJUSTMENT_FACTOR.sql
LOAD TABLE IDW.ADJUSTMENT_FACTOR
(
INSTRUMENT_ID,
ADJUSTMENT_DATE date('YYYY/MM/DD') null('0000/00/00'),
FILLER(1),
SOURCE_ID,
ADJ_FACTOR_P,
ADJ_FACTOR_GR,
ADJ_FACTOR_NR,
CREATED_BY ,
CREATED_ON datetime('YYYY/MM/DD hh:nn:ss') null('0000/00/00 00:00:00'),
FILLER(1),
UPDATED_BY ,
UPDATED_ON datetime('YYYY/MM/DD hh:nn:ss') null('0000/00/00 00:00:00'),
FILLER(1)
)
FROM '/Software/sybase/dba/IDB_T1_ASQ/dmp/ADJUSTMENT_FACTOR.bcpc'
DELIMITED BY ';'
ROW DELIMITED BY '\x0a'
QUOTES off
ESCAPES off
FORMAT ascii
WITH CHECKPOINT ON
PREVIEW ON
;
commit;
sybase@IDB_T1_ASQ > dbisql iq_l_ADJUSTMENT_FACTOR.sql
| Version | Date | Commentaires |
|---|---|---|
| 1.0 | 03/2009 | Version initiale |
Sybase IQ 12.7
BOL
Migrating from
Sybase Adaptive Server Enterprise to Sybase IQ
Sybase IQ 12.7
BOL : Bulk loading data using the LOAD TABLE statement
Sybase IQ 12.7
BOL : LOAD TABLE statement
Sybase IQ 12.7
BOL : INSERT LOCATION