1. 程式人生 > >Linux系統——MySQL基礎(二)

Linux系統——MySQL基礎(二)

# MySQL資料庫完全備份與恢復
## 資料庫備份的分類
1. 從物理與邏輯的角度,備份可以分為物理備份和邏輯備份。
(1)物理備份:對資料庫作業系統的物理檔案(資料檔案、日誌檔案)的備份。物理備份又可分為離線備份(冷備份)和聯機備份(熱備份)
冷備份:在關閉資料庫中的時候進行的
熱備份:資料庫處於執行狀態,這種備份依賴於資料庫的日誌檔案
溫備份:資料庫鎖定表格(不可寫入但可讀)的狀態下進行的
(2)邏輯備份:對資料庫邏輯元件(如表等資料庫物件)的備份
2. 從資料庫的備份策略角度,備份可分為完全備份、差異備份和增量備份
(1)完全備份:每次對資料進行完整的備份
對整個資料庫的備份、資料庫結構和檔案結構的備份,儲存的是備份完成時刻的資料庫,是差異備份與增量備份的基礎。
優點:備份與恢復操作簡單方便
缺點:資料存在大量的重複;佔用大量的空間;備份與恢復時間長
(2)差異備份:備份那些字從上次完全備份之後被修改過的所有檔案
備份的時間節點是從上次完整備份起,備份資料量會越來越大。恢復資料時,只需要恢復上次完全備份與最近的一次差異備份。
(3)增量備份:至於那些在上次完全備份揮著增量備份後被修改的檔案才會被備份
以上次完整備份或上次的增量備份的時間為時間點,僅備份這之間的資料辯護啊,因而備份的數量小,佔用空間小,備份速度快。但回覆是,需要從上一次的完整備份起到左後一次增量備份一次恢復,如中間某次的備份資料損壞,將導致資料的丟失。

## MySQL完全備份操作
1. (冷備份方式)直接打包資料裡資料夾
2. (熱備份方式)使用專用備份工具mysqldump
(1)對單個庫進行完全備份
格式:mysqldump -u使用者名稱 -p密碼 選項 空間名 > /備份路徑/備份檔名
```
[[email protected] ~]# mysqldump -uroot -p123456 yunjisuan > /tmp/yunjisuan-$(date +%F).sql
[[email protected] ~]# ls /tmp/
mysql.sock yum.log yunjisuan-2018-11-19.sql
```
(2)對多個庫進行完全備份
格式:mysqldump -u使用者名稱 -p密碼 選項 ==--databases== 空間名1 空間名2 > /備份路徑/備份檔名

```
[[email protected] ~]# mysqldump -uroot -p123456 --databases yunjisuan daisy > /tmp/yunjisuan-$(date +%F).sql
```
(3)對所有庫進行完全備份
格式:mysqldump -u使用者名稱 -p密碼 選項 --all-databases > /備份路徑/備份檔名

```
[[email protected] ~]# mysqldump -uroot -p123456 --opt --all-databases > /tmp/yunjisuan-$(date +%F).sql
# --opt 加快備份速度,當備份資料量大時使用
```
(4)對錶進行完全備份
格式:mysqldump -u使用者名稱 -p密碼 選項 空間名 表名 > /備份路徑/備份檔名

```
[[email protected] ~]# mysqldump -uroot -p123456 yunjisuan users > /tmp/yunjisuan-$(date +%F).sql
```
(5)對錶結構的備份
格式:mysqldump -u使用者名稱 -p密碼 -d 空間名 表名 > /備份路徑/備份檔名

```
[[email protected] ~]# mysqldump -uroot -p123456 -d yunjisuan users > /tmp/yunjisuan-$(date +%F).sql
```
## 使用mysqldump備份後,恢復資料庫
1. source命令(互動式)

```
[[email protected] ~]# mysqldump -uroot -p123456 --opt --all-databases > /tmp/mysql_all-$(date +%F).sql
[[email protected] ~]# ls /tmp/
mysql_all-2018-11-19.sql
[[email protected] ~]# 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)

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密碼 庫名 < 表備份指令碼的路徑

```
[[email protected] ~]# mysql -uroot -p123456 -e 'drop database yunjisuan;'
[[email protected] ~]# mysql -uroot -p123456 < /tmp/mysql_all-2018-11-19.sql
[[email protected] ~]# 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命令後重新建立新的日誌檔案。
==控制二進位制日誌大小==
```
[[email protected] mysql]# vim /etc/my.cnf
53 max_binlog_size=1024000
#二進位制日誌最大1M
```
只需定時執行flush logs方法重新建立新的日誌,生成二進位制檔案序列,並及時把這些日誌儲存到安全的地方就完成了一個時間段的增量備份。

開啟mysqlbinlog二進位制日誌功能:
方法一:
```
[[email protected] 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檔案內容

```
[[email protected] mysql]# mysqlbinlog mysql-bin.000006

```

方法二:使用mysqld--log-bin=檔案存放路徑/檔案字首 重新啟動mysql服務
每週選擇伺服器負載矯情的時間段,或者使用者訪問較少的時間段進行備份。

### MySQL增量恢復
#### 應用場景
1. 認為的SQL語句破壞了資料庫
2. 再進行下一次全北之前發生系統故障導致資料庫資料丟失
3. 在主從架構中,主庫資料發生了故障

#### 增量恢復的方法
1. 一般的恢復:備份的二進位制日誌內容全部恢復
格式:mysqlbinlog [--no-defaults] 增量備份檔案 | mysql -u 使用者名稱 -p 密碼

```
[[email protected] mysql]# mysqlbinlog /usr/local/mysql/data/mysql-bin.000012 | mysql -uroot -p123456
[[email protected] 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 密碼

```
[[email protected] mysql]# mysql -uroot -p123456 -e 'select * from yunjisuan.users;'
+-----------+-------------+
| user_name | user_passwd |
+-----------+-------------+
| daisy | 123456 |
| helen | 432543 |
| 小然 | 533223 |
| 綠小花 | 123123 |
+-----------+-------------+
[[email protected] mysql]# mysqlbinlog --start-position='509' --stop-position='710' /usr/local/mysql/data/mysql-bin.000013 | mysql -uroot -p123456
[[email protected] 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. 多配置檔案,多啟動程式的部署方案
多配置檔案,多啟動程式部署方案,是本文主要講解的方案,也是非常常用並極力推薦的多例項方案。下面來看配置示例。

```
[[email protected] /]# 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的依賴包。安裝命令如下:

```
[[email protected] ~]# yum -y install ncurses-devel libaio-devel
[[email protected] ~]# 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軟體,然後進行如下操作:

```
[[email protected] ~]# 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 #此軟體需提前準備
[[email protected] ~]# tar xf cmake-2.8.6.tar.gz -C /usr/src/
[[email protected] ~]# cd /usr/src/cmake-2.8.6/
[[email protected] cmake-2.8.6]# ./configure
[[email protected] cmake-2.8.6]# gmake && gmake install
[[email protected] cmake-2.8.6]# which cmake
```

2. 開始安裝MySQL
為了讓同學們學習更多的MySQL技術,接下來會以相對複雜的原始碼安裝來講解MySQL多例項的安裝。大型公司一般都會將MySQL軟體定製成rpm包,然後放到yum倉庫裡,使用yum安裝,中小企業裡的二進位制和編譯安裝的區別不大。
(1)建立MySQL使用者賬號
首先以root身份登入到Linux系統中,然後執行如下命令建立mysql使用者賬號:

```
[[email protected] ~]# useradd -s /sbin/nologin -M mysql
[[email protected] ~]# 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
配置及編譯安裝的步驟如下:

```
[[email protected] ~]# tar xf mysql-5.5.22.tar.gz -C /usr/src/
[[email protected] ~]# cd /usr/src/mysql-5.5.22/
[[email protected] 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(開啟影響效能)
# 提示:編譯時可配置的選項很多,具體可參考官方文件
[[email protected] mysql-5.5.22]# make && make install
```

下面設定不帶版本號的軟連結/usr/local/mysql,操作步驟如下:

```
[[email protected] mysql-5.5.22]# ln -s /usr/local/mysql-5.5.22 /usr/local/mysql
[[email protected] 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多例項的目錄如下:

```
[[email protected] ~]# mkdir -p /data/{3306,3307}/data
[[email protected] ~]# 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資料庫預設為使用者提供了多個配置檔案模板,使用者可以根據伺服器硬體配置的大小來選擇。

```
[[email protected] 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

```
[[email protected] ~]# 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目錄結果如下:

```
[[email protected] ~]# 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檔案到相關目錄下)

```
[[email protected] ~]# 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目錄結果如下:

```
[[email protected] ~]# 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

```
[[email protected] ~]# chown -R mysql.mysql /data
[[email protected] ~]# 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許可權,因為啟動檔案裡有資料庫管理員密碼,會被讀取到。

```
[[email protected] ~]# find /data -name "mysql" | xargs chmod 700
[[email protected] ~]# 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命令所在路徑,命令如下:

```
[[email protected] ~]# ls /usr/local/mysql/bin/mysql
/usr/local/mysql/bin/mysql
```

2)在PATH變數前面增加/usr/local/mysql/bin路徑,並追加到/etc/profile檔案中,命令如下:

```
[[email protected] ~]# echo 'export PATH=/usr/local/mysql/bin:$PATH' >> /etc/profile
#注意,echo後邊是單引號,雙引號的話變數內容會被解析掉。
[[email protected] ~]# tail -1 /etc/profile
export PATH=/usr/local/mysql/bin:$PATH
[[email protected] ~]# 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資料庫
初始化命令如下:

```
[[email protected] scripts]# ./mysql_install_db --basedir=/usr/local/mysql --datadir=/data/3306/data --user=mysql
[[email protected] scripts]# ./mysql_install_db --basedir=/usr/local/mysql --datadir=/data/3307/data --user=mysql
```

提示:
--basedir=/usr/local/mysql為MySQL的安裝路徑,--datadir為不同的例項資料目錄
(2)初始化資料庫的原理及結果說明
初始化資料庫的實質就是建立基礎的資料庫系統的庫檔案,例如:生成MySQL庫表等。
初始化資料庫後檢視對應例項的資料目錄,可以看到多瞭如下檔案:

```
[[email protected] scripts]# tree /data

#以下省略若干...
```

##### 啟動MySQL多例項的命令

```
[[email protected] scripts]# /data/3306/mysql start
Starting MySQL....
[[email protected] scripts]# /data/3307/mysql start
Starting MySQL....
[email protected] 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,實現開機自啟動,命令如下:

```
[ [email protected] ~]# echo "#mysql multi instances" >> /etc/rc.local
[[email protected] ~]# echo "/data/3306/mysql start" >> /etc/rc.local
[[email protected] ~]# echo "/data/3307/mysql start" >> /etc/rc.local
[[email protected] ~]# tail -3 /etc/rc.local
#mysql multi instances
/data/3306/mysql start
/data/3307/mysql start

#這裡一定要確保MySQL指令碼可執行~
```
##### 登陸MySQL測試

```
[[email protected] ~]# 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() |
+----------------+
| [email protected] |
+----------------+
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不同例項的資料庫設定獨立的密碼,命令如下:

```
[[email protected] ~]# mysqladmin -u root -S /data/3306/mysql.sock password '123123' #為mysql設定密碼
[[email protected] ~]# 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
```

提示:
基礎弱的同學,在測試時儘量保證多例項的密碼相同,可以減少麻煩,後面還原資料庫時會覆蓋密碼!
若要重啟多例項資料庫,也需要進行相應的如下配置。再重啟資料庫前,需要調整不同例項啟動檔案裡對應的資料庫密碼。

```
[[email protected] ~]# vim /data/3306/mysql
[[email protected] ~]# sed -n '7p' /data/3306/mysql #這是之前mysql多例項啟動腳本里mysql的登陸密碼變數
mysql_pwd=""
[[email protected] ~]# sed -i '7 s#""#"123123"#' /data/3306/mysql
[[email protected] ~]# sed -n '7p' /data/3306/mysql
mysql_pwd="123123" #修改成實際的登入密碼
[[email protected] ~]# sed -n '7p' /data/3307/mysql
mysql_pwd=""
[[email protected] ~]# sed -i '7 s#""#"123123"#' /data/3307/mysql
[[email protected] ~]# 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)語句。