Heim Datenbank MySQL-Tutorial Oracle数据表默认值列添加与行迁移(Row Migration)

Oracle数据表默认值列添加与行迁移(Row Migration)

Jun 07, 2016 pm 05:58 PM
oracle 数据表 添加 迁移 默认值

在笔者之前的文章中,已经探讨过给一个数据表添加有默认值列是一项非常危险的事情,特别是在在线生产环境下。给一张大数据表添加有默认值列,最直接的有下面几个严重危害: 系统高负荷运行,消耗大量资源。添加列操作是一次性的DDL操作,生成大量的Redo Log记

在笔者之前的文章中,已经探讨过给一个数据表添加有默认值列是一项非常“危险”的事情,特别是在在线生产环境下。给一张大数据表添加有默认值列,最直接的有下面几个严重危害:

系统高负荷运行,消耗大量资源。添加列操作是一次性的DDL操作,生成大量的Redo Log记录;
长期数据表锁定,阻碍生产系统作业。添加数据列期间,对数据表添加独占锁,此时阻碍其他DML操作;
破坏原有存储结构,造成大量的行迁移(Row Migration)数据。在每个数据行尝试添加进默认值,进行膨胀的同时,由于rowid的特性,会引起严重的行链接情况,损害原有数据表存储结构;



本文主要想聊聊由于默认值添加带来的行链接(Row Migration)现象。

1、从Row Migration现象谈起

Row Migration本质上是一种由于Oracle存储特性和数据行定位特性而发生的一种现象。在Oracle中,所有的数据行都是保留在数据块单元上的。一个数据块可以容纳若干条数据(通常条件下)。一些数据列,如varchar2类型,大部分情况下都是根据输入数据的长度进行空间分配。

那么,如果数据行列填入了更大的数据,也就是空间发生了拓展。数据块存储上就会发生何种变化呢?每个数据块都会预留一部分的空闲空间,作为数据行变化预留位置。如果长度继续拓展,那么会发生什么呢?

Oracle会尝试将这个数据行拷贝出,找个新的数据块进行存储。这样,就可以放下数据块。那么,一个新的问题出现了,就是Rowid问题。

在Oracle中,Rowid是定位一条记录的物理地址。Rowid包括数据文件相对编号、对象号、数据块号和Slot行号。Rowid普遍作为数据行的标记,保存在相关的索引叶子节点上。但是,当一个数据行被转移存储到另一个数据块,本质上物理存储位置已经发生变化。索引等对象中包括的Rowid面临着失效的问题。

Oracle解决这个问题是通过“虚拟门牌”的方法。这个数据行位置虽然已经到另外的地方,但是对应的Rowid并没有发生变化。当我们检索数据,Server Process定位到原来的位置时,它会找到一个转换跳转地址,那里面记录着真正的Rowid地址。这个就是发生了Row Migration。

Row Migration给系统性能带来了很多潜在的问题。比如,一行数据原来只需要寻找一个数据块记录,现在就需要寻找多个数据块才可以。这样就是带来的性能问题。

我们在进行默认值数据行添加的时候,就会带来Row Migration的爆发。

2、Row Migration与默认值列添加

下面我们通过实验,来证明Row Migration的出现。我们选择11gR2环境进行实验。


SQL> select * from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
CORE       11.2.0.1.0        Production

SQL> create table t as select object_id from dba_objects where 1=0;
Table created

--添加若干条记录;
SQL> insert into t select object_id from dba_objects where rownum
99 rows inserted

SQL> commit;
Commit complete


数据表T,在存储结构和空间分配上情况如下:


SQL> exec dbms_stats.gather_table_stats(user,'T',cascade => true);
PL/SQL procedure successfully completed

SQL> select bytes, blocks,extents from user_segments where segment_name='T';

    BYTES    BLOCKS   EXTENTS
---------- ---------- ----------
    65536         8         1

SQL> select blocks from user_tables where table_name='T';

   BLOCKS
----------
        1


User_segment中记录着给数据段分配的总空间,但这并不代表全部的HWM位置。User_tables中的blocks,才代表HWM下数据块的个数。从上面的结果看,HWM下一共只有一个数据块。从rowid分析看,实际也的确如此。


SQL> select dbms_rowid.rowid_block_number(rowid) blockno, count(*) from t group by dbms_rowid.rowid_block_number(rowid);

  BLOCKNO  COUNT(*)
---------- ----------
    85857        99


下面我们进行数据列添加。


SQL> alter table t add vc varchar2(1000) default lpad('T',500,'T');
Table altered

Executed in 0.078 seconds


对应的空间使用情况如下:


SQL> exec dbms_stats.gather_table_stats(user,'T',cascade => true);
PL/SQL procedure successfully completed

Executed in 0.141 seconds

SQL> select blocks from user_tables where table_name='T';

   BLOCKS
----------
       12

Executed in 0.016 seconds


SQL> select bytes, blocks,extents from user_segments where segment_name='T';

    BYTES    BLOCKS   EXTENTS
---------- ---------- ----------
   131072        16         2

SQL> select dbms_rowid.rowid_block_number(rowid) blockno, count(*) from t group by dbms_rowid.rowid_block_number(rowid);

  BLOCKNO  COUNT(*)
---------- ----------
    85857        99

Executed in 0.016 seconds


上面的情况可以看出,Oracle的数据表T已经推高了水位线HWM到12个块,从空间分配也分配了新的extent使用。

但是,所有数据行rowid没有变化。所有数据行的“门牌号”都没有变化,但是存储呢?很诡异的增加了。正常容量下,数据块情况应该是如下:


SQL> create table t_bak as select * from t;

Table created

SQL> exec dbms_stats.gather_table_stats(user,'T_BAK',cascade => true);

PL/SQL procedure successfully completed

SQL> select bytes, blocks,extents from user_segments where segment_name='T_BAK';

    BYTES    BLOCKS   EXTENTS
---------- ---------- ----------
   131072        16         2

SQL> select blocks from user_tables where table_name='T_BAK';

   BLOCKS
----------
        8

SQL> select dbms_rowid.rowid_block_number(rowid) blockno, count(*) from t_bak group by dbms_rowid.rowid_block_number(rowid);

  BLOCKNO  COUNT(*)
---------- ----------
    86589        14
    86588        14
    86585        14
    86586        14
    86591        14
    86590        14
    86587        14
    86592         1

8 rows selected


下面,我们来证明发生了行链接情况。

3、数据表行链接检验

Analyze语句一度是非常流行的收集数据表统计量的操作方式。但是随着dbms_stats包的成熟推广,analyze在统计量收集方面的功能已经渐渐弱化。但是,Oracle依然保留了这个语句的两个基本功能:对数据表进行行链接(Row Migration)检测和索引健康程度检测。

下面使用analyze语句进行数据表T的检测。首先我们需要创建分析结果的容纳数据表。



--调用Oracle_HOME下的脚本;
SQL>@?/rdbms/admin/utlchain.sql

Table created.

SQL> desc chained_rows;
Name                                     Null?   Type
----------------------------------------- -------- ----------------------------
OWNER_NAME                                        VARCHAR2(30)
TABLE_NAME                                        VARCHAR2(30)
CLUSTER_NAME                                      VARCHAR2(30)
PARTITION_NAME                                    VARCHAR2(30)
SUBPARTITION_NAME                                 VARCHAR2(30)
HEAD_ROWID                                        ROWID
ANALYZE_TIMESTAMP                                 DATE

SQL> create public synonym chained_rows for chained_rows;

Synonym created.

SQL> grant all on chained_rows to public;

Grant succeeded.


分析数据表,如下:

--检验数据行Row Migration情况;
SQL> analyze table t list chained rows into chained_rows;
Table analyzed

Executed in 0.125 seconds

--发生Row Migration次数;
SQL> select count(*) from chained_rows;

COUNT(*)
----------
       86

Executed in 0.016 seconds

SQL> select head_rowid from chained_rows where rownum

HEAD_ROWID
------------------
AAASUCAABAAAU9hAAN
AAASUCAABAAAU9hAAO
AAASUCAABAAAU9hAAP
AAASUCAABAAAU9hAAQ

Executed in 0.016 seconds

SQL> select * from t where rowid='AAASUCAABAAAU9hAAQ';

OBJECT_ID VC
---------- --------------------------------------------------------------------------------
       38 TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT

Executed in 0.016 seconds


在99行记录中,发生了86次行链接Row Migration情况。


4、结论

解决Oracle Row Migration的方法,就是进行数据表重构,重新对存储结构和Rowid进行整理。我们说,在生产环境下,进行有默认值数据列的添加操作,会引起一系列的问题,要三思而行。
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌
Will R.E.P.O. Crossplay haben?
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

So überprüfen Sie die Tabellenraumgröße von Oracle So überprüfen Sie die Tabellenraumgröße von Oracle Apr 11, 2025 pm 08:15 PM

Um die Oracle -Tablespace -Größe abzufragen, führen Sie die folgenden Schritte aus: Bestimmen Sie den Namen Tablespace, indem Sie die Abfrage ausführen: Wählen Sie Tablespace_Name aus dba_tablespaces. Abfragen Sie die Tablespace -Größe durch Ausführen der Abfrage: Summe (Bytes) als Total_Size, sum (bytes_free) als verfügbare_space, sum

Wie man Zeit in Oracle bekommt Wie man Zeit in Oracle bekommt Apr 11, 2025 pm 08:09 PM

Es gibt die folgenden Methoden, um Zeit in Oracle zu bekommen: current_timestamp: Gibt die aktuelle Systemzeit genau auf Sekunden zurück. SYSTIMESTAMP: genauer als Current_Timestamp, für Nanosekunden. SYSDATE: Gibt das aktuelle Systemdatum mit Ausnahme des Zeitteils zurück. To_char (sysdate, 'yyy-mm-dd hh24: mi: ss'): konvertiert das aktuelle Systemdatum und die Uhrzeit in ein bestimmtes Format. Extrakt: Extrahiert einen bestimmten Teil aus einem Zeitwert wie einem Jahr, Monat oder Stunde.

So sehen Sie den Instanznamen von Oracle So sehen Sie den Instanznamen von Oracle Apr 11, 2025 pm 08:18 PM

Es gibt drei Möglichkeiten, Instanznamen in Oracle anzuzeigen: Verwenden Sie den "SQLPLUS" und "Instance_name aus v $ Instance". Befehle in der Befehlszeile. Verwenden Sie den "show Instance_name;" Befehl in SQL*Plus. Überprüfen Sie die Umgebungsvariablen (Oracle_sid unter Linux) über den Task -Manager des Betriebssystems, den Oracle Enterprise Manager oder über das Betriebssystem.

So verschlüsseln Sie die Oracle -Ansicht So verschlüsseln Sie die Oracle -Ansicht Apr 11, 2025 pm 08:30 PM

Mit der Verschlüsselung von Oracle View können Sie Daten in der Ansicht verschlüsseln und so die Sicherheit sensibler Informationen verbessern. Die Schritte umfassen: 1) Erstellen des Master -Verschlüsselungsschlüssels (MEK); 2) Erstellen einer verschlüsselten Ansicht, der Ansicht und der Verschlüsselung der Ansicht und der MEK angeben; 3) Benutzern Sie die Benutzer, auf die verschlüsselte Ansicht zuzugreifen. Wie verschlüsselte Ansichten funktionieren: Wenn ein Benutzer nach einer verschlüsselten Ansicht nachgefragt wird, verwendet Oracle MEK, um Daten zu entschlüsseln und sicherzustellen, dass nur autorisierte Benutzer auf lesbare Daten zugreifen können.

Wie man die Oracle -Installation deinstalliert Wie man die Oracle -Installation deinstalliert Apr 11, 2025 pm 08:24 PM

Deinstallieren Sie die Methode für Oracle -Installationsfehler: Schließen Sie den Oracle -Service, löschen Sie Oracle -Programmdateien und Registrierungsschlüssel, Deinstallieren Sie Oracle -Umgebungsvariablen und starten Sie den Computer neu. Wenn das Deinstall fehlschlägt, können Sie das Oracle Universal Deinstall -Tool manuell deinstallieren.

So überprüfen Sie ungültige Nummern von Oracle So überprüfen Sie ungültige Nummern von Oracle Apr 11, 2025 pm 08:27 PM

Oracle Ungültige numerische Fehler können durch Fehlpaarung des Datentyps, numerische Überlauf, Datenkonvertierungsfehler oder Datenbeschäftigung verursacht werden. Zu den Schritten zur Fehlerbehebung gehören das Überprüfen von Datentypen, das Erkennen digitaler Überläufe, das Überprüfen von Datenkonvertierungen, das Überprüfen der Datenbeschädigung und das Erforschen anderer möglicher Lösungen wie das Konfigurieren des Parameters nls_numeric_characters und das Aktivieren der Datenüberprüfungs -Protokollierung.

So lösen Sie das Problem des Schließens von Oracle Cursor So lösen Sie das Problem des Schließens von Oracle Cursor Apr 11, 2025 pm 10:18 PM

Die Methode zur Lösung des Oracle Cursor Closeure -Problems umfasst: explizit den Cursor mithilfe der Close -Anweisung schließen. Deklarieren Sie den Cursor in der für Aktualisierungsklausel so, dass er nach Beendigung des Umfangs automatisch schließt. Deklarieren Sie den Cursor in der Verwendung der Verwendung so, dass er automatisch schließt, wenn die zugehörige PL/SQL -Variable geschlossen ist. Verwenden Sie die Ausnahmebehandlung, um sicherzustellen, dass der Cursor in jeder Ausnahmesituation geschlossen ist. Verwenden Sie den Verbindungspool, um den Cursor automatisch zu schließen. Deaktivieren Sie die Automatikübermittlung und Verzögerung des Cursors Schließen.

So richten Sie Benutzer von Oracle ein So richten Sie Benutzer von Oracle ein Apr 11, 2025 pm 08:21 PM

Befolgen Sie die folgenden Schritte, um einen Benutzer in Oracle zu erstellen: Erstellen Sie einen neuen Benutzer mit der Erstellung der Benutzeranweisung. Gewähren Sie die erforderlichen Berechtigungen mit der Zuschusserklärung. Optional: Verwenden Sie die Ressourcenanweisung, um das Kontingent festzulegen. Konfigurieren Sie andere Optionen wie Standardrollen und temporäre Tabellenspaces.

See all articles