一、MySQL的備份簡介
根據不同的分類標準可以分爲冷備,熱備,溫備:完全備份,部分備份:增量,差異,全備份等等,我們需要根據不同的需要,備份策略等選擇不同的備份方法和工具
二、常用的備份工具的使用方法:
1. mysqldump 比較常用的,比較適合備份少量數據。可以實現遠程備份表,數據庫。使用方法
Usage: mysqldump [OPTIONS] database [tables] OR mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...] OR mysqldump [OPTIONS] --all-databases [OPTIONS]
例如:我們把數據庫中個的hellodb備份到root家目錄下,然後恢復爲hellodb2。注意:備份的前要加鎖,放置備份過程有用戶寫入數據(記得備份完成後檢查是否成功)
手動添加鎖的方法
Mysql> FLUSH TABLES WITH READ LOCK; Mysql> FLUSH LOGS; # mysqldump hellodb > /tmp/helllodb.sql Mysql> unlock tables;
當然mysqldump也支持自動加鎖備份
[root@stu20 ~]# mysqldump -uroot -hlocalhost -p --lock-all-tables hellodb> /root/hellodb.sql [root@stu20 ~]# mysql -uroot -hlocalhost -p hellodb2< /root/hellodb.sql
這裏可以用多個選項:
--all-databases;備份所以庫
--databases db1 db2 指定多個庫
--lock-all-tables;備份前鎖定所有表,可以對不支持事務的myisam和aria做溫備
--single-transaction:如果引擎是innodb,直接用此選項不用鎖表也可
2. 實現二進制完成增量恢復
假如我們備份過後有刪除或者添加了表之後數據庫出故障了。此時就要用到二進制來做恢復了
a) 首先讓服務器離線
b) 把二進制日誌關閉
c) 導出進二進制日誌中查看服務器正常總之的最後一刻
d) 利用二進制日誌恢復
mysql> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000007 | 8730 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec) mysql> use hellodb Database changed mysql> create table binbin(name int); Query OK, 0 rows affected (0.48 sec) mysql> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000007 | 8825 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec) mysql> drop database hellodb; Query OK, 9 rows affected (0.23 sec) mysql> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000007 | 8912 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec)
此時的位置已經到了8912了,我們應該恢復到8825這個位置。
新建數據庫
mysql> create database hellodb; 導入表 [root@stu20 ~]# mysql hellodb < hellodb.sql [root@stu20 ~]# mysqlbinlog --start-position=8730 --stop-position=8825 /mydata/data/mysql-bin.000007 > /tmp/hdb.sql
此時我們關閉二進制日誌
mysql> set session sql_log_bin=0; mysql> source /tmp/hdb.sql mysql> show tables; +-------------------+ | Tables_in_hellodb | +-------------------+ | binbin |
此時我們的新建的表又出現了。
3. 基於邏輯卷的備份
a) 注意數據和二進制日誌都要放在邏輯捲上
b) 創建邏輯卷快照
c) 恢復的時候注意查看需要恢復的二進制文件的起始和結束位置
d) 請求全局鎖
e) 細節同上,這裏沒有給出過多演示
4. 好用的xtrabackup備份工具的使用
a) Xtrabackup是percona公司開發的一個方便的備份工具,開源,熱備,無阻塞。實現快速安全無阻塞,節約網絡帶,備份過程不打斷正在執行的事務,自動檢測備份的數據能否得到回覆。
b) 安裝xtrabackup工具並實現恢復
i. 去percona官網下載包,http://www.percona.com/software/percona-xtrabackup。直接yum安裝
ii. 安裝好了就可以使用了,xtrabackup備份工具會把備份的內容以時間命名放在一個文件中。我們可以穿件一個文件夾存放其備份數據,另外注意二進制日誌不要和數據放在同一個文件中。。
iii. 基於安全考慮,可以創建一個最小權限用戶進行備份,這裏不在演示。
iv. 完全備份,備份完成後會生成各個數據庫的文件和跟備份相關的數據
[root@localhost data]# mkdir /mybackups [root@localhost data]# innobackupex --user=root /mybackups/ [root@localhost ~]# ls /mybackups/2014-04-13_00-26-51/ backup-my.cnf performance_schema xtrabackup_checkpoints hellodb test xtrabackup_logfile ibdata1 xtrabackup_binary mysql xtrabackup_binlog_info
v. 還原數據的時候要對備份進行整理。一般情況下,在備份完成後,數據尚且不能用於恢復操作,因爲備份的數據中可能會包含尚未提交的事務或已經提交但尚未同步至數據文件中的事務。
1. [root@localhost ~]# innobackupex --apply-log /mybackups/2014-04-13_00-26-51/
vi. 檢查完後進行恢復,恢復的時候不需啓動mysql,而且恢復的時候xtrabackup會自動判斷原始數據存在的目錄。
[root@localhost data]# innobackupex --copy-back /mybackups/2014-04-13_00-26-51/
vii. 增量備份及其恢復
[root@localhost data]# innobackupex --incremental /mybackups --incremental-basedir=/mybackups/2014-04-13_00-26-51/
恢復前準備的階段有別與全備份,應該和並所以增量備份然後恢復合併後的全備份。
[root@localhost ~]# innobackupex --apply-log --read-only /mybackups/2014-04-13_01-49-50/ --incremental-dir=/mybackups/2014-04-13_00-26-51/
三、主從複製
1. myslq的複製原理:mysql會把操作記錄到二進制日誌,從服務器不停的向主服務器3306端口請求二進制日誌,然後從服務器會把二進制保存爲中繼日誌,一條一條寫進自己文件中(異步)
2. 怎麼實現讀寫分離:
用算法決定訪問哪個mysql服務器,但是這種方法使得前後端耦合度過與緊密,所以需要前後端加一個調度器,使得前端程序開發不需要依賴後端硬件的變動
算法:a.使用hash編碼delect語句進行計算,講結合與服務器個數取餘數,餘數結果就決定了使用哪個服務器,這樣就保證了同一條語句會發往同一個服務器,提高命中率。 b.使用環。 c.虛擬環。
使用中間分發器;
amoeba(阿米巴,國內)
mysql-proxy:(需要二次開發保證其更安全)
3. 配置過程
a) 修改主配置文件使其適應
[root@localhost ~]# vim /etc/my.cnf log-bin=/mydata/binlogs/master-bin---改變二進制文件存放位置,放置丟失 server-id = 1------------------------------修改serverID完成身份區別
b) 主服務器授權一個具有複製帳號的用戶
MariaDB [(none)]> grant replication slave,replication client on *.* TO 'xuxu'@'172.16.%.%' identified by 'xuxu';
c) 修改從服務器配置文件並連接主服務器
[root@localhost ~]# vim /etc/my.cnf Log-bin=OFF------關閉二進制日誌 Server-id=2----- relay-log =/mydata/relaylogs/relay-bin---啓用中繼日誌並改變存放位置 連接主服務器 MariaDB [(none)]> change master to master_host='172.16.20.65',master_user='xuxu',master_password='xuxu';
d) 手動啓動從服務器線程
MariaDB [(none)]> start slave;
e) OK,現在在主服務器做操作從服務器就可以實現同步了。次日如果停止slave關閉mysql,下次重啓從服務器會自動啓動slave
f) 假如我們的主服務器中已經有大量的數據了,此時如果從0開始複製,會消耗很長時間,這是我們就可以從半道開始複製。首先備份主服務器數據,講數據發送到從服務器中,然後把備份數據導入到從服務器,然後連接的時候指定開始複製的位置即可。
i. 主服務器
[root@localhost ~]# mysqldump --all-databases --flush-logs --master-data=2 --lock-all-tables > all.sql [root@localhost ~]# scp all.sql [email protected]:/root/ 此時查看二進制日誌位置 MariaDB [(none)]> show master status; +-------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +-------------------+----------+--------------+------------------+ | master-bin.000004 | 367 | | | +-------------------+----------+--------------+------------------+ 再插入一些數據 MariaDB [(none)]> create databases test2 MariaDB [(none)]> show master status; +-------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +-------------------+----------+--------------+------------------+ | master-bin.000004 | 490 | | | +-------------------+----------+--------------+------------------+ 1 row in set (0.00 sec) ii. 從服務器 [root@localhost ~]# mysql < all.sql MariaDB [(none)]> change master TO master_host='172.16.20.65',master_user='xuxu',master_password='xuxu',MASTER_LOG_FILE='master-bin.000004', MASTER_LOG_POS=327; MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | hellodb | | information_schema | | mysql | | performance_schema | | test | +--------------------+ (此時新創建的數據庫test2還沒有恢復) 啓動slave開始同步 MariaDB [(none)]> start slave; Query OK, 0 rows affected (0.01 sec) MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | hellodb | | information_schema | | mysql | | performance_schema | | test | | test2 | +--------------------+ 6 rows in set (0.00 sec)
好了,已經成功同步完成。
4. 爲了避免主從服務器的安全性和數據的同步性,設定一些服務器的工作特性是很有必要的
a) 保證兩個服務器的時間要同步,可以通過定義一個crontab來自動完成去一個時間服務器中自動同步時間
b) 另外,如果我們如果不小心向我們的從服務器寫數據了,會造成數據不一致。爲了避免這種情況我們可以在從服務器中定義禁止寫和刪除的操作。
在從服務器配置文件中定義read-only=ON (只能限制非super用戶的寫權限)
MariaDB [(none)]> show global variables like '%read_only%'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | innodb_read_only | OFF | | read_only | ON | | tx_read_only | OFF | +------------------+-------+ MariaDB [(none)]> create database test2; ERROR 1290 (HY000): The MariaDB server is running with the --read-only option so it cannot execute this statement
5. 半同步複製
a) 實現半同步複製(插件工作模式)google貢獻(當有多個從時,主服務器等待一個從反饋複製完成就OK,不用等待所以都ok)
b) 插件位置/usr/loca/mysql/lib/plugin
c) 主節點安裝(會自動去mysql/plugin/ 目錄下查找相應插件)
d) mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME'semissc_master.so'
e) mysql> SHOW GLOBAL VARIABLES LIKE '%semi%';
f)
g) 調整第一個參數爲ON,和time_out 時間
h) 從節點安裝
i)
k) 在主服務器驗證半同步複製是否生效
l) 卸載插件:mysql> uninstall ...
m) 幾個常用變量
o) 缺點:一旦某次等待超時,會自動降級爲異步,(可以使用監控來實現一旦降級運行自動腳本重新變爲同步)
6 . 複製過濾器(對服務器上對二進制日誌做過濾)
在主服務器上做過濾優點:節約帶寬,日誌。缺點:恢復的時候由於二進制不完整不能實現即使點還原。所以一般不採用。
服務器過濾方法(永久有效保存到配置文件)
master;(只能過濾到庫級別) binlog_do_db= binlog_ignore_db= slave:(可以過濾數據庫或者表) replicate_do_db= replicate_ignore_db= replicate_do_table=db_name.table_name(基於表做過濾) replicate_ignore_table= replicate_wild_do_table= replicate_wild_ignore_table=
7. 多主模型(互爲主從)
在兩臺服務器上各自建立一個具有複製權限的用戶;
修改配置文件:
# 主服務器上 [mysqld] server-id = 10 log-bin = mysql-bin relay-log = relay-mysql relay-log-index = relay-mysql.index auto-increment-increment = 2 auto-increment-offset = 1 # 從服務器上 [mysqld] server-id = 20 log-bin = mysql-bin relay-log = relay-mysql relay-log-index = relay-mysql.index auto-increment-increment = 2 auto-increment-offset = 2
然後各服務器接下來指定對另一臺服務器爲自己的主服務器即可:
server1|mysql> CHANGE MASTER TO ...,MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=811 server2|mysql> CHANGE MASTER TO ...,MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=710