Le COMMIT en Programmes Batch Avec DB2

Embed Size (px)

DESCRIPTION

Le COMMIT en Programmes Batch Avec DB2

Citation preview

SDDC-MTH-007-10

Global Services&&&&&&&&&&SDDC

Le COMMIT dans les programmes Batch

Avec DB2Global Services

LE COMMIT

DANS LES PROGRAMMES BATCH

AVEC DB2

Le prsent document constitue un guide mthodologique de gestion des commits dans les programmes batch dans un environnement db2.

Il a t rdig en mars 1995 par Yves Benaroch, puis ractualis en juin 2000 par Fred Catel.

Il contient un expos des rgles dimplmentation de lordre COMMIT et de diverses implications dans la programmation.

Les rgles exposes visent garantir une intgrit des donnes mises jours en cas de traitement normal et en cas de reprise aprs incident, tout en conservant des objectifs de performance.

Principe Gnral chez SDDC:

TOUS les programmes batch ralisant des mises jour doivent faire des commits intermdiaires si leur dure totale de traitement dpasse 30 secondes.

I - DEFINITION

1.1 Fonction

Quand lordre COMMIT est donn DB2, toutes les mises jour effectues dans les tables DB2

depuis le dernier commit

depuis le dbut du programme, sil sagit du premier commit

sont entrines.

Cest dire qu partir du moment o le commit est excut, les mises jour qui le prcdent sont dfinitives. (Sauf recourir des restaurations de tables un point antrieur par lutilitaire RECOVER).

Tant que le commit na pas t excut (ou jusqu la fin du programme), les mises jour sont rvocables.

1.2 Syntaxe

Cest un ordre SQL, qui dans un programme COBOL, scrit:

EXEC SQL COMMIT END-EXEC

Ou

EXEC SQL COMMIT WORK END-EXEC

La syntaxe COMMIT WORK est quivalente COMMIT. Cette syntaxe rpond des besoins de compatibilit entre le SQL* de DB2 et dautres SQL.

1.3 Limitations de sa porte

Attention. Lordre commit nest pas tolr des environnements IMS ou CICS. Il est simplement mis en commentaire par le prcompilateur. Les architectures telles que CICS assurent elles mmes la gestion des mises jours, pour DB2 mais aussi pour lensemble des ressources accdes (VSAM, etc). Cest le TWO PHASES COMMIT.

Il est ralis par lordre EXEC CICS SYNCPOINT END-EXEC.

1.4 COMMIT implicite ou explicite

Lordre EXEC SQL COMMIT ralise un commit explicite.

Tout processus qui se termine correctement (ne se terminant pas par un abend) ralise un commit implicite.

Il est donc inutile de coder un commit en fin de programme.

Attention. Le positionnement par programme dun code retour diffrent de zro nannule pas le commit implicite de fin de programme.

*: Structured Query Language: norme internationale commune ( n% prs) tous les SGBD.

II UTILITE - NECESSITE

2.1 Condition minimaleUn commit nest utile dans un programme que si lui ou un de ses sous-programmes ralise au moins une mise jour sur une table db2.

Depuis la V5 de DB2 et lintroduction des utilitaires online, il est ncessaire de placer un commit dans un plan lecture seule pour permettre une reorg de se terminer normalement (phase de SWITCH) pendant lexcution dun batch concurrent. Cette mesure est encore ltude et nest pas, pour linstant, un standard.

2.2 Inutilit Si le plan dun programme lecture seule est bind avec loption ISOLATION(CS) (Cursor Stability, dfaut SDDC), un commit ne sert rien, car les pages lues restent quoiquil arrive accessibles par les autres plans.

Si ce plan est bind avec ISOLATION(RR) (Repeatable Read), les pages lues restent verrouilles pour tre relues plus rapidement, et interdisent ainsi tout accs concurrent. Le commit libre les verrous et rend les pages accessibles.

Toutefois, un plan lecture seule bind avec ISOLATION(UR) (Uncommited Read, usuellement dconseill) ne sera pas victime des verrous poss par dautres plans, avec le risque de lire des donnes errones ou supprimes.

2.3 Plusieurs objectifs viss

2.3.1 Assurer une meilleure concurrence daccs aux donnes des tables DB2.

Les donnes modifies (INSERT, UPDATE, DELETE) par un programme sont verrouilles et inaccessibles, en lecture ou mise jour, tous les autres plans (sauf binds en UR). Si elles ne sont pas libres suffisamment vite, les plans demandeurs reoivent un sqlcode 911 (DEADLOCK ou TIMEOUT ) et tombent en principe en abend (ce point sera dvelopp plus loin). Seul le plan modifiant voit les donnes modifies, et peut donc les relire ou les modifier de nouveau.

Il est donc impratif deffectuer des commits frquents, un rythme infrieur la limite de timeout (dure variable selon les db2 et infrieure 60 secs) pour optimiser les accs concurrentiels.

Toutefois, il convient galement dappliquer certaines rgles, telles que

prohiber les ordres LOCK TABLE dans les programmes

viter les binds avec ISOLATION(RR)

viter les LOCKSIZE TABLESPACE ou TABLE

etc

qui ont pour consquence dannuler les effets du commit.

2.3.2 Acclrer le processus de retour arrire (ROLLBACK) Il est interdit de laisser un programme raliser des mises jour sans commit intermdiaire pendant un temps trop long. Nous avons dj vu que pendant cette priode les pages modifies restaient indisponibles aux autres utilisateurs.

Mais si pour une raison quelconque, abend ou rollback programm, le programme doit revenir en arrire, donc remettre les donnes dans leur tat dorigine, les pages resteront bloques jusqu la fin anormale du programme ou jusqu la complte excution de lordre ROLLBACK.

Classiquement, lannulation par DB2 des modifications prend autant de temps que les modifications elles-mmes. Ce qui doublera le temps dindisponibilit des donnes.

2.3.3 Permettre un redmarrage rapide de DB2 Lorsque se produit un arrt inattendu de DB2, tous les processus de mise jour en cours au moment de larrt seront suivis dun ROLLBACK lors du redmarrage. Le DB2 ne sera disponible, que lorsque tous les processus de ROLLBACK seront termins.

On comprend donc que si au moment de larrt dun DB2, tournait un programme responsable de millions de mises jour, sans commit intermdiaire, depuis des heures, on risque au redmarrage dattendre autant de temps (sinon plus) pour que DB2 puisse annuler toutes les modifications non commites. Cest la totalit du DB2 qui sera cette fois indisponible.

Ce dernier point sera amlior avec la V6 de DB2 mais cette perspective nautorise pas pour autant les mises jour sans commit intermdiaire.

III UNITE LOGIQUE DE TRAVAIL UNITE DE RECOVERY

3.1 Lunit logique de travail (LUW)

Lunit logique de travail est constitue dune squence doprations qui sont logiquement lies entre elles et insparables. Lunit logique de travail est inscable du point de vue applicatif pour assurer une cohsion des donnes.

Par exemple, lenregistrement dune transaction bancaire est une unit logique de travail constitue de:

la cration du mouvement (INSERT dans la table des mouvements)

la mise jour du solde du compte (UPDATE dans la table des soldes)

Il nest pas concevable de modifier le solde sans crer le mouvement lorigine de la mise jour du solde du compte. Ces deux oprations de mise jour sont solidaires, on ne peut envisager lune sans lautre.

On ne doit pas raliser de commit au milieu dune unit logique de travail.

Lunit logique de travail doit tre la plus fine possible.

Un commit ne peut tre fait qu la fin dune unit logique de travail.

Un rollback peut survenir au milieu dune unit logique de travail.

3.2 Lunit de restauration ou unit de RECOVERY (UR)

Lunit de restauration ou unit de recovery est constitue dune squence dunits logiques de travail. Cest cette squence de mises jour qui doit tre globalement entrine ou refuse.

Chaque squence est dlimite par un commit ou un rollback. Dans le cas standard, une unit de recovery est constitue de ce qui spare deux commits.

Habituellement, dans un contexte transactionnel (CICS, etc), les notions dunit logique de travail et dunit de recovery se superposent et se confondent. Il nest pas recommand, en standard, de coder un commit/syncpoint dans un programme CICS.

Par contre, dans un contexte batch, une unit de recovery correspond souvent plusieurs units logiques de travail. Lexcution du commit gnrant 2 I/O, il peut tre pnalisant de raliser des commits trop frquents.

IV LES CONSEQUENCES DU COMMIT

4.1 Les consquences sur le systme de verrouillage

Tous les verrous acquis sur les pages de donnes (ou sur les pages dindex pour les indexes de type 1) sont librs, sauf sur celles lies la position dun curseur WITH HOLD.

4.2 Les consquences sur les autres ordres SQL

Tous les curseurs ouverts sont automatiquement ferms sauf ceux dclars avec loption WITH HOLD;

Tous les ordres PREPARE (sql dynamique) sont perdus, sauf si le programme est bind avec loption KEEPDYNAMIC(YES).

V - LES IMPLICATIONS DANS LA PROGRAMMATION

5.1 La table de repriseChaque programme qui ralise des commits doit normalement possder une ligne qui lui est associe dans une table de reprise.

Si un programme peut sexcuter en multi-init ou en occurrences multiples, la table de reprise doit possder autant de lignes associes ce programme que le nombre maximum doccurrences de ce programme.

En dbut de traitement, le programme doit lire la ligne qui lui est associe dans la table de reprise, et le cas chant savoir dynamiquement retrouver la bonne occurrence. Ainsi, il connatra sa cl de repositionnement, et sa frquence de commit.

A la fin de chaque unit logique de travail, le programme se demande sil est utile de faire un commit, donc sil est en fin dunit de recovery. Si la rponse est positive, il commence par mettre jour sa ligne/occurrence de reprise avec la nouvelle valeur de la cl. Le commit doit tre excut immdiatement aprs cet UPDATE.

Des prcautions particulires sont prises pour minimiser les risques de contention lors des mises jour sur les tables de reprise:

conserver une ligne de 4 k (une page entire) par adjonction de filler.

prohiber le compactage qui annulerait la mesure prcdente

LOCKSIZE PAGE ou LOCKSIZE ROW (verrouillage la ligne)

vrifier dans les explains que les accs la table de reprise se font par lindex unique, et que toutes les colonnes sont adresses

considrer la table comme critique du point de vue des performances (surveillance des disques, droulement des utilitaires, etc.)

5.2 - Loption WITH HOLD dans les curseurs Le ou les curseurs, qui sont ouverts pendant lexcution de lordre commit, doivent tre dclars WITH HOLD, ce qui empchera leur fermeture implicite.

Cest au programme de dcider de la fermeture ou non des curseurs, et de leur rouverture. Cette option est particulirement utile si, comme cest souvent le cas en batch, louverture dun curseur est longue et coteuse. Par exemple, si les index sont peu ou mal accds, si des tris (order by, group by, distinct) sont ncessaires sur un volume important de lignes. Toutes ces oprations doivent tre renouveles chaque ouverture de curseur. Loption WITH HOLD permet de ntre pnalis quune fois par le poids du curseur, quel que soit le nombre de commits.

5.3 La cl de reprise Le repositionnement

5.3.1 Le repositionnement peut tre fonctionnellement impratif.

La cl de reprise doit correspondre un identifiant unique du point de vue de lunit logique de travail. Elle peut tre composite.

On doit pouvoir retrouver sans quivoque la dernire unit logique de travail accde lors du traitement incomplet prcdent.

Par exemple, un programme doit augmenter les prix de tous les articles de 1%.

En cas dinterruption anormale, il est prfrable de ne pas rappliquer laugmentation aux articles dj traits la fois prcdente.

Pour cela le curseur doit tenir compte du repositionnement.

EXEC SQL DECLARE CURS_1 CURSOR WITH HOLD FOR

SELECT ARTICLE, PRIX_VENTE

FROM TAB_ARTICLE

WHERE ARTICLE >:DERNIER-ARTICLE-LU

ORDER BY ARTICLE

END-EXEC

5.3.2 Le repositionnement peut tre superflu

Certains programmes mettent jour ou suppriment les critres de slection du curseur.

Par exemple, on supprime dune table historique les lignes dont la date de cration est antrieure 6 mois.

EXEC SQL DECLARE CURS_1 CURSOR WITH HOLD FOR

SELECT DATE_CREAT, ARTICLE

FROM HISTO_ARTICLE

WHERE DATE_CREAT n peut tre plus ou moins longue satisfaire.

De mme, si une condition dextraction est pose sur une colonne non indexe, dont la dispersion dans la table est fluctuante et alatoire (ex: PRIX_VENTE > 10000), le volume de donnes variera dun traitement lautre et surtout le temps coul entre deux lignes traiter et donc entre deux commits.

6.2 Le commit toutes les n secondes

Cest cette solution qui a notre prfrence, car elle limine presque totalement les inconvnients majeurs exposs plus haut.

Nous recommandons actuellement un commit toutes les 5 secondes.

Ds quune unit logique de travail est accomplie, le programme se demande sil sest coul plus de n secondes depuis le dernier commit. Si cest le cas la squence de commit sera excut, sinon le programme continue normalement et la prochaine unit logique est traite, et ainsi de suite jusqu ce que le seuil soit atteint.

Les commit frquence strictement constante peuvent parfois prsenter des inconvnients. Il importe dans certains cas (tables trs sollicites) quun commit soit indispensable, quelles que soient les conditions normales. Il importe donc de pouvoir forcer un commit.

6.3 Le commit frquence trop leve

Nanmoins, si les units logiques de travail sont simples, et quun commit est forc aprs chacune delles, la dure elapsed du programme augmentera. En effet, un commit force dans DB2 deux critures synchrones (DUAL LOGGING) sur les fichiers de log. Ceci a un cot.

Un ratio de plus dun commit par seconde est proscrire, sauf pour la mise jour de tables extrmement sensibles aux conflits daccs. Il doit faire lobjet dun avis des DBA.

VII STRUCTURE DES PROGRAMMES

7.1 Programme entirement DB2

Cest le cas idal. Toutes les mises jour sont alignes sur le mme point de commit.

La structure gnrale est la suivante:

lecture de la table de reprise, chargement de la cl de reprise

ouverture du curseur matre

boucle de traitement

fetch dune ligne du curseur matre

lectures et mises jour pour raliser une unit logique de travail

test sur la dure depuis le dernier commit

si la limite est atteinte: mise jour de la table de reprise et commit

sinon: poursuite de la boucle

fin de la boucle

mise jour de la table de reprise avec la valeur minimum de la cl

fin du programme

Rgle: ds quun programme met jour des donnes DB2, il ne doit mettre jour que des donnes DB2 ( donc exclure les critures sur squentiels ou UPDATE VSAM)

7.2 Fichier(s) squentiel(s) en entre

Ce cas de figure se ramne au cas prcdent, il suffit de considrer les fichiers squentiels comme lquivalent de curseurs DB2. Il faut donc prvoir un mcanisme de repositionnement jusquau dernier enregistrement trait et commit. Par scurit, le fichier physique ayant pu changer entre labend et la relance, il est prfrable de conserver, dans la table de reprise, la cl du fichier et son rang, et de vrifier au redmarrage que les deux correspondent.

7.3 Fichiers squentiels en critureTypiquement, ce sont les programmes dapurement, avec sauvegarde sur fichier des lignes supprimes. Il est trs dangereux de mlanger dans le mme programme des critures sur des fichiers squentiels avec des mises jour DB2.

En effet, les critures sur les fichiers squentiels sont ralises par MVS par externalisation de ses buffers. Cette opration nest pas, pour linstant, synchrone avec le commit DB2. Or, il est toujours possible quun problme survienne lors de lcriture physique:

erreur dentre sortie (disque ou lecteur hors service)

plus de place sur le disque

nombre maximum dextends atteint

etc

Une telle pratique est dautant plus dangereuse, quelle peut trs bien fonctionner sans problme pendant une longue priode. Et le jour o le problme survient, il nest pas certain quil soit mis en vidence. Sa rsolution est dautant plus improbable.

Anciennement couramment utilise, notamment par les Etudes Grands Magasins, cette technique est aujourdhui proscrire.

Les risques sont aujourdhui les mmes pour les fichiers VSAM. Nanmoins, une solution semblable au TWO PHASES COMMIT (voir plus haut) est annonce pour bientt.

7.4 Nouveaut 1999.En 1999, les Etudes Grands Magasins ont expriment une nouvelle technique pour leur chane Rsultats Unitaires, particulirement lourde et sensible. En plus de lintroduction du paralllisme et du sous-programme CMTEXIT, certains batch ont bnfici de la gestion du sqlcode 911 ( timeout ou deadlock).

En effet ce sqlccode est lun des plus frquents, il traduit une contention de verrouillage temporaire. De plus il saccompagne dun Rollback implicite depuis le prcdent commit.

Lide de base tait de permettre un programme de repartir lui mme son point de dpart logique (rcupration de sa cl de reprise et ouvertures des curseurs matres) aprs avoir dtect un sqlcode -911 sans attendre une intervention humaine. En effet, jusquici il fallait gnrer une fin anormale du programme par Abend et attendre quil soit relanc par les pilotes, ce qui tait parfois une cause de retard important..

La solution suggre consiste prendre en charge ce sqlcode 911 et tenter de recommencer le traitement un certain nombre de fois.

EXEC SQL UPDATE TABLE1

SET COL3 =:H-V

, COL4 =:H-V

WHERE COL1 =:H-V

AND COL2 =:H-V

END-EXEC.

aprs lexcution de lupdate, la rcupration du sqlcode 911

permet dviter de laisser filer labend et de redmarrer au dbut programme

IF SQLCODE NOT = 0 AND SQLCODE NOT = -911

CALL DB2ANOS .

.....

ELSE

IF SQLCODE = -911 AND CPT-LOCK