# MySQL數據庫徹底備份與恢復
## 數據庫備份的分類
1. 從物理與邏輯的角度,備份能夠分爲物理備份和邏輯備份。
(1)物理備份:對數據庫操做系統的物理文件(數據文件、日誌文件)的備份。物理備份又可分爲脫機備份(冷備份)和聯機備份(熱備份)
冷備份:在關閉數據庫中的時候進行的
熱備份:數據庫處於運行狀態,這種備份依賴於數據庫的日誌文件
溫備份:數據庫鎖定表格(不可寫入但可讀)的狀態下進行的
(2)邏輯備份:對數據庫邏輯組件(如表等數據庫對象)的備份
2. 從數據庫的備份策略角度,備份可分爲徹底備份、差別備份和增量備份
(1)徹底備份:每次對數據進行完整的備份
對整個數據庫的備份、數據庫結構和文件結構的備份,保存的是備份完成時刻的數據庫,是差別備份與增量備份的基礎。
優勢:備份與恢復操做簡單方便
缺點:數據存在大量的重複;佔用大量的空間;備份與恢復時間長
(2)差別備份:備份那些字從上次徹底備份以後被修改過的全部文件
備份的時間節點是從上次完整備份起,備份數據量會愈來愈大。恢復數據時,只須要恢復上次徹底備份與最近的一次差別備份。
(3)增量備份:至於那些在上次徹底備份揮着增量備份後被修改的文件纔會被備份
以上次完整備份或上次的增量備份的時間爲時間點,僅備份這之間的數據辯護啊,於是備份的數量小,佔用空間小,備份速度快。但回覆是,須要從上一次的完整備份起到左後一次增量備份一次恢復,如中間某次的備份數據損壞,將致使數據的丟失。html
## MySQL徹底備份操做
1. (冷備份方式)直接打包數據裏文件夾
2. (熱備份方式)使用專用備份工具mysqldump
(1)對單個庫進行徹底備份
格式:mysqldump -u用戶名 -p密碼 選項 空間名 > /備份路徑/備份文件名
```
[root@localhost ~]# mysqldump -uroot -p123456 yunjisuan > /tmp/yunjisuan-$(date +%F).sql
[root@localhost ~]# ls /tmp/
mysql.sock yum.log yunjisuan-2018-11-19.sql
```
(2)對多個庫進行徹底備份
格式:mysqldump -u用戶名 -p密碼 選項 ==--databases== 空間名1 空間名2 > /備份路徑/備份文件名java
```
[root@localhost ~]# mysqldump -uroot -p123456 --databases yunjisuan daisy > /tmp/yunjisuan-$(date +%F).sql
```
(3)對全部庫進行徹底備份
格式:mysqldump -u用戶名 -p密碼 選項 --all-databases > /備份路徑/備份文件名mysql
```
[root@localhost ~]# mysqldump -uroot -p123456 --opt --all-databases > /tmp/yunjisuan-$(date +%F).sql
# --opt 加快備份速度,當備份數據量大時使用
```
(4)對錶進行徹底備份
格式:mysqldump -u用戶名 -p密碼 選項 空間名 表名 > /備份路徑/備份文件名面試
```
[root@localhost ~]# mysqldump -uroot -p123456 yunjisuan users > /tmp/yunjisuan-$(date +%F).sql
```
(5)對錶結構的備份
格式:mysqldump -u用戶名 -p密碼 -d 空間名 表名 > /備份路徑/備份文件名sql
```
[root@localhost ~]# mysqldump -uroot -p123456 -d yunjisuan users > /tmp/yunjisuan-$(date +%F).sql
```
## 使用mysqldump備份後,恢復數據庫
1. source命令(交互式)數據庫
```
[root@localhost ~]# mysqldump -uroot -p123456 --opt --all-databases > /tmp/mysql_all-$(date +%F).sql
[root@localhost ~]# ls /tmp/
mysql_all-2018-11-19.sql
[root@localhost ~]# mysql -uroot -p123456
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| imployee_salary |
| mysql |
| performance_schema |
| test |
| yunjisuan |
+--------------------+
6 rows in set (0.00 sec)
mysql> drop database yunjisuan;
Query OK, 1 row affected (0.01 sec)vim
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| imployee_salary |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.00 sec)安全
mysql> source /tmp/mysql_all-2018-11-19.sql
Query OK, 0 rows affected (0.00 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| imployee_salary |
| mysql |
| performance_schema |
| test |
| yunjisuan |
+--------------------+
6 rows in set (0.00 sec)
```
2. mysql命令(非交互方式)
格式:mysql -u用戶名 -p密碼 < 庫備份腳本的路徑
mysql -u用戶名 -p密碼 庫名 < 表備份腳本的路徑bash
```
[root@localhost ~]# mysql -uroot -p123456 -e 'drop database yunjisuan;'
[root@localhost ~]# mysql -uroot -p123456 < /tmp/mysql_all-2018-11-19.sql
[root@localhost ~]# mysql -uroot -p123456 -e 'show databases;'
+--------------------+
| Database |
+--------------------+
| information_schema |
| imployee_salary |
| mysql |
| performance_schema |
| test |
| yunjisuan |
+--------------------+服務器
```
## MySQL備份思路
1. 按期實施備份,指定備份計劃或策略,並嚴格遵照
2. 除了進行徹底備份,開啓MySQL服務器的日誌功能是很重要的(徹底備份加上日誌,能夠對MySQL進行最大化還原)
3. 使用統一和易理解的備份名稱,推薦使用庫名揮着表名加上時間的命名規則,如mysql_user-20181118.sql,不要使用backup1之類沒有意義的名字。
## MySQL增量備份
MySQL是經過二進制日誌(mysqlbinlog)實現增量備份的。
一旦開啓mysqlbinlog這個日誌,用戶的每條SQL語句除了select功能,都會被記錄
二進制日誌在啓動MySQL服務器後開始記錄,並在文件到達max_binlog_size所設置的大小或者接收到flush logs命令後從新建立新的日誌文件。
==控制二進制日誌大小==
```
[root@localhost mysql]# vim /etc/my.cnf
53 max_binlog_size=1024000
#二進制日誌最大1M
```
只需定時執行flush logs方法從新建立新的日誌,生成二進制文件序列,並及時把這些日誌保存到安全的地方就完成了一個時間段的增量備份。
開啓mysqlbinlog二進制日誌功能:
方法一:
```
[root@localhost mysql]# vim /etc/my.cnf
50 log-bin=mysql-bin
113 #log-bin=mysql-bin
```
(1)當在/etc/my.cnf中開啓二進制日誌功能
(2)當使用SQL語句(除了select功能),/data目錄就會產生 mysql-bin.xx的文件
(3)此時,使用mysqlbinlog查看 mysql-bin.xx文件內容
```
[root@localhost mysql]# mysqlbinlog mysql-bin.000006
```
方法二:使用mysqld--log-bin=文件存放路徑/文件前綴 從新啓動mysql服務
每週選擇服務器負載矯情的時間段,或者用戶訪問較少的時間段進行備份。
### MySQL增量恢復
#### 應用場景
1. 認爲的SQL語句破壞了數據庫
2. 再進行下一次全北以前發生系統故障致使數據庫數據丟失
3. 在主從架構中,主庫數據發生了故障
#### 增量恢復的方法
1. 通常的恢復:備份的二進制日誌內容所有恢復
格式:mysqlbinlog [--no-defaults] 增量備份文件 | mysql -u 用戶名 -p 密碼
```
[root@localhost mysql]# mysqlbinlog /usr/local/mysql/data/mysql-bin.000012 | mysql -uroot -p123456
[root@localhost mysql]# mysql -uroot -p123456 -e 'select * from yunjisuan.users;'
+-----------+-------------+
| user_name | user_passwd |
+-----------+-------------+
| daisy | 123456 |
| helen | 432543 |
| 小然 | 533223 |
| 綠小花 | 123123 |
+-----------+-------------+
```
2. 基於時間點的恢復:便於跳過某個發生錯誤的時間點實現數據恢復
格式:
從日誌開頭截止到某個時間點的恢復:
mysqlbinlog [--no-defaults] --stop-datetime='年-月-日 小時:分鐘:秒' 二進制日誌 | mysql -u 用戶名 -p 密碼
從某個時間點到日誌結尾的恢復:
mysqlbinlog [--no-defaults] --start-datetime='年-月-日 小時:分鐘:秒' 二進制日誌 | mysql -u 用戶名 -p 密碼
從某個時間點到某個時間點的恢復:
mysqlbinlog [--no-defaults] --start-datetime='年-月-日 小時:分鐘:秒' --stop-datetime='年-月-日 小時:分鐘:秒' 二進制日誌 | mysql -u 用戶名 -p 密碼
```
mysql> show master status; #查看當前文件字符寫在哪一個位置
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000013 | 509 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
mysql> delete from yunjisuan.users where user_name='helen';
Query OK, 1 row affected (0.01 sec)
mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000013 | 710 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
```
3. 基於位置的恢復:可能在同一時間點既有錯誤的操做也有正確的操做,基於位置進行恢復更加精準
格式:
mysqlbinlog --stop-position='操做 id' 二進制日誌 | mysql -u 用戶名 -p 密碼
mysqlbinlog --start-position='操做 id' 二進制日誌 | mysql -u 用戶名 -p 密碼
```
[root@localhost mysql]# mysql -uroot -p123456 -e 'select * from yunjisuan.users;'
+-----------+-------------+
| user_name | user_passwd |
+-----------+-------------+
| daisy | 123456 |
| helen | 432543 |
| 小然 | 533223 |
| 綠小花 | 123123 |
+-----------+-------------+
[root@localhost mysql]# mysqlbinlog --start-position='509' --stop-position='710' /usr/local/mysql/data/mysql-bin.000013 | mysql -uroot -p123456
[root@localhost mysql]# mysql -uroot -p123456 -e 'select * from yunjisuan.users;'
+-----------+-------------+
| user_name | user_passwd |
+-----------+-------------+
| daisy | 123456 |
| 小然 | 533223 |
| 綠小花 | 123123 |
+-----------+-------------+
```
## 企業備份策略的應用
在企業中應用MySQL的備份策略
1. 中小公司,因爲數據量小,數據安全不是特別重要,容許小數量的細節數據丟失。所以,天天盡心過一次數據庫的全量備份便可。(定時任務+全備腳本)
2. 中大型公司,因爲數據量大,天天全被時間太長,並且。比較關注數據安全和完整,沒法承受數據丟失,哪怕只是少許的。對於這種類型的公司,一般採起全量備份+增量備份的方式進行,也就是每週進行一次全量備份(定時任務+全備腳本);天天進行一次增量備份。
中小企業場景,數據庫的全量備份如何實現?
第一種:採用rsync備份服務器
數據庫的定時任務備份結束之後,自動rsync推送到備份服務器。(要檢查數據完整性)
第二種:raid陣列
在MySQL服務器上,額外進行raid磁盤陣列的掛載在/backup上,全備腳本將備份備份在次目錄裏。
中大型或大型企業,MySQL備份策略如何實現
1. 全備+增備
2. 每週一次全備
3. 增備的實現有兩種方式
第一種:經過定時任務+增備切割腳本(天天0點,flush logs)
rsync至少設置兩個模塊,一個用在全量備份,另外一個用在增量備份,先將以前的日誌文件打包備份到備份服務器,在進行增量備份,文件與文件之間天天進行一次flush logs,mysql-bin文件裏保存的是天天的增量日誌,能夠設置對增量日誌天天打包,進行推送並測試推送數據的完整性,設置一個定時任務,錯後一天將前一天的數據包進行刪除處理
第二種:不推送,實時同步rsync+inotify
每週日的全量備份結束之後,進行一次flush logs,將mysql-bin.*實時同步到備份服務器上
數據庫的經常使用架構解析:
4. 主從複製
主MySQL數據庫經過mysqlbinlog將數據實時同步到備用MySQL數據庫上;(讀寫分離時),將這兩臺數據庫的使用功能區分開,一臺專門用來讀數據,一臺專門用來寫數據(減輕數據庫的讀壓力);當一主多從時,須要在從數據庫前設置負載均衡器
## MySQL數據庫企業 應用實踐
### MySQL的多實例應用
1. MySQL多實例就是在一臺服務器上同時開啓多個不一樣的服務器端口(如:3306,3307),同時運行多個MySQL服務進程,這些服務進程經過不一樣的socket監聽不一樣的服務器端口來提供服務。
2. MySQL多實例共用一套MySQL安裝程序,使用不一樣的my.cnf(也能夠相同)配置文件,啓動程序(也能夠相同)和數據文件。在提供服務時,多實例MySQL在邏輯上看起來是各自獨立的,它們根據配置文件的對應設定值,得到服務器相應數量的硬件資源。
MySQL多實例的做用
(1)有效利用服務器資源
當單個服務器資源有剩餘時,能夠充分利用剩餘的資源提供更多的服務,且能夠實現資源的邏輯隔離。
(2)節約服務器資源
當公司資金緊張,可是數據庫又須要各自盡可能獨立地提供服務,並且,須要主從複製等技術時,多實例就再好不過了。
#### MySQL多實例常見的配置方案
1. 單一配置文件,單一啓動程序的多實例部署方案
下面是MySQL官方文檔提到的單一配置文件,單一啓動程序多實例部署方案,但不推薦此方案,這裏僅做爲知識點說起,後文再也不涉及此方案的說明。my.cnf配置文件示例(MySQL手冊裏提到的方法)以下:
```
[mysqld_multi]
mysqld = /usr/bin/mysqld_safe
mysqladmin = /usr/bin/mysqladmin
user = mysql
[mysqld1]
socket = /var/lib/mysql/mysql.sock
port = 3306
pid-file = /var/lib/mysql/mysql.pid
datadir = /var/lib/mysql/
user = mysql
[mysqld2]
socket = /mnt/data/db1/mysql.sock
port = 3302
pid-file = /mnt/data/db1/mysql.pid
datadir = /mnt/data/db1/
user = mysql
skip-name-resolv
server-id=10
default-storage-engine=innodb
innodb_buffer_pool_size=512M
innodb_additional_mem_pool=10M
default_character_set=utf8
character_set_server=utf8
#read-only
relay-log-space-limit=3G
expire_logs_day=20
```
啓動程序的命令以下:
```
mysqld_multi --config-file=/data/mysql/my_multi.cnf start 1,2
```
該方案的缺點是耦合度過高,一個配置文件,很差管理。工做開發和運維的統一原則爲下降耦合度。
2. 多配置文件,多啓動程序的部署方案
多配置文件,多啓動程序部署方案,是本文主要講解的方案,也是很是經常使用並極力推薦的多實例方案。下面來看配置示例。
```
[root@localhost /]# tree /data
/data
├── 3306
│ ├── data #3306實例的數據目錄
│ ├── my.cnf #3306實例的配置文件
│ └── mysql #3306實例的啓動文件
└── 3307
├── data #3307實例的數據目錄
├── my.cnf #3307實例的配置文件
└── mysql #3307實例的啓動文件
4 directories, 4 files
```
提示:
這裏的配置文件my.cnf,啓動程序mysql都是獨立的文件,數據文件data目錄也是獨立的。
#### 安裝並配置多實例MySQL數據庫
##### 安裝MySQL多實例
1. 安裝MySQL須要的依賴包和編譯軟件
(1)安裝MySQL須要的依賴包
安裝MySQL以前,最好先安裝MySQL須要的依賴包,否則後面會出現不少報錯信息,到那時還得再回來安裝MySQL的依賴包。安裝命令以下:
```
[root@localhost ~]# yum -y install ncurses-devel libaio-devel
[root@localhost ~]# rpm -qa ncurses-devel libaio-devel
ncurses-devel-5.7-4.20090207.el6.x86_64
libaio-devel-0.3.107-10.el6.x86_64
```
(2)安裝編譯MySQL須要的軟件
首先經過網絡得到cmake軟件,而後進行以下操做:
```
[root@localhost ~]# ls -lh cmake-2.8.6.tar.gz
-rw-r--r-- 1 root root 5.4M 7月 19 20:43 cmake-2.8.6.tar.gz #此軟件需提早準備
[root@localhost ~]# tar xf cmake-2.8.6.tar.gz -C /usr/src/
[root@localhost ~]# cd /usr/src/cmake-2.8.6/
[root@localhost cmake-2.8.6]# ./configure
[root@localhost cmake-2.8.6]# gmake && gmake install
[root@localhost cmake-2.8.6]# which cmake
```
2. 開始安裝MySQL
爲了讓同窗們學習更多的MySQL技術,接下來會以相對複雜的源代碼安裝來說解MySQL多實例的安裝。大型公司通常都會將MySQL軟件定製成rpm包,而後放到yum倉庫裏,使用yum安裝,中小企業裏的二進制和編譯安裝的區別不大。
(1)創建MySQL用戶帳號
首先以root身份登陸到Linux系統中,而後執行以下命令建立mysql用戶帳號:
```
[root@localhost ~]# useradd -s /sbin/nologin -M mysql
[root@localhost ~]# id mysql
uid=500(mysql) gid=500(mysql) 組=500(mysql)
```
(2)獲取MySQL軟件包
MySQL軟件包的下載地址爲:https://dev.mysql.com/downloads/mysql/
提示:
本例以MySQL編譯的方式來說解,以前已經演示過二進制方式安裝了。在生產場景中,二進制和源碼包兩種安裝方法都是能夠用的,其應用場景通常沒什麼差異。不一樣之處在於,二進制的安裝包較大,名字和源碼包也有些區別,二進制安裝過程比源碼更快。
MySQL源碼包和二進制安裝包的名稱見下圖
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20181119220929495.)
(3)採用編譯方式安裝MySQL
配置及編譯安裝的步驟以下:
```
[root@localhost ~]# tar xf mysql-5.5.22.tar.gz -C /usr/src/
[root@localhost ~]# cd /usr/src/mysql-5.5.22/
[root@localhost mysql-5.5.22]# cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql-5.5.22 \
> -DMYSQL_DATADIR=/usr/local/mysql-5.5.22/data \ #數據存放目錄
> -DMYSQL_UNIX_ADDR=/usr/local/mysql-5.5.22/tmp/mysql.sock \ #MySQL進程間通訊的套接字位置
> -DDEFAULT_CHARSET=utf8 \ #默認字符集爲utf8
> -DDEFAULT_COLLATION=utf8_general_ci \ #默認字符集排序規則
> -DEXTRA_CHARSETS=gbk,gb2312,utf8,ascii \ #額外的字符集支持
> -DENABLED_LOCAL_INFILE=ON \ #是否啓用加載本地數據
> -DWITH_INNOBASE_STORAGE_ENGINE=1 \ #靜態編譯innodb存儲引擎到數據庫
> -DWITH_FEDERATED_STORAGE_ENGINE=1 \ #靜態編譯FEDERATED存儲引擎到數據庫
> -DWITH_BLACKHOLE_STORAGE_ENGINE=1 \ #靜態編譯blackhole存儲引擎到數據庫
> -DWITHOUT_EXAMPLE_STORAGE_ENGINE=1 \ #不編譯EXAMPLE存儲引擎到數據庫
> -DWITHOUT_PARTITION_STORAGE_ENGINE=1 \ #不支持數據庫分區
> -DWITH_FAST_MUTEXES=1 \
> -DWITH_ZLIB=bundled \ #zlib壓縮模式
> -DENABLED_LOCAL_INFILE=1 \ #是否啓用本地的LOCAL_INFILE
> -DWITH_READLINE=1 \ #使用捆綁的readline
> -DWITH_EMBEDDED_SERVER=1 \ #是否要創建嵌入式服務器
> -DWITH_DEBUG=0 #禁用DEBUG(開啓影響性能)
# 提示:編譯時可配置的選項不少,具體可參考官方文檔
[root@localhost mysql-5.5.22]# make && make install
```
下面設置不帶版本號的軟連接/usr/local/mysql,操做步驟以下:
```
[root@localhost mysql-5.5.22]# ln -s /usr/local/mysql-5.5.22 /usr/local/mysql
[root@localhost mysql-5.5.22]# ls /usr/local/mysql
bin data include lib mysql-test scripts sql-bench
COPYING docs INSTALL-BINARY man README share support-files
```
若是上述操做未出現錯誤,查看/usr/local/mysql目錄下有內容,則MySQL5.5.22源代碼包採用cmake方式的安裝就算成功了。
##### 建立MySQL多實例的數據文件目錄
在企業中,一般以/data目錄做爲MySQL多實例總的根目錄,而後規劃不一樣的數字(即MySQL實例端口號)做爲/data下面的二級目錄,不一樣的二級目錄對應的數字就做爲MySQL實例的端口號,以區別不一樣的實例,數字對應的二級目錄下包含MySQL的數據文件,配置文件及啓動文件等。
下面以配置3306,3307兩個實例爲例進行講解。建立MySQL多實例的目錄以下:
```
[root@localhost ~]# mkdir -p /data/{3306,3307}/data
[root@localhost ~]# tree /data/
/data/
├── 3306 #3306實例目錄
│ └── data #3306實例的數據文件目錄
├── 3307 #3307實例目錄
└── data #3307實例的數據文件目錄
4 directories, 0 files
```
提示:
(1)mkdir -p /data/{3306,3307}/data至關於mkdir -p /data/3306/data;mkdir -p /data/3307/data兩條命令
(2)若是是建立多個目錄,能夠增長如3308,3309這樣的目錄名,在生產環境中,通常爲3~4個實例爲佳。
##### 建立MySQL多實例的配置文件
MySQL數據庫默認爲用戶提供了多個配置文件模板,用戶能夠根據服務器硬件配置的大小來選擇。
```
[root@localhost mysql]# ls -l support-files/my*.cnf
-rw-r--r-- 1 root root 4751 7月 19 21:33 support-files/my-huge.cnf
-rw-r--r-- 1 root root 19805 7月 19 21:33 support-files/my-innodb-heavy-4G.cnf
-rw-r--r-- 1 root root 4725 7月 19 21:33 support-files/my-large.cnf
-rw-r--r-- 1 root root 4736 7月 19 21:33 support-files/my-medium.cnf
-rw-r--r-- 1 root root 2900 7月 19 21:33 support-files/my-small.cnf
```
注意:
這些配置文件裏的註釋很是詳細,不過是英文的。。。
上面是單實例的默認配置文件模板,若是配置多實例,和單實例會有不一樣。爲了讓MySQL多實例之間彼此獨立,要爲每個實例創建一個my.cnf配置文件和一個啓動文件MySQL,讓他們分別對應本身的數據文件目錄data。
首先,經過vim命令添加配置文件內容,命令以下:
```
vim /data/3306/my.cnf
vim /data/3307/my.cnf
```
不一樣的實例須要添加的my.cnf內容會有區別,其中的配置由官方的配置模板修改而來。固然,在實際工做中,咱們是拿早已配置好的模板來進行修改的,能夠經過rz等方式上傳配置文件模板my.cnf文件到相關目錄下。
MySQL3306,3307實例配置文件以下
##實例3306配置文件my.cnf
```
[root@localhost ~]# cat /data/3306/my.cnf
[client]
port = 3306
socket = /data/3306/mysql.sock #.sock 默認放在html目錄下,MySQL的實例文件 (經過這個實例文件將socket進程鏈接在一塊兒;停庫後文件不存在,mysql不能啓動時,手動pkill .sock文件和pid文件)
[mysqld]
user = mysql
port = 3306
socket = /data/3306/mysql.sock
basedir = /usr/local/mysql
datadir = /data/3306/data
open_files_limit = 1024
back_log = 600
max_connections = 800
max_connect_errors = 3000
table_open_cache = 614
external-locking = FALSE
max_allowed_packet = 8M
#binlog_cache_size = 1M
#max_heap_table_size = 64M
#read_buffer_size = 2M
#read_rnd_buffer_size = 16M
sort_buffer_size = 1M
join_buffer_size = 1M
thread_cache_size = 100
thread_concurrency = 2 #concurrency 併發
query_cache_size = 2M
query_cache_limit = 1M
query_cache_min_res_unit = 2k
#ft_min_word_len = 4
#default-storage-engine = MYISAM
thread_stack = 192K
transaction_isolation = READ-COMMITTED
tmp_table_size = 2M
max_heap_table_size = 2M
#log-bin=mysql-bin
#binlog_format=mixed
#slow_query_log
long_query_time = 1
pid-file = /data/3306/mysql.pid
relay-log = /data/3306/relay-bin
relay-log-info-file = /data/3306/relay-log.info
binlog_cache_size = 1M
max_binlog_cache_size = 1M
max_binlog_size = 2M
key_buffer_size = 16M
read_buffer_size = 1M
read_rnd_buffer_size = 1M
bulk_insert_buffer_size = 1M
0.lower_case_table_names = 1
skip-name-resolve
slave-skip-errors = 1032,1062
replicate-ignore-db = mysql
server-id = 1
#key_buffer_size = 32M
#bulk_insert_buffer_size = 64M
#myisam_sort_buffer_size = 128M
#myisam_max_sort_file_size = 10G
#myisam_repair_threads = 1
#myisam_recover
innodb_additional_mem_pool_size = 4M
innodb_buffer_pool_size = 32M
innodb_data_file_path = ibdata1:128M:autoextend
innodb_file_io_threads = 4
#innodb_write_io_threads = 8
#innodb_read_io_threads = 8
innodb_thread_concurrency = 8
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 2M
innodb_log_file_size = 4M
innodb_log_files_in_group = 3
innodb_max_dirty_pages_pct = 90
innodb_lock_wait_timeout = 120
innodb_file_per_table = 0
[mysqldump]
quick
max_allowed_packet = 2M
[mysql]
no-auto-rehash
#[myisamchk]
#key_buffer_size = 512M
#sort_buffer_size = 512M
#read_buffer = 8M
#write_buffer = 8M
#[mysqlhotcopy]
#interactive-timeout
[mysqld_safe]
log-error = /data/3306/mysql_yunjisuan3306.err
pid-file = /data/3306/mysqld.pid
```
提示:實例3307的配置文件只須要將3306配置文件裏的全部3306數字替換成3307(server-id換個數字)便可。
最終完成後的多實例根/data目錄結果以下:
```
[root@localhost ~]# tree /data
/data
├── 3306
│ ├── data
│ └── my.cnf #這個就是3306實例的配置文件
└── 3307
├── data
└── my.cnf #這個就是3307實例的配置文件
4 directories, 2 files
```
##### 建立MySQL多實例的啓動文件
MySQL多實例啓動文件的建立和配置文件的建立幾乎同樣,也能夠經過vim命令來添加,以下:
```
vim /data/3306/mysql
vim /data/3307/mysql
```
須要添加的MySQL啓動文件內容以下。(固然,在實際工做中咱們是拿早已配置好的模板來進行修改的,能夠經過rz等方式上傳配置文件模板MySQL文件到相關目錄下)
```
[root@localhost ~]# cat /data/3306/mysql
#!/bin/bash
###############################################
#this scripts is created by Mr.chen at 2016-06-25
port=3306
mysql_user="root"
mysql_pwd="" #這裏須要修改成用戶的實際密碼
CmdPath="/usr/local/mysql/bin"
mysql_sock="/data/${port}/mysql.sock"
#startup function
function_start_mysql(){
if [ ! -e "$mysql_sock" ];then
printf "Starting MySQL....\n"
/bin/sh ${CmdPath}/mysqld_safe --defaults-file=/data/${port}/my.cnf 2>&1 >/dev/null &
else
printf "MySQL is running...\n"
exit
fi
}
#stop function
function_stop_mysql(){
if [ ! -e "$mysql_sock" ];then
printf "MySQL is stopped...\n"
exit
else
printf "Stoping MySQL...\n"
${CmdPath}/mysqladmin -u ${mysql_user} -p${mysql_pwd} -S /data/${port}/mysql.sock shutdown
fi
}
#restart function
function_restart_mysql(){
printf "Restarting MySQL...\n"
function_stop_mysql
sleep 2
function_start_mysql
}
case $1 in
start)
function_start_mysql
;;
stop)
function_stop_mysql
;;
restart)
function_restart_mysql
;;
*)
printf "Usage: /data/${port}/mysql{start|stop|restart}\n"
esac
```
3307實例的啓動文件只需修改3306啓動文件的端口便可
最終完成後的多實例根/data目錄結果以下:
```
[root@localhost ~]# tree /data
/data
├── 3306
│ ├── data
│ ├── my.cnf #3306實例的配置文件
│ └── mysql #3306實例的啓動文件
└── 3307
├── data
├── my.cnf #3307實例的配置文件
└── mysql #3307實例的啓動文件
4 directories, 4 files
```
須要特別說明一下,在多實例啓動文件中,啓動MySQL不一樣實例服務,所執行的命令實質是有區別的,例如,啓動3306實例的命令以下:
```
mysqld_safe --defaults-file=/data/3306/my.cnf 2>&1 >/dev/null &
```
啓動3307實例的命令以下:
```
mysqld_safe --defaults-file=/data/3307/my.cnf 2>&1 >/dev/null &
```
下面看看在多實例啓動文件中,中止MySQL不一樣實例服務的實質命令。
中止3306實例的命令以下:
```
mysqladmin -uroot -pyunjisuan123 -S /data/3306/mysql.sock shutdown
```
中止3307實例的命令以下:
```
mysqladmin -u root -pyunjisuan123 -S /data/3307/mysql.sock shutdown
```
##### 配置MySQL多實例的文件權限
1)經過下面的命令,受權mysql用戶和組管理整個多實例的根目錄/data
```
[root@localhost ~]# chown -R mysql.mysql /data
[root@localhost ~]# find /data -name "mysql" | xargs ls -l
-rw-r--r--. 1 mysql mysql 1039 Jul 20 19:33 /data/3306/mysql
-rw-r--r--. 1 mysql mysql 1039 Jul 20 19:34 /data/3307/mysql
```
2)經過下面的命令,受權MySQL多實例全部啓動文件的mysql可執行,設置700權限最佳,注意不要用755權限,由於啓動文件裏有數據庫管理員密碼,會被讀取到。
```
[root@localhost ~]# find /data -name "mysql" | xargs chmod 700
[root@localhost ~]# find /data -name "mysql" | xargs ls -l
-rwx------. 1 mysql mysql 1039 Jul 20 19:33 /data/3306/mysql
-rwx------. 1 mysql mysql 1039 Jul 20 19:34 /data/3307/mysql
```
##### MySQL相關命令加入全局路徑的配置
(1)配置全局路徑的意義
若是不爲MySQL的命令配置全局路徑,就沒法直接在命令行輸入mysql這樣的命令,只能用全路徑命令(/usr/local/mysql/bin/mysql),這種帶着路徑輸入命令的方式很麻煩。
(2)配置MySQL全局路徑的方法
1)確認mysql命令所在路徑,命令以下:
```
[root@localhost ~]# ls /usr/local/mysql/bin/mysql
/usr/local/mysql/bin/mysql
```
2)在PATH變量前面增長/usr/local/mysql/bin路徑,並追加到/etc/profile文件中,命令以下:
```
[root@localhost ~]# echo 'export PATH=/usr/local/mysql/bin:$PATH' >> /etc/profile
#注意,echo後邊是單引號,雙引號的話變量內容會被解析掉。
[root@localhost ~]# tail -1 /etc/profile
export PATH=/usr/local/mysql/bin:$PATH
[root@localhost ~]# source /etc/profile
#執行source使上一行添加到/etc/profile中,內容直接生效
#以上命令的用途爲定義mysql全局路徑,實如今任意路徑執行mysql命令
```
提示:
更簡單的設置方法爲用下面命令作軟連接:ln -s /usr/local/mysql/bin/* /usr/local/sbin/,把mysql命令說在路徑連接到全局路徑/usr/local/sbin/的下面。
##### 初始化MySQL多實例的數據庫文件
上述步驟全都配置完畢後,就能夠初始化數據庫文件了,這個步驟其實也能夠在編譯安裝MySQL以後就操做,只不過放到這裏更合理一些。
(1)初始化MySQL數據庫
初始化命令以下:
```
[root@localhost scripts]# ./mysql_install_db --basedir=/usr/local/mysql --datadir=/data/3306/data --user=mysql
[root@localhost scripts]# ./mysql_install_db --basedir=/usr/local/mysql --datadir=/data/3307/data --user=mysql
```
提示:
--basedir=/usr/local/mysql爲MySQL的安裝路徑,--datadir爲不一樣的實例數據目錄
(2)初始化數據庫的原理及結果說明
初始化數據庫的實質就是建立基礎的數據庫系統的庫文件,例如:生成MySQL庫表等。
初始化數據庫後查看對應實例的數據目錄,能夠看到多了以下文件:
```
[root@localhost scripts]# tree /data
#如下省略若干...
```
##### 啓動MySQL多實例的命令
```
[root@localhost scripts]# /data/3306/mysql start
Starting MySQL....
[root@localhost scripts]# /data/3307/mysql start
Starting MySQL....
root@localhost scripts]# netstat -antup | grep 330
tcp 0 0 0.0.0.0:3307 0.0.0.0:* LISTEN 24743/mysqld
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 24020/mysqld
```
從輸出中能夠看到,3306和3307實例均已正常啓動。
#### 配置及管理MySQL多實例數據庫
##### 配置MySQL多實例數據庫開機自啓動
服務的開機自啓動很關鍵,MySQL多實例的啓動也不例外,把MySQL多實例的啓動命令加入/etc/rc.local,實現開機自啓動,命令以下:
```
[ root@localhost ~]# echo "#mysql multi instances" >> /etc/rc.local
[root@localhost ~]# echo "/data/3306/mysql start" >> /etc/rc.local
[root@localhost ~]# echo "/data/3307/mysql start" >> /etc/rc.local
[root@localhost ~]# tail -3 /etc/rc.local
#mysql multi instances
/data/3306/mysql start
/data/3307/mysql start
#這裏必定要確保MySQL腳本可執行~
```
##### 登錄MySQL測試
```
[root@localhost ~]# mysql -S /data/3306/mysql.sock #直接敲就進來了,並且身份仍是root。可是多了-S /data/3306/mysql.sock,用於區別登錄不一樣的實例
# -S 指定實例位置
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.5.22 Source distribution
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases; #查看當前全部的數據庫
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
4 rows in set (0.00 sec)
mysql> select user(); #查看當前的登錄用戶
25.| user() |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)
```
##### MySQL多實例數據庫的管理方法
MySQL安裝完成後,默認狀況下,MySQl管理員的帳號root是無密碼的。登錄不一樣的實例須要指定不一樣實例的mysql.sock文件路徑,這個mysql.sock是在my.cnf配置文件裏指定的。
下面是無密碼狀況下登錄數據庫的方法,關鍵點是-S參數及後面指定的/data/33306/mysql.sock,注意,不一樣實例的sock雖然名字相同,可是路徑是不一樣的,所以是不一樣的文件。
```
mysql -S /data/3306/mysql.sock
mysql -S /sata/3307/mysql.sock
#-S 指定實例位置,-u 指定數據庫 -p 指定密碼
```
下面是重啓對應實例數據庫的命令
```
/data/3306/mysql stop
/data/3307/mysql start
```
##### MySQL安全配置
MySQL管理員的帳號root密碼默認爲空,極不安全,能夠經過mysqladmin命令爲MySQL不一樣實例的數據庫設置獨立的密碼,命令以下:
```
[root@localhost ~]# mysqladmin -u root -S /data/3306/mysql.sock password '123123' #爲mysql設置密碼
[root@localhost ~]# mysql -uroot -p -S /data/3306/mysql.sock #沒法直接登錄了
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.5.22 Source distribution
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
#提示:3307實例設置方法和3306實例相同,只是鏈接時的mysql,sock路徑不一樣,這已經提醒屢次,你們要注意
```
帶密碼登錄不一樣實例數據庫的方法:
```
#登錄3306實例的命令以下:
mysql -uroot -p123123 -S /data/3306/mysql.sock
#登錄3307實例的命令以下:
mysql -uroot -p123123 -S /data/3307/mysql.sock
```
提示:
基礎弱的同窗,在測試時儘可能保證多實例的密碼相同,能夠減小麻煩,後面還原數據庫時會覆蓋密碼!
若要重啓多實例數據庫,也須要進行相應的以下配置。再重啓數據庫前,須要調整不一樣實例啓動文件裏對應的數據庫密碼。
```
[root@localhost ~]# vim /data/3306/mysql
[root@localhost ~]# sed -n '7p' /data/3306/mysql #這是以前mysql多實例啓動腳本里mysql的登錄密碼變量
mysql_pwd=""
[root@localhost ~]# sed -i '7 s#""#"123123"#' /data/3306/mysql
[root@localhost ~]# sed -n '7p' /data/3306/mysql
mysql_pwd="123123" #修改爲實際的登陸密碼
[root@localhost ~]# sed -n '7p' /data/3307/mysql
mysql_pwd=""
[root@localhost ~]# sed -i '7 s#""#"123123"#' /data/3307/mysql
[root@localhost ~]# sed -n '7p' /data/3307/mysql
mysql_pwd="123123"
```
多實例下正常中止數據庫的命令以下:
```
/data/3306/mysql stop
```
因爲選擇了mysqladmin shutdown的中止方式,因此中止數據庫時須要在啓動文件裏配置數據庫的密碼
```
/data/3306/mysql start
```
重點提示:
禁止使用pkill,kill -9,killall -9等命令強制殺死數據庫,這會引發數據庫沒法啓動等故障的發生。
##### 如何再增長一個MySQL的實例
若再3306和3307實例的基礎上,再增長一個MySQL實例,該怎麼辦?下面給出增長一個MySQL3308端口實例的命令集合:
```
mkdir -p /data/3308/data
\cp /data/3306/my.cnf /data/3308/
\cp /data/3306/mysql /data/3308/
sed -i 's#3306#3308#g' /data/3308/my.cnf
sed -i 's#server-id = 1#server-id = 8#g' /data/3308/my.cnf
sed -i 's#3306#3308#g' /data/3308/mysql
chown -R mysql:mysql /data/3308
chmod 700 /data/3308/mysql
cd /usr/local/mysql/scripts
./mysql_install_db --datadir=/data/3308/data --basedir=/usr/local/mysql --user=mysql
chown -R mysql:mysql /data/3308
egrep "server-id|log-bin" /data/3308/my.cnf
/data/3308/mysql start
netstat -antup | grep 3308
#提示:最好把server-id按照IP地址最後一個小數點的數字設置
#成功標誌:多了一個啓動的端口3308
若是配置之後,服務啓動後卻沒有運行起來,別忘了必定要看MySQL錯誤日誌,在/data/3308/my.cnf最下面有錯誤日誌路徑地址。
```
##### 多實例MySQL登錄問題分析
(1)多實例本地登陸MySQL
多實例本地登陸通常經過socket文件來指定具體登錄到哪一個實例,此文件的具體位置是在MySQL編譯過程或my.cnf文件中指定的。在本地登錄數據庫時,登錄程序會經過socket文件來判斷登錄的是哪一個數據庫實例。
例如:經過mysql -uroot -p '123123' -S /data/3307/mysql.sock可知,登錄的是3307這個實例。
mysql.sock文件是MySQL服務器端與本地MySQL客戶端進行通訊的UNIX套接字文件。
(2)遠程鏈接登錄MySQL多實例
遠程登錄MySQL多實例中的一個實例時,經過TCP端口(port)來指定說要登錄的MySQL實例,此端口的配置是在MySQL配置文件my.cnf中指定的。
例如:在mysql -uyunjisuan -p '123123' -h 192.168.200.101 -P 3307中,-P爲端口參數,後面接具體的實例端口,端口是一種「邏輯鏈接位置」,是客戶端程序被分派到計算機上特殊服務程序的一種方式,強調提早在192.168.200.101上對yunjisuan用戶作了受權。
### MySQL主從複製架構(AB複製)
1. MySQL數據庫支持單向,雙向,鏈式級聯,環狀等不一樣業務場景的複製。在複製過程當中,一臺服務器充當主服務器(Master),接收來自用戶的內容更新,而一個或多個其餘的服務器充當從服務器(Slave),接收來自主服務器binlog文件的日誌內容,解析出SQL,從新更新到從服務器,使得主從服務器數據達到一致。
2. 若是設置了鏈式級聯複製,那麼,從服務器(Slave)自己除了充當從服務器外,也會同時充當其下面從服務器的主服務器。鏈式級聯複製相似A-->B-->C的複製形式。
下圖爲單向主從複製架構邏輯圖,此架構只能在Master端進行數據寫入
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20181119225136506.)
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20181119225152671.?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzMwNDgwNA==,size_16,color_FFFFFF,t_70)
下圖爲雙向主主複製邏輯架構圖,此架構能夠在Master1端或Master2端進行數據寫入,或者兩端同時寫入數據(須要特殊設置)
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/2018111922521087.)
下圖爲線性級聯單向雙主複製邏輯架構圖,此架構只能在Master1端進行數據寫入,工做場景中,Master1和master2做爲主主互備,Slave1做爲從庫,中間的Master2須要作特殊的設置。
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20181119225223576.)
下圖爲環狀級聯單向多主同步邏輯架構圖,任意一個點均可以寫入數據,此架構比較複雜,屬於極端環境下的「成品」,通常場景慎用
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20181119225242563.?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzMwNDgwNA==,size_16,color_FFFFFF,t_70)
在當前的生產工做中,MySQL主從複製都是異步的複製方式,既不是嚴格實時的數據同步,可是正常狀況下給用戶的體驗是真實的。
#### MySQL主從複製的企業應用場景
##### 應用場景1:從服務器做爲主服務器的實時數據備份
1. 主從服務器架構的設置能夠大大增強MySQL數據庫架構的健壯性。例如:當主服務器出現問題時,咱們能夠人工或設置自動切換到從服務器繼續提供服務,此時從服務器的數據與宕機時的主數據庫幾乎是一致的。
2. 這相似NFS存儲數據經過inotify + rsync同步到備份的NFS服務器,只不過MySQL的複製方案是其自帶的工具。
3. 利用MySQL的複製功能進行數據備份時,在硬件故障,軟件故障的場景下,該數據備份是有效的,但對於人爲地執行drop,delete等語句刪除數據的狀況,從庫的備份功能就沒用了,由於從服務器也會執行刪除的語句。
##### 應用場景2:主從服務器實現讀寫分離,從服務器實現負載均衡
1. 主從服務器架構可經過程序(PHP,java等)或代理軟件(mysql-proxy,Amoeba)實現對用戶(客戶端)的請求讀寫分離,即讓從服務器僅僅處理用戶的select查詢請求,下降用戶查詢響應時間,以及同時讀寫在主服務器上帶來的訪問壓力。對於更新的數據(例如:update,insert,delete語句),則仍然交給主服務器處理,確保主服務器和從服務器保持實時同步。
2. 百度,淘寶,新浪等絕大多數的網站都是用戶瀏覽頁面多於用戶發佈內容,所以經過在從服務器上接收只讀請求,就能夠很好地減輕主庫的讀壓力,且從服務器能夠很容易地擴展爲多臺,使用LVS作負載均衡效果就很是棒了,這就是傳說中的數據庫讀寫分離架構。邏輯架構圖以下所示:
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20181119234724616.?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzMwNDgwNA==,size_16,color_FFFFFF,t_70)
##### 應用場景3:把多個從服務器根據業務重要性進行拆分訪問
能夠把幾個不一樣的從服務器,根據公司的業務進行拆分。例如:有爲外部用戶提供查詢服務的從服務器,有內部DBA用來數據備份的從服務器,還有爲公司內部人員提供訪問的後臺,腳本,日誌分析及供開發人員查詢使用的從服務器。這樣的拆分除了減輕主服務器的壓力外,還可使數據庫對外部用戶瀏覽,內部用戶業務處理及DBA人員的備份等互不影響。
#### 實現MySQL主從讀寫分離的方案
(1)經過程序實現讀寫分離(性能和效率最佳,推薦)
PHP和Java程序均可以經過設置多個鏈接文件輕鬆地實現對數據庫的讀寫分離,即當語句關鍵字爲select時,就去鏈接讀庫的鏈接文件,若爲update,insert,delete時,則鏈接寫庫的鏈接文件。
經過程序實現讀寫分離的缺點就是須要開發人員對程序進行改造,使其對下層不透明,但這種方式更容易開發和實現,適合互聯網業務場景。
根據業務重要性拆分從庫方案
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20181119234823358.?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzMwNDgwNA==,size_16,color_FFFFFF,t_70)
(2)經過開源的軟件實現讀寫分離
MySQL-proxy,Amoeba等代理軟件(速度分離調度器 )也能夠實現讀寫分離功能,這些軟件的穩定性和功能通常,不建議生產使用。絕大多數公司經常使用的仍是在應用端發程序實現讀寫分離。
(3)大型門戶獨立開發DAL層綜合軟件
百度,阿里等大型門戶都有開發牛人,會花大力氣開發適合本身業務的讀寫分離,負載均衡,監控報警,自動擴容,自動收縮等一系列功能的DAL層軟件。
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20181119234847466.?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzMwNDgwNA==,size_16,color_FFFFFF,t_70)
#### MySQL主從複製原理介紹
1. MySQL的主從複製是一個異步的複製過程(雖然通常狀況下感受是實時的,實際是有延遲時間的),數據將從一個MySQL數據庫(咱們稱之爲Master)複製到另外一個MySQL數據庫(咱們稱之爲Slave),在Master與Slave之間實現整個主從複製的過程是由三個線程參與完成的。其中有兩個線程(SQL線程和I/O線程)在Slave端,另一個線程(I/O線程)在Master端。
2. 要實現MySQL的主從複製,首先必須打開Master端的binlog記錄功能,不然就沒法實現。由於整個複製過程實際上就是Slave從Master端獲取binlog日誌,而後再在Slave上以相同順序執行獲取的binlog日誌中所記錄的各類SQL操做。
3. 要打開MySQL的binlog記錄功能,可經過在MySQL的配置文件my.cnf中的mysqld模塊([mysqld]標識後的參數部分)增長「log-bin」參數選項來實現,具體信息以下。
```
[mysqld]
log-bin=/data/3306/mysql-bin
```
提示:
有些同窗把log-bin放在了配置文件結尾,而不是[mysqld]標識後,從而致使配置複製不成功。
#### MySQL主從複製原理過程詳細描述
下面簡單描述MySQL Replication的複製原理過程
1)在Slave服務器上執行start slave命令開啓主從複製開關,開始進行主從複製
2)此時,Slave服務器的I/O線程會經過在Master上已經受權的複製用戶權限請求鏈接Master服務器,並請求從指定binlog日誌文件的指定位置(日誌文件名和位置就是在配置主從複製服務時執行change master命令指定的)以後開始發送binlog日誌內容。
3)Master服務器接收到來自Slave服務器的I/O線程的請求後,其上負責複製的I/O線程會根據Slave服務器的I/O線程請求的信息分批讀取指定binlog日誌文件指定位置以後的binlog日誌信息,而後返回給Slave端的I/O線程。返回的信息中除了binlog日誌內容外,還有在Master服務器端記錄的新的binlog文件名稱,以及在新的binlog中的下一個指定更新位置。
4)當Slave服務器的I/O線程獲取到Master服務器上I/O線程發送的日誌內容,日誌文件及位置點後,會將binlog日誌內容依次寫到Slave端自身的Relay Log(即中繼日誌)文件(MySQL-relay-bin.xxxx)的最末端,並將新的binlog文件名和位置記錄到master-info文件中,以便下一次讀取Master端新binlog日誌時可以告訴Master服務器重新binlog日誌的指定文件及位置開始請求新的binlog日誌內容。
5)Slave服務器端的SQL線程會實時檢測本地Relay Log中I/O線程新增長的日誌內容,而後及時地把Relay Log文件中的內容解析成SQL語句,並在自身Slave服務器上按解析SQL語句的位置順序執行應用這些SQL語句,並在relay-log.info中記錄當前應用中繼日誌的文件名及位置點。
通過了上面的過程,就能夠確保在Master端和Slave端執行了一樣的SQL語句。當複製狀態正常時,Master端和Slave端的數據是徹底同樣的。固然,MySQL的複製機制也有一些特殊狀況,具體請參考官方的說明,大多數狀況下,同窗們不用擔憂。
MySQL Replication的複製原理邏輯圖
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20181120000731737.?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzMwNDgwNA==,size_16,color_FFFFFF,t_70)
解析:
左邊爲主庫master,右邊爲從庫slave;
主庫有一個master主進程(socket進程)及一個I/O線程;
從庫有一個slave主進程,I/O線程及SQL線程。
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20181120003319368.?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzMwNDgwNA==,size_16,color_FFFFFF,t_70)
實現複製的過程:
主庫:
1. 主庫開啓二進制日誌 log_bin=mysql-bin
用戶向主庫的data數據目錄裏寫入數據,此時master主庫若已打開mysqlbinlog日誌,該日誌就會記錄該數據到mysqlbinlog二進制日誌內(I/O線程將用戶寫在master主庫的數據data目錄裏的數據記錄在二進制日誌內),開啓二進制日誌(log_bin=mysql-bin)後,纔會有I/O線程。用戶向主庫的data數據目錄裏寫入數據,此時master主庫若已打開mysqlbinlog日誌,該日誌就會記錄該數據到mysqlbinlog二進制日誌內(I/O線程將用戶寫在master主庫的數據data目錄裏的數據記錄在二進制日誌內),開啓二進制日誌(log_bin=mysql-bin)後,纔會有I/O線程。
2. 建立主從複製帳號
3. 主庫:server id=1
從庫:
4. 從庫開啓中繼日誌 relay-log=relay-bin
從庫的I/O線程緊盯主庫的二進制日誌,一旦有更新,從庫的I/O線程就會向主庫的I/O線程申請驗證,驗證經過後,主庫的I/O線程就會把對應的mysqlbinlog二進制日誌內容複製給從庫的I/O線程,從庫的I/O線程把複製的內容存放在中繼日誌relay-log從庫的I/O線程緊盯主庫的二進制日誌,一旦有更新,從庫的I/O線程就會向主庫的I/O線程申請驗證,驗證經過後,主庫的I/O線程就會把對應的mysqlbinlog二進制日誌內容複製給從庫的I/O線程,從庫的I/O線程返還的信息有binlog日誌內容(複製的內容)及新的binlog文件和POS值(position);從庫的I/O線程把複製的內容(binlog日誌內容)存放在中繼日誌relay-log
驗證信息:
(1)主庫IP
(2)主庫socket進程的端口號
(3)主庫的複製帳號和密碼
(4)複製哪一個二進制文件的名字
(5)二進制日誌文件中position具體位置
驗證信息錄入到從庫後,從庫信息記錄在master.info(記錄驗證信息和二進制日誌文件位置信息)
5. 此時SQL線程開始啓動,查看中繼日誌,將中繼日誌中的二進制翻譯成一條一條的SQL語句,跟蹤relay-bin,SQL線程使用relay-log.info作記錄
,執行從庫的mysql/data,從而完成主從複製的過程。
6. 主從複製驗證信息錄入
7. 在從庫中激活主從複製
8. 從庫:server id=不爲1 的值
特別說明:
當企業面試MySQL主從複製原理時,無論是面試仍是筆試,都要儘可能畫圖表達,而不是口頭講或文字描述,面試時能夠找黑板或拿出紙來給面試官詳細講解。
下面針對MySQL主從複製原理的重點進行小結:10. 主從複製是異步的邏輯的SQL語句級的複製11. 複製時,主庫有一個I/O線程,從庫有兩個線程,即I/O和SQL線程12. 實現主從複製的必要條件是主庫要開啓記錄binlog功能13. 做爲複製的全部MySQL節點的server-id都不能相同。14. binlog文件只記錄對數據庫有更改的SQL語句(來自主數據庫內容的變動),不記錄任何查詢(如select,show)語句。