首页 > 数据库技术 > 详细

[转]Oracle DB 执行用户管理的备份和恢复

时间:2014-06-18 15:20:15      阅读:496      评论:0      收藏:0      [点我收藏+]
• 说明用户管理的备份和恢复与服务器管理的备份和恢复之间的差异
• 执行用户管理的数据库完全恢复
• 执行用户管理的数据库不完全恢复
 
 
  • 备份和恢复的使用类型
数据库备份和恢复的类型包括:
• 用户管理的:不使用RMAN
– 使用OS 命令移动文件
– DBA 需要手动维护备份活动记录
• 服务器管理的:使用RMAN
 
有两种方法可用来恢复数据库。可以使用RMAN 并利用其自动恢复功能。它可以还原相应的文件,并使用非常少的命令使数据库恢复到当前状态。还可以手动进行恢复。这称为“用户管理的恢复”。用户管理的恢复需要使用OS 命令来移动文件,然后在SQL*Plus中发出恢复命令。
这两种方法都使用还原和恢复过程。
 
 
  • 执行用户管理的数据库备份
bubuko.com,布布扣
可以使用OS 命令创建数据文件的副本,从而备份数据库。操作过程取决于数据库是否处于ARCHIVELOG模式。如果是,则通过在复制表空间的数据文件之前将每个表空间置于备份模式,可以使数据库处于打开且可用状态。否则,在复制数据文件之前必须先关闭数据库。
归档模式下,手工热备份脚本:http://blog.csdn.net/rlhua/article/details/11850629
非归档模式下,手工冷备份脚本:http://blog.csdn.net/rlhua/article/details/11850445
 
 
  • 需要备份模式的场合
bubuko.com,布布扣
如果在执行数据操纵语言(DML) 语句期间写入某个块,则可能会影响该块的多个部分。对块的所有修改并不是同时发生的,因此在特定时间块可能会不一致。假设t
2表示介于块的不同部分的写入时间之间的时刻。如果在执行OS 复制命令期间,在t2时刻复制块,则该块被视为破碎的。此外,OS 复制命令不一定先复制文件头,因此在执行复制期间必须冻结文件头。
RMAN 可以设法处理此问题。如果读取的块是破碎的,则将不停地重复读取该块,直到该块一致为止。
但是,如果OS 命令(如Linux cp命令)正在复制数据文件,则不会将破碎块视为破碎块,且块的副本也不一致。为了补救这种情况,请将表空间甚至整个数据库置于备份模式。这样做的效果就是生成更多的重做。每个块的映像在修改之前会写入重做日志。然后,在恢复该数据文件中的块期间,可以使用破碎块的前像作为恢复基础,并将更多的重做数据应用于块。为了降低维护额外的重做数据带来的开销,Oracle 建议一次将一个表空间置于备份模式,同时复制其数据文件。
 
 
  • 确定要手动备份的文件
sys@TEST0924> select name from v$datafile;
 
NAME
----------------------------------------------------------------------------------------------------
/u01/app/oracle/oradata/test0924/system01.dbf
/u01/app/oracle/oradata/test0924/sysaux01.dbf
/u01/app/oracle/oradata/test0924/fla_tbs02.dbf
/u01/app/oracle/oradata/test0924/users01.dbf
/u01/app/oracle/oradata/test0924/example01.dbf
/u01/app/oracle/oradata/test0924/fla_tbs01.dbf
/u01/app/oracle/oradata/test0924/undotbs02.dbf
/u01/app/oracle/oradata/test0924/undotbs01.dbf
/u01/app/oracle/oradata/test0924/inventory01.dbf
 
9 rows selected.
 
sys@TEST0924> select name from v$controlfile;
 
NAME
----------------------------------------------------------------------------------------------------
/u01/app/oracle/oradata/test0924/control01.ctl
/u01/app/oracle/fast_recovery_area/test0924/control02.ctl
 
采用用户管理的备份要求了解磁盘上的数据文件名和位置,从而知道需要复制哪些文件。
通过查询V$DATAFILE视图确定要备份的数据文件。通过查询V$CONTROLFILE视图确定控制文件位置。只需要备份一个多路复用控制文件,因为它们是相同的。
 
 
  • 手动备份NOARCHIVELOG数据库
• 关闭数据库实例:
SQL> SHUTDOWNIMMEDIATE
 
• 将数据文件复制到备份位置:
$ cp $ORACLE_BASE/ORCL/datafile/*.dbf \
> /u02/backup/datafile
 
• 将控制文件复制到备份位置:
$ cp $ORACLE_BASE/ORCL/controlfile/*.ctl \
> /u02/backup/controlfile
 
• 启动实例并打开数据库:
SQL> STARTUP
 
通过关闭数据库并将所有数据文件和控制文件复制到一个备份目录,可以对NOARCHIVELOG数据库进行一致的整体数据库备份。由于文件复制操作是使用OS 命令
(在本例中为Linux cp命令)执行的,因此必须先关闭数据库。这会将数据库置于一致状态。如果数据库正在NOARCHIVELOG模式下运行,则这是唯一的选择。否则,在
ARCHIVELOG模式下,可以执行不一致备份,这样可以在执行备份时使数据库保持运行状态。
 
  • 手动备份ARCHIVELOG数据库
• 确定表空间及其数据文件:
sys@TEST0924> select file_name,tablespace_name from dba_data_files;
 
FILE_NAME                                          TABLESPACE_NAME
-------------------------------------------------- ------------------------------
/u01/app/oracle/oradata/test0924/users01.dbf       USERS
/u01/app/oracle/oradata/test0924/fla_tbs02.dbf     FLA_TBS2
/u01/app/oracle/oradata/test0924/sysaux01.dbf      SYSAUX
/u01/app/oracle/oradata/test0924/system01.dbf      SYSTEM
/u01/app/oracle/oradata/test0924/example01.dbf     EXAMPLE
/u01/app/oracle/oradata/test0924/fla_tbs01.dbf     FLA_TBS1
/u01/app/oracle/oradata/test0924/undotbs02.dbf     UNDOTBS2
/u01/app/oracle/oradata/test0924/undotbs01.dbf     UNDOTBS1
/u01/app/oracle/oradata/test0924/inventory01.dbf   INVENTORY
 
9 rows selected.
对每个表空间执行以下操作:
• 将表空间置于备份模式:
sys@TEST0924> alter tablespace users begin backup;
 
Tablespace altered.
 
• 将该表空间的数据文件复制到备份位置:
$ cp /u01/app/oracle/oradata/test0924/users01.dbf  /u02/backup/datafile
 
• 使该表空间退出备份模式:
sys@TEST0924> alter tablespace users end backup;
 
Tablespace altered.
 
如果数据库处于ARCHIVELOG模式下,则复制文件前不一定必须关闭数据库。最终会得到不一致备份,但应用重做数据后会使其恢复到一致状态。
启动备份模式:复制数据文件之前,必须将每个数据文件都置于备份模式。请使用ALTER TABLESPACE和ALTER DATABASE命令的BEGIN BACKUP子句来执行此操作。
以下是每个命令的语法:
ALTER TABLESPACE <tablespace> BEGIN BACKUP;
ALTER DATABASE BEGIN BACKUP;
ALTER TABLESPACE命令仅影响属于该表空间的那些数据文件。ALTER DATABASE影响数据库中的所有数据文件。
结束备份模式:使数据文件退出备份模式非常重要。关闭数据库时,不能有任何数据文件处于备份模式。如果尝试关闭处于该状态的数据库,将收到错误。此外,由于备份模式会导致生成额外的重做数据,因此会给系统带来额外的负载。如果不主动备份数据文件,则没有理由使任何数据文件处于备份模式。
注:此外,你需要归档出当前的重做日志文件,并将其安全备份。
 
 
  • 备份控制文件
备份控制文件的方式包括:
• 创建为映像副本,写入到指定名称的文件:
• 生成重新创建控制文件的脚本,写入到跟踪文件:
SQL> ALTER DATABASE BACKUP CONTROLFILE TO ‘/u01/backup/controlfile.bak‘;
Database altered.
SQL> ALTER DATABASE BACKUP CONTROLFILE TO TRACE;
Database altered.
 
每次对数据库进行结构更改时,都应备份控制文件。使用示例显示的命令之一执行此操作。第一条命令创建该文件的二进制副本。如果备份文件已存在且你希望覆盖该文件,则可以选择提供REUSE关键字。
第二条命令创建纯文本版本的控制文件,实际上是运行后会创建控制文件的脚本。生成的脚本被写入诊断跟踪目录,如:
$ORACLE_BASE/diag/rdbms/orcl/orcl/trace
你也可使用AS ‘filename‘子句指定跟踪文件的名称。
 
  • 执行用户管理的数据库完全恢复:概览
用户管理的数据库完全恢复:
• 将数据库恢复到最新的SCN
• 可以一次处理整个数据库,也可以一次处理一个数据文件或表空间
• 需要当前控制文件或备份控制文件
• 需要有待恢复的所有文件的备份
• 需要到目前为止的所有归档日志
 
数据库完全恢复会使数据库恢复至其最新状态。可以一次恢复整个数据库,也可以一次恢复一个表空间或数据文件。必须具备当前或备份控制文件,才能对数据库执行完全恢复。你还必须具有进行介质恢复时所需的所有文件的备份,或者具有自数据文件添加到数据库
以来生成的所有归档重做日志文件。
必须具备从执行备份的时间点到现在的所有可用归档日志。如果没有所有归档日志,则只能恢复到重做可用的上一个时间点。如果不需要任何归档日志,则只应用联机重做日志。
可查询以下视图:
• V$RECOVER_FILE:查看哪些文件需要介质恢复
• V$RECOVERY_LOG:查看执行恢复需要哪些归档日志
 
 
  • 对关闭的数据库执行完全恢复:概览
bubuko.com,布布扣
在某些情况下,属于SYSTEM表空间的文件受到损坏时,实例将自动关闭。当某些数据文件有问题时,即使实例保持运行状态,你也可以判定使数据库保持运行状态没有任何意义;受影响的数据库对象太多了。在这种情况下,请关闭数据库执行恢复。
如果数据库仍处于打开状态,则可以查询V$RECOVERY_FILE视图以了解哪些数据文件需要恢复,并在还原数据文件后查询V$RECOVERY_LOG以了解需要哪些归档日志。这会指示你需要从备份中还原哪些文件(如果有)。
然后关闭数据库。调查介质故障,确定问题原因。修复该问题,以便可以从备份中还原文件。例如,你可能需要更换磁盘驱动器。
现在,可使用RECOVER命令来执行恢复。将恢复范围限制在所需范围,如数据文件或表空间。如果需要,可恢复整个数据库。然后打开数据库。
 
 
  • 确定与恢复相关的文件
• 确定需要恢复的数据文件:
sys@TEST0924> SELECT file#, error FROM v$recover_file;
 
     FILE# ERROR
---------- -----------------------------------------------------------------
         4 FILE NOT FOUND
• 确定完成恢复所需的归档日志文件:
sys@TEST0924> SELECT archive_name FROM v$recovery_log;
 
no rows selected
 
如果数据库仍处于打开状态,请按照下述步骤查询文件。否则,请尝试启动实例并装载数据库以便发出查询。
为了确定哪些数据文件需要恢复,请查询V$RECOVER_FILE视图。ERROR列指明文件需要恢复的原因。如果此列具备OFFLINE NORMAL以外的任何值,则需要恢复。要查看所有受影响的数据文件和表空间的概况,请在此查询中加入V$DATAFILE和V$TABLESPACE。下面是一个示例:
SELECT r.FILE#, d.NAME df_name, t.NAME tbsp_name,d.STATUS, r.ERROR, r.CHANGE#, r.TIME
FROM V$RECOVER_FILE r, V$DATAFILE d, V$TABLESPACE t
WHERE t.TS# = d.TS# AND d.FILE# = r.FILE#;
 
sys@TEST0924> l
  1  SELECT r.FILE#, d.NAME df_name, t.NAME tbsp_name,d.STATUS, r.ERROR, r.CHANGE#, r.TIME
  2  FROM V$RECOVER_FILE r, V$DATAFILE d, V$TABLESPACE t
  3* WHERE t.TS# = d.TS# AND d.FILE# = r.FILE#
sys@TEST0924> /
 
     FILE# DF_NAME                                            TBSP_NAME  STATUS  ERROR                   CHANGE# TIME
---------- -------------------------------------------------- ---------- ------- -------------------- ---------- -------------------
         4 /u01/app/oracle/oradata/test0924/users01.dbf       USERS      ONLINE  FILE NOT FOUND                0
这可指示受损的程度,帮助你确定RECOVER命令的对象。
V$RECOVERY_LOG视图显示执行恢复所需的归档日志文件。如果列表显示某些文件已移出默认归档日志位置,则必须将它们还原到某个位置,再执行恢复。
记录这些查询的结果后,关闭数据库。
 
  • 还原与恢复相关的文件
bubuko.com,布布扣
确定了需要哪些数据文件和归档日志文件后,将它们还原到相应的磁盘位置。通过从备份位置复制某个数据文件来还原该数据文件,如下例所示:
[oracle@rtest ~]$ cp /u01/app/oracle/oradata/test0924/users01old.dbf /u01/app/oracle/oradata/test0924/users01.dbf
如果恢复需要任何归档日志,请检查这些日志是否仍位于归档日志的默认磁盘位置。这些日志可能不在默认位置,例如,已将它们移至磁带或其它磁盘驱动器。如果日志已被移动,则需将它们还原到默认归档日志位置或临时位置。如果默认位置(由LOG_ARCHIVE_DEST_1初始化参数指定)中有足够的可用空间,请在该位置还原日志。
否则,可以将日志置于某个其它磁盘位置。还原时,可指定该备用位置来查找归档日志文件。
如果必须移动数据文件,则必须在控制文件中记录这一事实。这是通过执行ALTERDATABASE RENAME FILE命令来完成的,如下例所示:
SQL> ALTER DATABASE RENAME FILE ‘/u01/app/oracle/oradata/test0924/users01.dbf‘ TO ‘/newdisk/ORCL/datafile/users01.dbf‘;
注:在执行ALTER DATABASE RENAME FILE命令之前,你必须启动实例并装载数据库。
 
如果您尚未执行此操作,请装载数据库并使所有数据文件联机。可以通过查询V$DATAFILE视图来检查每个数据文件的状态。可使用如下命令使数据文件联机:
SQL> ALTER DATABASE DATAFILE  ‘/newdisk/ORCL/datafile/users01.dbf‘ ONLINE;
 
 
  • 应用重做数据
bubuko.com,布布扣
现在,数据文件已还原到过去的某个时间点。归档日志文件也已还原到其默认位置或某个其它位置(仅用于此恢复)。你已准备就绪,可执行真正的恢复步骤,这意味着已应用重做且数据文件已恢复到最新SCN。请使用SQL*Plus RECOVER命令执行此操作。
如果没有指定AUTOMATIC选项,则系统会提示你指定要应用的每个重做日志文件。这样可以提高对恢复过程的控制。通常,AUTOMATIC用于完全恢复。
如果归档日志文件已还原到数据库默认位置以外的某个磁盘位置,则必须指定FROM子句。
提供存储这些文件的目录,恢复过程将在该目录中寻找文件。最后,打开数据库。此时已完全恢复。
 
  • 对打开的数据库执行完全恢复
bubuko.com,布布扣
如果在数据库处于打开状态时出现介质故障,则数据库将继续运行。尝试向其中的数据文件写入数据时,数据文件将自动脱机。对这些数据文件进行查询不会导致其脱机,但是会向发出查询的用户返回错误。
与恢复关闭的数据库类似,你首先需要查询需恢复的文件和归档日志。然后,使包含受损数据文件的所有表空间脱机。可使用如下命令完成该操作:
SQL> ALTER TABLESPACE survey OFFLINE TEMPORARY;
使用TEMPORARY选项会导致Oracle 对所有属于表空间的联机数据文件执行检查点操作。
经过检查点操作的数据文件在重新联机后不需要进行恢复,因为对于可能会影响它们的任何事务处理的最新SCN 而言,它们是最新的。尽管在此命令运行时数据文件必须可用,但此选项更符合需要。问题可能是临时的,你可以在不产生错误的情况下使表空间联机。
检查介质以确定问题原因。可使用DBVERIFY实用程序来执行此操作。如果文件被永久损坏,请按照前面就恢复关闭数据库所述的内容进行还原和恢复。还原和恢复步骤完
成后,应使所有表空间重新联机。
 
 
 
  • 执行用户管理的不完全恢复:概览
在以下情况下,可将数据库恢复到过去的时间点:
• 希望数据库处于出现用户错误或管理错误之前的状态。
• 在尝试块介质恢复后,数据库中包含损坏的块。
• 由于缺少某些重做日志文件而无法对数据库执行完全恢复。
• 希望创建一个测试数据库,使数据库处于过去某个时间的状态。
• 丢失了数据文件和一个或多个未归档重做日志文件。
 
不完全恢复是指不会使数据库恢复到已经过事务处理的最新SCN 的恢复。出于某种原因,只需将该数据库恢复到过去的某个时间点,而不是现在。执行不完全恢复时进行的处理不同于完全恢复处理,其差别主要在应用重做的数量上。
 
 
  • 选择不完全恢复方法
可通过以下方式指明何时停止应用重做数据:
• 指定停止的时间
• 指定停止的SCN
• 在执行恢复时发出CANCEL命令
 
bubuko.com,布布扣
 
计划不完全恢复时,请确定要使用哪种方法来指定何时停止应用重做数据。可以通过指定以下某一项来停止恢复过程:
• 时间:应停止恢复的日志时间。该操作可自动执行,这样恢复过程便不会提示你输入每个文件名。
• SCN:恢复应在该点停止的系统更改号。该操作可自动执行,这样恢复过程便不会提示你输入每个文件名。
• CANCEL:在恢复过程提示你输入下一个重做日志文件名称时,指定CANCEL关键字。不能自动执行该过程,因为你必须指定CANCEL来终止恢复操作。
 
 
  • 执行用户管理的不完全恢复
• 将数据库恢复到某一时刻:
SQL> RECOVER DATABASE UNTIL TIME ‘2005-12-14:12:10:03‘;
 
• 恢复数据库直到执行取消操作:
SQL> RECOVER DATABASEUNTIL CANCEL;
 
 
使用以下命令执行不完全恢复:
RECOVER [AUTOMATIC] DATABASE option
下面是选项的含义:
• AUTOMATIC:自动应用归档和重做日志文件
• option:UNTIL TIME ‘YYYY-MM-DD:HH24:MI:SS‘
UNTIL CANCEL
UNTIL CHANGE <integer>
USING BACKUP CONTROLFILE
 
基于取消的不完全恢复
基于取消的不完全恢复与对关闭数据库执行的完全恢复非常相似。差异在于执行RECOVER命令的方式;指定UNTIL CANCEL子句。此子句将导致恢复过程提示你确认要
应用的每个重做日志文件的建议名称。因此,在进行恢复过程中,系统会提示你确认已归档或联机的重做日志文件名,而且对于每个文件名,你可以接受它,也可以更改它。到达要让恢复停止的时间点时,请输入CANCEL,而不要接受文件名。这将停止恢复。完成此操作后,必须使用RESETLOGS选项打开数据库。数据库目前正在执行另一实例化操作,因此需要重置重做日志序列号。打开数据库后,请检查预警日志中的消息。通过这种方式,您可以获知恢复是否已成功。
基于时间和更改的不完全恢复
基于时间和更改的不完全恢复与基于取消的恢复类似,区别在于使用不同标准来指定停止恢复的时间。基于时间的恢复使用在RECOVER命令的命令行中指定的时间来获知何时停止。基于更改的恢复使用在命令行中指定的SCN。与所有的不完全恢复一样,之后必须使用RESETLOGS选项打开数据库。
注:要在恢复过程中自动应用重做日志文件,可以使用SQL*Plus SET AUTORECOVERY ON命令,在恢复提示符下输入AUTO,或者使用RECOVER AUTOMATIC命令。
 
  • 执行用户管理的不完全恢复:步骤
要执行用户管理的不完全恢复,请按以下步骤进行操作:
1. 关闭数据库。
2. 还原数据文件。
3. 装载数据库。
4. 恢复数据库。
5. 使用RESETLOGS选项打开数据库。
 
1.如果数据库已打开,请使用NORMAL、IMMEDIATE或TRANSACTIONAL选项将其关闭。
2.从备份还原所有数据文件。你必须使用在打算恢复到的时间之前创建的备份。可能还需要还原归档日志。如果有足够的可用空间,请还原到LOG_ARCHIVE_DEST位置或
使用ALTER SYSTEM ARCHIVE LOG START TO <LOCATION>命令或SET LOGSOURCE <LOCATION>命令来更改位置。在执行不完全恢复来恢复到某个时间点时,如果彼时数据库结构不同于当前的数据库结构,则你还需要还原控制文件。
3.装载数据库。
4.使用RECOVER DATABASE命令恢复数据库。
5.要使数据文件与控制文件和重做日志同步,请使用RESETLOGS选项打开数据库。
 
 
  • 用户管理的基于时间的恢复:示例
情况如下:
• 某个作业运行出错,必须取消其结果和影响。
• 该操作发生在15 分钟前,并且在此之后数据库活动很少。
• 你决定执行不完全恢复,将数据库还原到15 分钟前的状态。
SQL> SHUTDOWNIMMEDIATE
$ cp /BACKUP/*.dbf /u01/db01/ORADATA
SQL> STARTUP MOUNT
SQL> RECOVER DATABASE UNTIL    TIME ‘2005-11-28:11:44:00‘;
SQL> ALTER DATABASE OPEN RESETLOGS;
 
下面是使用UNTIL TIME恢复的典型情况。假设:
• 当前时间为2005 年11 月28 日中午12:00。
• 某个作业运行出错,影响了多个方案中的许多表。
• 该操作大约发生在上午11:45。
• 因为大多数员工现在都在开会,所以数据库活动很少。必须还原到作业运行前数据库的状态。
因为知道错误的大概时间,而且自上午11:44 以来数据库的结构未发生更改,所以可以使用UNTIL TIME方法:
1.如果数据库已打开,请使用NORMAL、IMMEDIATE或TRANSACTIONAL选项将其关闭。
2.从备份(如果可能,使用最新的)还原所有数据文件。可能还需要还原归档日志。如果有足够的可用空间,请还原到LOG_ARCHIVE_DEST位置或使用ALTER SYSTEM 
ARCHIVE LOG START TO <LOCATION>命令或SET LOGSOURCE <LOCATION>命令来更改位置。
3.装载数据库。
4.恢复数据库:
SQL> recover database until time ‘2005-11-28:11:44:00‘ 
ORA-00279: change 148448 … 11/27/05 17:04:20 needed for thread 
...
Media recovery complete.
5.要使数据文件与控制文件和重做日志同步,请使用RESETLOGS选项打开数据库:
SQL> alter database open resetlogs;
SQL> archive log list
...
Oldest online log sequence 0
Next log sequence to archive 1
Current log sequence 1
恢复成功完成后,会通知用户数据库已经可用,需要重新输入恢复时间(上午11:44)之后输入的所有数据。
 
  • 用户管理的基于取消的恢复:示例
情况与基于时间的示例相同,除了以下各项:
• 重做日志未进行多路复用。
• 一个联机重做日志丢失。
• 丢失的重做日志未归档。
• 该重做日志包含自上午11:34 以来的信息。
• 丢失了26 分钟的数据。
• 用户可以手动重新输入其数据。
 
在目录中搜索重做日志文件后,发现找不到重做日志log2a.rdo且该日志尚未归档。
因此,无法恢复到此点之后。
查询V$ARCHIVED_LOG后确定缺少归档日志序列48 (log2a.rdo):
SQL> SELECT * FROM v$archived_log;
RECID STAMP ... FIRST_CHANGE# FIRST_TIME
----- --------- ... ------------- ----------
1 318531466 ... 88330 05-11-15:12:43
47 319512880 ... 309067 05-11-28:11:26
 
 
按以下步骤恢复数据库:
• 关闭数据库。
• 从最新备份还原所有数据文件。
• 装载数据库。
• 执行RECOVER DATABASE UNTIL CANCEL。
• 执行ALTER DATABASE OPEN RESETLOGS以打开数据库。
基于取消的恢复与基于时间的恢复步骤相同,除了RECOVER DATABASE这一步。执行RECOVER DATABASE UNTIL CANCEL命令时,它将恢复数据库直到找不到日志文件。提示你输入丢失的归档重做日志文件的名称时,请输入CANCEL;恢复将在该时间点停止。

http://blog.csdn.net/rlhua/article/details/12682217

[转]Oracle DB 执行用户管理的备份和恢复,布布扣,bubuko.com

[转]Oracle DB 执行用户管理的备份和恢复

原文:http://www.cnblogs.com/gispf/p/3791359.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!