1. 归档模式是什么,生产库为什么要开
先讲一个真实的教训。我早年间接手过一套跑了两年的业务系统,数据库跑在非归档模式下,每天凌晨做一次全量备份。当时觉得备份有了就万事大吉,结果某天凌晨磁盘阵列突然坏了两块盘,数据文件所在的盘组直接掉了。恢复的时候才发现,最近的一次全量备份是前一天凌晨的,这意味着当天所有业务数据全部丢失,而且因为没开归档,redo log里那点增量根本不够用来做不完全恢复。最后只能拿昨天的备份恢复,损失了近一整天的数据。
那次事故之后,我接手任何一套Oracle数据库,第一件事就是检查归档模式是否开启。归档模式说白了,就是数据库在每次日志切换之后,把写满的redo log文件复制一份保存到指定位置。这些保存下来的文件就是归档日志,它们和全量备份组合在一起,才能支撑起真正的“按时间点恢复”。
非归档模式下,日志切换之后旧的redo log会被直接覆盖,数据库只能恢复到上一次备份的时刻,中间的数据全部丢失。而归档模式下,通过全量备份加归档日志,你可以把数据库恢复到任意一个历史时间点,甚至可以恢复到故障发生前的最后一秒。
更关键的是,归档模式是搭建Data Guard、使用LogMiner做日志分析、以及实现在线热备份的基础。只要你的数据库是生产环境,无论是跑业务系统还是做数据仓库,没有任何理由不开归档模式。开发库和测试库可以不开,但生产库必须开,这是数据库运维的底线。
这篇文章会把查看和开启归档模式的完整流程讲清楚,包括环境检查、参数配置、操作步骤和常见故障排查。内容基于Oracle 11g到19c的通用实践,有一点Linux基础、能自己登录数据库执行SQL的人都可以照着操作。
2. 动手之前,先搞清楚数据库当前处于什么状态
2.1 用一条命令快速查看归档模式状态
查看当前数据库是否处于归档模式,最直接的方式是用SQL*Plus登录数据库后执行archive log list命令。这个命令是Oracle提供的最直观的归档状态查看方式,输出信息一目了然。
sqlplus / as sysdba SQL> archive log list; Database log mode Archive Mode Automatic archival ENABLED Archive destination /u01/app/oracle/archive Oldest online log sequence 120 Next log sequence to archive 122 Current log sequence 122关键看两行:Database log mode显示Archive Mode代表已经开启,显示No Archive Mode代表没开;Automatic archival显示ENABLED代表自动归档开启,显示DISABLED代表即使处于归档模式也没有自动归档。
Archive destination这一行列出了归档日志的存放路径,如果这里为空,说明没有配置归档路径,这种情况即使归档模式开启了也存不下日志,后续会专门讲这个问题。
2.2 用SQL查询验证更详细的状态信息
如果你需要更详细的信息,比如归档目的地是否有效、归档日志的序列号范围,可以通过查询动态性能视图和历史视图来确认。v$database视图的log_mode字段直接显示数据库当前的日志模式。
SELECT name, log_mode, open_mode FROM v$database;返回结果中log_mode为ARCHIVELOG代表归档模式,为NOARCHIVELOG代表非归档模式。open_mode字段显示数据库是READ WRITE(读写模式)还是MOUNTED(挂载模式),开启归档的过程中需要确认数据库所处的挂载状态。
如果你还想知道归档目的地是否可用,可以查询v$archive_dest_status视图。这个视图会列出所有配置的归档目的地以及它们当前的状态,STATUS为VALID表示目的地正常可用,如果是ERROR或INACTIVE则需要处理。
SELECT dest_name, status, destination, error FROM v$archive_dest_status WHERE dest_name IN ('LOG_ARCHIVE_DEST_1', 'LOG_ARCHIVE_DEST_2');2.3 查看当前日志序列号,判断归档日志是否在持续产生
除了确认模式本身,还要确认归档日志确实在正常产生。日志切换时会产生新的序列号,每一次切换之后,当前日志序列号都会递增,归档日志也会同步增加一份。
SELECT sequence#, archived, status FROM v$log ORDER BY sequence#; SELECT MAX(sequence#) AS max_archived_seq FROM v$archived_log;v$log视图显示当前所有redo log日志组的状态,archived字段标记日志组是否已经归档。v$archived_log记录了所有已经生成的归档日志信息,查询MAX(sequence#)可以得到最新的归档序列号。
如果数据库处于非归档模式,你会在v$log中看到部分日志组显示CURRENT或ACTIVE但没有对应的归档记录。这时需要注意,在非归档模式下,日志切换时可能会因为无法覆盖尚未备份的日志而导致数据库挂起,这也是非归档模式在生产环境中风险极高的原因之一——因为只要日志写满但无法覆盖,整个数据库就会hang住,直接拒绝所有新的写入请求。
3. 完整开启归档模式,操作步骤与核心参数说明
3.1 开启前必须做的三件事
开启归档模式不是一条命令就完事的操作,它涉及数据库实例的重启,任何误操作都可能导致业务中断。在我实际操作中,开启归档模式前有三件事必须确认清楚。
第一,确认磁盘空间是否充足。归档日志会持续增长,必须计算好存放目录的空间。一个简单的估算方法:如果数据库每天产生10GB的redo log,归档日志也大约是这个量级,建议至少预留7天的归档日志空间。如果使用快速恢复区(Fast Recovery Area,FRA),启动归档时Oracle会自动把归档日志放到这里,那就需要确保FRA容量足够大,否则归档日志写满FRA会导致数据库直接hang住,这是一种非常常见的生产事故。
第二,确认维护窗口时间。开启归档模式需要重启数据库实例,从shutdown immediate到alter database open完成,整个过程一般来说几分钟内可以完成,但如果你在业务高峰期操作,这个窗口期内的所有请求都会失败。所以建议在业务低谷期操作,并提前和业务方沟通好维护窗口。
第三,确认当前是否有未完成的备份。如果数据库处于非归档模式,并且使用了alter database backup controlfile之类的备份命令,建议先完成一次全量备份。更严谨的做法是,在开启归档模式之后再做一次全量备份——因为开启归档之前的备份无法配合归档日志用于恢复,完整备份的基线应该是开启归档之后的那一次全量备份。
3.2 一步步操作:从shutdown到open的完整流程
一切确认无误之后,按以下步骤操作。以下命令均以sysdba身份登录SQL*Plus执行。
先关闭数据库实例。生产库建议使用shutdown immediate,Oracle会自动完成事务回滚和进程清理,如果长时间无法关闭,可以使用shutdown transactional等待事务完成,尽量不要贸然使用shutdown abort,除非是紧急情况。
sqlplus / as sysdba SQL> shutdown immediate;接下来,数据库实例关闭后,需要以MOUNT模式启动。这里有个新手容易犯的错误:startup之后直接执行alter database archivelog,会报ORA-01126: database must be mounted in this instance and not open in any instance错误。原因在于,归档模式的修改需要在数据库处于MOUNT状态而非OPEN状态时才能执行。
SQL> startup mount;然后执行开启归档的命令:
SQL> alter database archivelog;这条命令本身执行速度很快,它修改的是控制文件中的数据库日志模式记录,不需要做数据迁移。执行成功后返回Database altered.。
之后打开数据库,让业务恢复访问:
SQL> alter database open;最后,再次用archive log list确认状态:
SQL> archive log list; Database log mode Archive Mode Automatic archival ENABLED Archive destination /u01/app/oracle/archive Oldest online log sequence 120 Next log sequence to archive 123 Current log sequence 123到这里,归档模式已经成功开启。
3.3 关键参数配置:归档路径与归档格式
归档模式开启之后,必须确认归档日志写入的位置和文件命名格式。如果这两个参数没配置好,后续恢复可能会遇到各种麻烦。
归档路径的核心参数是log_archive_dest和log_archive_dest_n。其中log_archive_dest是旧的单一目的地参数,log_archive_dest_n支持配置多个目的地,最多可以配置31个。在实际运维中,建议至少配置两个归档目的地。原因很实际:如果归档日志只写一份,一旦磁盘坏了归档日志也就全没了,那么数据库依然无法恢复到最新状态。多写一份就多一层保障,而且Oracle对多个归档目的地的处理是同步写入的,不会因为多一个目的地而影响性能太多。
ALTER SYSTEM SET log_archive_dest_1='LOCATION=/u01/app/oracle/archive MANDATORY'; ALTER SYSTEM SET log_archive_dest_2='LOCATION=/u02/app/oracle/archive2';上面第一行的MANDATORY关键字表示这个目的地是强制的,只有归档日志成功写入该目的地,日志切换才能完成。如果不加MANDATORY,默认是OPTIONAL,归档失败时数据库不会立即挂起,而是在后台不断重试。
归档格式的参数是log_archive_format,如果是Oracle 11g及以上版本,建议使用以下格式:
ALTER SYSTEM SET log_archive_format='arch_%t_%s_%r.arc' SCOPE=SPFILE;这个格式中各占位符的含义是:%t表示线程编号(RAC环境下每个实例对应一个线程号),%s表示日志序列号,%r表示resetlogs的ID。有了%r这个标识,即使数据库执行过不完全恢复并重置了日志序列号,归档文件名也不会冲突。
这个参数必须设置到SPFILE中,因为它要在实例启动时读取,如果只在当前会话中生效,下次重启又恢复原样。修改后需要重启实例才能生效。
3.4 快速恢复区与自动归档的选择
在Oracle 11g之后,很多环境会使用快速恢复区来管理备份和归档文件。如果配置了db_recovery_file_dest,归档日志默认会写到快速恢复区中,而不需要显式配置log_archive_dest_n指向某个文件系统目录。
ALTER SYSTEM SET db_recovery_file_dest='/u03/fast_recovery_area'; ALTER SYSTEM SET db_recovery_file_dest_size=100G;使用快速恢复区的优势在于统一管理,备份和归档共享同一份空间,Oracle自动管理空间回收。但它的风险也很明显:如果快速恢复区的空间被占满,数据库会立即挂起,因为归档日志写不进去了。很多DBA在快速恢复区满的时候被搞到焦头烂额,原因就在这。
所以我个人的建议是,对于生产系统,不要把归档和备份放在同一个快速恢复区,直接用文件系统目录指定归档路径,再配合一个独立的备份目录。这样即使备份把磁盘写满了,归档日志依然有独立的写空间,至少不会因为备份而影响数据库可用性。
自动归档的控制参数是log_archive_start,但要注意,这个参数在Oracle 10g之后已经被废弃了,数据库默认就是自动归档。如果你看到一些老教程让你设置log_archive_start=true,可以直接忽略,这个参数在11g和19c中执行会直接报错或提示已被废弃。
3.5 RAC环境开启归档模式的特殊说明
如果你管理的是RAC集群环境,开启归档模式的思路一样,但操作细节有区别。RAC环境中,数据库同样需要先关闭所有实例,然后在其中一个实例以MOUNT模式启动,执行alter database archivelog,最后同步启动所有实例。
srvctl stop database -d orcl srvctl start instance -d orcl -i orcl1 -o mount sqlplus / as sysdba SQL> alter database archivelog; SQL> alter database open;之后用srvctl start database -d orcl启动所有实例,并通过srvctl config database -d orcl -a确认归档配置。
这里有一个RAC特别容易踩的坑:每个实例都需要配置独立的log_archive_dest_n。比如两个实例的RAC环境,LOG_ARCHIVE_DEST_1和LOG_ARCHIVE_DEST_2可能会配置成指向共享存储上的同一目录,这种情况没有问题;但如果每个实例都有独立的归档目录,必须保证每个实例都能正确写入,否则某一实例的日志切换会hang住。在多实例环境中,建议把归档目录配置在共享存储上,避免某个实例访问不到其他实例的归档目录。
4. 开启归档之后,日常运维必须掌握的几个动作
4.1 手动切换日志,验证归档是否正常
归档模式开启之后,建议手动触发一次日志切换,然后马上查看归档日志是否生成。这个动作相当于验证整个归档链路的完整性和正确性,别等到真正需要恢复时才发现归档日志根本写不进去。
ALTER SYSTEM SWITCH LOGFILE;执行这条命令会强制Oracle切换到下一个redo log日志组。切换之后,原来的日志组会进入ACTIVE状态,随后被归档进程复制到归档目录,最终变为INACTIVE状态。
然后查看归档日志是否生成:
SELECT sequence#, name, blocks, block_size, creator FROM v$archived_log ORDER BY sequence# DESC FETCH FIRST 3 ROWS ONLY;或者直接到文件系统查看:
ls -lht /u01/app/oracle/archive | head -5如果看到最新的归档文件已经生成,说明归档链路正常。如果v$archived_log里查不到记录,或者文件系统里没有新的归档文件,就需要检查归档进程状态和告警日志,这属于后面会讲到的问题排查内容。
4.2 归档日志会一直膨胀,必须建立清理机制
归档目录不像数据库数据文件那样有固定大小,它会随着业务的写入量持续增长。如果业务每天产生50GB的redo log,归档日志就会以每天50GB的速度增长,不清理的话,再大的磁盘也会被撑爆。
清理归档日志最稳妥的方式,是基于全量备份来清理。核心原则是:归档日志的保留时间至少要覆盖到最近一次全量备份的时间点。如果每天凌晨2点做全量备份,那么在备份完成之前,不要删除任何归档日志;备份完成后,可以删除这个备份时间点之前的归档日志。
一种最简单的清理思路是,保留最近7天的归档日志,更早的直接删除。这个策略适合业务增长相对平稳、每天数据量变化不大的系统。但如果你想做更精细的管理,建议通过RMAN来清理:
RMAN> DELETE ARCHIVELOG ALL COMPLETED BEFORE 'SYSDATE-7';这条命令会删除7天前且已被备份过的归档日志(准确来说,是已经被RMAN标记为备份过的归档日志)。使用RMAN的好处是,它会自动检查归档日志是否已被备份,未被备份的归档日志即使超过7天也不会删除,这样能避免误删需要用于恢复的日志。
需要注意,绝对不要在归档目录里直接rm -rf删除归档文件,这样做会让控制文件中的归档信息与文件系统不一致,后续RMAN备份时会报错,甚至影响恢复操作。正确做法永远是使用RMAN或者先查询v$archived_log确认后再处理。
4.3 监控归档目录空间,设置合理告警阈值
归档目录满了是生产中比较常见的事故场景。一旦归档目录满了,ARCH进程无法写入新的归档日志,Oracle会挂起所有事务——因为在强制归档模式下,日志切换需要等待归档完成,如果归档写不进去,redo log文件也无法覆盖,整个数据库都无法写入。
我见过不少案例,就是因为没人盯归档目录,结果磁盘悄悄写满,业务突然就停了。所以归档目录的空间监控一定要提前做好。
最原始的监控方式,是每天写脚本检查归档目录的使用率:
#!/bin/bash # 检查归档目录使用率,超过90%告警 THRESHOLD=90 USAGE=$(df -h /u01/app/oracle/archive | awk 'NR==2 {print $5}' | tr -d '%') if [ "$USAGE" -gt "$THRESHOLD" ]; then echo "Archive dir usage $USAGE% exceeds threshold $THRESHOLD%" | mail -s "Oracle Archive Alert" dba@example.com fi这个脚本可以作为cron定时任务,每小时执行一次。当然,如果有Zabbix、Prometheus这类监控系统,直接在监控面板上添加上这个目录的磁盘空间监控,设置告警阈值,效果更好。告警阈值我建议分两级:80%做预警,90%做紧急告警。这样你既能在问题发生前从容处理,也不至于被频繁的告警信息骚扰。
4.4 归档模式下的备份策略调整
归档模式开启后,数据库的备份策略需要同步调整,否则光开了归档但没有相应的备份配合,等于白白增加了额外IO和存储开销,却享受不到归档带来的恢复能力。
正确做法是:全量备份加归档日志备份组合使用。完整备份的周期可以是每周一次或每天一次,取决于恢复时间目标(Recovery Time Objective,RTO)和数据恢复点目标(Recovery Point Objective,RPO)。归档日志则持续备份,确保每一次日志切换后产生的归档日志都被纳入备份体系。
RMAN备份完整数据库的经典命令:
rman target / RMAN> BACKUP DATABASE PLUS ARCHIVELOG DELETE INPUT;这里的DELETE INPUT表示备份归档日志之后直接删除原归档文件,这样既完成了备份,也顺带清理了归档目录空间,一举两得。这种备份方式执行一次,全量备份和归档日志备份都在里面,恢复时逻辑清晰。
值得提醒的是,不要只做全量备份而忽略归档日志备份,也不要光归档不清理。归档日志本身只是中间产物,核心目标是保证“全量备份+归档日志”可以恢复数据库到任意时间点,然后在此基础上回收无用的归档文件。这个思路想明白了,后续运维都会变得很清晰。
5. 开启归档模式过程中的常见故障与排查思路
5.1 ORA-00265: 要求实例恢复,无法归档
这是从非归档模式切换到归档模式时容易遇到的一个错误。报错信息类似:
ORA-00265: instance recovery required, cannot set ARCHIVELOG mode出现这个错误的原因,通常是因为数据库上一次是异常关闭的(比如使用了shutdown abort),实例在Mount状态下检测到有未完成的事务恢复。Oracle需要在归档模式修改之前,先完成实例恢复,确保数据文件的SCN一致性。
排查思路很简单,先让数据库完成恢复。打开数据库执行一次正常关闭,再用正常流程启动到Mount状态,重新执行alter database archivelog。如果数据文件损坏严重无法打开,那就不是切换归档模式的问题了,需要先处理恢复问题。
这个错误提醒我们,切换归档模式前一定要保证数据库是正常关闭的。引用我之前遇到的一次现场:某天新来的同事在数据库异常重启后,马上就执行启动Mount并尝试开启归档,结果就报了这个错误。后面正常alter database open完成恢复后再关库,重新来一遍,问题就没了。
5.2 ORA-16038: 日志无法归档,数据库直接hang住
ORA-16038: log 1 sequence# 123 at ... cannot be archived这条错误,基本可以确认归档目的地出问题了。最常见的原因是磁盘空间不足,归档进程无法写入新文件。
这里有一个细节:如果是使用了快速恢复区并且快速恢复区空间满了,Oracle会在告警日志中记录ORA-19809: error occurred in the Recovery Area和ORA-19815: Warning: db_recovery_file_dest_size of ... bytes is 100% used等报错信息,出现这类报错时数据库可能会直接挂起拒绝写入,需要立即处理。
处理步骤一般是:优先确认归档目的地是否可写、空间是否充足;如果空间不够,清理过期归档日志;如果是路径权限问题,检查目录权限和数据库进程用户是否一致;处理完成之后,通过alter system archive log start或者手动触发日志切换恢复正常。
这里特别提醒,不要直接强制重启数据库来“恢复”,因为如果数据库已经因为归档写不了而挂起,重启后还会是同样的问题。必须先解决归档写不进去的原因,再恢复数据库的正常运行。
5.3 归档日志不生成或生成延迟特别大
有时候切换到归档模式后,发现日志切换已经发生,但归档目录中迟迟看不到新的归档文件。这种情况通常不是模式没开起来,而是归档进程出现问题。
排查顺序可以先看归档进程状态:
SELECT process, status FROM v$archive_processes;正常状态下应看到多个ARCH进程状态为ACTIVE。如果进程状态异常,可以尝试重启实例,或手动触发一次日志切换看看能否恢复。
再看一下告警日志,查看归档相关的错误信息:
tail -100 $ORACLE_BASE/diag/rdbms/orcl/orcl/trace/alert_orcl.log | grep -i archive告警日志中会记录归档进程的详细错误,比如目的地不可达、文件权限问题、IO错误等。大部分情况下,根据告警日志中的ORA-xxxxx错误码,就能准确定位问题所在。
另外一个常见的原因是,归档目的地配置在了本地文件系统,但数据库运行用户对目录没有写权限。比如归档目录属主是root,而Oracle进程用户是oracle,这种情况下归档进程自然会报权限错误。设置归档目录时,建议在创建目录后立刻执行chown oracle:oinstall调整属主,避免这种问题。
5.4 日志切换频繁导致归档进程跟不上
如果业务写入量特别大,或者redo log日志组文件太小,会导致日志切换非常频繁,归档进程来不及处理,归档日志生成延迟越来越大,甚至影响业务。
这种情况通常可以通过调整redo log的大小来缓解。一个合适的redo log大小,应该能让日志切换频率保持在15到30分钟一次比较理想。如果你的数据库每几分钟就切换一次日志,说明日志文件太小了,需要添加更大的日志组。
ALTER DATABASE ADD LOGFILE GROUP 4 '/u01/app/oracle/oradata/orcl/redo04.log' SIZE 2G;添加新日志组之后,可以手动切换几次日志,让旧的日志组慢慢退役,最后把新日志组设为当前使用。
同时,也可以适当增加归档进程数量:
ALTER SYSTEM SET log_archive_max_processes=4;归档进程数默认为2或4,在日志切换频繁的环境中可以调大到8,但不建议无脑调大,需要结合系统CPU和IO负载情况判断。我的实际经验是,大部分业务量级的数据库,归档进程保持默认值就够了,真正的问题通常在redo log太小球才会翻转。
5.5 常见问题排查速查表
整理一个速查表,方便遇到问题时快速定位:
| 故障现象 | 常见原因 | 最先排查的地方 |
|---|---|---|
| 切换归档模式报ORA-00265 | 实例上次未正常关闭,需要实例恢复 | 检查数据库是否正常关闭,完成后重试 |
| 日志切换后数据库挂起 | 归档目录空间不足或路径不可写 | 检查磁盘空间、目录权限、归档目的地状态 |
| 归档目录文件不增长 | 归档进程异常或目的地配置错误 | 查询v$archive_processes和告警日志 |
| ORA-19809/19815快速恢复区满 | 快速恢复区空间耗尽 | 清理快速恢复区内的过期备份和归档日志 |
| 日志切换频繁影响性能 | redo log日志组太小 | 添加更大的日志组并切换 |
| 归档进程状态异常 | 实例异常或资源不足 | 检查告警日志、系统负载,必要时重启实例 |
6. 归档模式开启之后,再做一次全量备份
很多人在开启归档模式后就认为工作完成了,但我要强调一个细节:开启归档模式之后,请务必立刻做一次全量备份。
为什么?因为归档日志的恢复能力必须和它之后的全量备份配合使用。你把数据库恢复到某个时间点的时候,恢复路径是:最近一次全量备份 + 这之后到目标时间点的所有归档日志。如果你在开启归档模式之前做的全量备份,这个备份点已经早于归档日志的起始点,恢复时可能出现备份与归档日志之间断档的情况,无法完整恢复。
用RMAN执行全量备份:
rman target / RMAN> BACKUP DATABASE PLUS ARCHIVELOG DELETE INPUT;注意这里使用的是PLUS ARCHIVELOG而不是简单地BACKUP DATABASE。加上PLUS ARCHIVELOG之后,RMAN会自动在备份数据库之前先备份当前的归档日志,并在备份完成后删除已备份的归档日志。这样整个备份过程中产生的归档日志也被完整包含了,恢复的链条不断。
这条命令执行完,你的备份策略才算是真正建立在归档模式之上了。之后配合每日归档日志备份和定期全量备份,数据库的恢复能力才算完整。
7. 归档模式运维中容易被忽视的几个细节
最后分享几个实操中容易被忽视的细节,都是踩过坑之后才总结出来的。
第一,定期检查归档目的地状态,不要只在出问题时才想到看。我建议在每周的数据库巡检清单中加入一条:查询v$archive_dest_status,确认所有归档目的地状态为VALID。如果是ERROR状态,尽早发现和提早处理,要比等到业务停了再抢修从容得多。
第二,归档日志的保留时长,要结合业务恢复需求和存储成本来做平衡。有的银行系统要求能恢复到任意时间点,那归档日志就要长期保留;有的内部系统只需要恢复到前一周,那保留两周就够了。这个策略明确之后,再配合自动化清理工具执行,不要等到磁盘满了才手动清。
第三,部署监控脚本时,不要只监控归档目录所在的文件系统空间。如果你用的是快速恢复区,需要额外监控db_recovery_file_dest_size参数设置的容量是否足够,同时关注V$RECOVERY_FILE_DEST视图中的空间使用情况,因为这里的空间使用率是Oracle自己管理的。
第四,如果数据库同时承担OLTP业务和批量任务,日志切换的频率在不同时段差异会非常大。批量任务跑批的时候,日志切换可能非常频繁,归档日志的生成速度也会很快。可以在批量任务高峰期前手动执行一次日志切换,让归档进程提前开始工作,避免高峰期日志切换和归档积压同时发生。
根据我个人多年的运维体会,归档模式不是一个配置完就可以彻底忘记的功能,它需要日常的关注与维护。但只要把查看状态、定期备份、空间监控和故障排查这几个动作都落实到日常运维中,归档模式就能真正成为数据库数据安全的坚实防线。希望这篇文章能帮你把归档模式的查看与开启流程一次走顺,不再踩我当年踩过的坑。