怎么恢复损坏后的undo 表空间(一)

本文介绍了一种在Oracle数据库中遇到undo表空间损坏的情况下的恢复步骤。该数据库运行在非归档模式下,通过离线并删除损坏的undo表空间文件,创建新的undo表空间来解决此问题。

怎么恢复损坏后的undo 表空间(一)

  今天是2013-08-30,目前有这么一种情况。
  数据库运行在非归档模式下,在关闭数据库的时候采用正常关闭。打开 数据库之后提示undo表空间损坏。信息如下:

   对于这种情况进行的恢复步骤如下:
[oracle@oracle-one RHYS]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.1.0 Production on Wed Aug 14 21:12:09 2013

Copyright (c) 1982, 2009, Oracle.  All rights reserved.

Connected to an idle instance.

SQL>
SQL>
SQL> startup
ORACLE instance started.

Total System Global Area  405020672 bytes
Fixed Size                  2213816 bytes
Variable Size             251660360 bytes
Database Buffers          146800640 bytes
Redo Buffers                4345856 bytes
Database mounted.
ORA-01157: cannot identify/lock data file 3 - see DBWR trace file
ORA-01110: data file 3: '/opt/app/oracle/RHYS/undotbs01.dbf'


SQL> select open_mode from v$database;

OPEN_MODE
--------------------
MOUNTED

SQL> exit
Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
[oracle@oracle-one RHYS]$ adrci

ADRCI: Release 11.2.0.1.0 - Production on Wed Aug 14 21:15:48 2013

Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.

ADR base = "/opt/app/oracle"
adrci> show homepath
ADR Homes:
diag/tnslsnr/oracle-one/listener
diag/rdbms/rhys/RHYS
adrci> set homepath
DIA-48431: Must specify at least one ADR home path

adrci> set homepath diag/rdbms/rhys/RHYS
adrci> show alert -tail 20
2013-08-14 21:12:13.533000 +08:00
PMON started with pid=2, OS id=3650
VKTM started with pid=3, OS id=3652 at elevated priority
VKTM running at (10)millisec precision with DBRM quantum (100)ms
GEN0 started with pid=4, OS id=3656
DIAG started with pid=5, OS id=3658
DBRM started with pid=6, OS id=3660
PSP0 started with pid=7, OS id=3662
DIA0 started with pid=8, OS id=3664
MMAN started with pid=9, OS id=3666
DBW0 started with pid=10, OS id=3668
LGWR started with pid=11, OS id=3670
CKPT started with pid=12, OS id=3672
SMON started with pid=13, OS id=3674
RECO started with pid=14, OS id=3676
MMON started with pid=15, OS id=3678
starting up 1 dispatcher(s) for network address '(ADDRESS=(PARTIAL=YES)(PROTOCOL=TCP))'...
MMNL started with pid=16, OS id=3680
starting up 1 shared server(s) ...
ORACLE_BASE from environment = /opt/app/oracle
ALTER DATABASE   MOUNT
2013-08-14 21:12:19.026000 +08:00
Successful mount of redo thread 1, with mount id 2735871469
Database mounted in Exclusive Mode
Lost write protection disabled
Completed: ALTER DATABASE   MOUNT
ALTER DATABASE OPEN
Errors in file /opt/app/oracle/diag/rdbms/rhys/RHYS/trace/RHYS_dbw0_3668.trc:
ORA-01157: cannot identify/lock data file 3 - see DBWR trace file
ORA-01110: data file 3: '/opt/app/oracle/RHYS/undotbs01.dbf'
ORA-27046: file size is not a multiple of logical block size
Additional information: 1
Errors in file /opt/app/oracle/diag/rdbms/rhys/RHYS/trace/RHYS_ora_3691.trc:
ORA-01157: cannot identify/lock data file 3 - see DBWR trace file
ORA-01110: data file 3: '/opt/app/oracle/RHYS/undotbs01.dbf'
ORA-1157 signalled during: ALTER DATABASE OPEN...
2013-08-14 21:12:20.498000 +08:00
Checker run found 1 new persistent data failures
adrci> exit
[oracle@oracle-one RHYS]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.1.0 Production on Wed Aug 14 21:16:48 2013

Copyright (c) 1982, 2009, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> alter database datafile '/opt/app/oracle/RHYS/undotbs01.dbf' offline drop;

Database altered.

SQL> alter database open;

Database altered.

SQL> show parameter undo

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
_optimizer_undo_cost_change          string      11.2.0.1
undo_management                      string      AUTO
undo_retention                       integer     900
undo_tablespace                      string      UNDOTBS1


SQL> create undo tablespace undotbs2 datafile '/opt/app/oracle/RHYS/undotbs2.dbf' size 50M autoextend on next 5M maxsize 200M;

Tablespace created.

SQL> alter system set undo_tablespace=undotbs2;

System altered.

SQL> select usn,status from v$rollstat;

       USN STATUS
---------- ---------------
         0 ONLINE
        11 ONLINE
        12 ONLINE
        13 ONLINE
        14 ONLINE
        15 ONLINE
        16 ONLINE
        17 ONLINE
        18 ONLINE
        19 ONLINE
        20 ONLINE

11 rows selected.

SQL> col name for a60
SQL> set linesize 200
SQL> select file#,status from v$datafile;

     FILE# STATUS
---------- -------
         1 SYSTEM
         2 ONLINE
         3 OFFLINE
         4 ONLINE
         5 ONLINE
         6 ONLINE

6 rows selected.

SQL> select file#,status,name from v$datafile;

     FILE# STATUS  NAME
---------- ------- ------------------------------------------------------------
         1 SYSTEM  /opt/app/oracle/RHYS/system01.dbf
         2 ONLINE  /opt/app/oracle/RHYS/sysaux01.dbf
         3 OFFLINE /opt/app/oracle/RHYS/undotbs01.dbf
         4 ONLINE  /opt/app/oracle/RHYS/users01.dbf
         5 ONLINE  /opt/app/oracle/RHYS/test.dbf
         6 ONLINE  /opt/app/oracle/RHYS/undotbs2.dbf

6 rows selected.

SQL> drop tablespace undotbs1 including contengs and datafiles;
drop tablespace undotbs1 including contengs and datafiles
                                   *
ERROR at line 1:
ORA-01911: CONTENTS keyword expected


SQL> drop tablespace undotbs1 including contents and datafiles;

Tablespace dropped.

SQL> select file#,status,name from v$datafile;

     FILE# STATUS  NAME
---------- ------- ------------------------------------------------------------
         1 SYSTEM  /opt/app/oracle/RHYS/system01.dbf
         2 ONLINE  /opt/app/oracle/RHYS/sysaux01.dbf
         4 ONLINE  /opt/app/oracle/RHYS/users01.dbf
         5 ONLINE  /opt/app/oracle/RHYS/test.dbf
         6 ONLINE  /opt/app/oracle/RHYS/undotbs2.dbf

SQL>

<think>我们正在处理关于MySQL 8.0中如何回收膨胀的UNDO表空间的问题。用户询问的是“optimize undo tablespace reclaim space”,但实际上在MySQL 8.0中,UNDO表空间的管理已经自动化,通常不需要手动回收。但是,如果遇到UNDO空间膨胀的问题,我们可以采取些措施。 根据引用[1]:在MySQL 8.0.14之前,调整`innodb_undo_tablespaces`设置可以增加或减少活动的UNDO表空间的数量。但是,从MySQL 8.0.14开始,`innodb_undo_tablespaces`已经被弃用,并且默认使用两个UNDO表空间(innodb_undo_001和innodb_undo_002),并且这些表空间是自动扩展的。在8.0.14及以后版本,我们不再需要手动管理UNDO表空间的数量。 然而,即使UNDO表空间是自动管理的,有时也可能因为长时间运行的事务导致UNDO空间无法及时回收,从而出现空间膨胀。我们可以通过以下步骤来处理: 1. **检查长时间运行的事务**:长时间运行的事务会阻止InnoDB清理UNDO日志。使用以下SQL查询长时间运行的事务: ```sql SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX; ``` 2. **检查UNDO表空间的使用情况**:从MySQL 8.0.21开始,我们可以通过`INFORMATION_SCHEMA.INNODB_TABLESPACES`查看UNDO表空间的使用情况: ```sql SELECT SPACE, NAME, FILE_SIZE/1024/1024 AS FILE_SIZE_MB, ALLOCATED_SIZE/1024/1024 AS ALLOCATED_SIZE_MB FROM INFORMATION_SCHEMA.INNODB_TABLESPACES WHERE NAME LIKE 'innodb_undo%'; ``` 3. **回收UNDO表空间**:在MySQL 8.0中,UNDO表空间是自动回收的,但有时可能需要手动触发。我们可以通过重启MySQL实例来强制回收UNDO表空间,但这在生产环境中通常不可行。另方法是尝试调整UNDO表空间的数量(尽管8.0.14后已弃用,但在某些版本中可能仍有效)或者等待事务提交后自动回收。 4. **使用UNDO表空间截断(truncate)**:MySQL 8.0支持在运行时截断UNDO表空间。这需要满足两个条件: - 至少有两个活动的UNDO表空间- 系统变量`innodb_undo_log_truncate`必须为ON(默认值)。 当满足条件时,InnoDB会自动选择UNDO表空间进行截断,将其缩小到初始大小(由`innodb_undo_log_truncate_size`定义,默认为16MB)。我们可以通过设置以下参数来调整截断的频率: ```ini innodb_undo_log_truncate = ON innodb_max_undo_log_size = 100M # 当UNDO日志超过此大小时,触发截断 ``` 5. **手动触发截断**:虽然通常是自动的,但我们也可以通过强制超过`innodb_max_undo_log_size`来触发截断。例如,我们可以临时将`innodb_max_undo_log_size`设置得比当前UNDO表空间小,然后InnoDB会很快触发截断。 注意:在截断过程中,被截断的UNDO表空间会暂时离线,因此需要另UNDO表空间来承担负载。这就是为什么至少需要两个UNDO表空间。 综上所述,在MySQL 8.0中,我们通常不需要手动回收UNDO表空间,因为自动截断机制会处理。但如果遇到空间膨胀,我们可以检查并终止长时间运行的事务,并确保自动截断机制正常工作。 如果用户的环境是MySQL 8.0.14及以上,那么`innodb_undo_tablespaces`设置已经不再需要,系统会自动管理两个UNDO表空间,并自动截断。 如果用户需要立即回收空间,可以考虑以下步骤: - 确保没有长时间运行的事务。 - 确保`innodb_undo_log_truncate=ON`和`innodb_max_undo_log_size`设置合理(例如,设置为100MB)。 - 如果UNDO表空间已经很大,可以尝试重启MySQL服务(在允许的情况下),因为重启会重新初始化UNDO表空间。 但是,请注意,在生产环境中重启可能不可行,因此更推荐调整参数并等待自动截断。 引用说明: - 引用[1]说明了在MySQL 8.0.14之前如何调整UNDO表空间的数量,但我们的情况是8.0,且8.0.14后该变量被弃用。 - 引用[2]提到MySQL 8.0实现了UNDO日志的加密,与空间回收无关。 - 引用[3]是关于临时表空间的,与UNDO表空间无关。 因此,我们主要参考MySQL 8.0的官方文档关于UNDO表空间自动截断的机制。 **操作步骤总结:** 1. 检查并结束长时间运行的事务。 2. 确认自动截断功能开启(默认是开启的)。 3. 调整`innodb_max_undo_log_size`为个合理的值(如100MB),以触发截断。 4. 如果以上方法无效且允许重启,则重启MySQL服务。 注意:在截断过程中,可能会对性能有短暂影响,因为需要将活跃的UNDO日志迁移到另UNDO表空间。 如果用户使用的是MySQL 8.0.14及以上版本,那么系统默认已经配置了两个UNDO表空间,并且自动截断是开启的,所以通常不需要手动干预。 **相关问题:** 1. 如何监控MySQL中UNDO表空间的使用情况? 2. 在MySQL 8.0中,如何配置UNDO表空间的自动截断参数? 3. 为什么需要至少两个UNDO表空间才能进行截断? 4. 长时间运行的事务对UNDO表空间有什么影响?</think>### MySQL 8.0 UNDO表空间回收指南 在MySQL 8.0中回收膨胀的UNDO表空间,主要通过**自动截断机制(innodb_undo_log_truncate)** 实现。以下是具体操作步骤: #### 1️⃣ 检查当前UNDO状态 ```sql -- 查看UNDO表空间使用情况 SELECT NAME, FILE_SIZE/1024/1024 AS size_mb, ALLOCATED_SIZE/1024/1024 AS allocated_mb FROM INFORMATION_SCHEMA.INNODB_TABLESPACES WHERE NAME LIKE 'innodb_undo%'; -- 检查截断功能状态 SHOW VARIABLES LIKE 'innodb_undo_log_truncate'; ``` #### 2️⃣ 启用自动截断(默认开启) ```ini # 在my.cnf中确保配置[^1] innodb_undo_log_truncate = ON # 启用自动截断 innodb_max_undo_log_size = 1073741824 # 超过1GB时触发截断(默认值) innodb_undo_tablespaces = 2 # 至少需要2个UNDO表空间[^1] ``` #### 3️⃣ 手动触发回收(可选) ```sql -- 强制触发截断过程(需满足触发条件) SET GLOBAL innodb_undo_log_truncate = 1; ``` #### 4️⃣ 监控回收进度 ```sql -- 查看截断状态 SHOW STATUS LIKE 'Innodb_undo_truncate%'; -- 检查活跃事务(长时间事务会阻塞回收) SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX; ``` #### 📌 关键机制说明 1. **自动触发条件**:当任何UNDO表空间超过`innodb_max_undo_log_size`时,MySQL自动将其截断至初始大小(默认10MB)[^1] 2. **双表空间要求**:必须有≥2个活跃UNDO表空间,才能轮流进行截断操作[^1] 3. **阻塞因素**:存在活跃的旧事务时,相关UNDO日志不会被回收 4. **加密支持**:MySQL 8.0支持UNDO日志的静态加密,不影响回收[^2] #### ⚠️ 注意事项 1. 从MySQL 8.0.14开始,`innodb_undo_tablespaces`参数已弃用,系统默认创建2个UNDO表空间 2. 禁止直接删除UNDO文件(如`ibdata1`),否则会导致数据损坏 3. 回收操作期间性能影响:截断过程会短暂暂停purge线程 > **最佳实践**:定期检查长时间运行的事务(>1小时),避免UNDO空间持续膨胀。若紧急回收,可在业务低峰期重启MySQL实例(强制重建UNDO文件)[^3]。 --- ### 📚 相关问题 1. 如何监控MySQL中UNDO表空间的实时使用情况? 2. 长时间运行的事务如何影响UNDO表空间的回收效率? 3. MySQL 8.0与5.7版本在UNDO管理机制上有哪些主要区别? 4. 启用UNDO表空间加密是否会影响自动回收功能?[^2] [^1]: 在MySQL 8.0.14之前,调整`innodb_undo_tablespaces`可动态增减UNDO表空间,移除的表空间需等待事务结束后才失效 [^2]: MySQL 8.0实现了UNDO/REDO日志的静态加密,此功能不影响自动截断机制 [^3]: MySQL 5.7引入共享临时表空间,避免为每个临时表创建独立表空间带来的性能损耗
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值