備份恢復
1. 本地備份 使用mysqldump進行備份非常簡單,在備份數據庫的時候,我們還可以同時使用管道gzip命令對備份文件進行壓縮,可以採用Rsync的異地備份方式方式,將備份服務器的目錄掛載到數據庫服務器,將數據庫文件備份打包後,通過crontab定時備份數據:
備份數據使用命令:
#!/bin/sh time=`date +"("%F")"%R`
$/usr/local/mysql/bin/mysqldump -u root -p111 database_backup | gzip > /home/zhenghan/mysql/mysql_backup.$time.gz # crontab -l # m h dom mon dow command00 00 * * * /home/zhenghan/mysql/backup.sh
恢復數據使用命令:
gzip -d mysql_backup.\(2014-06-17\)00\:00.gz mysql_backup.(2014-06-17)00:00
#mysql –u root -p111 < /home/zhenghan/mysql/mysql_backup.\(2014-06-17\)00\:00
3. MySQL本身自帶的mysqldump備份 使用mysqldump可以把整個數據庫裝載到一個單獨的文本文件中。這個文件包含有所有重建您的數據庫所需要的SQL命令。這個命令取得所有的模式(schema)並且將其轉換成DDL語法(CREATE語句,即數據庫定義語句),取得所有的數據,並且從這些數據中創建INSERT語句。這個工具將您的數據庫中所有的設計倒轉。因爲所有的東西都被包含到了一個文本文件中。這個文本文件可以用一個簡單的批處理和一個合適SQL語句導回到MySQL中。
4. 直接複製數據庫文件的備份形式 直接拷貝數據文件最爲直接、快速、方便,但缺點是基本上不能實現增量備份。爲了保證數據的一致性,需要在備份文件前,執行以下SQL語句:FLUSH TABLES WITH READ LOCK;也就是把內存中的數據都刷新到磁盤中,同時鎖定數據表,以保證拷貝過程中不會有新的數據寫入。這種方法備份出來的數據恢復也很簡單,直接拷貝回原來的數據庫目錄下即可。
以root用戶啓動服務,則可以使用以下語句備份
select * from user into outfile '/user/local/mysql/backup/db1'
誤刪除數據後怎麼辦。誤刪數據分類:
1、delete
2、drop table 或truncate table
3、drop database
4、rm命令刪除整個mysql實例
誤刪數據行通過flashback恢復數據,需要確保binlog_format=row和binlog_row_image=full
如果誤刪數據涉及到了多個事務需要將事務的順序調過來再執行。
不建議在主庫上執行,恢復出一個備份或是找一個從庫作爲臨時庫,在這個臨時庫操作,確認後恢復到主庫。
不止要說誤刪數據的事後處理辦法,更重要的是要做到事前預防
1、把sql_safe_updates參數設置爲on,這樣如果在忘記delete,update,語句中加where條件,或者where條件裏面沒有包含索引字段話這條語句執行就會報錯。
2、代碼上線前必須經過sql審計
使用truncate /drop table和drop database命令刪除的數據無法通過flashback來恢復。即使配了binlog_format=row,執行這三個命令時,binlog還是statement格式,binlog只有一個trncate/drop語句。
這時需要全量備份及增量日誌,要求定期的全量備份並且有實時備份的binlog。例如:
1、取最新一次全量備份,
2、用備份恢復出一個臨時庫
3、從日誌裏面取出需要的日誌
4、把這些日誌除了誤刪除數據的語解碼器全部應用到臨時庫
爲了加速恢復數據,可以在使用mysqlbinlog加上一個-database參數指定誤刪表所在的庫。避免恢復數據時還要應用其他日誌的情況。
在應用日誌時,需要跳過誤操作的那個語句binlog,
a:如果原實例沒有使用gtid模式,只能在應用到包含12點binlog文件,先用-stop-position參數很執行到誤操作之前的日誌,然後再用-start-position從誤操作之後的日誌繼續執行。
b:如果實例使用了gtid模式,假設誤操作命令的gtid是gtid1,那麼只需要執行set gtid_next=gtid1;beigin;commit; 先把這個gtid加到臨時實例的gtid集合,之後按順序執行binlg的時候就會自動跳過誤操作的語句。
以上還不夠快,可以這樣將這個臨時實例設置成線上備庫的從庫
1、在start slave之前,先通過執行change replication filter replicate_do_table=(tbl_name)命令就可以讓臨時庫只同步誤操作的表
2、這樣也可以用上並行複製技術來加速整個數據恢復過程。
如發現當前實例需要binlog是從master.000005開始的,但是在備庫上執行show binlogs顯示最小的文件是binlog是master.000007,意味着少了2個文修的,就需要從binlog的備份系統中的找到這兩個文件。
1、從備份系統下載master.00005和master000006這兩個文件放到備庫的日誌目錄下
2、打開日誌目錄下的master.index文件,在文件開頭加入兩行,內容分輥是./master.000005和 ./master000006
3、重啓備庫,目的是要讓備庫重新識別這兩件日誌文件
4、現在備庫上就有了臨時庫需要的所有binlog了,建立主備關係,就可以正常同步了。
搭建延遲複製的備庫,延遲複製的備庫是一種特殊的備庫,通過change master to master_delay=N命令,可以指定這個備庫持續保持跟主庫有N秒的延遲,在發現誤刪後,在備庫上執行stop slave再通過之前說的方法跳過這個操作合鄰,就可以恢復出這個需要的數據。
確保MySQL打開 log-bin選項
備份:
mysqldump --database db1 db2 db3 >test.sql
備份所有數據庫
mysqldump --all-database
mysqldump -uroot -p test emp dept>emp_dept.sql #備份數據庫emp、dept表
mysqldump -uroot -T /tmp test emp --fields-terminated-by ',' #備份數據庫test下的所有表爲逗號分割的文本,備份到/tmp emp.txt ,查看emp.txt
對於事務存儲引擎innodb和BDB來說,可以採用--single-transaction 此選項將使得innodb存儲引擎得到一個snapshot,使得備份的數據能夠保證一致性。
完全恢復
mysql -uroot -p dbname<bakfile
將備份恢復後的數據並不完整,還需要將備份後執行的日誌進行重做
mysqlbinlog binlog-file \ mysql -uroot -proot
例如:
mysqldump -uroot -p -l -F test>test.dmp
-l表示所有表加讀鎖,-F表示生成一個新的日誌文件,此時,test中emp表的數據如下:
稍後恢復數據
mysql -uroot -p test<test.dmp
使用mysqlbinlog恢復自mysqldump備份以來的binlog
mysqlbinlog localhost-bin.0000015 | mysql -uroot -p test
基於時間點恢復
在mysql中不完全恢復分爲基於時間點恢復和基於位置的恢復。
基於時間點恢復操作步驟。
用以下語句恢復到故障前
mysqlbinlog --stop-date='2005-04-20 9:45:33' /var/log/mysql/bin.123456 | mysql -uroot -proot
跳過時間點,繼續執行後面的binlog
mysqlbinlog --start-date='2005-04-20 10:02:00' /var/log/mysql/bin123456 | mysql -uroot -proot
基於位置恢復
mysqlbinlog --start-date='2005-04-20 9:45:33' --stop-date ='2005-04-20 10:04:33' /var/log/mysql/bin.123456 > /tmp/mysql_restore.sql
找到出錯語句前後的位置號,
mysqlbinlog --stop-position ='38649' /var/log/mysql/bin.123456
| mysql -uroot -proot
mysqlbinlog --start-position= '38748' /var/log/mysql/bin.123456 | mysql -uroot -proot
冷備份,停數據庫服務,cp數據文件
熱備份
myisam引擎
mysqlhotcopy db_name /path/to/new_directory
flush tables with read lock,然後cp數據文件到備份目錄即可
innodb引擎
ibbackup是熱備份工具,收費。ibbackup不會覆蓋任何重名文件,如果重名,則可能會失敗。
需要編輯my.cnf和用於備份的配置backup-my.cnf文件
備份完成後,會有數據文件和日誌文件。
進行日誌重做
ibbackup --apply-log /home/pekka/backup-my.cnf
服務重啓後,利用binlog日誌將備份點與故障點之間的剩餘數據進行恢復
mysqlbinlog binlog-file | mysql -uroot -proot
xtrabackup熱備工具,開源免費,支持在線熱備,備份速度快,佔用磁盤空間小等特點
只能備份innodb和 xtradb兩種數據表。
備份開始時開啓一個後臺檢測進程,實時檢測redo log的變化,一旦發現有redo log寫入,立刻將日誌記入後臺日誌文件xtrabackup log中,之後複製innodb 的數據文件和系統表空間文件ibdata1,待複製結束後,執行flush tables withd read lock,複製frm,myi,myd等文件(執行flush tables withd read lock的目的是爲了防止數據表發生DDL操作,並且在這一時刻獲得binlog位置),最後發生unlock tables把表設置爲可寫讀狀態,最終停止xtrabackup_log。
創建備份用戶
create user 'backup'@'%' identified by 123456
grant reload ,lock tables, replication client, create tablespace,super on *.* to 'backup'@'%'
創建備份目錄路徑 mkdir -p /data/backup/hotbackup/
創建innobackupex的配置文件 /tmp/my.cnf
[mysqld]
datadir="/home/mysql_test/mysqlhome/data/"
innodb_data_home_dir="/home/mysql_test/mysqlhome/data1"
innodb_data_file_path="ibdata1:10M:autoextend"
innodb_log_group_home_dir="/home/mysql_test/ysqlhome/data/"
innodb_log_files_in_group=2
innodb_log_files_size=3223328877
進行全量備份
innobackupex --user=backup -password=12345 --socket=/tmp/mysql_test.sock --defaults-file=/tmp/my.cnf /data/backup/hotbackup/full --no-timestamp
恢復全備
innobackupex --apply-log --use-memory=20G /data/backup/hotbackup/full
恢復備份到mysql數據文件目錄,要先關閉mysqlsql,重命名原數據文件目錄,再創建一個新的數據文件,將備份數據複製到新的數據文件目錄下,賦權重啓
增量備份
innobackupex --user=back --password=123445 --socket=/tmp/mysql_test.sock --defaults-file= /tmp/my.cnf --incremental /data/backup/hotbackup/incremental_one --incremental-basedir=/data/backup/hotbackup/base --no-timestamp --paraller=2
innobackupex --user=back --password=123445 --socket=/tmp/mysql_test.sock --defaults-file= /tmp/my.cnf --incremental /data/backup/hotbackup/incremental_two --incremental-basedir=/data/backup/hotbackup/incremental_one --no-timestamp --paraller=2
增量備份恢復
1、恢復基礎備份(全備)
2、恢復增量備份到基礎備份(開始恢復的增量備份要添加 --redo-only,最後一次增量備份去掉--redo-only參數)
3、對整體的基礎備份進行恢復,回滾那些未提交的數據。
innobackupex --apply-log --redo-only --use-memory=20G /data/backup/hotbackup/base
將增量備份incremental_one 應用到基礎備份base
innobackupex --apply-log --redo-only --use-memory=20G /data/backup/hotbackup/base
--incremental-dir=/data/backup/hotbackup/incremental_one/
將增量備份incremental_two應用到基礎備份base
innobackupex --apply-log --use-memory=20G /data/backup/hotbackup/base
--incremental-dir=/data/backup/hotbackup/incremental_two/
把所有合在一起的基礎備份整體進行一次apply操作,回滾未提交的數據
innobackupex --apply-log --use-memory=20G /data/backup/hotbackup/base
把恢復完的備份複製到數據文件目錄中,賦權,然後重啓mysql數據庫
--slave-infor 會將master的binary log的文件名和偏移位置保存到xtrabackup_slave_info文件中
--safe-slave-backup則會暫停slave的SQL線程,直到沒有打開的臨時表時候開始備份,待備份結束後SQL線程會自動啓動,這樣操作的目的主要是確保一致性的複製狀態。
innobackupex --user=back --password=123456 --socket=/tmp/mysql_test.sock --defaults-file=/tmp/my.cnf --slave-info --safe-slave-backup /data/backup/hotback/cloneslave --notimestamp --parallel=2
在slave的主機上進行還原
innobackupex --apply-log --redo-only --use-memory=20G /data/backup/hotbackup/cloneslave
將還原的文件複製到新從庫newslave上
在主機上添加對主機newslave的授權
grant replication slave on *.* to 'repl'@'salve2' identified by 123456
在主機newslave上拷貝主機slave的my.cnf文件,並且修改server-id參數,修改完畢後啓動新的從庫newslave
查找主機slave備份後生成的xtrabackup_slave_info文件 提取其中的master_log_file和master_log_pos然後在新的從庫newslave上進行 change master to
change master to
master_host='master'
master_user='rep1'
master_password='1233455'
master_log_file='mysql-bin.0000004'
master_log_pos=12343
啓動從庫 start slave
導出表
select * from table inot outfile '/tmp/emp.txt' fields terminated by ',' (字段分隔符,默認製表符\t)(optinal 只加在char varchar text字符型字段上) enclosed by '"'(字段引用符 默認不使用引用符) escaped by '\'(轉義字符默認\) lines starting by ''(每行前都加此字符串) terminated by '\b' (行結束符)
如果在目標目錄下有重名文件,則不會創建成功。源文件不能被自動覆蓋
mysqldump導出數據爲文本
mysqldump -uroot -T target_dir dbname tablename [option]
--fields-terminated-by =name 字段分隔符
--fields-enclosed-by =''字段引用符
--fields-optionally-enclosed-by= '字段引用符,只有在char varchar text字段上'
--fields-escapted-by =轉義字符
--fields-terminated-by=記錄結束符
導入表
load data [local] infile 'filename' into table tablename[option]
load data infoe '/tmp/emp.txt' into table emp fields terminated by ',' enclosed by '"';
ignore 3 lines(忽略前3行) (id,content,name 只想加載部分列)
set id=id+10(在id的內容後加上10)
mysqlimport -uroot -p [local] dbname order_tab.txt []
mysqlimport -uroot test /tmp/emp.txt --fields-terminated-by='' --fields-enclosed-by=''
如果導入和導出是跨平臺操作,要注意設置參數line-terminated-by,windows上設置line-terminated-by='\r\n' linux上設置爲line-terminated-by='\n';