python程式設計-利用python程式設計寫一個購物小程式
資料庫備份與恢復
資料庫備份的重要性
1、在生產環境中,資料的安全性至關重要
2、任何資料的丟失都可能產生嚴重的後果
3、造成資料丟失的原因
- 程式錯誤
- 人為操作錯誤
- 運算錯誤
- 磁碟故障
- 災難(如火災,地震)和盜竊
資料庫備份的分類
從物理與邏輯的角度,備份可分為
物理備份:對資料庫作業系統的物理檔案(如資料檔案、日誌檔案等)的備份
物理備份方法
- 冷備份(離線備份):是在關閉資料庫的時候進行的
- 熱備份(聯機備份):資料庫處於執行狀態,依賴於資料庫的日誌檔案
- 溫備份:資料庫鎖定表格(不可寫入但可讀)的狀態下進行備份操作
邏輯備份:對資料庫邏輯元件(如:表等資料庫物件)的備份
從資料庫的備份策略角度,備份可分為
完全備份:每次對資料庫進行完整的備份
差異備份:備份自從上次完全備份之後被修改過的檔案
增量備份:只有在上次完全備份或者增量備份後被修改的檔案才會被備份
MySQL資料庫完全備份與恢復
常見的備份方法
物理冷備
備份時資料庫處於關閉狀態,直接打包資料庫檔案
備份速度快,恢復時也是最簡單的
專業備份工具mysqldump或mysqlhotcopy
mysqldump常用的邏輯備份工具
mysqlhotcopy僅擁有備份MyISAM和ARCHIVE表
啟用二進位制日誌進行增量備份
進行增量備份,需要重新整理二進位制日誌
第三方工具備份
免費的MySQL熱備份軟體Percona XtraBackup
MySQL資料庫完全備份簡介
1、是對整個資料庫、資料庫結構和檔案結構的備份
2、儲存的是備份完成時刻的資料庫
3、是差異備份與增量備份的基礎
4、每次對資料進行完整的備份,完全備份是增量備份的基礎,完全備份儲存的是備份完成時刻的資料庫
5、優點:
備份與恢復操作簡單方便
6、缺點
資料存在大量的重複
佔用大量的備份空間
備份與恢復時間長
資料庫完全備份分類
物理冷備份與恢復
關閉MySQL資料庫
使用tar命令直接打包資料庫資料夾
直接替換現有MySQL目錄即可
mysqldump備份與恢復
MySQL自帶的備份工具,可方便實現對MySQL的備份
可以將指定的庫、表匯出為SQL指令碼(.sql結尾)
物理冷備份與恢復步驟
在MySQL中先建立庫,再建立表,寫入記錄(用於驗證)
mysql> select * from abc;
+------+----------+-------+-------+
| id | name | score | hobby |
+------+----------+-------+-------+
| NULL | zhangsan | 99 | 2 |
| NULL | wangwu | 98 | 1 |
| NULL | chenqi | 97 | 3 |
+------+----------+-------+-------+
3 rows in set (0.00 sec)
先關閉資料庫服務,再打包備份
[root@server1 ~]# systemctl stop mysqld.service
[root@server1 ~]# tar zcvf /opt/mysql_all-$(date +%F).tar.gz /usr/local/mysql/data
[root@server1 ~]# cd /opt
[root@server1 opt]# ls
mysql_all-2020-12-24.tar.gz rh
將原來的資料移走到備份資料夾中,解壓剛才備份的tar包到/restore目錄下,再移動到mysql服務的資料夾中
[root@server1 ~]# mkdir bak #建立備份資料夾
[root@server1 ~]# mv /usr/local/mysql/data bak #將現在的資料庫檔案移動至備份資料夾,以模擬資料庫損壞
[root@server1 ~]# mkdir restore #建立恢復資料夾
[root@server1 ~]# tar zxvf /opt/mysql_all-2020-12-24.tar.gz -C restore/ #解壓打包的備份至恢復資料夾
[root@server1 data]# ls
auto.cnf ib_logfile0 mysql
ib_buffer_pool ib_logfile1 performance_schema
ibdata1 lcx sys
[root@server1 data]# pwd
/root/restore/usr/local/mysql/data
[root@server1 ~]# mv restore/usr/local/mysql/data/ /usr/local/mysql/ #將解壓後的備份資料移動至資料庫資料夾中
重啟mysql服務,登入mysql,檢視資料是否恢復
mysql> select * from lcx.abc;
+------+----------+-------+
| id | name | score |
+------+----------+-------+
| 1 | zhangsan | 99 |
| 2 | wangwu | 98 |
| 3 | chenqi | 97 |
+------+----------+-------+
3 rows in set (0.01 sec)
mysqldump備份和恢復
備份
mysqldump -u root -p --all-databses > all-data-$(date +%F).sql ###備份所有資料庫
mysqldump -u root -p -databases auth mysql > auth-mysql.sql ###備份auth和mysql庫
mysqldump -u root -p auth > auth-$(data +%F).sql ###備份auth資料庫
mysqldump -u root -p mysql user > mysql-user-$(date +%F).sql ###備份mysql的user表
mysqldump -u root -p -d mysql user > /tmp/desc-mysql-user.sql ###備份mysql庫user表的結構
恢復
方法一:基於mysql命令恢復
[root@server1 ~]# mysqldump -u root -p lcx > test-$(date +%F).sql #使用mysqldump工具備份lcx庫
Enter password: #輸入密碼,不顯示
mysql> drop database lcx; #刪除lcx庫模擬資料庫故障
Query OK, 1 row affected (0.00 sec)
mysql> create database test2; #建立空庫
Query OK, 1 row affected (0.00 sec)
[root@server1 ~]# mysql -u root -p test2 < test-2020-12-24.sql #恢復至test2庫
Enter password: #輸入密碼,不顯示
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test2 |
+--------------------+
5 rows in set (0.00 sec)
mysql> use test2
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+-----------------+
| Tables_in_test2 |
+-----------------+
| abc |
+-----------------+
1 row in set (0.00 sec)
mysql> select * from abc;
+------+----------+-------+
| id | name | score |
+------+----------+-------+
| 1 | zhangsan | 99 |
| 2 | wangwu | 98 |
| 3 | chenqi | 97 |
+------+----------+-------+
3 rows in set (0.00 sec)
方法二:source基於指令碼恢復
mysql> use test2;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> source /root/test-2020-12-24.sql; #通過.sql格式的備份檔案恢復至當前庫中
………………
Query OK, 3 rows affected (0.00 sec) #恢復三條記錄
Records: 3 Duplicates: 0 Warnings: 0
………………
mysql> show tables;
+-----------------+
| Tables_in_test2 |
+-----------------+
| abc |
+-----------------+
1 row in set (0.00 sec)
mysql> select * from abc;
+------+----------+-------+
| id | name | score |
+------+----------+-------+
| 1 | zhangsan | 99 |
| 2 | wangwu | 98 |
| 3 | chenqi | 97 |
+------+----------+-------+
3 rows in set (0.00 sec)
MySQL資料庫增量備份與恢復
MySQL的日誌檔案記錄了詳細的操作過程,千萬不能隨便刪
MySQL資料庫增量備份
使用mysqldump進行完全備份存在的問題
備份資料中有重複資料
備份時間與恢復時間過長
MySQL增量備份是自上一次備份後增加/變化的檔案或者內容
特點
沒有重複資料,備份量不大,時間短
恢復需要上次完全備份及完全備份之後所有的增量備份才能恢復,而且要對所有增量備份進行逐個反推恢復
MySQL沒有提供直接的增量備份方法
可通過MySQL提供的二進位制日誌間接實現增量備份
MySQL二進位制日誌對備份的意義
二進位制日誌儲存了所有更新或者可能更新資料庫的操作
二進位制日誌在啟動MySQL伺服器後開始記錄,並在檔案達到max_binlog_size所設定的大小或者接收到flush logs命令後重新建立新的日誌檔案
只需定時執行flush logs方法重新建立新的日誌,生成二進位制檔案序列,並及時把這些日誌儲存到安全的地方就完成了一個時間段的增量備份
MySQL資料庫增量恢復
一般恢復
將所有備份的二進位制日誌內容全部恢復
斷點恢復
基於位置恢復
資料庫在某一時間點可能既有錯誤的操作也有正確的操作
可以基於精準的位置跳過錯誤的操作
基於時間點恢復
跳過某個發生錯誤的時間點實現資料恢復
增量恢復的方法
一般恢復
mysqlbinlog [–no-defaults] 增量備份檔案 | mysql -u 使用者名稱 -p
基於位置的恢復
恢復資料到指定位置(誤操作前的位置,不要選擇誤操作的位置)
mysqlbinlog --stop-position=‘操作id’ 二進位制日誌 | mysql -u 使用者名稱 -p密碼
從指定的位置開始恢復資料(誤操作後正確操作的位置,與時間節點不同,選擇誤操作後的第一個位置節點)
mysqlbinlog --start-position=‘操作id’ 二進位制日誌 | mysql -u 使用者名稱 -p密碼
mysql> select * from abc; #未恢復前狀態
+------+----------+-------+
| id | name | score |
+------+----------+-------+
| 1 | zhangsan | 99 |
| 2 | wangwu | 98 |
| 3 | chenqi | 97 |
+------+----------+-------+
3 rows in set (0.00 sec)
找出要恢復的位置
at 7079 #誤操作前的位置,不要選擇誤操作的位置
at 7183 #誤操作後正確操作的位置,與時間節點不同,選擇誤操作後的第一個位置節點
[root@server1 ~]# mysqlbinlog --no-defaults --stop-position='7079' /usr/local/mysql/data/mysql_bin.000002 | mysql -uroot -p123456
#根據日誌檔案選擇恢復開始位置,路徑,資料庫,“--stop-datetime”換成“--stop-position”
基於時間點恢復
跳過某個發生錯誤的時間點實現資料恢復
恢復資料到指定時間(停止錯誤操作的時間)
mysqlbinlog --stop-datetime=‘錯誤時間’ 二進位制日誌 | mysql -u 使用者名稱 -p密碼
#恢復資料至指定的位置(誤操作開始時間)
mysqlbinlog --start-datetime=‘正確操作時間’ 二進位制日誌 | mysql -u 使用者名稱 -p密碼
#從指定的位置開始恢復資料(跳過誤操作後指定正確操作的時間)
備份
[root@server1 ~]# mkdir -p /opt/time_sql #建立時間還原點資料夾
[root@server1 ~]# mysqldump -uroot -p test2 > /opt/time_sql/test2-$(date +%F).sql #備份test2庫
Enter password:
[root@server1 ~]# vi /etc/my.cnf #資料庫配置檔案中新增
[mysqld] #此模組新增
log_bin=/usr/local/mysql/data/mysql_bin #開啟增量備份
[root@server1 ~]# systemctl restart mysqld.service
[root@server1 ~]# ls /usr/local/mysql/data/ 檢視會發現日誌檔案mysql_bin.00000,此時內容為空
auto.cnf ib_logfile1 mysql_bin.index
ib_buffer_pool ibtmp1 performance_schema
ibdata1 mysql sys
ib_logfile0 mysql_bin.000001 test2
[root@server1 ~]# mysqldump -uroot -p123456 test2 > /opt/test2.sql #執行一次完整備份
[root@server1 ~]# mysqladmin -uroot -p123456 flush-logs #將二進位制日誌更新,產生新的日誌檔案
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
[root@server1 ~]# ls /usr/local/mysql/data/ #檢視產生第二個日誌檔案mysql_bin.000002
auto.cnf ib_logfile1 mysql_bin.000002 test2
ib_buffer_pool ibtmp1 mysql_bin.index
ibdata1 mysql performance_schema
ib_logfile0 mysql_bin.000001 sys
[root@server1 ~]# mysql -uroot -p123456
mysql> select * from abc;
+------+----------+-------+
| id | name | score |
+------+----------+-------+
| 1 | zhangsan | 99 |
| 2 | wangwu | 98 |
| 3 | chenqi | 97 |
+------+----------+-------+
3 rows in set (0.00 sec)
mysql> insert into abc (id,name,score) values(1,'aaa',96),(2,'bbb',95),(3,'ccc',100); #正確操作
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> delete from abc where name='zhangsan'; #刪除資料,模擬錯誤操作
Query OK, 1 row affected (0.00 sec)
mysql> insert into abc (id,name,score) values(6,'abc',100); #正確操作
Query OK, 1 row affected (0.00 sec)
mysql> select * from abc;
+------+--------+-------+
| id | name | score |
+------+--------+-------+
| 2 | wangwu | 98 |
| 3 | chenqi | 97 |
| 1 | aaa | 96 |
| 2 | bbb | 95 |
| 3 | ccc | 100 |
| 6 | abc | 100 |
+------+--------+-------+
6 rows in set (0.00 sec)
[root@server1 ~]# mysqladmin -uroot -p123456 flush-logs; #執行日誌更新
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
[root@server1 ~]# ls /usr/local/mysql/data/ #檢視是否新生成的日誌mysql_bin.000003,剛操作的動作不在新生成的日誌檔案中,在mysql_bin.000002中,可通過檢視知道
auto.cnf ib_logfile1 mysql_bin.000002 sys
ib_buffer_pool ibtmp1 mysql_bin.000003 test2
ibdata1 mysql mysql_bin.index
ib_logfile0 mysql_bin.000001 performance_schema
[root@server1 ~]# mysqlbinlog --no-defaults --base64-output=decode-rows -v /usr/local/mysql/data/mysql_bin.000002 ###查詢該二進位制日誌內容是否正確,--base64以64為解碼器,output=decode-rows輸出並按行進行讀取, -v顯示
………………
# at 910 #操作位置
#201224 21:05:50 server id 1 end_log_pos 958 CRC32 0x1213a56a Write_rows: table id 219 flags: STMT_END_F #操作時間
### INSERT INTO `test2`.`abc` #以下為操作內容
### SET
### @1=6
### @2='abc'
### @3=100
………………
找出要恢復的時間點
201224 21:05:24 --stop-datetime #誤操作的時間
201224 21:05:50 --start-datetime #正確操作的時間
進資料庫可以看到沒有已經誤操作的狀態
mysql> select * from abc;
+------+--------+-------+
| id | name | score |
+------+--------+-------+
| 2 | wangwu | 98 |
| 3 | chenqi | 97 |
| 1 | aaa | 96 |
| 2 | bbb | 95 |
| 3 | ccc | 100 |
| 6 | abc | 100 |
+------+--------+-------+
6 rows in set (0.00 sec)
mysql> source /opt/test2.sql; #恢復原先的備份
mysql> show tables;
+-----------------+
| Tables_in_test2 |
+-----------------+
| abc |
+-----------------+
1 row in set (0.00 sec)
mysql> select * from abc; #資料已經恢復,但沒有剛才操作的資料
+------+----------+-------+
| id | name | score |
+------+----------+-------+
| 1 | zhangsan | 99 |
| 2 | wangwu | 98 |
| 3 | chenqi | 97 |
+------+----------+-------+
3 rows in set (0.00 sec)
[root@server1 ~]# mysqlbinlog --no-defaults --stop-datetime='2020-12-24 21:05:24' /usr/local/mysql/data/mysql_bin.000002 | mysql -uroot -p123456 #根據日誌檔案選擇恢復停止時間,路徑,資料庫
mysql: [Warning] Using a password on the command line interface can be insecure.
mysql> select * from abc; #檢視資料庫可以檢視恢復至誤刪除前的狀態
+------+----------+-------+
| id | name | score |
+------+----------+-------+
| 1 | zhangsan | 99 |
| 2 | wangwu | 98 |
| 3 | chenqi | 97 |
| 1 | aaa | 96 |
| 2 | bbb | 95 |
| 3 | ccc | 100 |
+------+----------+-------+
6 rows in set (0.00 sec)
[root@server1 ~]# mysqlbinlog --no-defaults --start-datetime='2020-12-24 21:05:50' /usr/local/mysql/data/mysql_bin.000002 | mysql -uroot -p123456 #根據日誌檔案選擇恢復開始時間,路徑,資料庫
mysql: [Warning] Using a password on the command line interface can be insecure.