TRUNCATE TABLE原理解析

article/2025/9/22 10:06:51

34b542c8f78b9e6f07afbb73daa16472.gif

众所周知,TRUNCATE TABLE是一种快速清空表内数据的一种方式,与delete方式不同,truncate只产生非常少的redo和undo,就实现了清空表数据并降低表HWM的功能。本文主要围绕TRUNCATE TABLE的实现原理和TRUNCATE TABLE的恢复来展开。

首先构造测试环境,并通过10046以及redo dump去分析truncate的整个操作过程。其中10046用于观察truncate对于字典基表的操作;redo dump用于观察truncate对于segment header以及L1、L2位图块的操作。

  • OS: redhat 6.5

  • db:11.2.0.4

  • 基于assm

segment&extent info:
SYS@:>select owner,segment_name,header_file,header_block from dba_segments where segment_name='TRUNCATE_TABLE' and owner='TEST';OWNER                SEGMENT_NAME         HEADER_FILE HEADER_BLOCK
-------------------- -------------------- ----------- ------------
TEST                 TRUNCATE_TABLE                 5         1898SYS@:>select extent_id,file_id,block_id,blocks from dba_extents where segment_name='TRUNCATE_TABLE' and owner='TEST' order by 1;EXTENT_ID    FILE_ID   BLOCK_ID     BLOCKS
---------- ---------- ---------- ----------0          5       1896          81          5      12104          82          5      12112          83          5      12120          84          5      12128          85          5      12136          86          5      12144          87          5      12152          88          5      11904          89          5      11912          810          5      11920          811          5      11928          812          5      11936          813          5      11944          814          5      11952          815          5      11960          816          5      16256        12817          5      16384        12818          5      16512        12819          5      16768        12820          5      22528        12821          5      22656        12822          5      22784        12823          5      22912        12824          5      23040        12825          5      23168        12826          5      23296        12827          5      23424        128

通过10046和redo dump去观察truncate操作:

SYS@TEST(test):1>select count(*) from test.truncate_table;COUNT(*)
----------113426SYS@:>alter system flush SHARED_POOL;System altered.SYS@:>alter system flush BUFFER_CACHE;System altered.SYS@:>alter system switch logfile;System altered.SYS@:>select * from v$log;GROUP#    THREAD#  SEQUENCE#      BYTES  BLOCKSIZE    MEMBERS ARC STATUS           FIRST_CHANGE# FIRST_TIME         NEXT_CHANGE# NEXT_TIME
---------- ---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- ------------------ ------------ ------------------1          1         85   52428800        512          1 NO  CURRENT                4116465 21-APR-18            2.8147E+142          1         83   52428800        512          1 NO  INACTIVE               4092314 20-APR-18               4116301 21-APR-183          1         84   52428800        512          1 NO  INACTIVE               4116301 21-APR-18               4116465 21-APR-18SYS@:>oradebug setmypid;
Statement processed.
SYS@:>oradebug tracefile_name
/u01/app/oracle/diag/rdbms/test/test/trace/test_ora_7091.trc
SYS@:>oradebug event 10046 trace name context forever,level 12;
Statement processed.
SYS@:>truncate table test.truncate_table;
Table truncated.
SYS@:>oradebug event 10046 trace name context off;
Statement processed.
SYS@TEST(test):1>alter system dump logfile '/u01/app/oracle/oradata/test/redo01.log';
System altered.

从10046 trace里搜出对基表的dml操作:

update:
[root@prim1-11g ~]# grep -i "^update"  /u01/app/oracle/diag/rdbms/test/test/trace/test_ora_7091.trc
update obj$ set obj#=:4, type#=:5,ctime=:6,mtime=:7,stime=:8,status=:9,dataobj#=:10,flags=:11,oid$=:12,spare1=:13, spare2=:14 where owner#=:1 and name=:2 and namespace=:3 and remoteowner is null and linkname is null and subname is null
update sys.mon_mods$ set inserts = inserts + :ins, updates = updates + :upd, deletes = deletes + :del, flags = (decode(bitand(flags, :flag), :flag, flags, flags + :flag)), drop_segments = drop_segments + :dropseg, timestamp = :time where obj# = :objn
update tab$ set ts#=:2,file#=:3,block#=:4,bobj#=decode(:5,0,null,:5),tab#=decode(:6,0,null,:6),intcols=:7,kernelcols=:8,clucols=decode(:9,0,null,:9),audit$=:10,flags=:11,pctfree$=:12,pctused$=:13,initrans=:14,maxtrans=:15,rowcnt=:16,blkcnt=:17,empcnt=:18,avgspc=:19,chncnt=:20,avgrln=:21,analyzetime=:22,samplesize=:23,cols=:24,property=:25,degree=decode(:26,1,null,:26),instances=decode(:27,1,null,:27),dataobj#=:28,avgspc_flb=:29,flbcnt=:30,trigflag=:31,spare1=:32,spare2=decode(:33,0,null,:33),spare4=:34,spare6=:35 where obj#=:1
update seg$ set type#=:4,blocks=:5,extents=:6,minexts=:7,maxexts=:8,extsize=:9,extpct=:10,user#=:11,iniexts=:12,lists=decode(:13, 65535, NULL, :13),groups=decode(:14, 65535, NULL, :14), cachehint=:15, hwmincr=:16, spare1=DECODE(:17,0,NULL,:17),scanhint=:18, bitmapranges=:19 where ts#=:1 and file#=:2 and block#=:3
delete:
[root@prim1-11g ~]# grep -i "^delete"  /u01/app/oracle/diag/rdbms/test/test/trace/test_ora_7091.trc      
delete from superobj$ where subobj# = :1
delete from tab_stats$ where obj#=:1

对基表的修改主要是:

  • 修改obj$,tab$的dataobj#

  • 修改seg$的对应信息如(extents,blocks,hwmincr等等)

  • 删除tab_stats$对应对象的统计信息

对于segment header以及L1、L2位图块的操作,只能通过redo dump去观察,因为在logminer中只会记录数据块的变更,而对于segment header和L1、L2位图块的操作在logminer里只记录操作类型为internal或者unsupported,没有什么有价值的信息。

通过对redo dump的分析,发现truncate操作只对segment header,L2位图块,第一个L1位图块和 HWM block所属的L1位图块进行了修改。

对于segment header:

  • 修改块的dataobj#

  • 修改LHWM和HHWM

  • 修改extent map、aux map以及extents个数

对于L2位图块:

  • 删除L1 ranges

  • 修改L2块的dataobj#

对于第一个L1位图块:

  • 修改第一个L1块的dataobj#

  • set hwm为ext#为0的第3+1个块(即段头块+1)

对于HWM block所属的L1位图块:

  • clear HWM flag

truncate的实质是在不修改数据块的情况下,通过修改segment header的data_object_id、hwm、extent map、aux map等信息来实现清空表的目的,其中还涉及数据字典基表以及L1、L2位图块的修改,所以说truncate操作只是存储数据的数据块没有产生任何redo和undo,但是segment header、位图块、数据字典基表还是会产生redo和undo。

关于作者

李翔宇,云和恩墨西区交付技术顾问,长期服务移动运营商行业客户,熟悉Oracle性能优化,故障诊断,特殊恢复。

今年的数据技术嘉年华大会上,李翔宇老师将带来题为《在通过案例深入解析Oracle内部原理》的演讲,与大家一起探索CBO和ASM rebalance的一些内部机制,精彩不容错过!

更多数据库行业相关内容,欢迎光临 2021 数据技术嘉年华 :https://www.modb.pro/dtc2021(扫描下方二维码免费领取大会门票)

END

推荐阅读:267页!2020年度数据库技术年刊

推荐下载:2020数据技术嘉年华PPT下载


2020数据技术嘉年华近50个PPT下载、视频回放已上传墨天轮平台,可在“数据和云”公众号回复关键词“2020DTC”获得!

你知道吗?我们的视频号里已经发布了很多精彩的内容,快去看看吧!↓↓↓

点击下图查看更多 ↓

56c0cb275a306ae3774df84a6bd8f683.png

b96c478a6804efdcb3ac631e63e27eb5.png

f67b563331abcd8edf57cca6e76547f3.png

云和恩墨大讲堂 | 一个分享交流的地方

长按,识别二维码,加入万人交流社群

请备注:云和恩墨大讲堂

  点个“在看” 

你的喜欢会被看到❤


http://chatgpt.dhexx.cn/article/VsYrtaeS.shtml

相关文章

HDFS Truncate文件截断

前言 在linux操作系统的使用中,有的时候我们可能想对某个现有的文件做尾部的截取(比如为了保留头部关键信息),但同时又不想重新写一个新的文件出来,这个时候我们其实可以采用系统提供的truncate命令。单词truncate的本…

oracle 数据库truncate,Oracle中的truncate用法

语法:TRUNCATE TABLE table; 在使用truncate语句(DDL语言)可以删除表中的所有记录。使用truncate语句删除数据时,通常要比使用delete语句快得多,这是因为使用truncate语句删除数据时,不会产生任何回退信息,因此执行t…

mysql truncate 条件_MySQL的TRUNCATE关键字

在MysqL中,还有一种方式可以删除表中的所有记录,需要使用TRUNCATE关键字。 TRUNCATE [TABLE] 表名 参数说明 表名,指定要执行删除操作的数据表 在数据库chapter03中创建一张表tab_truncate 图片描述" title""> 向数据表tab…

truncate命令简介

一、truncate命令简介 truncate命令通常用于将文件缩小或扩展到指定的大小。如果文件大于指定的大小,则会丢失额外的数据。如果文件较短,则会对其进行扩展,并且扩展部分的读数为零字节。 二、truncate命令安装 我们使用turncate命令之前需要…

Linux 命令(147) —— truncate 命令

文章目录 1.命令简介2.命令格式3.选项说明4.常用示例参考文献 1.命令简介 truncate 将文件的大小缩小或扩展到指定的大小。 如果指定的文件不存在将被创建。 如果文件大于指定的大小,则会丢失额外的数据。如果较短,它将被扩展,扩展的稀疏部…

Public Key Infrastructure——公钥基础设施

今天做一篇关于PKI的笔记,PKI是目前来说信息安全领域很流行的技术,它的应用已经很广泛了。 PKI是指公钥基础设施,它是通过公钥加密技术和数字签名服务保证传输数据的安全。它最重要的几个部分是公钥加密算法,数字证书,…

检查安装包(grid infrastructure和Oracle database所需补丁)

检查安装包 根据文档说明,安装 Grid Infrastructure 和 Oracle Database 所需的补丁包有: binutils-2.15.92.0.2 compat-libcap1-1.10 compat-libstdc-33-3.2.3 elfutils-libelf-0.97 elfutils-libelf-devel-0.97 expat-1.95.7 gcc-3.4.6 gcc-c…

DAIR-V2X: A Large-Scale Dataset for Vehicle-Infrastructure Cooperative 3D Object Detection

VICAD系统开发挑战 :缺乏来自真实场景的VICAD数据集。 3 DAIR-V2X 数据集 DAIR-V2X 采集来自真实场景的大规模、多模态、多视图数据集,带有 3D 标签注释,用于车辆-路边设施协同感知。 针对车辆和路边设施传感器之间的时间异步问题&#xff…

ins40401 oracle,安装orace grid infrastructure 提示[INS-40404]问题

grid infrastructure 提示“[INS-40404] The installer has detected a configured instance of oracle grid infrastructure software on the server! 今天是2013-12-03,描述一下出现这个错误的过程,我没按照正常的方式删掉 grid infrastructure,而是直接删掉了安装目录,但…

A/B-Test (Overlapping Experiment Infrastructure: More, Better, Faster Experimenta)

本文针对上周的工作进行了总结,上上周的工作将在接下来通过文章进行总结,主要内容为DEIN 模型。 为了解决推荐算法基于web实验的模型验证,我参考了Overlapping Experiment Infrastructure: More, Better, Faster Experimentation 2010 的goo…

Infrastructure-Based Object Detection and Tracking for Cooperative Driving Automation: A Survey

由于基础设施的(infrastructure-based)传感器安装位置和姿势的灵活性,基于基础设施的目标检测和跟踪系统可以增强联网车辆的感知能力。 一、基于基础设施的感知系统 基于基础设施的目标感知系统包含四个典型阶段:1)信…

公钥基础设施 (Public-key infrastructure PKI)

公钥基础设施 PKI 1.功能2.设计3.认证方法3.1证书机构(CA)3.2信任网络(Wot)3.3简单的公共关键基础设施(SKPI)3.4分散的PKI3.5基于区块链的 PKI 4.使用 密码学上,公开密钥基础建设借着数字证书认…

shell infrastructure host占用cpu_网速、CPU、内存监控软件TrafficMonitor

Traffic Monitor 是一款 Windows 平台的网速、CPU等监控悬浮窗软件,可以显示当前网速、CPU及内存占用率,小窗口可以拖动到窗口的任意位置,并且支持嵌入到任务栏显示,历史流量统计等功能。 Traffic Monitor 是免安装的,打开即用。下载地址:https://github.com/zhongyan…

Oracle 12cR1 Grid Infrastructure 安装指南之一(官方直译)

1 Oracle Grid Infrastructure安装清单 以下清单提供了所需的 Preinstallation 步骤的列表. 使用此清单可协调任务, 以帮助确保在启动Oracle Grid Infrastructure以进行群集安装之前完成所有系统和存储准备和配置任务. 1.1系统硬件, 软件和配置清单 本节包含以下服务器配置…

HLA RTI(Run-time Infrastructure)

RTI(Run-time Infrastructure) 概述 主要作用 具体实现了HLA接口规范。为了实现联邦内部各个联邦成员之间进行高效的信息交换,HLA接口规范用文字定义了各种标准服务和接口,而RTI则用程序设计语言将这些标准的服务和接口转成了标…

DDS之DCPS Infrastructure模块

DCPS Infrastructure Infrastructure ModuleEntityEntity IdentifierQoS policyListenerStatusStatusConditionEnabling Entities QosPolicyStatusStatus 定义StatusMask 定义Listener callback定义Listener callback的实现 Condition and WaitSet Infrastructure Module 从Inf…

Oracle 19.3 Grid Infrastructure 软件安装详细教程

更多文章,欢迎关注作者公众号,欢迎一起交流。 1 安装环境 CentOS 7.9Oracle Database 19.3 - Enterprise Edition 2 安装配置 2.1 内存要求 1)数据库安装:至少1GB,推荐2G以上; 2)Grid安装&…

Oracle 19c Grid Infrastructure安装

概述 本文描述在单个主机上(不是RAC)GI 19c的安装。 Oracle数据库软件19c已安装,但未创建任何数据库。参见这篇文章。 主机为Oracle Linux 7,主机上已安装先决条件包(oracle-database-preinstall-19c),数据库软件用户…

infra-structure Ad Hoc

“infrastructure”模式: 所谓infrastructure是在一种整合有线与无线局域网架构的应用模式,与ad- hoc不同的是配备无线网卡的设备必须通过ap来进行无线通讯,设置后,无线网络设备就必须有AP(Access Pointer)…