mysql和mariadb備份工具xtrabackup和mariabackup(mariadb上版本必須用這個)

簡介 

  xtraBackup(PXB) 工具是 Percona 公司用 perl 語言開發的一個用於 MySQL 數據庫物理熱備的備份工具,支持 MySQl(Oracle)、Percona Server 和 MariaDB,而且所有開源,真可謂是業界良心。阿里的 RDS MySQL 物理備份就是基於這個工具作的。因爲是採起物理拷貝的方式來作的備份,因此速度很是快,幾十G數據幾分鐘就搞定了,而它巧妙的利用了mysql 特性作到了在線熱備份,不用像之前作物理備份那樣必須關閉數據庫才行,直接在線就能完成整庫或者是部分庫的全量備份和增量備份。新版本的xtrabackup改爲了cmake安裝,和之前有點不同。mysql

版本說明:這裏安裝的版本是2.4.6,而2.3.3以後不備份死鎖了,若是數據庫是mysql 5.7以後的必需要裝2.4.4才能夠用,固然了, 會向下兼容的。linux

bin/
├── innobackupex -> xtrabackup
├── xbcloud
├── xbcloud_osenv
├── xbcrypt
├── xbstream
└── xtrabackup 

  其中最主要的是 innobackupex 和 xtrabackup,前者是一個 perl 腳本,後者是 C/C++ 編譯的二進制。Percona 在2.3 版本用C重寫了 innobackupex ,innobackupex 功能所有集成到 xtrabackup 裏面,只有一個 binary,另外爲了使用上的兼容考慮,innobackupex 做爲 xtrabackup 的一個軟連接。對於二次開發來講,2.3 擺脫了以前2個進程協做的負擔,架構上明顯要好於以前版本。(Percona XtraBackup 2.3 發佈以後,推薦的備份方法是使用 xtrabackup 腳本。 )正則表達式

xtrabackup 是用來備份 InnoDB 表的,不能備份非 InnoDB 表,和 mysqld server 沒有交互;innobackupex 腳本用來備份非 InnoDB 表,同時會調用 xtrabackup 命令來備份 InnoDB 表,還會和 mysqld server 發送命令進行交互,如加讀鎖(FTWRL)、獲取位點(SHOW SLAVE STATUS)等。簡單來講,innobackupex 在 xtrabackup 之上作了一層封裝。sql

通常狀況下,咱們是但願能備份 MyISAM 表的,雖然咱們可能本身不用 MyISAM 表,可是 mysql 庫下的系統表是 MyISAM 的,所以備份基本都經過 innobackupex 命令進行;另一個緣由是咱們可能須要保存位點信息。數據庫

另外幾個工具相對小衆些,xbcrypt 是加解密備份文件用的;xbstream 相似於tar,是 Percona 本身實現的一種支持併發寫的流文件格式;二者在備份和解壓時都會用到(若是備份用了加密和併發)。xbcloud 工具的做用是:把所有或部分 xbstream 檔案從雲上下載或上傳到雲。centos

XtraBackup原理

  2.3版本以前 innobackupex 和 xtrabackup 這2個工具之間的交互和協調是經過控制文件的建立和刪除來實現的,2.3版本將 innobackupex 功能所有集成到 xtrabackup 裏面,也就不須要他們之間的通訊。這裏介紹基於老的架構(2.2版本),可是原理和2.3是同樣的,只是實現上的差異。服務器

PXB 備份過程架構

  1. innobackupex 在啓動後,會先 fork 一個進程,啓動 xtrabackup進程,而後就等待 xtrabackup 備份完 ibd 數據文件;
  2. xtrabackup 在備份 InnoDB 相關數據時,是有2種線程的,1種是 redo 拷貝線程,負責拷貝 redo 文件,1種是 ibd 拷貝線程,負責拷貝 ibd 文件;redo 拷貝線程只有一個,在 ibd 拷貝線程以前啓動,在 ibd 線程結束後結束。xtrabackup 進程開始執行後,先啓動 redo 拷貝線程,從最新的 checkpoint 點開始順序拷貝 redo 日誌;而後再啓動 ibd 數據拷貝線程,在 xtrabackup 拷貝 ibd 過程當中,innobackupex 進程一直處於等待狀態(等待文件被建立)。
  3. xtrabackup 拷貝完成idb後,通知 innobackupex(經過建立文件),同時本身進入等待(redo 線程仍然繼續拷貝);
  4. innobackupex 收到 xtrabackup 通知後,執行FLUSH TABLES WITH READ LOCK (FTWRL),取得一致性位點,而後開始備份非 InnoDB 文件(包括 frm、MYD、MYI、CSV、opt、par等)。拷貝非 InnoDB 文件過程當中,由於數據庫處於全局只讀狀態,若是在業務的主庫備份的話,要特別當心,非 InnoDB 表(主要是MyISAM)比較多的話整庫只讀時間就會比較長,這個影響必定要評估到。
  5. 當 innobackupex 拷貝完全部非 InnoDB 表文件後,通知 xtrabackup(經過刪文件) ,同時本身進入等待(等待另外一個文件被建立);
  6. xtrabackup 收到 innobackupex 備份完非 InnoDB 通知後,就中止 redo 拷貝線程,而後通知 innobackupex redo log 拷貝完成(經過建立文件);
  7. innobackupex 收到 redo 備份完成通知後,就開始解鎖,執行 UNLOCK TABLES;
  8. 最後 innobackupex 和 xtrabackup 進程各自完成收尾工做,如資源的釋放、寫備份元數據信息等,innobackupex 等待 xtrabackup 子進程結束後退出。

在上面描述的文件拷貝,都是備份進程直接經過操做系統讀取數據文件的,只在執行 SQL 命令時和數據庫有交互,基本不影響數據庫的運行,在備份非 InnoDB 時會有一段時間只讀(若是沒有MyISAM表的話,只讀時間在幾秒左右),在備份 InnoDB 數據文件時,對數據庫徹底沒有影響,是真正的熱備。併發

InnoDB 和非 InnoDB 文件的備份都是經過拷貝文件來作的,可是實現的方式不一樣,前者是以page爲粒度作的(xtrabackup),後者是 cp 或者 tar 命令(innobackupex),xtrabackup 在讀取每一個page時會校驗 checksum 值,保證數據塊是一致的,而 innobackupex 在 cp MyISAM 文件時已經作了flush(FTWRL),磁盤上的文件也是完整的,因此最終備份集裏的數據文件都是寫入完整的。app

增量備份

PXB 是支持增量備份的,可是隻能對 InnoDB 作增量,InnoDB 每一個 page 有個 LSN 號,LSN 是全局遞增的,page 被更改時會記錄當前的 LSN 號,page中的 LSN 越大,說明當前page越新(最近被更新)。每次備份會記錄當前備份到的LSN(xtrabackup_checkpoints 文件中),增量備份就是隻拷貝LSN大於上次備份的page,比上次備份小的跳過,每一個ibd文件最終備份出來的是增量 delta 文件。

MyISAM 是沒有增量的機制的,每次增量備份都是所有拷貝的。

增量備份過程和全量備份同樣,只是在 ibd 文件拷貝上有不一樣。

恢復過程

若是看恢復備份集的日誌,會發現和 mysqld 啓動時很是類似,其實備份集的恢復就是相似 mysqld crash後,作一次 crash recover。

恢復的目的是把備份集中的數據恢復到一個一致性位點,所謂一致就是指原數據庫某一時間點各引擎數據的狀態,好比 MyISAM 中的數據對應的是 15:00 時間點的,InnoDB 中的數據對應的是 15:20 的,這種狀態的數據就是不一致的。PXB 備份集對應的一致點,就是備份時FTWRL的時間點,恢復出來的數據,就對應原數據庫FTWRL時的狀態。

由於備份時 FTWRL 後,數據庫是處於只讀的,非 InnoDB 數據是在持有全局讀鎖狀況下拷貝的,因此非 InnoDB 數據自己就對應 FTWRL 時間點;InnoDB 的 ibd 文件拷貝是在 FTWRL 前作的,拷貝出來的不一樣 ibd 文件最後更新時間點是不同的,這種狀態的 ibd 文件是不能直接用的,可是 redo log 是從備份開始一直持續拷貝的,最後的 redo 日誌點是在持有 FTWRL 後取得的,因此最終經過 redo 應用後的 ibd 數據時間點也是和 FTWRL 一致的。

因此恢復過程只涉及 InnoDB 文件的恢復,非 InnoDB 數據是不動的。備份恢復完成後,就能夠把數據文件拷貝到對應的目錄,而後經過mysqld來啓動了。

查看數據庫支持引擎(mysql和mariadb默認是Innodb引擎):

show engines;

查看數據庫表支持的引擎

show create table table_name; 

安裝

一、下載地址

  你能夠根據本身的需求選擇不一樣的操做系統和版本(我這裏是用最新的版本)

wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.11/binary/tarball/percona-xtrabackup-2.4.11-Linux-x86_64.libgcrypt145.tar.gz

二、加壓縮後,mv更改目錄名爲xtrabackup,而後加入環境變量方便使用。

export PATH=$PATH:/root/xtrabackup/bin/
source /etc/profile

完整備份

   xtrabackup選項

  xtrabackup 工具備許多參數,具體可去官網查詢(xtrabackup 參數選項 | innobackupex 參數選項),這裏簡單介紹 innobackupex 一些經常使用的參數。

  1) innobackupex 參數選項

  --defaults-file=[MY.CNF]    //指定配置文件:只能從給定的文件中讀取默認選項。 且必須做爲命令行上的第一個選項;必須是一個真實的文件,它不能是一個符號連接。

  --databases=#    //指定備份的數據庫和表,格式爲:--database="db1[.tb1] db2[.tb2]" 多個庫之間以空格隔開,若是此選項不被指定,將會備份全部的數據庫。

  --include=REGEXP    //用正則表達式的方式指定要備份的數據庫和表,格式爲 --include=‘^mydb[.]mytb’ ,對每一個庫中的每一個表逐一匹配,所以會建立全部的庫,不過是空的目錄。--include 傳遞給 xtrabackup --tables。

  --tables-file=FILE    //此選項的參數須要是一個文件名,此文件中每行包含一個要備份的表的完整名稱,格式爲databasename.tablename。該選項傳遞給 xtrabackup --tables-file,與--tables選項不一樣,只有要備份的表的庫纔會被建立。

  注意:部分備份(--include、--tables-file、--database)須要開啓 innodb_file_per_table 。

  --compact    //建立緊湊型備份,忽略全部輔助索引頁,只備份data page;經過--apply-log中重建索引--rebuild-indexs。

  --compress    //此選項指示xtrabackup壓縮備份的InnoDB數據文件,會生成 *.qp 文件。

  --decompress    //解壓縮qp文件,爲了解壓縮,必須安裝 qpress 工具。 Percona XtraBackup不會自動刪除壓縮文件,爲了清理備份目錄,用戶應手動刪除 * .qp文件:find /data/backup -name "*.qp" | xargs rm。

  --no-timestamp    //指定了這個選項備份將會直接存儲在 BACKUP-DIR 目錄,再也不建立時間戳文件夾。

  --apply-log    //應用 BACKUP-DIR 中的 xtrabackup_logfile 事務日誌文件。通常狀況下,在備份完成後,數據尚且不能用於恢復操做,由於備份的數據中可能會包含還沒有提交的事務或已經提交但還沒有同步至數據文件中的事務。所以,此時數據文件仍處於不一致狀態。「準備」的主要做用正是經過回滾未提交的事務及同步已經提交的事務至數據文件使得數據文件處於一致性狀態。

  --use-memory=#    //此選項接受一個字符參數(1M/1MB,1G/1GB,默認100M),僅與--apply-log一塊兒使用,該選項指定prepare時用於崩潰恢復(crash-recovery)的內存。

  --copy-back    //拷貝先前備份全部文件到它們的原始路徑。但原路徑下不能有任何文件或目錄,除非指定 --force-non-empty-directories 選項。

  --force-non-empty-directories    //恢復時指定此選項,可以使 --copy-back 和 --move-back 複製文件到非空目錄,即原data目錄下能夠有其餘文件,可是不能有與恢復文件中同名的文件,不然恢復失敗。

  --rsync    //此選項可優化本地文件(非InnoDB)的傳輸。rsync工具一次性拷貝全部非InnoDB文件,而不是爲每一個文件單首創建cp,在備份恢復不少數據庫和表時很是高效。此選項不能和 --stream 一塊兒使用。

  --incremental    //這個選項告訴 xtrabackup 建立一個增量備份,而不是徹底備份。它傳遞到 xtrabackup 子進程。當指定這個選項,能夠設置 --incremental-lsn 或 --incremental-basedir。若是這2個選項都沒有被指定,--incremental-basedir 傳遞給 xtrabackup 默認值,默認值爲:基礎備份目錄的第一個時間戳備份目錄。

  --incremental-basedir=DIRECTORY    //該選項接受一個字符串參數,該參數指定做爲增量備份的基本數據集的完整備份目錄。它與 --incremental 一塊兒使用。

  --incremental-dir=DIRECTORY    //該選項接受一個字符串參數,該參數指定了增量備份將與完整備份相結合的目錄,以便進行新的完整備份。它與 --incremental 選項一塊兒使用。

  --redo-only    //在「準備基本完整備份」 和 「合併全部的增量備份(除了最後一個增備)」時使用此選項。它直接傳遞給xtrabackup的 xtrabackup --apply-log-only 選項,使xtrabackup跳過"undo"階段,只作"redo"操做。若是後面還有增量備份應用到這個全備,這是必要的。有關詳細信息,請參閱xtrabackup文檔。

  --parallel=NUMBER-OF-THREADS    //此選項接受一個整數參數,指定xtrabackup子進程應用於同時備份文件的線程數。請注意,此選項僅適用於文件級別,也就是說,若是您有多個.ibd文件,則它們將被並行複製; 若是您的表一塊兒存儲在一個表空間文件中,它將不起做用。

  2) xtrabackup 參數選項

  --apply-log-only    //這個選項使在準備備份(prepare)時,只執行重作(redo)階段,這對於增量備份很是重要

 

  這裏這用的是centos7.4.x和5.5.56-MariaDB MariaDB Server,這裏以zabbix數據庫備份爲背景。

三、建立備份的目錄

mkdir -p /data/mysql

四、進行完整備份

innobackupex --defaults-file=/etc/my.cnf --user=root  --password=123456 --socket=/var/lib/mysql/mysql.sock  /data/root

五、查看備份目錄(鏈接數據庫,開始拷貝redo log,拷貝innodb表文件,鎖表、拷貝非innodb表文件,中止拷貝redo log,解鎖。)

  其中zabbix和test、mysql、performance_schema都是已經備份的數據庫,backup-my.cnf是備份的my.cnf配置文件。

xtrabackup_checkpoints:備份類型(如徹底或增量)、備份狀態(如是否已經爲prepared狀態)和LSN(日誌序列號)範圍信息;

 xtrabackup_info:記錄備份的基本信息,uuid、備份命令、備份時間、binlog、LSN、以及其餘加密壓縮等信息。

xtrabackup_logfile:備份的重作日誌文件。

 六、全盤恢復

   6.1首先中止數據庫服務,並準備好數據的恢復目錄(爲了避免覆蓋原有的數據,建議從新找個位置存放數據庫文件,我這裏是默認的/var/lib/mysql/),

systemctl stop mariadb

  6.2準備(prepare)一個徹底備份: --apply-log ( /data/root/2018-05-09_01-28-45/ 爲備份目錄,執行以後 xtrabackup_checkpoints 文件中的 backup_type = full-prepared )

[root@bogon root]# innobackupex --apply-log /data/root/2018-05-09_01-28-45/

  6.3執行恢復操做:

innobackupex  --defaults-file=/etc/my.cnf --copy-back --rsync /data/root/2018-05-09_01-28-45/

  提示咱們這個說原來數據庫存放目錄是否是空的(它其實說不讓咱們在原來的數據庫目錄恢復,要不你換地方,要不你刪除原來全部的數據庫文件,我這裏爲了防止意外,就換個地方)

  

  首先,咱們得修改my.cnf配置文件中數據庫存放位置的路徑,更改後的目錄是咱們剛纔新建的目錄。

  

  再此執行恢復操做,提示OK。

  

  6.四、剛纔咱們中止了mariadb服務,如今咱們除了要開啓數據庫服務外,還得給新的mysql目錄全部文件mysql用的屬主和屬組的權限。

[root@bogon root]# chown -R mysql.mysql /data/mysql
[root@bogon root]# systemctl start mariadb

  測試,咱們最開始備份了全部全部數據庫(備份完成後,我刪除了zabbix配置裏面的幾個監控項,當恢復完成後原來的監控項都已經恢復)

增量備份、恢復

   注意、只有InnoDB引擎支持增量備份,MyISAM只支持完整備份。

  一、首先咱們要對數據庫進行一個全備。

innobackupex -uroot -p123456 --socket=/var/lib/mysql/mysql.sock --no-timestamp /data/backup/all_backup

  二、而後咱們修改數據庫操做,再進行第一次增量備份。注意,--incremental-basedir=指的是對誰進行增量備份,這裏咱們是第一次增量備份,因此這裏指的應該是全備。

innobackupex -uroot -p123456 --socket=/var/lib/mysql/mysql.sock  --no-timestamp --incremental /data/backup/incremental-dir-1 --incremental-basedir=/data/backup/all_backup/

  三、而後咱們再對數據庫進行修改,再進行第二次增量備份。這裏咱們增量的部分是相對第一次增量備份到第二次增量備份的差別部分,因此這裏--incremental-basedir=應該是指的第一次增量備份incremental-dir-1

innobackupex -uroot -p123456 --no-timestamp --socket=/var/lib/mysql/mysql.sock  --incremental /data/backup/incremental-dir-2/  --incremental-basedir=/data/backup/incremental-dir-1/

  四、上面咱們對數據庫進行了兩次不一樣的修改,也作了兩次增量,下面咱們來看增量備份的恢復方法(爲了試驗效果明顯,我這裏刪除了兩次增量備份增長的部分)。首先咱們要準備一個完整備份(全備)

innobackupex --apply-log --redo-only /data/backup/all_backup/

  五、而後恢復第一次增量備份恢復,注意:只要不是最後一次增量備份的恢復,都須要加上--redo-only參數。

innobackupex --apply-log --redo-only /data/backup/all_backup/  --incremental-dir=/data/backup/incremental-dir-1

  六、第二次增量備份的恢復,這裏是最後一次增量備份的恢復,因此不用加--redo-only參數。

innobackupex --apply-log /data/backup/all_backup/  --incremental-dir=/data/backup/incremental-dir-2

  七、將兩次增量備份,合併到完整備份中(合併完成後,跟完整備份的恢復方法同樣)

innobackupex --apply-log /data/backup/all_backup/

  八、爲了數據一致性,先中止mariadb數據庫服務。這裏咱們的數據庫文件目錄是/var/lib/mysql下,我給他換個位置到/data/mysql(你也能夠直接mv  /var/lib/mysql  var/lib/mysql.bak,而後再新建一個mysql目錄),記得要修改/etc/my.cnf文件中datadir=路徑。

mkdir -p /data/mysql

  九、恢復的目錄有了,咱們下面開始恢復,想到與被上面合成到一塊兒的增量備份文件copy到/data/mysql/這個目錄下。

innobackupex --copy-back /data/backup/all_backup/

  十、只恢復文件還不行,這會兒/data/mysql/下的文件(包含一級目錄都是屬主和屬組都是root,,咱們須要給mysql權限)

chown mysql:mysql -R /data/mysql/

  十一、啓動數據庫服務,增量備份的備份和恢復完整。

systemctl restart  mariadb

差別備份、恢復(建議使用)

   增量備份的優缺點:

  一、上面咱們說了xtrabackup的增量備份和恢復,增量備份有它的好處,就是每次進行相對上次備份有不一樣的地方進行備份,可是中間若是哪一個備份掛了(丟失了),那就無法恢復了,並且增量備份通常都是每間隔幾個小時備份一次(最次也得天天進行一次增量備份)。恢復起來實際上是很麻煩的,可能須要你恢復的時候,增量備份已經好幾百個了,除非你寫腳本,不然我的感受很麻煩的。

  二、咱們知道增量備份的時候有個參數--incremental-dir=,它的意思是根據以前的哪次備份進行差別性備份,之前增量狀況是首先一個全備,第一次增量的作法是根據全備進行備份,第二次增量備份的作法是根據第一次增量備份進行備份,依次類推。很麻煩。

  三、既然能夠指定根據哪次作增量備份,咱們就直接每次根據完整備份進行增量備份----差別備份。這樣作的好處是恢復時候只須要恢復最後一次增量備份就行,缺點是咱們每次都是根據完整備份進行備份,長時間下去會佔用空間很大。

備份:

一、首先進行一次完整備份

innobackupex -uroot -p123456 --socket=/var/lib/mysql/mysql.sock --no-timestamp /data/backup/all_backup

二、第一次次增量備份

innobackupex -uroot -p123456 --socket=/var/lib/mysql/mysql.sock  --no-timestamp --incremental /data/backup/incremental-dir-1 --incremental-basedir=/data/backup/all_backup/

三、第二次增量備份

innobackupex -uroot -p123456 --socket=/var/lib/mysql/mysql.sock  --no-timestamp --incremental /data/backup/incremental-dir-2 --incremental-basedir=/data/backup/all_backup/

四、第三次增量備份

innobackupex -uroot -p123456 --socket=/var/lib/mysql/mysql.sock  --no-timestamp --incremental /data/backup/incremental-dir-3 --incremental-basedir=/data/backup/all_backup/

注意,上面咱們每次備份都是根據完整備份進行增量備份的。

恢復:

一、首先準備一個全備

innobackupex --apply-log --redo-only /data/backup/all_backup/

二、恢復最後一次備份,這裏恢復是確定最後一次恢復,因此不用加--redo-only參數

innobackupex --apply-log /data/backup/all_backup/  --incremental-dir=/data/backup/incremental-dir-3

三、將增量備份合併到完整備份中。

innobackupex --apply-log /data/backup/all_backup/

四、爲了數據一致性,先中止mariadb數據庫服務。這裏咱們的數據庫文件目錄是/var/lib/mysql下,我給他換個位置到/data/mysql(你也能夠直接mv  /var/lib/mysql  var/lib/mysql.bak,而後再新建一個mysql目錄),記得要修改/etc/my.cnf文件中datadir=路徑。

mkdir -p /data/mysql

五、恢復的目錄有了,咱們下面開始恢復,想到與被上面合成到一塊兒的增量備份文件copy到/data/mysql/這個目錄下。

innobackupex --copy-back /data/backup/all_backup/

六、只恢復文件還不行,這會兒/data/mysql/下的文件(包含一級目錄都是屬主和屬組都是root,,咱們須要給mysql權限)

chown mysql:mysql -R /data/mysql/

七、啓動數據庫服務,增量備份的備份和恢復完整。

systemctl restart  mariadb

注意:

  一、完整備份須要備份到另一個位置,若是你恢復失敗的,你的完整備份裏面的參數也會跟着改變了,這個時候須要再恢復就困難了。相反我只須要把完整備份的備份cp到完整備份的目錄裏面就OK了,能夠接着折騰了。

  二、若是你不備份你的完整備份,一旦恢復失敗,想要從新恢復,那你就等着哭吧。

參考與:https://www.linuxidc.com/Linux/2017-03/142380.htm

 

mariadb10.1以上版本使用的是mariabackup這個備份工具,而不是 xtrabackup,mariabackup是要單獨安裝的。安裝完後按照一下步驟操做:

yum -y  install MariaDB-backup

  

源服務器:

  注意:這裏若是你備份的是10.3的版本數據庫,必定要以10.3版本的數據恢復,不然將沒法恢復,親測,10.3.8的版本文件沒法在10.1.34上沒法恢復。

一、源服務器建立一個備份的目標目錄,例如mkdir var/databasebackup,附加讀寫權限;

二、用mariabackup --backup --target-dir /data/mysqlbak --user username --password userpassword ,備份的是服務器上全部數據庫,固然你也能夠加參數--databases來指定要備份數據庫;

目標服務器:

一、一樣創建一個還原的目標目錄,例如mkdir /data/mysqlbak,附加讀寫權限;

二、把源服務器上備份的數據庫文件拷貝到目標服務器/data/mysqlbak下;

三、先用mariabackup --prepare --target-dir /data/mysqlbak --user username --password userpassword,將備份文件規範化,這裏能夠得到備份文件的備份log節點,有助於主從同步使用,假如你有主從同步的話;

四、用 mariabackup --copy-back --target-dir /data/mysqlbak --user username --password userpassword ,來還原數據庫;(記住在還原前清掉數據庫目錄)

五、將數據庫文件附上數據庫權限,chown -R mysql:mysql /var/lib/mysql

六、重啓服務器systemctl restart mysql。

 https://blog.csdn.net/qooer_tech/article/details/80811615

相關文章
相關標籤/搜索