"Lost Writes" sind ein selten auftretendes Phänomen, für die es ab der Oracle Datenbankversion 18c einen Schutz gibt, der verhindert, dass durch "Lost Writes" Dateninkonsistenzen entstehen. Was sind "Lost Writes" und wie sieht der Schutz aus? Lesen Sie dazu diesen Tipp.
Eigentlich soll es ja nie passieren: Eine Software schreibt etwas auf die Festplatte und die meldet auch einen erfolgreichen Schreibvorgang obwohl die dauerhafte Speicherung auf der Festplatte noch nicht abgeschlossen ist. Und dann passiert es: ein Ereignis sorgt dafür, dass der endgültige Schreibvorgang auf die Festplatte verhindert wird. Die Software hatte ja eine Erfolgsmeldung bekommen und geht von der erfolgreichen Speicherung nun leider irrtümlich aus - man spricht nun von einem "Lost Write". Wenn der betroffene Speicherblock später aufgerufen wird, hat er einen älteren Stand, als die Software annimmt.
Das oben beschriebene Szenario sollte eigentlich niemals auftreten und in der Praxis tritt es auch sehr selten auf, aber durch die heutigen Cache-Technologien bei den Festspeichern ist es durchaus denkbar. Übertragen auf die Oracle Datenbank betrifft das oben beschriebene Szenario die Datenblöcke bzw. Datendateien. Der Database Writer (DBWR) schreibt diese Blöcke aus dem Buffer Cache und wartet auf eine Erfolgsmeldung des Storage. Dieser kann wiederum Caches nutzen, die ausfallen können - wie schon geschrieben ein Vorfall, der sehr selten ist. Wenn nun ein Datenblock später wieder in den Buffer Cache gelesen wird, dieser aber beim letzten Schreibvorgang nicht wirklich erfolgreich auf die Festplatte geschrieben wurde, würde eine veraltete Version geladen und die Daten wären nicht mehr konsistent.
Für hochverfügbare Datenbanken, die einen durch Cache-Technologie hochperformanten Storage nutzen ist es sinnvoll, dafür zu sorgen, dass beim Lesen eines Blocks geprüft wird, dass dieser Block auch wirklich dem letzten durch die Software gespeicherten Stand entspricht.
Die Oracle Datenbank hat in jedem Oracle Datenblock eine Markierung, bei welcher SCN (System Change Number) die letzte Datenänderung im Datenblock vorgenommen wurde. Darüber kann man also testen, ob ein vorliegender Datenblock aktuell ist. In Oracle 11g wurde der Instanzparameter DB_LOST_WRITE_PROTECT eingeführt, um einen ersten Schutz vor Lost Writes zu implementieren. Dieser wirkt aber nur in einer Physical Standby Database Umgebung und sorgt dafür, dass auf der Seite der Physical Standby Datenbank beim Apply der Redo Logs (was ja einem Recovery-Vorgang entspricht) die auch in den Log-Einträgen stehenden SCNs mit denen in den Datenblöcken auf der Standby Seite verglichen werden. Letztlich wird damit sichergestellt, dass sich ein Lost Write nicht auch auf die Standby Datenbank überträgt. Im Fehlerfall kann dann von der Primärdatenbank auf die Standbydatenbank umgeschaltet werden, wobei je nach Betriebsmodus der Standbyumgebung auch die letzten Transaktionen verloren gehen können.
Ab Oracle 18c gibt es den Schutz vor Lost Writes auch ohne Standby Konfigurationen. Dabei wird die Idee verfolgt, dass man diesen Schutz ja auch aufbauen kann, wenn man sich für jeden benutzten Datenblock die letzte SCN zusätzlich merken würde. Genau dieses übernehmen die in Oracle 18c Enterprise Edition eingeführten "Shadow Tablespaces". Diese Tablespaces speichern also keine Nutzdaten, sondern nur die letzten SCNs der Oracle Datenblöcke. Die Shadow Tablespaces benötigen dabei also viel weniger Platz als normale Tablespaces. Die Empfehlung ist, dass man ca. 2% von dem Speicher einplant, den man über dieses Feature schützen möchte. Das Feature "Lost Write Protection" kann für einzelne Tablespaces oder Datendateien eingesetzt werden. Dabei kann berücksichtigt werden, welcher Storage für welche Datendateien eingesetzt wird, bzw. eine Unterscheidung nach Wichtigkeit vorgenommen werden. Wenn beim Lesen eines Oracle Datenblocks über den Vergleich mit der im Shadow Tablespace gespeicherten SCN festgestellt wird, dass der Datenblock veraltet ist, erfolgt die Fehlermeldung "ORA-65478: shadow lost write protection - found lost write" und die Datenbankadministration muß ein Recovery anstoßen.
Der Schutz wirkt sowohl für normale DML Operationen als auch für SQL*Loader im Conventional Path Modus.
Für eine Oracle Datenbank können ein oder mehrere Shadow Tablespaces angelegt werden. Danach wird deren Nutzung nur noch aktiviert. Die Zuordnung, in welchem Shadow Tablespace die SCN eines Datenblocks gespeichert wird, übernimmt das Datenbanksystem, die Datenbankadministration hat darauf keinen Einfluß. Shadow Tablespaces können für Non-CDBs, CDB und PDBs erstellt werden.
Das Vorgehen ist dabei recht einfach:
Schritt 1: Shadow Tablespace anlegen
Zunächst werden ein oder mehrere Shadow Tablespaces als Bigfile Tablespace erstellt mit
CREATE BIGFILE TABLESPACE <ts_name> DATAFILE '<filename>' SIZE 20M LOST WRITE PROTECTION;
Also zum Beispiel:
CREATE BIGFILE TABLESPACE shadow_cdb_lwp1 DATAFILE '/u02/app/oracle/oradata/ORCL/shadow_lwp1_pdb1.dbf' SIZE 10M LOST WRITE PROTECTION;
Ob ein Tablespace ein Shadow Tablespace ist, oder nicht, können Sie in DBA_TABLESPACES abfragen:
select tablespace_name,status,contents from dba_tablespaces; TABLESPACE_NAME STATUS CONTENTS ------------------------------ --------- --------------------- SYSTEM ONLINE PERMANENT SYSAUX ONLINE PERMANENT UNDOTBS1 ONLINE UNDO TEMP ONLINE TEMPORARY USERS ONLINE PERMANENT SHADOW_CDB_LWP1 ONLINE LOST WRITE PROTECTION
Schritt 2: LOST WRITE PROTECTION für die Datenbank aktivieren
Nach dem Erstellen der Shadow Tablespaces muß das Feature "Lost Write Protection" für die Datenbank eingeschaltet werden:
Für Non-CDBs oder CDBs: ALTER DATABASE ENABLE LOST WRITE PROTECTION; Für PDBs: ALTER PLUGGABLE DATABASE ENABLE LOST WRITE PROTECTION;
Damit ist die Datenbank aber nur vorbereitet, das Feature immer noch nicht aktiv.
Schritt 3: Schutz für Tablespaces oder Datendateien einschalten
Jetzt muß noch für Tablespaces oder Datendateien der Schutz eingeschaltet werden:
ALTER TABLESPACE <ts_name> ENABLE LOST WRITE PROTECTION; oder ALTER DATABASE DATAFILE '<db_filename>' ENABLE LOST WRITE PROTECTION; bzw. ALTER PLUGGABLE DATABASE DATAFILE '<db_filename>' ENABLE LOST WRITE PROTECTION;
Falls Sie es zuvor versäumt haben, die Datenbank in den Modus "LOST WRITE PROTECTION" zu versetzen (siehe Schritt 2), erscheint die folgende Fehlermeldung:
SQL> ALTER TABLESPACE users ENABLE LOST WRITE PROTECTION; ALTER TABLESPACE users ENABLE LOST WRITE PROTECTION * ERROR at line 1: ORA-65474: lost write tablespace does not exist or has insufficient space or lost write is off
Im Data Dictionary kann man den Status in den View DBA_TABLESPACES oder DBA_DATA_FILES sehen:
desc dba_tablespaces Name Null? Type ----------------------------------------- -------- ---------------------------- TABLESPACE_NAME NOT NULL VARCHAR2(30) BLOCK_SIZE NOT NULL NUMBER INITIAL_EXTENT NUMBER NEXT_EXTENT NUMBER MIN_EXTENTS NOT NULL NUMBER MAX_EXTENTS NUMBER MAX_SIZE NUMBER PCT_INCREASE NUMBER MIN_EXTLEN NUMBER STATUS VARCHAR2(9) CONTENTS VARCHAR2(21) LOGGING VARCHAR2(9) FORCE_LOGGING VARCHAR2(3) EXTENT_MANAGEMENT VARCHAR2(10) ALLOCATION_TYPE VARCHAR2(9) PLUGGED_IN VARCHAR2(3) SEGMENT_SPACE_MANAGEMENT VARCHAR2(6) DEF_TAB_COMPRESSION VARCHAR2(8) RETENTION VARCHAR2(11) BIGFILE VARCHAR2(3) PREDICATE_EVALUATION VARCHAR2(7) ENCRYPTED VARCHAR2(3) COMPRESS_FOR VARCHAR2(30) DEF_INMEMORY VARCHAR2(8) DEF_INMEMORY_PRIORITY VARCHAR2(8) DEF_INMEMORY_DISTRIBUTE VARCHAR2(15) DEF_INMEMORY_COMPRESSION VARCHAR2(17) DEF_INMEMORY_DUPLICATE VARCHAR2(13) SHARED VARCHAR2(13) DEF_INDEX_COMPRESSION VARCHAR2(8) INDEX_COMPRESS_FOR VARCHAR2(13) DEF_CELLMEMORY VARCHAR2(14) DEF_INMEMORY_SERVICE VARCHAR2(12) DEF_INMEMORY_SERVICE_NAME VARCHAR2(1000) LOST_WRITE_PROTECT VARCHAR2(7) CHUNK_TABLESPACE VARCHAR2(1)
Die Spalte "LOST_WRITE_PROTECT" zeigt an, ob für einen Tablespace das Feature aktiviert ist, also
alter tablespace users ENABLE LOST WRITE PROTECTION; Tablespace altered. SQL> select TABLESPACE_NAME,LOST_WRITE_PROTECT from dba_tablespaces; TABLESPACE_NAME LOST_WR ------------------------------ ------- SYSTEM OFF SYSAUX OFF UNDOTBS1 OFF TEMP OFF USERS ENABLED SHADOW_CDB_LWP1 OFF
Damit wird dieses natürlich auch für alle Datendateien dieses Tablespace angezeigt:
desc dba_data_files Name Null? Type ----------------------------------------- -------- ---------------------------- FILE_NAME VARCHAR2(513) FILE_ID NUMBER TABLESPACE_NAME VARCHAR2(30) BYTES NUMBER BLOCKS NUMBER STATUS VARCHAR2(9) RELATIVE_FNO NUMBER AUTOEXTENSIBLE VARCHAR2(3) MAXBYTES NUMBER MAXBLOCKS NUMBER INCREMENT_BY NUMBER USER_BYTES NUMBER USER_BLOCKS NUMBER ONLINE_STATUS VARCHAR2(7) LOST_WRITE_PROTECT VARCHAR2(7) select file_name,LOST_WRITE_PROTECT from dba_data_files; FILE_NAME LOST_WR ------------------------------------------ ------- /u02/app/oracle/oradata/ORCL/system01.dbf OFF /u02/app/oracle/oradata/ORCL/sysaux01.dbf OFF /u02/app/oracle/oradata/ORCL/users01.dbf ENABLED /u02/app/oracle/oradata/ORCL/undotbs01.dbf OFF
Falls ein Lost Write auftritt und Sie auf betroffene Daten zugreifen erfolgt die folgende Fehlermeldung:
SQL> SELECT * FROM no_lost_write; SELECT * FROM no_lost_write * ERROR at line 1: ORA-65478: shadow lost write protection - found lost write
Sie können den Schutz auf der Ebene der Datenbank abschalten mit
ALTER DATABASE DISABLE LOST WRITE PROTECTION; oder ALTER PLUGGABLE DATABASE DISABLE LOST WRITE PROTECTION;
Auf der Ebene der Tablespaces bzw. Datendateien können Sie den Schutz
Die Kommandos sind sprechend:
ALTER TABLESPACE users SUSPEND LOST WRITE PROTECTION; ALTER TABLESPACE users REMOVE LOST WRITE PROTECTION; ALTER DATABASE DATAFILE '/u02/app/oracle/oradata/ORCL/users01.dbf' SUSPEND LOST WRITE PROTECTION; ALTER PLUGGABLE DATABASE DATAFILE '/u02/app/oracle/oradata/ORCL/users01.dbf' SUSPEND LOST WRITE PROTECTION; ALTER DATABASE DATAFILE '/u02/app/oracle/oradata/ORCL/users01.dbf' REMOVE LOST WRITE PROTECTION; ALTER PLUGGABLE DATABASE DATAFILE '/u02/app/oracle/oradata/ORCL/users01.dbf' REMOVE LOST WRITE PROTECTION;
Ab Oracle 18c bietet die Oracle Datenbank einen Schutz vor Schäden an Daten durch Lost Writes durch Shadow Tablespaces.
Lost Write Protection ist Bestandteil der Enterprise Edition. Dieses ist beschrieben im Licensing Guide.
Weitere Informationen
Zurück zum Anfang des Artikels
Zurück zur Community-Seite