【MOS】如何利用RMAN可傳輸表空間遷移資料庫到不同位元組序的平臺(文件 ID 1983639.1)

東北胖子發表於2018-03-19

如何利用 RMAN 可傳輸表空間遷移資料庫到不同位元組序的平臺 (文件 ID 1983639.1)

適用於:

Oracle Database - Enterprise Edition - 版本 10.1.0.2 到 12.1.0.1 [發行版 10.1 到 12.1]
本文件所含資訊適用於所有平臺
******************* 警告 *************

Document 1334152.1 Corrupt IOT when using Transportable Tablespace to HP from different OS
Document 13001379.8 Bug 13001379 - Datapump transport_tablespaces produces wrong dictionary metadata for some tables 

目標

從 Oracle 資料庫 10g 開始,你可以跨平臺的傳輸表空間。這篇文件提供了一個逐步指導,來解釋如何實現 ASM 資料檔案和 OS 檔案系統資料檔案的傳輸表空間。

如果你的目標是遷移一個資料庫到不同的位元組序平臺,如下的步驟概述瞭如何使用可傳輸表空間遷移一個資料庫到一個新的平臺:

1.- 在目標平臺上建立一個新的,空的資料庫。
2.- 從源庫匯入傳輸操作要求的物件到目標庫。
3.- 從源庫為所有的使用者表空間匯出可傳輸的後設資料。
4.- 轉移使用者表空間的資料檔案到目標系統。
5.- 使用 RMAN 轉換資料檔案到目標系統的位元組序格式。
6.- 匯入所有使用者表空間的可傳輸後設資料到目標資料庫。
7.- 從源庫匯入餘下的資料庫物件和後設資料(傳輸操作未移動的部分)到目標庫。

你也可以在源平臺轉換資料檔案,轉換完成後轉移他們到目標平臺。

MAA 白皮書“利用表空間傳輸實現平臺遷移”請參考:

http://www.oracle.com/technetwork/database/features/availability/maa-wp-11g-platformmigrationtts-129269.pdf

 

從 11.2.0.4,12c 之後,如果要轉換到 Linux x86-64,那麼參考如下文件:

   Reduce Transportable Tablespace Downtime using Cross Platform Incremental Backup [1389592.1]

 

解決方案

支援的平臺

請查詢 V$TRANSPORTABLE_PLATFORM 來檢視受支援的平臺,並確定每個平臺的位元組序。

SQL> COLUMN PLATFORM_NAME FORMAT A32
SQL> SELECT * FROM V$TRANSPORTABLE_PLATFORM;

PLATFORM_ID PLATFORM_NAME                    ENDIAN_FORMAT
----------- -------------------------------- --------------
          1 Solaris[tm] OE (32-bit)          Big
          2 Solaris[tm] OE (64-bit)          Big
          7 Microsoft Windows IA (32-bit)    Little
         10 Linux IA (32-bit)                Little
          6 AIX-Based Systems (64-bit)       Big
          3 HP-UX (64-bit)                   Big
          5 HP Tru64 UNIX                    Little
          4 HP-UX IA (64-bit)                Big
         11 Linux IA (64-bit)                Little
         15 HP Open VMS                      Little
          8 Microsoft Windows IA (64-bit)    Little
          9 IBM zSeries Based Linux          Big
         13 Linux 64-bit for AMD             Little
         16 Apple Mac OS                     Big
         12 Microsoft Windows 64-bit for AMD Little
         17 Solaris Operating System (x86)   Little


如果源平臺和目標平臺是不同的位元組序,那麼必須在源平臺或者目標平臺上做一個額外的步驟,來轉換被傳輸的表空間到目標格式。如果它們是同樣的位元組序,那麼不需要做轉換,表空間可以像同平臺那樣傳輸。

傳輸表空間

  1. 傳輸表空間前的準備工作
    • 檢查表空間是自包含的:
      SQL> execute sys.dbms_tts.transport_set_check('TBS1,TBS2', true);
      SQL> select * from sys.transport_set_violations;

      注意:在表空間被傳輸之前,這些違反傳輸標準的問題必須被解決。
    • 要成功的執行傳輸表空間匯出,表空間必須在 READ ONLY 模式:
      SQL> ALTER TABLESPACE TBS1 READ ONLY;
      SQL> ALTER TABLESPACE TBS2 READ ONLY;
  2. 匯出後設資料
    • 使用傳統匯出工具:
      exp userid=\'sys/sys as sysdba\' file=tbs_exp.dmp log=tba_exp.log transport_tablespace=y tablespaces=TBS1,TBS2
    • 使用資料泵匯出:
      首先建立資料泵使用的目錄物件,例如:
      CREATE OR REPLACE DIRECTORY dpump_dir AS '/tmp/subdir' ;
      GRANT READ,WRITE ON DIRECTORY dpump_dir TO system;

      然後初始化資料泵匯出:
      expdp system/password DUMPFILE=expdat.dmp DIRECTORY=dpump_dir TRANSPORT_TABLESPACES = TBS1,TBS2

      如果你想要在執行一個傳輸表空間操作的同時進行嚴格的包含關係檢查,那麼使用 TRANSPORT_FULL_CHECK 引數。
      expdp system/password DUMPFILE=expdat.dmp DIRECTORY = dpump_dir TRANSPORT_TABLESPACES= TBS1,TBS2 TRANSPORT_FULL_CHECK=Y

      如果被傳輸的表空間集不是自包含的,那麼匯出會失敗。
  3. 使用 V$TRANSPORTABLE_PLATFORM 來確定每個平臺的位元組序,你可以在每個平臺例項執行如下查詢:
    SELECT tp.platform_id,substr(d.PLATFORM_NAME,1,30), ENDIAN_FORMAT
    FROM V$TRANSPORTABLE_PLATFORM tp, V$DATABASE d
    WHERE tp.PLATFORM_NAME = d.PLATFORM_NAME;

    如果你發現位元組序是不同的,那麼傳輸表空間集時必須進行轉換:
    RMAN> convert tablespace TBS1 to platform="Linux IA (32-bit)" FORMAT '/tmp/%U';

    RMAN> convert tablespace TBS2 to platform="Linux IA (32-bit)" FORMAT '/tmp/%U';

    然後複製資料檔案和匯出的檔案到目標環境。
  4. 匯入可傳輸表空間
    • 使用傳統匯入工具:
      imp userid=\'sys/sys as sysdba\' file=tbs_exp.dmp log=tba_imp.log transport_tablespace=y datafiles='/tmp/....','/tmp/...'
    • 使用資料泵:
      CREATE OR REPLACE DIRECTORY dpump_dir AS '/tmp/subdir';
      GRANT READ,WRITE ON DIRECTORY dpump_dir TO system;

      然後執行:
      impdp system/password DUMPFILE=expdat.dmp DIRECTORY=dpump_dir TRANSPORT_DATAFILES='/tmp/....','/tmp/...' REMAP_SCHEMA=(source:target) REMAP_SCHEMA=(source_sch2:target_schema_sch2)

      如果你想要改變傳輸的資料庫物件的屬主,可以使用 REMAP_SCHEMA。
  5. 將表空間置於 read/write 模式:
    SQL> ALTER TABLESPACE TBS1 READ WRITE;
    SQL> ALTER TABLESPACE TBS2 READ WRITE;

使用 DBMS_FILE_TRANSFER

你也可以是使用 DBMS_FILE_TRANSFER 來拷貝資料檔案到另外一個主機。

從 12c 和 11.2.0.4 開始 DBMS_FILE_TRANSFER 預設的進行轉換。若使用 DBMS_FILE_TRANSFER,當目標資料庫收到一個來自不同位元組序的平臺的檔案時,它對每一個塊進行轉換。作為可傳輸操作的一部分,在資料檔案被移動到目標資料庫後,不需 RMAN 轉換,即可匯入。

在低於 11.2.0.4 的版本上,對於 ASM 檔案同樣需要執行上面的步驟。但是如果位元組序格式不同,那麼你必須在轉移檔案後,使用 RMAN 轉換。檔案無法直接在不同平臺的兩個 ASM 例項間進行拷貝。


如下是一個使用範例:

RMAN> CONVERT DATAFILE
      '/hq/finance/work/tru/tbs_31.f',
      '/hq/finance/work/tru/tbs_32.f',
      '/hq/finance/work/tru/tbs_41.f'
      TO PLATFORM="Solaris[tm] OE (32-bit)"
      FROM PLATFORM="HP TRu64 UNIX"
      DB_FILE_NAME_CONVERT= "/hq/finance/work/tru/", "/hq/finance/dbs/tru"
      PARALLELISM=5;


相同的範例,但是這裡顯示目的地是一個 ASM 磁碟組:

RMAN> CONVERT DATAFILE
      '/hq/finance/work/tru/tbs_31.f',
      '/hq/finance/work/tru/tbs_32.f',
      '/hq/finance/work/tru/tbs_41.f'
      TO PLATFORM="Solaris[tm] OE (32-bit)"
      FROM PLATFORM="HP TRu64 UNIX"
      DB_FILE_NAME_CONVERT="/hq/finance/work/tru/", "+diskgroup"
      PARALLELISM=5;

 

 

*** 警告***

  • 當使用可傳輸表空間(TTS)從 Solaris,Linux 或者 AIX 遷移到 HP/UX 時,索引組織表(IOT)可能損壞。
    這是 BUG:9816640 帶來的限制。
    當前針對這個問題沒有補丁。索引組織表(IOT)需要在 TTS 之後進行重建。

    參考文件 1334152.1 Corrupt IOT when using Transportable Tablespace to HP from different OS
  • 當使用被 drop 掉的列,可能遇到這個 Bug:13001379 - Datapump transport_tablespaces produces wrong dictionary metadata for some tables can occur。文件 1440203.1 給出了這個警告的細節。

使用 DBMS_FILE_TRANSFER 的已知問題

=> 未公開的 Bug 13636964 - ORA-19563 from RMAN convert on datafile copy transferred with DBMS_FILE_TRANSFER (Doc ID 13636964.8)
 確認受影響的版本     
    11.2.0.3 
 問題在如下版本修復   
    12.1.0.1 (Base Release)
    11.2.0.4 (Future Patch Set) 
    
描述

    使用 DBMS_FILE_TRANSFER 轉移的檔案在 RMAN convert 操作中失敗。
    例如:
     RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
     RMAN-00571: ===========================================================
     RMAN-03002: failure of conversion at target command at 01/24/2012 16:22:23
     ORA-19563: cross-platform datafile header validation failed for file +RECO/soets_9.tf 
     
    Rediscovery Notes:
     如果 RMAN 轉換一個使用 DBMS_FILE_TRANSFER 轉移的檔案失敗,那麼可能是由於這個 Bug。
     
    規避方案:
     使用 OS 工具轉移檔案。
=> Dbms_file_transfer Corrupts Dbf File When Copying between endians (Doc ID 1262965.1)

 

額外的資源

社群: Database Utilities

仍有其它問題嗎? 使用如上的社群來搜尋相似的討論,或者就此主題開啟一個新的討論。

可傳輸表空間使用的限制

  1. 源庫和目標庫必須使用相同的字符集和國家字符集。
  2. 如果目標庫上已經有一個同名的表空間,無法進行傳輸。然而,你可以在傳輸之前,重新命名要傳輸的表空間或者目標庫上的表空間。
  3. 若物件帶有下層物件(例如物化檢視)或者被包含的物件(例如分割槽表),則無法被傳輸。除非所有下層物件或者被包含的物件都在這個表空間集裡。
    • 檢視 Oracle Database Utilities 文件中的表"Objects Exported and Imported in Each Mode",裡面有幾個物件型別在表空間模式中不被匯出。
  4. 如果表空間物件的所有者在目標庫中不存在,則需要在開始可傳輸表空間匯入之前,手動的建立使用者名稱。

    • 如果你使用了 spatial 索引,那麼:
      • 注意在 10gR1 和 10gR2 中,對於 spatial 索引,不支援跨不同位元組序平臺的 TTS 操作。這個限制在 11g 中取消了。
      • 在匯出之前和傳輸之後,必須執行專門的 spatial 包,請參閱 Oracle Spatial 文件.
  5. 從 Oracle Database 11gR1 開始,對於含有 XMLType 的表空間,必須使用資料泵來匯出和匯入表空間後設資料。

    如下的查詢返回了包含 XMLType 的表空間的列表:
    select distinct p.tablespace_name
    from dba_tablespaces p, dba_xml_tables x, dba_users u, all_all_tables t
    where t.table_name=x.table_name and
          t.tablespace_name=p.tablespace_name and
          x.owner=u.username;

    傳輸帶有 XMLType 的表空間有如下限制
    1. 目標資料庫必須安裝 XML DB。
    2. XMLType 表引用的 schema 不能是 XML DB 標準 schema。
    3. XMLType 表引用的 schema 不能有迴圈依賴。
    4. XMLType 表上的任何行級別安全性都會在匯入時丟失。
    5. 如果一個傳輸的 XMLType 表的 schema 不在目標資料庫裡,它會被匯入並且註冊。如果這個 schema 在目標資料庫裡已經存在了,就會返回一個錯誤,除非使用 ignore=y 選項。
  6. 高階佇列可傳輸表空間不支援帶有多個容器的 8.0 相容版高階佇列。
  7. 你無法傳輸 SYSTEM 表空間或者使用者 SYS 擁有的物件。
  8. 不透明型別(例如 RAW,BFILE 和 AnyTypes)可以被傳輸,但是他們不會在跨平臺傳輸操作中被轉換。他們的實際框架只有應用知道,所以應用必須在這些型別被移動到新的平臺後處理位元組序的問題。
  9. 浮點數 BINARY_FLOAT 和 BINARY_DOUBLE 型別是可以傳輸的,但必須使用 Data Pump,不能使用原始的匯出工具 EXP。
  10. 其它更多的限制和要求,請檢視以下文件: Document 1454872.1 - Transportable Tablespace (TTS) Restrictions and Limitations: Details, Reference, and Version Where Applicable

ASM 檔案的可傳輸表空間匯出/匯入

  • 使用 RMAN CONVERT

    沒有直接的方法將 ASM 檔案作為可傳輸表空間匯出/匯入。但是,可以通過 RMAN 實現這個功能。

    請務必遵照如下步驟:
    1. 匯出表空間前的準備。

      • 檢查表空間是自包含的:
        SQL>execute sys.dbms_tts.transport_set_check('TBS1,TBS2', true);
        SQL> select * from sys.transport_set_violations;

        注意:這些違反限制的結果必須在表空間傳輸前解決。
      • 要成功的進行可傳輸表空間匯出,這些表空間必須處於 READ ONLY 模式。
        SQL> ALTER TABLESPACE TBS1 READ ONLY;
        SQL> ALTER TABLESPACE TBS2 READ ONLY;
    2. 匯出後設資料。
      • 使用原始匯出工具:
        exp userid=\'sys/sys as sysdba\' file=tbs_exp.dmp log=tba_exp.log transport_tablespace=y tablespaces=TBS1,TBS2
      • 使用資料泵匯出:
        CREATE OR REPLACE DIRECTORY dpump_dir AS '/tmp/subdir';
        GRANT READ,WRITE ON DIRECTORY dpump_dir TO system;

        然後執行:
        expdp system/password DUMPFILE=expdat.dmp DIRECTORY=dpump_dir TRANSPORT_TABLESPACES = TBS1,TBS2

        如果你想要在執行可傳輸表空間操作同時進行嚴格的包容性檢查,那麼使用 TRANSPORT_FULL_CHECK 引數:
        expdp system/password DUMPFILE=expdat.dmp DIRECTORY = dpump_dir TRANSPORT_TABLESPACES= TBS1,TBS2 TRANSPORT_FULL_CHECK=Y

      如果傳輸的表空間不是自包含的,那麼匯出會出錯。
    3. 使用 V$TRANSPORTABLE_PLATFORM 找到目標庫準確的平臺名。你可以在目標平臺例項上執行如下的查詢。
      SELECT tp.platform_id,substr(d.PLATFORM_NAME,2,30), ENDIAN_FORMAT
      FROM V$TRANSPORTABLE_PLATFORM tp, V$DATABASE d
      WHERE tp.PLATFORM_NAME = d.PLATFORM_NAME;
    4. 以目標平臺的格式,從 ASM 檔案生成一個 OS 檔案。
      RMAN> CONVERT TABLESPACE TBS1
            TO PLATFORM 'HP-UX (64-bit)' FORMAT '/tmp/%U';
      RMAN> CONVERT TABLESPACE TBS2
            TO PLATFORM 'HP-UX (64-bit)' FORMAT '/tmp/%U';
    5. 拷貝生成的檔案到目標伺服器(如果跟源伺服器不是同一臺機器)。
    6. 匯入可傳輸表空間。
      • 使用原始的匯入工具:
        imp userid=\'sys/sys as sysdba\' file=tbs_exp.dmp log=tba_imp.log transport_tablespace=y datafiles='/tmp/....','/tmp/...'
      • 使用資料泵匯入:
        CREATE OR REPLACE DIRECTORY dpump_dir AS '/tmp/subdir';
        GRANT READ,WRITE ON DIRECTORY dpump_dir TO system;

        然後執行:
        impdp system/password DUMPFILE=expdat.dmp DIRECTORY=dpump_dir TRANSPORT_DATAFILES='/tmp/....','/tmp/...' REMAP_SCHEMA=(source:target) REMAP_SCHEMA=(source_sch2:target_schema_sch2)

        如果你想要改變傳輸的資料庫物件的屬主的話,可以使用 REMAP_SCHEMA 引數。
    7. 將表空間放置在 read/write 模式。
      SQL> ALTER TABLESPACE TBS1 READ WRITE;
      SQL> ALTER TABLESPACE TBS2 READ WRITE;

      如果你想要將資料檔案從 ASM 環境傳輸到檔案系統,那麼操作到此結束。但如果你想要在兩個 ASM 環境之間傳輸表空間,那麼你要繼續下面的操作。
    8. 使用 rman 拷貝檔案'/tmp/....dbf' 到 ASM 環境。
      rman nocatalog target /
      RMAN> backup as copy datafile '/tmp/....dbf' format '+DGROUPA';

      這裡 +DGROUPA 是 ASM 磁碟組名字。
    9. 將資料檔案交換到這個拷貝。
      如果是 10g 資料庫,首先要將資料檔案離線:
      SQL> alter database datafile '/tmp/....dbf' offline;

      檔案交換到這個拷貝:
      rman nocatalog target /
      RMAN> switch datafile '/tmp/....dbf' to copy;

      記下在 +DGROUPA 磁碟組中建立的拷貝的名字,例如,'+DGROUPA/s101/datafile/tts.270.5'。
    10. 使檔案重新線上,我們首先要 recover 它。
      SQL> recover datafile '+DGROUPA/s101/datafile/tts.270.5';
      SQL> alter database datafile '+DGROUPA/s101/datafile/tts.270.5' online;
    11. 檢查資料檔案確實已經是 ASM 環境的一部分,並且線上。
      SQL> select name, status from v$datafile;

      輸出應該是:
      +DGROUPA/s101/datafile/tts.270.5 ONLINE
  • 使用DBMS_FILE_TRANSFER

    你同樣可以使用 DBMS_FILE_TRANSFER 來將資料檔案從一個 ASM 磁碟組拷貝到另外一個,甚至到另外一個主機上。從 10gR2 開始你同樣可以使用 DBMS_FILE_TRANSFER 來拷貝資料檔案從 ASM 到檔案系統,以及從檔案系統到 ASM。

    PUT_FILE 過程讀取一個本地檔案或者 ASM 並且聯絡遠端資料庫來建立一個在遠端檔案系統的拷貝。被拷貝的檔案是原始檔,拷貝帶來的新檔案是目標檔案。直到過程成功完成,目標檔案都不會被關閉。

    語法:
    DBMS_FILE_TRANSFER.PUT_FILE(
       source_directory_object       IN  VARCHAR2,
       source_file_name              IN  VARCHAR2,
       destination_directory_object  IN  VARCHAR2,
       destination_file_name         IN  VARCHAR2,
       destination_database          IN  VARCHAR2);

    其中:
    • source_directory_object: 在本地源端拷貝的檔案所在的目錄物件。在源端,這個目錄物件必須存在。
    • source_file_name: 從本地檔案系統拷貝的檔案的名字。這個檔案必須存在於本地檔案系統上 source_directory_object 所指定的目錄裡。
    • destination_directory_object: 這是在目標端檔案所要放置的目錄物件。這個目錄物件必須存在於遠端檔案系統。
    • destination_file_name: 放在遠端檔案系統的檔案的名字。在遠端檔案系統目標目錄中必須沒有重名的檔案。
    • destination_database: 指向作為拷貝檔案的目的地的遠端資料庫的資料庫連結的名字。

    如果我們想要使用 DBMS_FILE_TRANSFER.PUT_FILE 來從源端傳輸檔案到目的地主機,步驟3,4,5做如下修改:
    1. 在目標資料庫主機建立一個目錄,授權給本地使用者。這是檔案要在目標端放置的目錄物件,必須在遠端的檔案系統存在。
      CREATE OR REPLACE DIRECTORY target_dir AS '+DGROUPA';
      GRANT WRITE ON DIRECTORY target_dir TO "USER";
    2. 在源資料庫主機建立一個目錄。這是要拷貝的檔案在本地源端所存在的目錄物件。這個目錄物件必須在源端存在。
      CREATE OR REPLACE DIRECTORY source_dir AS '+DGROUPS/subdir';
      GRANT READ,WRITE ON DIRECTORY source_dir TO "USER";
      CREATE OR REPLACE DIRECTORY source_dir_1 AS '+DGROUPS/subdir/subdir_2';
    3. 建立一個 dblink 連線到目標資料庫主機:
      CREATE DATABASE LINK DBS2 CONNECT TO 'user' IDENTIFIED BY 'password' USING 'target_connect';

      這裡 target_connect 是目標資料庫的連線字串,USER 是我們將要用來轉移資料檔案的使用者。
    4. 連線到源例項。會用到如下專案:
      • dbs1: 到源資料庫的連線字串
      • dbs2: 到目標資料庫的 dblink
      • a1.dat: 源資料庫的檔名
      • a4.dat: 目標資料庫的檔名
      CONNECT user/password@dbs1

      -- - put a1.dat to a4.dat (using dbs2 dblink)
      -- - level 2 sub dir to parent dir
      -- - user has read privs on source_dir_1 at dbs1 and write on target_dir 
      -- - in dbs2
      BEGIN
          DBMS_FILE_TRANSFER.PUT_FILE('source_dir_1', 'a1.dat',
                                      'target_dir', 'a4.dat', 'dbs2' );
      END;

 

參考

http://www.oracle.com/technetwork/database/features/availability/maa-wp-11g-platformmigrationtts-129269.pdf 

BUG:13001379 - DATAPUMP TRANSPORT_TABLESPACES PRODUCES WRONG METADATA FOR SOME TABLES
http://docs.oracle.com/cd/E16655_01/appdev.121/e17602/d_ftran.htm#CHDEFEGG 
NOTE:13001379.8 - Bug 13001379 - Datapump transport_tablespaces produces wrong dictionary metadata causing errors like ORA-7445 [qeaeMinmax] / ORA-1858 etc...
NOTE:1334152.1 - Corrupt IOT when using Transportable Tablespace to HP from different OS
NOTE:1324000.1 - ASMCMD Copy to Convert Endianess using RMAN fails in 11g
NOTE:13636964.8 - Bug 13636964 - ORA-19563 from RMAN convert on datafile copy transferred with DBMS_FILE_TRANSFER

NOTE:1262965.1 - Dbms_file_transfer Corrupts Dbf File When Copying between endians
NOTE:1389592.1 - 11G - Reduce Transportable Tablespace Downtime using Cross Platform Incremental Backup
BUG:9816640 - ORA-600 [6200] ORA-600 [KDDUMMY_BLKCHK] IOT CORRUPTION CODE 6401 AFTER TTS



..........................................................................................................................................................................................................................................................................................................

● 本文來自於MOS轉載文章,(文件 ID  1983639.1)

● 本文在itpub(http://blog.itpub.net/26736162)、部落格園(http://www.cnblogs.com/lhrbest)和個人微信公眾號(xiaomaimiaolhr)上有同步更新

● QQ群:230161599  微信群:私聊

● 小麥苗分享的其它資料:http://blog.itpub.net/26736162/viewspace-1624453/

● 小麥苗雲盤地址http://blog.itpub.net/26736162/viewspace-1624453/

● QQ群: 230161599   微信群:私聊

● 聯絡我請加QQ好友(642808185),註明新增緣由

版權所有,歡迎分享本文,轉載請保留出處

..........................................................................................................................................................................................................................................................................................................

手機長按下圖識別二維碼或微信客戶端掃描下邊的二維碼來關注小麥苗的微信公眾號:xiaomaimiaolhr,免費學習最實用的資料庫技術。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26736162/viewspace-2128460/,如需轉載,請註明出處,否則將追究法律責任。

相關文章