Inhaltsverzeichnis
Informix: ALTER-MODE und Flag 8388608
Kurzfassung
Bei der Untersuchung von zwei replizierten Tabellen wurde das Flag
8388608 (hexadezimal 0x800000) zunaechst als ALTER-MODE-Flag
interpretiert. Das ist falsch. Das echte CDR-ALTER-MODE-Flag ist
4194304 (hexadezimal 0x400000).
0x800000 kennzeichnet eine In-Place-Alter-Historie (IPA) im
Partition-Header. Es kann bestehen bleiben, obwohl alle Datenseiten bereits
auf der aktuellen Row-Version liegen.
SERIAL kann als 4-Byte-INTEGER repliziert werden. Die unterschiedliche
Definition ist daher kein Replikationsbruch: Der Leaf darf id als
SERIAL erzeugen, waehrend der Master INTEGER ohne eigene
Serial-Sequenz speichert.
cdr alter –off scheiterte trotzdem mit Return Code 137, weil die
Unset-Pruefung das Master-Dictionary (coltype 2) streng mit dem lokalen
Katalog (coltype 262) vergleicht. Zusaetzlich existierte ein
Shadow-Replicate. Der spaetere MODIFY (id INTEGER) glich den Katalog zwar
kuenstlich an und entblockte –off, war fachlich aber falsch, weil dadurch
die lokale Soll-Serial-Definition verloren ging.
Anonymisierte Umgebung
- Informix: 12.10.FC14WE
- Leaf:
servera, begrenzter ER-Server, SEND-ONLY - Master:
serverb(IDserver_id_b) aufserverb_host - Zieldatenbank:
datenbank_a - Master-Datenbank:
datenbank_b - Datenbank-Owner:
benutzerA - Tabellen:
tabelleAundtabelleB - Replicates:
replikatAundreplikatB
Die beiden relevanten Bits
| Dezimal | Hexadezimal | Bedeutung |
|---|---|---|
| 4194304 | 0x400000 | Echtes CDR-ALTER-MODE-Flag |
| 8388608 | 0x800000 | IPA-Historie im Partition-Header |
Das echte ALTER-MODE-Flag wird von oncheck -pt als
TBLspace flagged for CDR alter mode angezeigt. Bei gesetztem
0x800000 allein erscheint dieser Text nicht.
Diagnoseabfrage
Die urspruengliche Suchabfrage nach dem Flag 8388608 lautet:
SELECT t.dbsname,t.tabname, p.flags, BITAND(p.flags, 8388608) AS alter_mode_bit FROM sysmaster:systabnames t, sysmaster:sysptnhdr p, systables tab WHERE t.partnum = p.partnum AND BITAND(p.flags, 8388608) > 0 AND t.tabname = tab.tabname AND tab.tabid > 99 ORDER BY t.dbsname,t.tabname;
Diese Abfrage findet Partitionen mit IPA-Historie, beweist aber keinen aktiven CDR-ALTER-MODE. Fuer die Unterscheidung der beiden Bits kann beispielsweise folgende Abfrage verwendet werden:
SELECT t.dbsname, t.tabname, BITAND(p.flags, 4194304) AS cdr_alter_mode, BITAND(p.flags, 8388608) AS ipa_history FROM sysmaster:systabnames t, sysmaster:sysptnhdr p, systables tab WHERE t.partnum = p.partnum AND t.dbsname = 'datenbank_a' AND t.tabname IN ('tabelleA', 'tabelleB') AND t.tabname = tab.tabname AND tab.tabid > 99;
Zusaetzlich zeigt oncheck -pt den echten ALTER-MODE-Status:
oncheck -pt datenbank_a:benutzerA.tabelleA
Bei der betroffenen Umgebung war 0x400000 nicht gesetzt, waehrend
0x800000 gesetzt war. DML war deshalb nicht wegen des vermeintlichen
ALTER-MODE-Bits blockiert.
Zusammenhang mit In-Place-Alter
Die Spalten pta_oldvers und pta_newvers im Partition-Header
beschreiben die IPA-Versionskette. Ein gesetztes 0x800000 kann daher
zusammen mit einer solchen Versionsspanne auftreten.
Ob noch alte Datenseiten vorhanden sind, wird mit oncheck -pT geprueft,
nicht anhand des Bits:
Home Data Page Version Summary
Version Count
n (oldest) 0
...
m (current) Anzahl der Datenseiten
Wenn alle alten Versionen den Count 0 haben und nur die aktuelle Version
Datenseiten traegt, ist die IPA operativ abgeschlossen. Das Bit kann trotzdem
noch als Header-Historie vorhanden sein. update_ipa raeumt alte
Datenseiten auf; es setzt den Partition-Header nicht zwingend zurueck.
Ursache fuer Return Code 137
Im Online-Log erschien sinngemaess:
GC operation alter mode unset operation on a replicated table failed: Mismatch between local table dictionary and master dictionary CDR WARNING: Column type or size mismatch detected
Der einzige Schemaunterschied war:
| Spalte | Leaf | Master und Master-Dictionary |
|---|---|---|
id | SERIAL NOT NULL (coltype 262) | INTEGER, nullable (coltype 2) |
SERIAL und INTEGER sind hinsichtlich der Speicherbreite kompatibel
und koennen ordnungsgemaess repliziert werden. Fuer das CDR-Dictionary sind
es trotzdem unterschiedliche Typen. Die Spalte id war Teil des
Replikationsschluessels (pknum 1, zusammen mit nlcode als pknum 2).
Deshalb scheiterte die strenge Unset-Pruefung von cdr alter –off mit
Return Code 137. Das ist kein Beleg dafuer, dass die Replikation von SERIAL
nach INTEGER unzulaessig waere.
Ein aktiver Shadow-Replicate vom Master kann diesen Zustand zusaetzlich festhalten. Auf einem Limited Server ist das Loeschen von Replicates nicht erlaubt (Return Code 75); solche Verwaltungsaktionen muessen auf dem Master ausgefuehrt werden.
Durchgefuehrte Bereinigung
- Shadow-Replicate auf
serverbgeloescht. - Fuer beide Tabellen ALTER-MODE kontrolliert gesetzt und ausgeschaltet.
Die anschliessende Aenderung von id auf INTEGER war ein Fehler und
haette entfallen muessen:
cdr alter --on datenbank_a:benutzerA.tabelleA ALTER TABLE tabelleA MODIFY (id INTEGER); -- FALSCH: nicht nachmachen cdr alter --off datenbank_a:benutzerA.tabelleA cdr alter --on datenbank_a:benutzerA.tabelleB cdr alter --off datenbank_a:benutzerA.tabelleB
Der dokumentierte MODIFY-Schritt wurde tatsaechlich ausgefuehrt und
entblockte –off, war aber fachlich nicht korrekt. id haette lokal
als SERIAL NOT NULL bleiben muessen. Der Soll-Zustand ist daher in einem
separaten, kontrollierten Auftrag wiederherzustellen.
- Offene IPA-Datenseiten mit
update_ipabereinigt:
DATABASE sysadmin; EXECUTE FUNCTION task('table update_ipa', 'tabelleA', 'datenbank_a'); EXECUTE FUNCTION task('table update_ipa', 'tabelleB', 'datenbank_a');
- Anschliessend beide Partitionen mit einem Slow-Alter neu geschrieben:
cdr alter --on datenbank_a:benutzerA.tabelleA ALTER FRAGMENT ON TABLE tabelleA INIT IN datenbankbereichA; cdr alter --off datenbank_a:benutzerA.tabelleA
Der letzte Schritt wurde analog fuer tabelleB ausgefuehrt. Dabei wurden
keine Daten per Unload/Load bewegt, kein Katalog manuell geaendert und kein
Remaster vom Leaf durchgefuehrt.
Ergebnis
| Tabelle | Flags | 0x800000 | 0x400000 | pta_old/new | id-coltype |
|---|---|---|---|---|---|
tabelleA | 0x0000090A | 0 | 0 | 0 / 0 | 2 |
tabelleB | 0x0000080A | 0 | 0 | 0 / 0 | 2 |
oncheck -pt zeigt jetzt nur noch die Replikationskennzeichnung, nicht
mehr CDR alter mode. Die Zeilenanzahl blieb unveraendert. Die Primaer-
und Unique-Indizes wurden nicht veraendert.
Wegen des falschen MODIFY erzeugt ein INSERT ohne angegebene id auf
dem Leaf aktuell keine lokale Seriennummer mehr. Das ist ein Fehlerzustand:
Der Soll-Zustand dieses SEND-ONLY-Knotens ist weiterhin SERIAL NOT NULL
auf dem Leaf und INTEGER im Master. Andere unabhaengige Serial-Spalten
bleiben davon unberuehrt.
Betriebsregeln
- CDR-ALTER-MODE mit
oncheck -pt, dem Bit
BITAND(flags, 4194304) > 0, dem Online-Log und Fehler 19992
diagnostizieren. * Nicht ''BITAND(flags, 8388608)'' als ALTER-MODE-Nachweis verwenden. * IPA mit ''oncheck -pT'' anhand der Version Counts beurteilen. * Bei Return Code 137 die Unset-Pruefung und den Shadow-Zustand untersuchen. ''SERIAL'' lokal gegen ''INTEGER'' im Master ist als Replikationskonvertierung zulaessig, auch wenn das Dictionary coltype 262 gegen 2 meldet. * Bei Replikationsschluesseln muessen Namen, Reihenfolge und die Replikationskompatibilitaet stimmen. SERIAL lokal und INTEGER im Master kann dabei eine beabsichtigte Konvertierung sein. * Shadow-Replicates auf dem fuehrenden Master verwalten, nicht auf einem Limited Leaf. * Den Datenbank- und Owner-Qualifier bei ''cdr alter'' immer angeben. * ''sysmaster''-Pseudo-Tabellen nicht per UPDATE veraendern. * Replizierte Tabellen nur nach kontrolliertem ''cdr alter --on'', Shadow-/Participant-Bereinigung und anschliessendem ''--off'' aendern. Die lokale SERIAL-Definition dabei nicht auf INTEGER aendern, nur um die Unset-Pruefung zu umgehen.
Betroffene Objekte und Umgebung
- Informix: 12.10.FC14WE,
INFORMIXSERVER=tcp_servera - Leaf:
servera; Master:serverb - Datenbank:
datenbank_a - Tabellen:
tabelleAundtabelleB - Replicates:
replikatA(TeilnehmertabelleA) und
replikatB (Teilnehmer tabelleB)
Befund
ipa_history ist kein Spaltenflag. Informix In-Place-Alter (IPA) laesst
Datenseiten nach einem ALTER TABLE zunaechst in der alten Row-Version.
Erst ein spaeteres INSERT oder UPDATE schreibt die jeweilige Zeile in das
neue Layout. Sichtbar ist dies in oncheck -pT unter Home Data Page
Version Summary sowie in sysmaster:sysptnhdr mit pta_oldvers und
pta_newvers.
Bei tabelleA wurden 1504 Seiten in Version 0 (oldest) und 656 Seiten in
Version 1 (current) gefunden; nupdates war 3596. Bei tabelleB waren
2034 Seiten in Version 0 und nur 1 Seite in Version 1; nupdates war 11.
In beiden Faellen gab es nur eine neue Version (0 → 1). Der groesste Teil
der Zeilen war daher noch nicht auf das neue Layout umgeschrieben. Das ist
kein Datenfehler.
Ursache und zeitlicher Ablauf
Ursache waren manuelle ALTER TABLE … MODIFY-Laeufe als User
informix, nicht ein automatischer Job und nicht das Flag selbst.
- Am 04.09.2026 erledigte
task('table update_ipa')eine aeltere IPA.
Danach wurden die Partitionen neu aufgebaut; die neuen Partitionen
hatten anschliessend keine offene IPA. * Am 07.09.2026 wurden unter anderem ''nbwvorwahl CHAR(7)'' und ''tabelleB.handynr CHAR(16)'' gesetzt. Diese Definitionen waren bereits in frueheren Dictionary-Dumps vorhanden und waren nicht der Ausloeser der zweiten Seitenversion. * Die IPA-treibende Aenderung war der Wechsel von ''id INTEGER'' zu ''id SERIAL NOT NULL'': bei ''tabelleA'' am 07.09.2026 und bei ''tabelleB'' am 08.09.2026. Dazu kamen Syntaxversuche am Serial-Typ, ein UPDATE auf ''id IS NULL'' sowie ''cdr alter --off''. * Am 08.09.2026 wurden Sitzungen von einem Arbeitsplatz beendet, die betroffene Sitzungen hielten.
Die lokalen und Master-Dictionary-Staende waren dabei nicht gleich: Im
Master war id als INTEGER definiert, lokal als SERIAL. Der
Nahtabzug zeigte fuer tabelleA bereits SERIAL NOT NULL und fuer
tabelleB noch INTEGER; im aktuellen Schema sind beide lokal
SERIAL NOT NULL. Dadurch bleibt das ER-Dictionary fachlich zu klaeren,
auch wenn die Speicherbreite von SERIAL und INTEGER kompatibel ist.
Warum die Historie stehen blieb
task('table update_ipa') vom 04.09.2026 bezog sich nur auf die damaligen
Partitionen. Nach den neuen Alters am 07. und 08.09. wurde die Bereinigung
nicht erneut ausgefuehrt. IPA schreibt die alten Seiten nicht sofort um,
sondern erst bei spaeterem DML.
Empfohlene Behebung
- Eine offene IPA nur aufloesen, wenn dies fuer Reorg, Versionswechsel,
Revert oder Monitoring erforderlich ist. Normale DML konvertiert Zeilen
nach und nach. - Wenn alle Seiten bewusst auf die aktuelle Version gebracht werden sollen, dies in einem Wartungsfenster und nach Abstimmung mit ER ausfuehren:
DATABASE sysadmin; EXECUTE FUNCTION task('table update_ipa', 'tabelleA', 'datenbank_a'); EXECUTE FUNCTION task('table update_ipa', 'tabelleB', 'datenbank_a');
Optional kann die Task-Variante mit ''parallel'' verwendet werden. Nicht unter Last und nicht parallel zu Anwendungsschreibern auf denselben Tabellen ausfuehren; bei replizierten Tabellen ist der ER-Alter-Mode zu beruecksichtigen. Nach dem Checkpoint erneut ''oncheck -pT'' ausfuehren. Bei abgeschlossener IPA traegt nur noch die aktuelle Version Seiten; die alten Versionen haben Count 0. - Nicht nochmals ''ALTER TABLE ... MODIFY'' auf ''id'', ''nbwvorwahl'' oder ''handynr'' zur Sicherheit ausfuehren. Auch gleiche oder kompatible MODIFYs koennen erneut Alter-Mode und IPA-Versionen erzeugen. - Die ER-Masterdefinition und den lokalen Soll-Typ abstimmen. Wenn ''id'' absichtlich ''SERIAL'' sein soll, muss die Replicate-Definition kontrolliert nachgezogen werden; ein weiteres lokales Alterieren loest den Dictionary-Mismatch nicht. - Kein zweites ''update_ipa'' auf Verdacht starten: Die Task schreibt alle Restzeilen um und erzeugt I/O, Log- sowie ER-Apply-Last. Vorher muss ''oncheck -pT'' den Bedarf bestaetigen. - Nacharbeiten dokumentieren: verantwortlicher Aenderer, Soll-Typ im Master und die Frage, ob weitere Leaf-Knoten denselben Stand benoetigen.
- IBM/HCL: Troubleshooting Tips for Alter Operations
- IBM/HCL: Resolve outstanding in-place alter operations
- IBM/HCL: CDR Return Codes 137 (Dictionary-Mismatch) und 75 (Limited Server)
Stichworte
Informix, Enterprise Replication, CDR, ALTER-MODE, In-Place-Alter, IPA, sysptnhdr, oncheck, cdr alter, Dictionary-Mismatch, Shadow-Replicate, Limited Server
