<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Oracle - Concepts et Exemples &#187; undo</title>
	<atom:link href="https://blog.developpez.com/pachot/tag/undo/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/pachot</link>
	<description>Les fonctionalités et concepts d&#039;Oracle à partir de traductions et de démos</description>
	<lastBuildDate>Sun, 03 Apr 2016 20:36:21 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.42</generator>
	<item>
		<title>A quoi sert l&#8217;undo (rollback segment), par Jonathan Lewis</title>
		<link>https://blog.developpez.com/pachot/jl_why_undo/</link>
		<comments>https://blog.developpez.com/pachot/jl_why_undo/#comments</comments>
		<pubDate>Fri, 09 Apr 2010 18:08:09 +0000</pubDate>
		<dc:creator><![CDATA[pachot]]></dc:creator>
				<category><![CDATA[Jonathan Lewis]]></category>
		<category><![CDATA[undo]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Cet article est la traduction d&#8217;un article de Jonathan Lewis publié sur son blog. L&#8217;article original en anglais se trouve ici. Merci à Mohamed Houri qui m&#8217;a aidé pour cette traduction. L&#8217;article précédent Undo et Redo et Recovery en quelques &#8230; <a href="https://blog.developpez.com/pachot/jl_why_undo/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<blockquote><p><ins>Cet article est la traduction d&rsquo;un article de Jonathan Lewis publié sur son blog. L&rsquo;article original en anglais se trouve <a href="http://jonathanlewis.wordpress.com/2010/02/09/why-undo/">ici</a>.<br />
<br />
Merci à Mohamed Houri qui m&rsquo;a aidé pour cette traduction.</p>
<p>L&rsquo;article précédent <a href="http://blog.developpez.com/pachot/p8687/concepts/undo/jl-nutshell1/">Undo et Redo et Recovery en quelques mots</a> nous montre que l&rsquo;information <strong>undo</strong> est contenue dans le <strong>redo</strong> en tant que <em>change vector</em> pour les blocks d&rsquo;<em>undo</em>. On peut donc se demander pourquoi Oracle a introduit les tablespaces d&rsquo;<em>undo</em> (aussi connues comme tablespace des <em>rollback segments</em>) pour implémenter la lecture consistante, au lieu d&rsquo;utiliser seulement les <strong>redo</strong> pour retrouver une image passée des données.<br />
</ins></p></blockquote>
<p>Un post sur le <a href="http://forums.oracle.com/forums/thread.jspa?threadID=1016183&amp;tstart=0">forum OTN</a> pose la question suivante: <em>Puisque le redo contient à la fois l&rsquo;information passée et l&rsquo;information courante, pourquoi donc Oracle n&rsquo;utilise pas les redo logs pour récupérer cette information ? Pourquoi avoir besoin de l&rsquo;undo alors que le redo a déjà cette information ?<br />
</em></p>
<p>Ce fil de discussion a généré des réponses intéréssantes, mais las plupart de ces réponses expliquent <strong>comment</strong> l&rsquo;undo et le redo fonctionnent, plutôt que d&rsquo;expliquer <strong>pourquoi</strong> les architectes d&rsquo;Oracle Corp. ont choisi d&rsquo;implémenter l&rsquo;undo et le redo tel qu&rsquo;ils l&rsquo;ont fait. Comme je suis assis dans un aéroport (Zurich) à attendre un avion, je vais utiliser ce temps pour partager mon opinion sur le pourquoi.</p>
<p>Le <em><strong>redo</strong></em> est là pour deux raisons: pour la récupération des données en cas de panne (<em>recoverability</em>), et pour optimiser les performances (<em>efficiency</em>).<br />
Si l&rsquo;on journalise chaque modification que l&rsquo;on fait sur la base de données, alors on peut toujours restaurer une ancienne copie de la base et réappliquer le journal des modifications pour amener la base de données à l&rsquo;état courant. C&rsquo;est la récupération en cas de panne.<br />
Maintenant, si nous faisons en sorte que ces journaux soient le premier point de protection des modifications de nos données, alors on n&rsquo;a plus besoin d&rsquo;écrire sur disque chaque bloc de données au moment où on le modifie, mais seulement un faible volume d&rsquo;information. C&rsquo;est là qu&rsquo;est l&rsquo;optimisation. (Cependant, le fait de regrouper toutes les modifications dans un petit volume rends les I/O plus performants, mais on introduit aussi un point de contention vu que l&rsquo;on concentre une grande activité sur un petit volume).</p>
<p>L&rsquo;<em><strong>undo</strong></em> (d&rsquo;une manière ou d&rsquo;une autre) doit exister si l&rsquo;on veut faire des lectures consistentes (<em>read consistency</em>). Personne n&rsquo;est autorisé à voir les modifications de nos données tant que nous ne les avons pas comittées. Et mêmes commitées, nos modifications ne doivent pas être visibles des requêtes qui ont commencé avant notre commit. Il faut donc garder l&rsquo;ancienne version des données quelque part. C&rsquo;est où les choses deviennent moins intuitives, mais par contre très ingénieuses avec Oracle.<br />
<span id="more-24"></span><br />
Observez l&rsquo;enregistrement de redo (<em>redo record</em>) suivant. C&rsquo;est un enregistrement de <em>redo </em>généré au milieu d&rsquo;une transaction, et il représente le redo généré par Oracle lorsqu&rsquo;on a modifié la quatrième colonne d&rsquo;une ligne dans une table, de la valeur de 42 à la valeur 43.</p>
<blockquote><pre>
REDO RECORD - Thread:1 RBA: 0x000056.00000028.0014 LEN: 0x0128 VLD: 0x01
SCN: 0x0000.0028efae SUBSCN: 3 02/09/2010 14:59:40
CHANGE #1 TYP:0 CLS:20 AFN:2 DBA:0x0080065f OBJ:4294967295 SCN:0x0000.0028efae SEQ: 24 OP:5.1
ktudb redo: siz: 112 spc: 5414 flg: 0x0022 seq: 0x0112 rec: 0x19
  xid: 0x0002.028.000009af
ktubu redo: slt: 40 rci: 24 opc: 11.1 objn: 49428 objd: 49428 tsn: 5
Undo type:  Regular undo       Undo type:  Last buffer split:  No
Tablespace Undo: No
             0x00000000
KDO undo record:
KTB Redo
op: 0x02  ver: 0x01
op: C uba: 0x0080065f.0112.18
Array Update of 1 rows:
tabn: 0 slot: 41(0x29) flag: 0x2c lock: 0 ckix: 11     <strong>&lt;----- ligne 42 du bloc</strong> <ins>(slot indexé à partir de 0)</ins>
ncol: 4 nnew: 1 size: 0
KDO Op code:  21 row dependencies Disabled
  xtype: XAxtype KDO_KDOM2 flags: 0x00000080 bdba: 0x0180000a hdba: 0x01800009
itli: 2 ispac: 0 maxfr: 4863
vect = 9
col 3: [ 2] c1 2b     <strong>&lt;----- la 4ème colonne revient à la valeur 42</strong> <ins>(hexa:2b) (col indexée à partir de 0)</ins> 

CHANGE #2 TYP:0 CLS: 1 AFN:6 DBA:0x0180000a OBJ:49428 SCN:0x0000.0028efae SEQ: 41 OP:11.19
KTB Redo
op: 0x02  ver: 0x01
op: C  uba: 0x0080065f.0112.19
Array Update of 1 rows:
tabn: 0 slot: 41(0x29) flag: 0x2c lock: 2 ckix: 11     <strong>&lt;----- ligne 42 du bloc</strong>
ncol: 4 nnew: 1 size: 0
KDO Op code:  21 row dependencies Disabled
  xtype: XAxtype KDO_KDOM2 flags: 0x00000080  bdba: 0x0180000a  hdba: 0x01800009
itli: 2  ispac: 0  maxfr: 4863
vect = 9
col 3: [ 2] c1 2c     <strong>&lt;----- la 4ème colonne prends à la valeur 43</strong> <ins>(hexa:2c)</ins>
</pre>
</blockquote>
<p>Vous pouvez constater que cet enregistrement de redo comprend deux modifications (les <em>change vectors</em> CHANGE #1 and CHANGE #2) et j&rsquo;ai annoté les deux lignes qui montrent que la valeur a été modifiée de 42 à 43. En principe, les <em>redo logs</em> d&rsquo;Oracle contiennent effectivement l&rsquo;information nécessaire à la génération de l&rsquo;ancienne version des données. Alors, pourquoi Oracle a introduit les tablespaces d&rsquo;<em>undo</em> pour la lecture consistente alors que les <em>redo logs</em> semblent avoir toute l&rsquo;information nécessaire ?</p>
<p>Pour répondre à cette question, nous devons raisonner &lsquo;<em>multi-user</em>&lsquo;. C&rsquo;est très facile d&rsquo;oublier qu&rsquo;Oracle est un système multi-utilisateur, lorsqu&rsquo;on essaie de comprendre certaines fonctionnalités. Mais si on ignore ce fait, on oublie de réfléchir à ce qui se passe du point de vue des autres sessions, et on oublie aussi de réfléchir sur leur impact.</p>
<p>1er point: Je suis en train d&rsquo;exécuter une très longue transaction, et de nombreuses autres sessions exécutent des petites requêtes et des transactions très courtes. Les autres sessions doivent voir les données telles qu&rsquo;elles étaient avant que je ne les aie modifiées. Si elles devaient lire le <em>redo</em> pour accéder à ces données, les fichiers <em>redo logs</em> devraient alors pouvoir atteindre la taille nécessaire pour contenir toute l&rsquo;information de journalisation des modifications (nouvelles et anciennes valeurs) de <strong>toutes les sessions</strong> pour <strong>toutes les transactions</strong> qui se sont exécutées depuis que j&rsquo;ai démarré ma transaction. Qe doit-on faire lorsque les fichier <em>redo log</em> sont pleins ?</p>
<p>2ème point: Si ma longue transaction se plante et doit faire un rollback, alors les informations des anciennes valeurs seront mélangées avec tous les changements (anciennes et nouvelles valeurs) que tout le monde a faits depuis que j&rsquo;ai démarré ma transaction, et ma session va alors probablement devoir faire un grand nombre d&rsquo;I/O aléatoires pour trouver les modifications antérieures. Bien sûr, on peut rendre cette tâche plus efficace (et aussi améliorer le point 1) en faisant en sorte que chaque transaction écrive son propre journal dans son propre fichier de redo. Mais cela rendrait plus complexe la gestion de fichiers (ouvrir et fermer des fichiers à chaque début et fin de transaction), ainsi que la récupération en cas de panne car il faut appliquer les <em>redo</em> dans le bon ordre.</p>
<p>3ème point: Oracle ne nettoie pas chaque bloc modifié lorsq&rsquo;une transaction commite. Si je commite une transaction mais je ne nettoie pas le bloc X, comment la prochaine session qui va voir ce block saura que ma transaction a commité et  quand est ce qu’elle a commité ? Si nous n’avions utilisé que les <em>redo logs</em> la prochaine session aurait du aller voir l&rsquo;endroit du <em>redo log</em> où on a journalisé la modification du bloc X, et avancer jusqu&rsquo;à ce qu&rsquo;elle trouve la journalisation du commit (ou aller jusqu&rsquo;à la fin du redo, ou trouver le SCN correspondant dans le redo et ainsi, en déduire que ma transaction n’a pas commitée ou n’a pas commité à temps). Mais alors, chaque enregistrement redo aurait du avoir un pointeur sur l’enregistrement redo qui le suit, ce qui veut dire qu&rsquo;à chaque fois que nous aurions créé un enregistrement redo, nous aurions du aller voir le précédent enregistrement redo pour le modifier, ce qui ne serait pas très efficace. Le plan B serait d&rsquo;avoir un mécanisme pour maintenir une longue liste infinie de toutes les transactions et de leur <em>commit SCN</em> quelque part dans la base de donnée &#8211; et c&rsquo;est cet &lsquo;infini&rsquo; qui n&rsquo;est pas une idée séduisante.</p>
<p>Et cela peut se poursuivre ainsi. Vous pouvez trouver des opérations pour lesquelles il est parfaitement acceptable d&rsquo;utiliser le redo comme source pour l&rsquo;undo, mais si vous prenez en compte toutes les options d&rsquo;un système multi-utilisateur avec une activité diverse, alors vous trouverez que certaines opérations auraient ou causeraient quelques problèmes.</p>
<p>La solution d&rsquo;Oracle est de garder la partie &lsquo;utilisable&rsquo; de l&rsquo;information de retour arrière, l&rsquo;<strong><em>undo</em></strong>, à un emplacement complètement différent de celui du <strong><em>redo</em></strong>. Plutôt que de créer une troisième structure de stockage de données, ils ont choisi de les mettre dans la base, en utilisant des blocs de données ordinaires. Vous pouvez réfléchir à la manière dont cela résout les points que j&rsquo;ai soulevés ci-dessus.</p>
<p>Parce que les blocs d&rsquo;<em>undo</em> sont des blocs de base de données ordinaires, ils sont protégés par les <em>redo logs</em>, et peuvent être récupérés en cas de panne, comme peut l’être le reste de la base de données, sans avoir à rajouter un code différent pour le <em>recovery</em>. Le <em>change vector</em> de retour arrière que nous avons vu précédemment est en réalité le <em>change vector</em> &lsquo;vers l&rsquo;avant&rsquo; pour rejouer la modification du bloc d&rsquo;undo. Cela ajoute un overhead sur les redo log, car on écrit les undo deux fois, mais c&rsquo;est ce que nous faisons de toute façon avec n&rsquo;importe quelle modification (écriture dans le bloc et écriture dans le redo log). Les blocs d&rsquo;undo bénéficient en plus du mécanisme standard de cache LRU: si un bloc d&rsquo;undo est souvent utilisé, il reste en mémoire, et c&rsquo;est parfait puisque l&rsquo;undo généré récemment a plus de chance d&rsquo;être celui dont on aura besoin pour la lecture consistante.</p>
<p>Comme nous gardons les flux d&rsquo;undo dans la base de donnée, nous n&rsquo;avons pas à nous préoccuper des sessions qui, constamment, ouvrent ou ferment des fichiers lorsqu&rsquo;elles démarrent ou terminent des transactions. Nous avons juste à maintenir un catalogue qui liste les transactions actives et qui pointe sur l&rsquo;adresse du tablespace d&rsquo;undo où la transaction est en train de mettre ses enregistrements d&rsquo;undo (c&rsquo;est le rôle de la <strong>table des transactions</strong> de l&rsquo;<strong>entête des segments d&rsquo;undo</strong> &#8211; voir <a href="http://blog.developpez.com/pachot/p8689/concepts/undo/jl-glossary-undo/">glossaire</a>)</p>
<p>Parce que nous utilisons le bloc comme unité de stockage, et que l&rsquo;<em>undo</em> de chaque transaction est à part, lorsque j&rsquo;écris mes enregistrements d&rsquo;undo ils sont regroupés ensembles (j&rsquo;acquiers et je remplis un seul bloc à la fois). Donc, si je dois faire un rollback de ma transaction, la lecture d&rsquo;un seul bloc ramènera beaucoup d’enregistrements d&rsquo;undo, et cela minimisera les I/O aléatoires que je dois faire pour lire l&rsquo;enchaînement d&rsquo;undo.</p>
<p>Si je lance une très longue transaction alors que d&rsquo;autres sessions sont aussi en train de générer du <em>redo</em>, il y a une certaine indépendance entre mon undo et celui de ces autres sessions. Dans un compromis entre &lsquo;tous les undo dans un même fichier&rsquo; et &lsquo;chaque transaction a son propre fichier&rsquo;, Oracle a permis d&rsquo;avoir des segments d&rsquo;undo multiples, c&rsquo;est à dire l&rsquo;équivalent d&rsquo;un relativement petit nombre de fichiers partagés. Ce qui veut dire que la longue transaction est cantonnée à un seul segment d&rsquo;undo et que toutes les autres sessions peuvent réutiliser (en réécrivant) tout espace disponible dans le reste de la tablespace d&rsquo;undo, de manière plus efficace. (Bien sûr on peut toujours se retrouver avec une erreur du type &lsquo;fichier plein&rsquo;, mais cette stratégie permet à la base de données de survivre plus longtemps lors d&rsquo;activités concurrentes, sur le même volume d&rsquo;espace disque).</p>
<p>Ce serait impossible d&rsquo;expliquer tous les détails subtils des problèmes qui sont évités, ou minimisés, en stockant l&rsquo;<em>undo</em> dans la base de données, et en l&rsquo;utilisant comme Oracle le fait, mais l&rsquo;idée est la suivante: si vous voulez savoir pourquoi Oracle utilise une tablespace d&rsquo;undo plutôt que les <em>redo logs</em> pour ses lectures consistantes, pour ses rollbacks et pour calculer à quel moment le commit a eu lieu, alors il suffit uniquement de penser à tous les scénarios que vous auriez du prendre en compte et que vous auriez du résoudre seulement à l&rsquo;aide des <em>redo logs</em>. Cela vous donnerait une idée de la surcharge et de la complexité que vous auriez du introduire, et vous aurait permis de voir à quel point les tablespaces d&rsquo;undo rendent les choses (relativement) plus simple et plus efficaces.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Undo et Redo et Recovery en quelques mots, par Jonathan Lewis</title>
		<link>https://blog.developpez.com/pachot/jl_nutshell1/</link>
		<comments>https://blog.developpez.com/pachot/jl_nutshell1/#comments</comments>
		<pubDate>Fri, 09 Apr 2010 18:08:04 +0000</pubDate>
		<dc:creator><![CDATA[pachot]]></dc:creator>
				<category><![CDATA[Jonathan Lewis]]></category>
		<category><![CDATA[redo]]></category>
		<category><![CDATA[undo]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Cet article est la traduction d&#8217;un article de Jonathan Lewis publié sur son blog. L&#8217;article original en anglais se trouve ici. Lorsque vous modifiez un bloc de donnée, en modifiant une ligne d&#8217;une table par exemple, ou en marquant une &#8230; <a href="https://blog.developpez.com/pachot/jl_nutshell1/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<blockquote><p><ins>Cet article est la traduction d&rsquo;un article de Jonathan Lewis publié sur son blog. L&rsquo;article original en anglais se trouve <a href="http://jonathanlewis.wordpress.com/2009/10/14/nutshell-1/">ici</a>.<br />
</ins></p></blockquote>
<p>Lorsque vous modifiez un bloc de donnée, en modifiant une ligne d&rsquo;une table par exemple, ou en marquant une entrée d&rsquo;index comme supprimée, voici ce que fait Oracle:</p>
<ol>
<li>génération d&rsquo;information <b><i>redo</i></b> sous forme d&rsquo;un vecteur de modification (<i>change vector</i> pour décrire les modifications qui doivent être faites sur le bloc</li>
<li>génération d&rsquo;information <b><i>undo</i></b> pour décrire l&rsquo;ancienne version des données qui vont changer.<br />
Cet undo est en réalité une information <b><i>redo</i></b> (un autre <i>change vector</i>) qui décrit comment créer cette information <b><i>undo</i></b></li>
<li>écriture de ces informations dans le buffer de journalisation (<i>redo log buffer</i>)<br />
Ces 2 <i>change vectors</i> sont regroupés (celui de l&rsquo;<i>undo</i> est toujours en premier) en un seul enregistrement <b><i>redo record</i></b></li>
<li>la modification sur le <strong>bloc d&rsquo;undo</strong> est effectuée</li>
<li>la modification sur le <strong>bloc de données</strong> (table ou index) est effectuée</li>
</ol>
<p>Le <b><i>redo</i></b> doit être écrit sur disque avant que le bloc de donnée et le bloc d&rsquo;undo ne le soient. <ins>[voir note ci-dessous]</ins><br />
Le bloc d&rsquo;undo et le bloc de donnée seront écrits sur disque plus tard, et ce même si la transaction n&rsquo;est pas encore commitée.</p>
<p><strong>Question</strong>: Si l&rsquo;instance se plante avant que la transaction ne soit commitée, comment Oracle va pouvoir récupérer l&rsquo;ancienne version des données, puisque elle a été écrasée par la nouvelle version non commitée ?<br />
<span id="more-22"></span><br />
<strong>Réponse</strong>: Après le plantage, le processus de récupération (<i>instance recovery</i>) connait l&rsquo;heure du dernier checkpoint de chaque fichier de données (<i>datafile</i>) et va appliquer le <b><i>redo</i></b> sur les fichiers de la tablespace d&rsquo;<b><i>undo</i></b>, de la même manière qu&rsquo;il le fait sur les autres fichiers des tablespaces &lsquo;permanentes&rsquo;.</p>
<p>A partir de là, la base est à jour, et le processus de recovery voit alors voir les dernières versions aussi bien pour les blocs de données que pour les blocs d&rsquo;<b><i>undo</i></b>.</p>
<p>La tablespace d&rsquo;undo contient la table des transactions (<i>transaction table</i>) dans le bloc d&rsquo;entête du segment d&rsquo;undo (<i>undo segment header</i>) et, comme elle est maintenant à jour, le processus de recovery peur détecter que la transaction n&rsquo;a pas été commitée. Il peut alors faire un <b>rollback</b>, en utilisant les informations contenues dans les blocs d&rsquo;<b><i>undo</i></b> afin de récupérer les anciennes données de la table.</p>
<p><strong>Notes</strong>:</p>
<p>Cette description d&rsquo;une modification de donnée est un schéma général général. Il y a des cas particuliers qui rendent ce mécanisme un peu plus complexe. Entre autres, il y a un traitement particulier quand le changement est fait juste au début de la transaction: en 10g les quelques premières modifications que fait une transaction vont utiliser un mécanisme spécial &#8211; à condition qu&rsquo;il n&rsquo;y ait qu&rsquo;une seule instance (donc pas en RAC). Ce mécanisme est optimisé en utilisant la gestion de l&rsquo;undo en mémoire (private redo threads et in-memory undo)</p>
<p>Voire aussi le <a href="http://blog.developpez.com/pachot/p8681/concepts/jl-glossary-undo/">glossaire undo</a> à propos du <i>undo segment header</i> et de la <i>transaction table</i></p>
<p><ins><br />
Oracle s&rsquo;assure toujours que lorsque les modifications faites en mémoire (dans le <i>buffer cache</i>) sont écrites sur disque (dans les <i>datafiles</i>), alors le <i>redo</i> associé qui a été écrit en mémoire (dans le <i>log buffer</i>) a auparavant été flushé sur disque, dans les fichiers <i>redo log</i>.<br />
Si besoin DBWR (database writer) va attendre que LGWR (log writer) ait terminé cette écriture.<br />
C&rsquo;est ce mécanisme (écriture du log en premier &#8211; connu comme le protocole <i>Write Ahead Log</i>) qui assure que les journaux (<i>redo logs</i>) ont toujours l&rsquo;information nécessaire pour défaire (undo) les modifications écrites sur disque.<br />
</ins></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Définitions Undo, Rollback Segment et Table de transactions , par Jonathan Lewis</title>
		<link>https://blog.developpez.com/pachot/jl_glossary_undo/</link>
		<comments>https://blog.developpez.com/pachot/jl_glossary_undo/#comments</comments>
		<pubDate>Fri, 09 Apr 2010 18:07:55 +0000</pubDate>
		<dc:creator><![CDATA[pachot]]></dc:creator>
				<category><![CDATA[Jonathan Lewis]]></category>
		<category><![CDATA[Traductions]]></category>
		<category><![CDATA[undo]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Cet article une traduction du glossaire de Jonathan Lewis publié sur son blog. L&#8217;article original en anglais se trouve ici. Bloc d&#8217;entête de segment (&#8216;Segment Header Block&#8217; ou simplement &#8216;Segment Header&#8217;) L&#8217;entête des segments undo (&#8216;Undo Segment Header&#8217;) Table des &#8230; <a href="https://blog.developpez.com/pachot/jl_glossary_undo/">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<blockquote><p><ins>Cet article une traduction du glossaire de Jonathan Lewis publié sur son blog. L&rsquo;article original en anglais se trouve <a href="http://jonathanlewis.wordpress.com/2009/06/23/glossary/">ici</a>.<br />
</ins></p></blockquote>
<ul>
<li>Bloc d&rsquo;entête de segment (&lsquo;Segment Header Block&rsquo; ou simplement &lsquo;Segment Header&rsquo;)</li>
<li>L&rsquo;entête des segments undo (&lsquo;Undo Segment Header&rsquo;)</li>
<li>Table des transactions (&lsquo;Transaction Table&rsquo;)</li>
<li>Undo</li>
<li>Rollback</li>
</ul>
<p><span id="more-23"></span><br />
<strong>Bloc d&rsquo;entête de segment (<em>Segment Header Block</em> ou simplement <em>Segment Header</em>):</strong></p>
<p>Historiquement, c&rsquo;est le premier bloc du premier <em>extent</em> d&rsquo;un segment, celui qui maintient les information critiques sur la taille du segment, le nombre et l&rsquo;emplacement des <em>extents</em>, et des informations de contrôle à propos de l&rsquo;espace libre du segment.<br />
Dans les versions récentes d&rsquo;Oracle, il peut y avoir quelques blocs juste avant ce bloc d&rsquo;entête, utilisés pour la gestion de l&rsquo;espace libre. Cette variante vient de l&rsquo;implémentation des tablespaces <strong>ASSM</strong> (<em>Automatic Segment Space Management</em> &#8211; gestion automatique de l&rsquo;espace libre des segments)</p>
<p>La vue DBA_EXTENTS vous donne le fichier et le numéro de block (file_id et block_id) du premier extent, et la vue DBA_SEGMENTS vous donne la position du block d&rsquo;entête <em>segment header</em> dans cet extent.</p>
<p>Les segments d&rsquo;<strong><em>undo</em></strong> ont une particularité: le bloc d&rsquo;entête de segment contient des informations supplémentaires (la table des transactions &#8211; <strong><em>transaction table</em></strong>) qui sont spécifiques au mécanisme d&rsquo;<em>undo</em> d&rsquo;Oracle.</p>
<p><strong>L&rsquo;entête des segments undo (<em>Undo Segment Header</em>)</strong>:</p>
<p>C&rsquo;est un cas particulier du bloc <em>segment header</em>. La différence principale, c&rsquo;est qu&rsquo;il contient la table des transactions (<em>transaction table</em>). C&rsquo;est une liste, de taille fixe, des transactions les plus récentes, portant l&rsquo;information concernant leur statut, leurs SCN, et des pointeurs vers les enregistrements d&rsquo;undo (<em>undo records</em>) associés à la transaction.<br />
Le <strong>undo segment header</strong>, dans le cas de la gestion automatique des undo, contient aussi une <em>Retention Map</em> qui note le commit SCN de chaque extent, et permet à Oracle de savoir quand un extent a dépassé la période de rétention <strong>undo_retention</strong>.</p>
<p><strong>Table des transactions (<em>Transaction Table</em>)</strong>: </p>
<p>Chaque bloc d&rsquo;<em>undo segment header</em> a une place pour la table des transactions. Lorsque une transaction débute, elle choisit le segment d&rsquo;undo qu&rsquo;elle va utiliser, puis prends la plus ancienne entrée (<strong><em>transaction header &lsquo;slot&rsquo;</em></strong>) dans cette table des transactions. </p>
<p>Cette entrée (ce &lsquo;<em>slot</em>&lsquo;) sera l&rsquo;identifiant de la transaction, et cette information sera visible de deux manières:</p>
<ol>
<li>Comme identifiant de transaction dans V$TRANSACTION</li>
<li>Comme verrou de type TX (transaction) et mode 6 (exclusif) dans V$LOCK, posé par la session qui execute la transaction</li>
</ol>
<p>Dans les deux cas, la transaction est identifiée par les triplet:</p>
<ul>
<li><strong>undo segment number</strong>: le numéro du segment d&rsquo;undo qui contient la table des transactions. C&rsquo;est la colonne XIDUSN de V$TRANSACTION</li>
<li><strong>slot number</strong>:le numéro d&rsquo;entrée dans cette table. C&rsquo;est la colonne XIDSLOT de V$TRANSACTION</li>
<li><strong>sequence number</strong>: le nombre d&rsquo;entrées dans la table étant limitée, chaque fois qu&rsquo;une entrée est réutilisée, ce numéro de sequence est incrémenté. C&rsquo;est la colonne XIDSQN de V$TRANSACTION</li>
</ul>
<p>Au début de la transaction, le &lsquo;start SCN&rsquo; est écrit dans cette table. Lorsque la transaction est commitée, il est remplacé par le &lsquo;commit SCN&rsquo; <ins>[voir la définition du SCN <a href="http://blog.developpez.com/pachot/p8681/concepts/scn/jl-glossary-scn/">ici</a>]</ins></p>
<p>Donc une entrée de la table des transaction, c&rsquo;est à dire un &lsquo;<strong><em>transaction table slot</em></strong>&lsquo; représente une seule transaction. Dans V$TRANSACTION, l&rsquo;identifiant est sur trois colonnes XIDUSN, XIDSLOT et XIDSQN. Sur les versions les plus récentes d&rsquo;Oracle, l&rsquo;identifiant est aussi repris en une seule colonne XID de type RAW(8).<br />
<ins>Dans V$LOCK un verrou a deux colonnes pour son identification (ID1 et ID2). Les verrous de type TX ont les informations USN (décalé de 2 octets à gauche) et SLOT dans ID1 et SQN dans ID2</ins></p>
<p><em><strong>Undo</strong></em>: (aussi appelé information de <em>rollback</em>): </p>
<p>C&rsquo;est l&rsquo;information qui décrit comment revenir en arrière sur les modifications d&rsquo;un block (<em>&lsquo;db block change&rsquo;</em>). L&rsquo;<strong><em>undo</em></strong> est stocké dans les segments d&rsquo;<em>undo</em>, qui sont créés dans les tablespaces d&rsquo;<em>undo</em>, et chacun de ces segments possède son &lsquo;catalogue&rsquo; (la table des transactions) qui pointe versà l&rsquo;endroit où la transaction a écrit son premier enregistrement d&rsquo;<em>undo</em>.</p>
<p>Dans les versions plus anciennes, le DBA devait décider combien de segments undo (appelés <strong><em>rollback segments</em></strong> à l&rsquo;époque) il devait créer et où les mettre. Dans les versions récentes, le DBA doit seulement créer une tablespace d&rsquo;undo par instance (une seule tablespace undo étant active) et laisser Oracle décider dynamiquement de combien de segments d&rsquo;undo il a besoin. A l&rsquo;exception de quelques cas particuliers, chaque modification d&rsquo;un bloc est précédée par la création d&rsquo;un enregistrement d&rsquo;undo.</p>
<p>On entend souvent dire que c&rsquo;est l&rsquo;image complète du bloc qui est copiée dans les enregistrements d&rsquo;<em>undo</em>. C&rsquo;est faux, et cette idée vient probablement d&rsquo;un ancien comportement d&rsquo;Oracle, en version 5.0, qui utilisait une &lsquo;image avant&rsquo; pour garder une copie du bloc. En fait, une enregistrement d&rsquo;<em>undo</em> contient normalement un taille fixe de 80 octets, plus l&rsquo;information minimale qui permet de faire revenir un bloc à son état avant la modification.</p>
<p>A partir de la 10.2, le mécanisme d&rsquo;<em>undo</em> a changé, avec l&rsquo;introduction des &lsquo;<em>private redo threads</em>&lsquo; et de l&rsquo;undo en mémoire (&lsquo;<em>in-memory undo</em>&lsquo;).  On peut dire que celà n&rsquo;a modifié que le moment où ces enregistrements d&rsquo;undo sont écrits dans les blocs d&rsquo;undo. Si on regarde les blocs d&rsquo;undo après que la transaction ait été comittée, il n&rsquo;est pas possible de savoir si la transaction a utilisé les &lsquo;in-memory undo&rsquo; ou le mécanisme classique.</p>
<p><strong>Rollback</strong>: </p>
<p>Ce terme est utilisé comme synonyme d&rsquo;<em>undo</em>, mais c&rsquo;est aussi la commande qui indique à Oracle que les modifications qui ont été effectuées par la transaction active courante doivent être défaites. Lorsque vous faites un <strong>rollback</strong>, votre session va remonter toute la chaine des enregistrements d&rsquo;<em>undo</em> qu&rsquo;elle a généré, et se servir de chacun pour faire un retour arrière sur la modification précédente. Elle va aussi flagger l&rsquo;enregistrement <em>undo</em> comme &lsquo;appliqué par l&rsquo;utilisateur&rsquo;.<br />
Chaque modification effectuée durant ce retour arrière va à son tour générer du <strong><em>redo</em></strong>, ce qui veut dire que le rollback peut être aussi couteux que la modification initiale. Il faut donc éviter d&rsquo;écrire du code qui va écrire des données temporairement avec l&rsquo;intention de les rollbacker à la fin. </p>
<p>Enfin, la dernière étape du rollback est un commit, qui va appeler le log writer pour synchroniser les fichiers redo à partir du log buffer.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
