zoukankan      html  css  js  c++  java
  • Oracle 实例恢复

    -=======================

    -- Oracle 实例恢复

    --=======================

     

    一、Oracle实例失败

        Oracle实例失败多为实例非一致性关闭所致,通常称为崩溃(crash)。实例失败的结果等同于shutdown abort。

        实例失败的原因

            电源负载故障

            硬件故障

            后台进程失败

            异常关闭数据库

        实例失败后的状况

            数据库可能丢失已提交的事务以及存储了未提交的事务,导致数据库出现不一致的情况

        解决方案

            使用startup 重新启动实例。实例实现自动恢复,根据联机日志文件前滚提交的事务,回滚未提交的事务

            查看告警日志、跟踪日志等找出出现故障的原因

           

        更多常见的故障请参考:Oracle 常见故障及日常规划

       

    二、检查点

        检查点在体系结构中已经讨论,实例的恢复与检查点息息相关,因此再次讨论检查点进程

       

        1.什么是检查点

            是一个数据库事件,用于减少崩溃恢复时间,检查点位置决定了实例恢复的起始位置

            由后台进程触发,触发时ckpt进程通知dbwn进程将数据缓冲区的脏数据写入到数据文件

            ckpt进程同时负责更新数据文件的头部信息及控制文件上的检查点信息

           

        2.检查点的触发条件

                在日志切换的时候(自动切换或手动切换)

                数据库用immediate ,transaction ,normal选项shutdown数据库的时候

                用户手动触发(alter system checkpoint)

                alter tablespace tablespace_name begin | end bakcup

                alter tablespace tablespace_name offline

                alter database datafile '<dir>' offline

                alter tablespace | datafile read only

               

        3.检测点队列

            是一个脏数据库链表

            检查点队列中的每一条修改过的记录包一个唯一的数据块标识符(日志文件号,块编号,偏移量)

            最早队列将被优先写入到数据文件(而不论期间是否被多次修改)

            最早队列被写入完成后将从队列中清除

           

        4.检查点的分类

            完全检查点

                在Oracle 8i 以前,当检查点发生时,Oracle将脏缓冲列表上的数据全部写入到数据文件,称为完全检查点,又称常规检查点

                特定的触发条件

                    alter system switch logfile

                    shutdown normal,immediate,transactional

                    alter system checkpoint

            增量检查点(fast-start checkpoint)

                主要是引入了检查点队列机制,每s,ckpt将检查点队列中最老的RBA更新到控制文件,RBA(重做日志块地址)同时将作为实例恢复的起点

                增量检查点则细分了完全检查点,使得数据可以周期性按最老的数据块写入到数据文件

                每一个脏块会被移到检查点队列里面去,按照LRBA(Low RBA第一次对此块修改对应的redo block address)来排列

                最早写入检查点队列数据块的low rba值是最小的,即便该队列中的最小队列被修改多次,但修改后它在检查点队列里的顺序不会改变

                当执行增量检查点时,DBWn从检查点队列按照LRBA的顺序来保证先修改的数据可以按顺序优先被写出来实现检查点的增进

                此时ckpt进程使用轻量级的控制文件更新协议,将当前最低的RBA写入控制文件

                ckpt在进行轻量级更新时,并不会改写控制文件中数据文件的检查点信息及数据文件头信息

                仅仅是记录控制文件检查点SCN并根据增量检查点写出增进RBA信息

                通过将完全检查点转变为增量检查点将大大缩短实例的恢复时间

                注:更新数据文件头部及控制文件滞后于检查点事件的发生

                增量检查点的触发   

                    满足初始话文件log_checkpoint_interval、log_checkpoint_timeout、

                                  fast_start_io_target、fast_start_mttr_target的设置的值

                    最小的日志文件的大小

                    Buffer Cacha中脏块的数量

       

            部分检查点

                表空间的脏数据写入到磁盘

                由alter tablespace tablespace_name offline 触发

       

        5.完全检查点与增量检查点的差异

            完全检查点会将检查点的信息同时写入到控制文件及数据文件

            增量检查点则只将RBA写入到控制文件

       

        6.查看检查点的信息,设置LOG_CHECKPOINTS_TO_ALERT参数为true

            ALTER SYSTEM SET LOG_CHECKPOINTS_TO_ALERT = TRUE ;

       

        --查看log_checkpoints_to_alert参数

            SQL> SHOW PARAMETER log_checkpoints_to_alert

     

            NAME                                 TYPE        VALUE

            ------------------------------------ ----------- ------------------------------

            log_checkpoints_to_alert             boolean     FALSE

     

        --设置log_checkpoints_to_alert参数

            SQL> ALTER SYSTEM set log_checkpoints_to_alert = TRUE;

     

            System altered.    

           

        --清空告警日志文件的内容

            SQL> ho cat /dev/null > /u01/app/oracle/admin/orcl/bdump/alert_orcl.log

       

        --查看数据文件头部信息中控制文件的信息为3037172

        SQL> SELECT file#,status,tablespace_name ,

          2  dbms_flashback.get_system_change_number cur_scn,

          3  to_char(resetlogs_time,'yyyy-mm-dd hh24:mi:ss') rst_dt,

          4  resetlogs_change# rst_scn,

          5  to_char(checkpoint_time,'yyyy-mm-dd hh24:mi:ss') ckpt_dt,

          6  checkpoint_change# ckpt_scn,checkpoint_count ckpt_cnt

          7  FROM v$datafile_header;

     

             FILE# STATUS  TABLESPACE_NAME    CUR_SCN RST_DT                 RST_SCN CKPT_DT               CKPT_SCN   CKPT_CNT

        ---------- ------- --------------- ---------- ------------------- ---------- ------------------- ---------- ----------

                 1 ONLINE  SYSTEM             3037641 2010-07-20 11:59:23    2837290 2010-07-25 19:05:30    3037172        531

                 2 ONLINE  UNDOTBS1           3037641 2010-07-20 11:59:23    2837290 2010-07-25 19:05:30    3037172        493

                 3 ONLINE  SYSAUX             3037641 2010-07-20 11:59:23    2837290 2010-07-25 19:05:30    3037172        532

                 4 ONLINE  USERS              3037641 2010-07-20 11:59:23    2837290 2010-07-25 19:05:30    3037172        534

                 5 ONLINE  EXAMPLE            3037641 2010-07-20 11:59:23    2837290 2010-07-25 19:05:30    3037172        489

                 6 ONLINE  TBS1               3037641 2010-07-20 11:59:23    2837290 2010-07-25 19:05:30    3037172        412

                 7 ONLINE  TBS1               3037641 2010-07-20 11:59:23    2837290 2010-07-25 19:05:30    3037172        407

        7 rows selected.

     

        SQL> save /u01/app/oracle/oradata/query_1.sql;

        Created file /u01/app/oracle/oradata/query_1.sql

       

            SQL> ALTER SYSTEM SWITCH LOGFILE;  --切换日志

     

            System altered.

                     

            SQL> ho cat /u01/app/oracle/admin/orcl/bdump/alert_orcl.log | more  --查看告警日志

            Sun Jul 25 19:14:29 2010

            Beginning log switch checkpoint up to RBA [0xd.2.10], SCN: 3037657

            Thread 1 advanced to log sequence 13

              Current log# 3 seq# 13 mem# 0: /u01/app/oracle/oradata/orcl/redo3a.rdo

              Current log# 3 seq# 13 mem# 1: /u01/app/oracle/oradata/orcl/redo3b.rdo

     

        SQL> @/u01/app/oracle/oradata/query_1.sql;   --数据文件头部滞后分钟后与告警日志记录的SCN相同

     

             FILE# STATUS  TABLESPACE_NAME    CUR_SCN RST_DT                 RST_SCN CKPT_DT               CKPT_SCN   CKPT_CNT

        ---------- ------- --------------- ---------- ------------------- ---------- ------------------- ---------- ----------

                 1 ONLINE  SYSTEM             3037803 2010-07-20 11:59:23    2837290 2010-07-25 19:14:29    3037657        532

                 2 ONLINE  UNDOTBS1           3037803 2010-07-20 11:59:23    2837290 2010-07-25 19:14:29    3037657        494

                 3 ONLINE  SYSAUX             3037803 2010-07-20 11:59:23    2837290 2010-07-25 19:14:29    3037657        533

                 4 ONLINE  USERS              3037803 2010-07-20 11:59:23    2837290 2010-07-25 19:14:29    3037657        535

                 5 ONLINE  EXAMPLE            3037803 2010-07-20 11:59:23    2837290 2010-07-25 19:14:29    3037657        490

                 6 ONLINE  TBS1               3037803 2010-07-20 11:59:23    2837290 2010-07-25 19:14:29    3037657        413

                 7 ONLINE  TBS1               3037803 2010-07-20 11:59:23    2837290 2010-07-25 19:14:29    3037657        408

     

        SQL> SELECT TO_CHAR(sysdate,'yyyy-mm-dd hh24:mi:ss') FROM dual;  --时间滞后分钟 19:19:59 - 19:14:29

     

        TO_CHAR(SYSDATE,'YY'

        -------------------

        2010-07-25 19:19:59

     

            SQL> ALTER SYSTEM CHECKPOINT;  --产生检查点

     

            System altered.

     

            SQL> ho cat /u01/app/oracle/admin/orcl/bdump/alert_orcl.log | more  --查看告警日志中的SCN: 3037881

            Sun Jul 25 19:14:29 2010

            Beginning log switch checkpoint up to RBA [0xd.2.10], SCN: 3037657

            Thread 1 advanced to log sequence 13

              Current log# 3 seq# 13 mem# 0: /u01/app/oracle/oradata/orcl/redo3a.rdo

              Current log# 3 seq# 13 mem# 1: /u01/app/oracle/oradata/orcl/redo3b.rdo

            Sun Jul 25 19:19:34 2010

            Completed checkpoint up to RBA [0xd.2.10], SCN: 3037657

            Sun Jul 25 19:21:55 2010

            Beginning global checkpoint up to RBA [0xd.116.10], SCN: 3037881

            Completed checkpoint up to RBA [0xd.116.10], SCN: 3037881

     

        SQL> @/u01/app/oracle/oradata/query_1.sql;  --数据文件头部同步与告警日志记录的SCN相同,为3037881

     

             FILE# STATUS  TABLESPACE_NAME    CUR_SCN RST_DT                 RST_SCN CKPT_DT               CKPT_SCN   CKPT_CNT

        ---------- ------- --------------- ---------- ------------------- ---------- ------------------- ---------- ----------

                 1 ONLINE  SYSTEM             3037890 2010-07-20 11:59:23    2837290 2010-07-25 19:21:55    3037881        533

                 2 ONLINE  UNDOTBS1           3037890 2010-07-20 11:59:23    2837290 2010-07-25 19:21:55    3037881        495

                 3 ONLINE  SYSAUX             3037890 2010-07-20 11:59:23    2837290 2010-07-25 19:21:55    3037881        534

                 4 ONLINE  USERS              3037890 2010-07-20 11:59:23    2837290 2010-07-25 19:21:55    3037881        536

                 5 ONLINE  EXAMPLE            3037890 2010-07-20 11:59:23    2837290 2010-07-25 19:21:55    3037881        491

                 6 ONLINE  TBS1               3037890 2010-07-20 11:59:23    2837290 2010-07-25 19:21:55    3037881        414

                 7 ONLINE  TBS1               3037890 2010-07-20 11:59:23    2837290 2010-07-25 19:21:55    3037881        409

     

        --查看完全检查点           

            SQL> SELECT addr,indx ,rtckp_scn,

              2    rtckp_tim,

              3    rtckp_rba_seq,rtckp_rba_bno

              4  FROM x$kccrt;

     

            ADDR           INDX RTCKP_SCN        RTCKP_TIM            RTCKP_RBA_SEQ RTCKP_RBA_BNO

            -------- ---------- ---------------- -------------------- ------------- -------------

            B7D59C10          0 3037881          07/25/2010 19:21:55             13           278      

     

            SQL> show parameter log_check  --查看log_checkpoint_timeout的值

     

            NAME                                 TYPE        VALUE

            ------------------------------------ ----------- ------------------------------

            log_checkpoint_interval              integer     0

            log_checkpoint_timeout               integer     1800

            log_checkpoints_to_alert             boolean     TRUE

           

            ho cat  /u01/app/oracle/admin/orcl/bdump/alert_orcl.log --告警日志文件中Incremental checkpoint

            ----------------------------------------------------------------------------------     

            Sun Jul 25 19:22:46 2010

            Incremental checkpoint up to RBA [0xd.119.0], current log tail at RBA [0xd.119.0]

            Sun Jul 25 19:52:51 2010

            Incremental checkpoint up to RBA [0xd.37a.0], current log tail at RBA [0xd.420.0]

     

            ---------------------------------------------------------------------------------

            SQL> select CPDRT,CPLRBA_SEQ||'.'||CPLRBA_BNO||'.'||CPLRBA_BOF "Low RBA",

              2  CPODR_SEQ||'.'||CPODR_BNO||'.'||CPODR_BOF "On disk RBA",CPODS,CPODT,CPHBT

              3  from x$kcccp where indx = 0;  --获得控制文件中增量检查点的信息

     

                 CPDRT Low RBA             On disk RBA   CPODS   CPODT                  CPHBT

            ---------- ------------------- ------------- ------- --------------------   --------

                   97 13.5574.0            13.6391.0     3041226 07/25/2010 22:16:37    725323317

                  

                --CPDRT列是检查点队列中的脏块数目.

                --CPODS列是on disk rba的scn

                --CPODT列是on disk rba的时间戳

                --CPHBT列是心跳

     

        7.更详细的检查点介绍:针对checkpoint的概要分析

                              晶晶实验九之详细论述增量检查点篇

       

    三、实例恢复

        1.当打开非一致性关闭或shutdown abort数据库时,将导致实例恢复

        2.实例恢复过程为自动

        3.使用联机重做日志文件中的信息来同步数据文件

        4.涉及到两类不同的操作

            前滚:数据文件被还原到实例失败之前的状态

            回滚:已修改但未提交的数据将被撤销到修改之前的状态

           

    四、实例恢复的过程

    下面的图片来自Oracle官方教材

     

     

     

        1.首先Oracle会比较控制文件中检查点与数据文件头部信息,发现数据不一致

        2.从最后检查点之后到日志文件尾部将被重新应用到数据文件,同时产生undo信息(回滚),此阶段也称为cache recovery

        3.数据文件中包含已提交或未提交的数据,尽管存在未提交的数据,此时数据库已经被打开,允许用户连接

        4.未提交的事务将被回滚

        5.数据文件中仅包含已提交的数据

       

    五、调整实例恢复

        1.为参数文件中对恢复过程有影响的联机日志记录数量和数据块设置合适的大小

        2.调整联机日志文件的大小来影响检查点发生的频率

        3.使用SQL 命令发生检查点事件

        4.使用Fast-start fault recovery

        5.几个恢复相关的参数

            LOG_CHECKPOINT_TIMEOUT        -->两次checkpoint之间间隔的时间(单位是秒) ,该参数现已很少使用

            LOG_CHECKPOINT_INTERVAL       -->两次checkpoint之间redo block 数据块的个数(不是db_block),

                                                --   redo block size = os block size 该参数现已很少使用

            FAST_START_MTTR_TARGET        -->指定多长时间完成实例恢复(单位是秒) (后面演示中重点讨论)

            RECOVERY_PARALLELISM          -->指定前滚时的并发度

            FAST_START_PARALLEL_ROLLBACK  -->回滚阶段时预先UNDO需要使用的块,然后增加回滚并发度

                                                -- 2路CPU建议设置为LO,四路CPU建议设置为HI,否则缺省置为false

            FAST_START_IO_TARGET          -->数据库宕机所要做的恢复所需的IO的数量,10g之后很少使用

     

    六、实例恢复相关的视图     

        V$INSTACE_RECOVERY                -->查看fast_start_mttr_target设置以及系统MTTR相关信息

        V$FAST_START_SERVERS              -->事务回滚时相关并发信息

        V$FAST_START_TRANSACTION          -->正在恢复的事务的相关信息

        完全检查点

            select * from X$KCCRT where indx=0;

               

        增量检查点

            SQL> select * from X$KCCCP where indx=0;

     

    七、实例恢复演示       

        --删除告警日志

            SQL> ho rm -f /u01/app/oracle/admin/orcl/bdump/alert_orcl.log          

     

            SQL> SELECT * FROM scott.emp WHERE ename = 'SCOTT';

     

                 EMPNO ENAME                          JOB              MGR HIREDATE         SAL     DEPTNO

            ---------- ------------------------------ --------- ---------- --------- ---------- ----------

                  7788 SCOTT                          ANALYST         7566 19-APR-87       7100         20

                 

        --更新SCOTT的薪水且提交事务

            SQL> UPDATE scott.emp SET sal = sal / 2 WHERE ename = 'SCOTT';

     

            1 row updated.

     

            SQL> COMMIT;

     

            Commit complete.

       

        --插入两条新记录且不提交事务

            SQL> INSERT INTO scott.emp(empno,ename,job) SELECT '2001','Mark','Develpoer' FROM dual;

     

            1 row created.

     

            SQL> INSERT INTO scott.emp(empno,ename,job) SELECT '2002','Mary','Designer' FROM dual;

     

            1 row created.

     

            SQL> SELECT * FROM scott.emp WHERE empno IN (2001,2002);

     

                 EMPNO ENAME                          JOB              MGR HIREDATE         SAL     DEPTNO

            ---------- ------------------------------ --------- ---------- --------- ---------- ----------

                  2001 Mark                           Develpoer

                  2002 Mary                           Designer

       

        --强制关闭实例并重启实例,则实例将自动回滚

            SQL> SHUTDOWN ABORT;

            ORACLE instance shut down.

            SQL> STARTUP

            ORACLE instance started.

     

            Total System Global Area  251658240 bytes

            Fixed Size                  1218796 bytes

            Variable Size              88082196 bytes

            Database Buffers          159383552 bytes

            Redo Buffers                2973696 bytes

            Database mounted.

            Database opened.

       

        --从告警日志中获得回滚的相关信息

        SQL> ho ls /u01/app/oracle/admin/orcl/bdump

        alert_orcl.log  orcl_arc0_4016.trc  orcl_arc1_4018.trc  orcl_lgwr_3995.trc

     

        SQL> ho cat /u01/app/oracle/admin/orcl/bdump/alert_orcl.log

     

            ----------------------------------------------------------------

     

            ALTER DATABASE   MOUNT

            Thu Jul 22 12:44:40 2010

            Setting recovery target incarnation to 10

            Thu Jul 22 12:44:40 2010

            Successful mount of redo thread 1, with mount id 1252833332

            Thu Jul 22 12:44:40 2010

            Database mounted in Exclusive Mode

            Completed: ALTER DATABASE   MOUNT

            Thu Jul 22 12:44:41 2010

            ALTER DATABASE OPEN

            Thu Jul 22 12:44:41 2010

            Beginning crash recovery of 1 threads  --开始crash recovery

            Thu Jul 22 12:44:41 2010

            Started redo scan                      --扫描redo

            Thu Jul 22 12:44:42 2010

            Completed redo scan

             142 redo blocks read, 58 data blocks need recovery

            Thu Jul 22 12:44:42 2010

            Started redo application at

             Thread 1: logseq 4, block 3156

            Thu Jul 22 12:44:42 2010

            Recovery of Online Redo Log: Thread 1 Group 3 Seq 4 Reading mem 0

              Mem# 0 errs 0: /u01/app/oracle/oradata/orcl/redo3a.rdo

              Mem# 1 errs 0: /u01/app/oracle/oradata/orcl/redo3b.rdo

            Thu Jul 22 12:44:42 2010

            Completed redo application

            Thu Jul 22 12:44:43 2010

            Completed crash recovery at         --完成恢复

             Thread 1: logseq 4, block 3298, scn 2921577

             58 data blocks read, 58 data blocks written, 142 redo blocks read

            Thu Jul 22 12:44:43 2010

            LGWR: STARTING ARCH PROCESSES

            ARC0: Archival started

            ARC1: Archival started

            LGWR: STARTING ARCH PROCESSES COMPLETE

            ARC1 started with pid=17, OS id=4018

            ARC0 started with pid=16, OS id=4016

            Thu Jul 22 12:44:45 2010

            Thread 1 advanced to log sequence 5

            Thread 1 opened at log sequence 5

              Current log# 1 seq# 5 mem# 0: /u01/app/oracle/oradata/orcl/redo1a.rdo

              Current log# 1 seq# 5 mem# 1: /u01/app/oracle/oradata/orcl/redo1b.rdo

            Successful open of redo thread 1

            Thu Jul 22 12:44:45 2010

            MTTR advisory is disabled because FAST_START_MTTR_TARGET is not set --FAST_START_MTTR_TARGET未设置

     

            --------------------------------------------------------------------------------------------------

            --对scott用户已提交,故恢复之后为已提交的状态

            SQL> SELECT * FROM scott.emp WHERE ename = 'SCOTT';

     

                 EMPNO ENAME                          JOB              MGR HIREDATE         SAL     DEPTNO

            ---------- ------------------------------ --------- ---------- --------- ---------- ----------

                  7788 SCOTT                          ANALYST         7566 19-APR-87       3550         20

     

            --新增加的两条记录未提交,实例恢复之后被回滚     

            SQL> SELECT * FROM scott.emp WHERE empno IN (2001,2002);

     

            no rows selected

     

    八、设置FAST_START_MTTR_TARGET参数

    /*

        FAST_START_MTTR_TARGET参数的作用就是减少cache recovery的恢复时间。

        当设定了FAST_START_MTTR_TARGET值后,数据库管理增量检查点写入尝试达到设定的目标恢复时间

        如果设定的值合理,则整个恢复过程将接近所设定的时间

        注:当使用FAST_START_MTTR_TARGET参数时,应当关闭FAST_START_IO_TARGET, LOG_CHECKPOINT_INTERVAL,

            LOG_CHECKPOINT_TIMEOUT 参数。如果设定这些参数将会妨碍cache recovery满足指定的FAST_START_MTTR_TARGET值

        应当为FAST_START_MTTR_TARGET设置合理的时间值

            缺省值为0,表示关闭检查点自动调整功能

            最大值为3600,当设定值大于3600,将被自动取整为3600

            最小值为1,当设定为时1,事实上不切合实际因此,恢复时间也不能达到设定的目标值 */

           

        更多关于FAST_START_MTTR_TARGET参数的优化:Instance Recovery Performance Tuning: Fast-Start Fault Recovery

              

        --将fast_start_mttr_target的值置为0

            SQL> alter system set fast_start_mttr_target = 0;

     

            System altered.

     

            SQL> CREATE TABLE tb_test AS SELECT * FROM all_objects WHERE 1=2; --新建一张表

     

            Table created.

     

            SQL> INSERT INTO tb_test SELECT * FROM all_objects;  --插入记录到新表

     

            49945 rows created.

     

            --下面的查询中可以看到ESTIMATED_MTTR为28

                SQL> SELECT recovery_estimated_ios,actual_redo_blks,target_mttr,estimated_mttr,

                  2  optimal_logfile_size  FROM v$instance_recovery;

     

                RECOVERY_ESTIMATED_IOS ACTUAL_REDO_BLKS TARGET_MTTR ESTIMATED_MTTR OPTIMAL_LOGFILE_SIZE

                ---------------------- ---------------- ----------- -------------- --------------------

                                   762            11661           0             28

     

                SQL> COMMIT;   --提交事务

     

                Commit complete.

               

                SQL> SELECT recovery_estimated_ios,actual_redo_blks,target_mttr,estimated_mttr,

                  2  optimal_logfile_size  FROM v$instance_recovery;

     

                RECOVERY_ESTIMATED_IOS ACTUAL_REDO_BLKS TARGET_MTTR ESTIMATED_MTTR OPTIMAL_LOGFILE_SIZE

                ---------------------- ---------------- ----------- -------------- --------------------

                                   767            11669           0             28     

     

            --由上可知,commit仅仅是将日志缓冲区的内容更新到日志文件

           

                SQL> ALTER SYSTEM CHECKPOINT;  --手动更新检查点

     

                System altered.

     

                SQL> SELECT recovery_estimated_ios,actual_redo_blks,target_mttr,estimated_mttr,

                  2  optimal_logfile_size  FROM v$instance_recovery;

     

                RECOVERY_ESTIMATED_IOS ACTUAL_REDO_BLKS TARGET_MTTR ESTIMATED_MTTR OPTIMAL_LOGFILE_SIZE

                ---------------------- ---------------- ----------- -------------- --------------------

                                     0                0           0             28     

                   

            --上面的查询可以看到字段RECOVERY_ESTIMATED_IOS和ACTUAL_REDO_BLKS 的值已经减少到0

            --检查点的产生将database buffer中的脏内容写入到了数据文件中

            --ESTIMATED_MTTR没有发生变化,因为该列为非实时更新列

    转:http://blog.csdn.net/leshami/article/details/5768233

           

  • 相关阅读:
    react系列教程
    实现 React Hooks
    实现 call、apply、bind
    Webpack概念
    写一个简单的模板引擎
    闭包和let块级作用域
    react系列(六)Redux Saga
    react系列(五)在React中使用Redux
    java学习12天2020/7/17
    java学习第十一天2020/7/16
  • 原文地址:https://www.cnblogs.com/andy6/p/5728805.html
Copyright © 2011-2022 走看看