數據庫的備份與恢復

  1. 數據備份:將源數據再次存儲到新的位置
    mysql

  2. 數據恢復:將備份好的數據從新應用到數據庫系統sql

  3. 常見的備份類型:shell

      a.按照是否備份整個數據集來分數據庫

          徹底備份:備份從開始到執行備份這一時刻的全部數據集vim

          增量備份:備份從上次備份到此次備份時刻變化的數據集緩存

          差別備份:備份從上一次徹底備份到這一備份時刻變化的數據集安全

     b.按照備份的數據庫對象來分bash

          物理備份:經過複製數據集在文件系統中的文件來備份服務器

          邏輯備份:在數據庫的客戶端工具上使用SQL語句,應用程序或其餘腳本文件作備份的操做併發

     c.按照備份時,還能提供的服務分類

         熱備份:備份的過程當中,能夠對備份的數據集作讀寫操做

         溫備份:備份的過程當中,只能對備份的數據集只能作讀操做,不可有寫操做

         冷備份:備份的過程當中,直接將服務下線,讀寫操做均沒法執行

4.    備份的數據內容:
        1.數據;
        2.二進制日誌
        3.InnoDB存儲之前的事務日誌文件;
        4.代碼——存儲過程,存儲函數,觸發器,事件調度器等;
        5.當前服務器上用於啓動數據服務是所使用的配置文件;
        6.操做系統上與MySQL或MariaDB相關的配置——sudo任務、cron任務等;

經常使用的備份數據的方法:

    1)使用select語句導出數據作備份,而後使用load data命令作數據恢復

         備份類型:由於是使用SQL語句作備份的,因此是溫備份

         備份語句:SELECT .....  INTO OUTFILE "file_name" [FIELDS TERMINATED BY 'string'] [ENCLOSED BY 'char']  [ESCAPED BY 'char'] ]   [LINES [STARTING BY 'string']  [TERMINATED BY 'string']]

         數據導入語句(數據恢復):LOAD DATA INFILE 「/path/file_name」 INTO TABLE table_name  [FIELDS TERMINATED BY 'string'] [ENCLOSED BY 'char']  [ESCAPED BY 'char'] ]   [LINES [STARTING BY 'string']  [TERMINATED BY 'string']]

        FIELDS各選項內容

            TERMINATED BY 'string'  :指定導出或者導入時的字段分隔符

             ENCLOSED BY 'char' :指定導入或導出時的引用符號

             ESCAPED BY 'char'  :定義轉義字符默認是  \

        LINES各選項內容

            STARTING BY 'string':指定行的起始符號,默認不指定

            TERMINATED BY 'string':指定行的分隔符,默認換行符

數據備份恢復實例:

MariaDB [hellodb]> lock tables students read;  給表添加讀鎖,以避免在作數據備份的時候,數據發生變化
MariaDB [hellodb]> select * from students into outfile "stud.txt"; //將students表內的全部內容,備份,放到stud.txt文件中
Query OK, 25 rows affected (0.01 sec)
由於這次操做在hellodb數據庫中作的,因此默認文件將會建立在hellodb數據庫下的stud.txt文件中
查看stud.txt文件內的內容
MariaDB [hellodb]> unlock tables;  釋放鎖
[root@bogon ~]# cat /var/lib/mysql/hellodb/stud.txt
1    Shi Zhongyu    22    M    2    3
2    Shi Potian    22    M    1    7
3    Xie Yanke    53    M    2    6
4    Ding Dian    32    M    4    4
5    Yu Yutong    26    M    3    1
6    Shi Qing    46    M    5    7
7    Xi Ren    19    F    3    9
8    Lin Daiyu    17    F    7    5

圖片.png

MariaDB [hellodb]> delete from students;  //清除students表中的數據
MariaDB [hellodb]> select * from students; //查看students表中是否有數據
Empty set (0.00 sec)

MariaDB [hellodb]> load data infile "/var/lib/mysql/hellodb/stud.txt" into table students; //作數據恢復,使用的文件請用絕對路徑
Query OK, 25 rows affected (0.09 sec)                
Records: 25  Deleted: 0  Skipped: 0  Warnings: 0

MariaDB [hellodb]> select * from students;  //再次查看錶
+-------+---------------+-----+--------+---------+-----------+
| StuID | Name          | Age | Gender | ClassID | TeacherID |
+-------+---------------+-----+--------+---------+-----------+
|     1 | Shi Zhongyu   |  22 | M      |       2 |         3 |
|     2 | Shi Potian    |  22 | M      |       1 |         7 |
|     3 | Xie Yanke     |  53 | M      |       2 |         6 |

注意:1.這種備份操做,屬於邏輯備份和溫備份,備份時須要提早給表施加讀鎖;

          2.使用select導出數據,只會導出數據,但不會導出表的格式,因此當咱們使用load data導入數據時,要保證表存在,且表結構與以前相同,因此這種備份只能作表數據備份恢復,

MariaDB [hellodb]> alter table students drop TeacherID;  //刪除最後一個字段
MariaDB [hellodb]> load data infile "/var/lib/mysql/hellodb/stud.txt" into table students;
Query OK, 25 rows affected, 25 warnings (0.01 sec)   
Records: 25  Deleted: 0  Skipped: 0  Warnings: 25

MariaDB [hellodb]> select * from students;
+-------+---------------+-----+--------+---------+
| StuID | Name          | Age | Gender | ClassID |
+-------+---------------+-----+--------+---------+
|     1 | Shi Zhongyu   |  22 | M      |       2 |
|     2 | Shi Potian    |  22 | M      |       1 |
|     3 | Xie Yanke     |  53 | M      |       2 |
|     4 | Ding Dian     |  32 | M      |       4 |
作恢復時,會有警告,可是不影響前面幾個字段的數據恢復,最後一個字段沒法恢復
MariaDB [hellodb]> alter table students drop Name;刪除中間字段
MariaDB [hellodb]> load data infile "/var/lib/mysql/hellodb/stud.txt" into table students;
Query OK, 25 rows affected, 100 warnings (0.01 sec)  
Records: 25  Deleted: 0  Skipped: 0  Warnings: 100

MariaDB [hellodb]> select * from students;
+-------+-----+--------+---------+
| StuID | Age | Gender | ClassID |
+-------+-----+--------+---------+
|     1 |   0 |        |       0 |
|     2 |   0 |        |       0 |
|     3 |   0 |        |       0 |
|     4 |   0 |        |       0 |
|     5 |   0 |        |       0 |
|     6 |   0 |        |       0 |
出現警告,但數據恢復操做執行完成,可是因爲多個字段間數據類型等不一致,會致使表數據沒法正常恢復;


刪除表操做
MariaDB [hellodb]> drop table students;
Query OK, 0 rows affected (0.04 sec)

MariaDB [hellodb]> load data infile "/var/lib/mysql/hellodb/stud.txt" into table students;
ERROR 1146 (42S02): Table 'hellodb.students' doesn't exist
會顯示錯誤,表不存在沒法恢復

          3.當咱們使用哪一個數據庫作數據導出時,其導出的文件會默認存在該數據庫的目錄下;固然咱們可使用變量 secure_file_priv修改保存路徑,可是此變量是隻讀變量;

          4.若咱們導出的數據內容,變換了默認格式,則在導入的時候也應該使用相同的格式導入,不然表內容出錯;

MariaDB [hellodb]> select * from hellodb.students into outfile "students1.txt" fields terminated by ":";  //導出數據時,變換默認的分隔符
Query OK, 25 rows affected (0.02 sec)

[root@bogon ~]# cat /var/lib/mysql/hellodb/students1.txt
1:Shi Zhongyu:22:M:2:3
2:Shi Potian:22:M:1:7
3:Xie Yanke:53:M:2:6
4:Ding Dian:32:M:4:4
5:Yu Yutong:26:M:3:1

導入時,不變換分隔符
MariaDB [hellodb]> load data infile "/var/lib/mysql/hellodb/students1.txt" into table students;
Query OK, 25 rows affected, 150 warnings (0.02 sec)  
Records: 25  Deleted: 0  Skipped: 0  Warnings: 150

MariaDB [hellodb]> select * from students;
+-------+------+-----+--------+---------+-----------+
| StuID | Name | Age | Gender | ClassID | TeacherID |
+-------+------+-----+--------+---------+-----------+
|     1 |      |   0 |        |    NULL |      NULL |
|     2 |      |   0 |        |    NULL |      NULL |
|     3 |      |   0 |        |    NULL |      NULL |
|     4 |      |   0 |        |    NULL |      NULL |

        5.在作數據導入,可使用mysqlimport命令

            用法mysqlimport [options] db_name textfile1

[root@bogon ~]# mysqlimport -d hellodb /var/lib/mysql/hellodb/students.txt 
hellodb.students: Records: 25  Deleted: 0  Skipped: 0  Warnings: 0

mysqlimport原理和load data相同,只是執行方式不一樣

    mysqlimport選項:

        --fields-terminated-by=..., --fields-enclosed-by=..., --fields-optionally-enclosed-by=..., --fields-escaped-by=...
            --lines-terminated-by=...
            --use-threads=N:使用多mysql線程實現併發導入;
            --lock-tables, -l:給表施加鎖;
            --local, -L:讀取客戶端本地的某文件,將其中的內容恢復之表中;
            --ignore-lines=N:導入數據時忽略前N行記錄;

 2)使用mysqldump工具作數據的備份和恢復;

            此備份恢復是針對數據庫及數據庫中數據集作恢復的

格式:mysqldump [options] [db_name [tbl_name ...]]
        shell> mysqldump [options] db_name [tbl_name ...] 
        shell> mysqldump [options] --databases db_name ...
        shell> mysqldump [options] --all-databases

mysqldump原理:會將你要導出的表,或數據庫,寫成SQL語句而且標準輸出,此時須要咱們用重定向,將這些內容,寫入一個新的文件之中,將文件後綴改成.sql,  使得其能夠在mysql之中運行,從而達到數據恢復的效果

        簡單示例:

[root@bogon ~]# mysqldump hellodb students > stud.sql
vim stud.sql

圖片.png

而後咱們刪掉表而且作恢復

MariaDB [hellodb]> drop table students;
Query OK, 0 rows affected (0.02 sec)

MariaDB [hellodb]> \. stud.sql
Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)
......

    mysqldump的經常使用選項

          鏈接選項:
            -u, -h, -p, -P, -S, --protocol;用法和mysql相同
        篩選選項:
            --all-databases, -A   備份全部的數據庫
            --databases, -B  指定須要備份的數據庫;一旦寫上此選項,則該選項後面的全部內容都被當成數據庫名稱,並且在輸出的文件中,每一個數據庫前都會加上建立數據庫和use語句;

加--databases和不加--databases的區別
不加--databases ,不會建立數據庫,只會恢復其中的表,因此咱們須要依賴一個指定的數據庫才行

圖片.png         

加上--databases 
會建立出數據庫,而且在建立數據庫之中建立相應的表

圖片.png

  --ignore-table=db_name.tbl_name 指定不導出哪一個表,一個該選項只能寫一個表
            --no-data, -d   再也不導出表中的數據,僅僅導出表結構

圖片.png          

         --routines, -R
                導出存儲函數和存儲過程,但不會導出它們的屬性值;
            --events, -E
                導出事件調度器;
            --triggers
                導出觸發器,此功能默認開啓,想要關閉可使用--skip-triggers選項;
            --tables
                覆蓋了--databases選項,使得其後面全部的參數都被看成表名處理;使用了此選項,每次mysqldump僅能導出一個庫中表的數據;
                    格式爲:--tables db_name tbl_name1 tbl_name2 ...

示例:導出某個數據的某個表
[root@bogon ~]# mysqldump --database hellodb students > hello.sql   //若不加--tables 怎會將students表,當數據庫處理,顯然這不是數據庫,則報錯
mysqldump: Got error: 1049: "Unknown database 'students'" when selecting the database
[root@bogon ~]# mysqldump --database hellodb --tables students > hello.sql  因此須要加一個--tables作分隔

            --where=´where_condition´, -w ´where_condition´
                指定篩選條件並導出表中符合篩選條件的數據;
                如:--where='Name=James'

        DDL選項:
            --add-drop-database
                在導出的數據文件中的每個create databases語句前加上drop database if exists的語句先刪除指定的數據庫;

/*!40000 DROP DATABASE IF EXISTS `hellodb`*/;   //會在建立數據庫前一行添加此行

    

            --add-drop-table
                在導出的數據文件中的每個create table語句前加上drop table if exists語句,先刪除指定表;默認已經開啓的功能;
            --no-create-db, -n
                在使用了--databases或者--all-databases選項時,在導出的文件中回加上建立數據庫的語句;而一旦使用的此選項,前兩個選項的功能會被抑制;

圖片.png           


        --no-create-info, -t
                不會在導出的文件中添加建立表的語句;
            --replace
                全部向表中添加數據的操做語句均被替換成REPLACE語句,而不是INSERT語句;

        字符集選項:
            --default-character-set=charset_name
                在導出數據的過程當中,指定導出時使用的字符集;
                此選項有時很重要,遷移數據的目標主機上和當前服務器的字符集若是不相同,可能會致使亂碼;
                默認的字符集:utf8
            --set-charset
                在導出的數據結果中加上SET NAMES statement語句,默認此功能已被啓用。
                想要關閉此功能,可使用選項:--skip-set-charset;

        與主從複製相關的選項:
            --delete-master-logs
                在執行了一次dump操做以後,會向主服務器發送一個PURGE BINARY LOGS statement,以刪除其二進制日誌;而且會自動激活--master-data選項的功能;
            --master-data[=value]
                該選項主要用來創建一個複製操做;
                    當值爲1時,導出的數據文件中會記錄CHANGE MASTER語句;
                    當值爲2時,導出的數據文件中會記錄CHANGE MASTER語句,但該語句被註釋;
                    默認值爲無任何值,意味着在導出的數據文件中不會記錄CHANGE MASTER語句;

                    在使用此選項時,會自動忽略--lock-tables選項;
                    當使用了--single-tranaction選項時,也會自動激活--lock-all-tables;

        格式化選項:
            --compact
                緊湊格式輸出,即:簡化輸出的數據內容,幾乎全部的註釋類信息都不會被輸出到文件中;
                至關於:--skip-add-drop-table, --skip-add-locks, --skip-comments, --skip-disable-keys, and --skip-set-charset選項的組合;
            --complete-insert, -c
                在INSERT語句中加入各個被操做的列的名稱;
            --tab=path, -T path
                將每一個表的結構定義用的SQL語句和表中存儲的數據內容,分別導出到指定的目錄中,使用不一樣的文件進行保存;其中TBL_NAME.sql文件存放表的定義格式,TBL_NAME.txt文件存放表中的數據;在導出數據內容的時候,實質上就是使用了SELECT ... OUTFILE 'tbl_name.txt'語句,默認的字段分隔符就是"\t";

                使用此選項操做時,必需要有一個前提條件:client和server必須是同一臺主機,且mysql用戶對指定的目錄要有寫權限,同時鏈接數據庫的用戶必須有FILE權限;並且還要求不能和--databases或--all-databases選項一塊兒使用。

                    --fields-terminated-by=..., --fields-enclosed-by=..., --fields-optionally-enclosed-by=..., --fields-escaped-by=..., --lines-terminated-by=...
                上述選項能夠在此時應用,用於指定各類分隔符;
            --quote-names, -Q
                引用表名或列名時,使用何種引用符號,默認的引用符號爲反向單引號,即:`

        性能選項:
            --delayed-insert
                在非事務型存儲引擎管理的表中,在INSERT操做時能夠支持DELAYED功能;
                在MySQL的5.6.6開始已經被廢棄;
            --disable-keys, -K
                在INSERT語句先後加上禁用和啓用索引的語句;
                在大量的數據插入時,此選項頗有用,默認開啓的;
            --insert-ignore
                使用INSERT IGNORE語句代替INSERT語句;
            --quick, -q
                快速導出數據,在導出大表時很是有用;
                默認導出數據時會一次性檢索表中全部數據並加入到內存中,而使用該選項則是檢索一行導出一行;

        加鎖和事務有關的選項:
            --add-locks
                在INSERT語句的先後加上LOCK TABLES和UNLOCK TABLES語句,默認開啓;
            --flush-logs, -F
                在開始導出數據前事先刷寫二進制日誌(二進制日誌手動的滾動);
                若是使用了--all-databases選項,則依次在導出各個數據庫以前都會執行FLUSH LOGS;
                若是使用了--lock-all-tables或--master-data選項,則刷寫日誌僅執行一次;等價於FLUSH TABLES WITH READ LOCK;鎖定全部表,能夠保證數據的一致性;
            --flush-privileges
                在導出全部數據庫以後在數據文件的結尾加上FLUSH PRIVILEGES語句;
                通常會在導出mysql庫或者依賴於mysql庫時都應該使用此選項;
            --lock-all-tables, -x
                爲全部的表施加一個一直持續到數據導出結束的全局讀鎖。該選項僅在數據導出開始時施加一次讀鎖,而該鎖鎖全部表且永久鎖,直到數據導出結束纔會釋放;
                該選項開啓後會自動關閉--single-transaction和--lock-tables選項;
            --lock-tables, -l
                在導出每一個數據庫的數據以前依次對該數據庫中的全部表施加讀鎖(屢次的鎖施加過程),對於非事務型的存儲引擎(如:MyISAM)的表能夠進行並行鎖操做;但對於事務型存儲引擎(如:InnoDB)的表來講,使用--single-tranaction選項更好,由於InnoDB無需徹底鎖表;
            --single-transaction
                該選項在導出數據前將設置一個事務,且隔離級別爲REPEATABLE-READ,而且同時發送一個START TRANSACTION語句給服務器端;
                該選項在導出InnoDB存儲引擎的表時很是有用,一旦開啓事務,則意味着數據庫會有一致性和持久性的安全保護,不會阻塞任何其餘會話或線程的數據處理。
            --no-autocommit
                在INSERT語句先後加上SET @@autocommit=0及SET @@autocommit=1的語句,而且在須要提交事務時添加COMMIT語句;
            --order-by-primary
                若是被導出的表中存在主鍵索引或惟一鍵索引,則排序後按照順序導出數據;
                對於導出MyISAM表比導出InnoDB表更有用;


完整示例:

    1.導出一個innodb引擎的表

        [root@bogon ~]# mysqldump --database hellodb --no-create-db --tables students --single-transaction --flush-logs > hello.sql
  MariaDB [hellodb]> drop table students;   //破壞數據
Query OK, 0 rows affected (0.04 sec)

    2.作數據恢復

MariaDB [hellodb]> set @@sql_log_bin=0;
Query OK, 0 rows affected (0.00 sec)

MariaDB [hellodb]> \. hello.sql
Query OK, 0 rows affected (0.00 sec)

MariaDB [hellodb]> set @@sql_log_bin=1;
Query OK, 0 rows affected (0.00 sec)

    注意:

        1.在作備份的時候,一樣須要咱們給表施加鎖,面對MyISAM表咱們添加--lock-tables,面對innodb表須要添加,--single-transaction

        2.在作數據導出時,儘可能添加--flush-logs選項,刷寫二進制日誌,這樣之後能夠更方便的使用該二進制日誌作增量恢復;

        3.在作數據恢復時,也會產生二進制日誌,可是這種日誌內容,是多餘的,咱們能夠手動關閉二進制日誌記錄功能,等待恢復完成後,再手動開啓

     3)使用lvm2作備份恢復;

            是物理備份,溫備份

            備份原理:使用快照技術,將此事此刻的數據庫系統內容作標記,若數據庫某一內容發生變化,則將其原數據內容複製到快照空間中,沒發生變化的則不會作快照。

            恢復原理:將快照後的內容保存到其餘文件中,若數據庫丟失,則能夠將快照的內容複製到數據庫目錄中,實現恢復;

具體操做:

        1.添加新的磁盤(作快照方便)

            爲其建立卷組,及邏輯卷,並格式化邏輯卷,建議文件系統類型爲ext4

pvcreate /dev/sdb
vgcreate -s 16M testvg /dev/sdb
lvcreate -L 10GiB -n testlv testvg
mkfs -t ext4  /dev/testvg/testlv
mkdir /data/mysql
mount /dev/testvg/testlv /data/mysql/   //將作好的邏輯卷掛載到/data/mysql下

            2.關閉mysql服務,修改mysql數據庫目錄爲新目錄,並將原來的數據庫內容複製一份到新數據庫目錄下

cp -a /var/lib/mysql/* /data/mysql/
chown -R mysql. /data/mysql/
修改/etc/my.cnf(設置selinxu策略)
[mysqld]
datadir=/data/mysql
開啓服務

            3.進入mysql交互命令中,施加全局鎖

MariaDB [(none)]> flush tables with read lock;

            4.爲數據庫目錄建立快照,

lvcreate -s -L 1GiB -p r -n mysql_photo /dev/testvg/testlv
建立完成以後,解鎖
MariaDB [(none)]> unlock tables;

            5.掛載快照,並將其內容複製出去,而後刪除快照

mount /dev/testvg/mysql_photo /mydata/photo/
cp -a /mydata/photo/* /mysql/

            6.作數據恢復(線下恢復),因此須要關閉mysql服務

[root@bogon ~]# systemctl stop mariadb.service
[root@bogon ~]# cp -a /mysql/* /data/mysql/
[root@bogon ~]# chown -R mysql. /data/mysql/  修改權限
[root@bogon ~]# systemctl start mariadb.service 啓動服務
[root@bogon ~]# mysql -S /data/mysql/mysql.sock鏈接數據庫

注意:快照恢復是物理備份,和徹底備份,若想實現對快照後數據變化的恢復,則須要咱們使用二進制日誌文件


    4)使用xtrabackup工具作恢復

            物理備份

            對MyISAM引擎的表作溫備份(施加全局鎖,或備份鎖)

            對innodb引擎的表作熱備份(備份並監控redo log,在其備份期間若redo log還在變化,則會將變化的內容寫入緩存,並依次備份,等備份結束還會對備分內容重寫,實現熱備份)

        步驟:

            備份過程:備份redo log文件以及獲取二進制文件座標點,並作備份

            準備過程:若引擎是innodb,則對備份好的redo log文件作檢測,主要是對一些事物,實現前滾或回滾

            恢復過程:物理恢復,須要關閉服務

        語法:

            innobackupex [options] /path/file

option:
                    鏈接選項:
                        --user=USERNAME
                        --host=HOSTNAME
                        --port=PORT
                        --password=PASSWORD
                        --socket=SOCKET_FILE_NAME
                    功能選項:
                        --backup:實施數據備份過程;(默認)
                        --prepare:實施準備過程;
                        --copy-back:實施數據恢復過程;
                        --apply-log:在準備過程當中,用於應用redo log;
                        --redo-only:在準備過程當中,僅應用redo log;
                        --incremental:在數據備份的過程當中,實施增量備份;
                        --incremental-basedir:在實施增量備份時,用於指定增量備份的參考目錄;

innobackupex /ttt
......
180804 05:45:17 completed OK!
[root@bogon ~]# ll /ttt/
總用量 4
drwx------. 12 root root 4096 8月   4 05:45 2018-08-04_05-45-15  默認徹底備份

            增量備份

[root@bogon 2018-08-04_05-52-36]# innobackupex --incremental --incremental-basedir /ttt/2018-08-04_05-45-15 /ttt   //基於徹底備份的目錄作增量備份

            準備(須要安照步驟依次準備):每次準備都會把增量內容添加到徹底備份上

[root@bogon ttt]# innobackupex --apply-log --redo-only /ttt/2018-08-04_05-45-15/  /徹底備份準備
innobackupex --apply-log --redo-only /ttt/2018-08-04_05-45-15/ --incremental-dir /ttt/2018-08-04_05-52-36/  //增量備份準備
                                       徹底備份目錄                                    增量備份目錄

            恢復:(須要中止mysql服務,而且保證datadir下爲空),不然報錯

Original data directory /var/lib/mysql is not empty!

[root@bogon ttt]# innobackupex --copy-back /ttt/2018-08-04_05-45-15/   //恢復只須要寫徹底備份目錄
[root@bogon ttt]# chown -R mysql. /var/lib/mysql/  //修改權限

            啓動服務便可;

相關文章
相關標籤/搜索