第二十九節 MySQL數據庫企業級應用實踐
一,概述
1.1 MySQL介紹
MySQL屬於傳統關系型數據庫產品,它開放式的架構使得用戶選擇性很強,同時社區開發與維護人數眾多。其功能穩定,性能卓越,且在遵守GPL協議的前提下,可以免費使用與修改,也為MySQL的推廣與使用帶來了更多的利好。在MySQL成長與發展過程中,支持的功能逐漸增多,性能也不斷提高,對平台的支持也越來越多。
MySQL是一種關系型數據庫管理系統,關系型數據庫的特點是將數據保存在不同的表中,再將這些表放入不同的數據庫中,而不是將所有數據統一放在一個大倉庫里,這樣的設計增加了MySQL的讀取速度,而且靈活性和可管理性也得到了很大提高。訪問及管理MySQL數據庫的最常用標准化語言為SQL結構化查詢語言。
1.2 MariaDB 數據庫的誕生背景介紹
自甲骨文公司收購MySQL后,其在商業數據庫與開源數據庫領域市場的占有份額都躍居第一,這樣的格局引起了業內很多的人士的擔憂,因為商業數據庫的老大有可能將MySQL閉源。為了避免Oracle將MySQL閉源,而無開源的類MySQL數據庫可用,MySQL社區采用分支的方式來避開這個風險。MariaDB數據庫就這樣誕生了,MariaDB是一個向后兼容,可能在以后替代MySQL的數據庫產品,其官方地址為:https://mariadb.org/ 。不過,這里還是建議大家選擇更穩定,使用更廣泛的MySQL數據庫,可以先測試MariaDB數據庫,等使用的人員更多一些,社區更活躍后再考慮使用為好。
二,MySQL多實例介紹
在之前LNMP的講解中,已經針對MySQL數據庫進行了介紹,並說明了為什么要選擇MySQL數據庫,以及MySQL數據庫在Linux系統下的多種安裝方式,同時講解了MySQL的二進制方式單實例安裝,基礎優化等內容,本節將為同學們講解更為實用的MySQL多實例安裝,主從復制集群等重要應用實踐。
2.1 什么是MySQL多實例
- 簡單的說,MySQL多實例就是在一台服務器上同時開啟多個不同的服務器端口(如:3306,3307),同時運行多個MySQL服務進程,這些服務進程通過不同的socket監聽不同的服務器端口來提供服務。
- 這些MySQL多實例共用一套MySQL安裝程序,使用不同的my.cnf(也可以相同)配置文件,啟動程序(也可以相同)和數據文件。在提供服務時,多實例MySQL在邏輯上看起來是各自獨立的,它們根據配置文件的對應設定值,獲得服務器相應數量的硬件資源。
- 打個比方吧,MySQL多實例就相當於房子的多個卧室,每個實例可以看作一間卧室,整個服務器就是一套房子,服務器的硬件資源(CPU,Mem,Disk),軟件資源(Centos操作系統)可以看作房子的衛生間,廚房,客廳,是房子的公用資源。
- 其實很多網絡服務都是可以配置多實例的,例如Nginx,Apache,Haproxy,Redis,Memcache等。這在門戶網站使用得很廣泛。
2.2 MySQL多實例的作用與問題
MySQL多實例的作用如下:
(1)有效利用服務器資源
當單個服務器資源有剩余時,可以充分利用剩余的資源提供更多的服務,且可以實現資源的邏輯隔離。
(2)節約服務器資源
當公司資金緊張,但是數據庫又需要各自盡量獨立地提供服務,而且,需要主從復制等技術時,多實例就再好不過了。
MySQL多實例有它的好處,但也有其弊端,比如,會存在資源互相搶占的問題。
當某個數據庫實例並發很高或有SQL慢查詢時,整個實例會消耗大量的系統CPU,磁盤I/O等資源,導致服務器上的其他數據庫實例提供服務的質量一起下降。這就相當於大家住在一個房子的不同卧室一樣,早晨起來上班,都要刷牙,洗臉等,這樣衛生間就會長期占用,其他人要等待一樣。不同實例獲取的資源是相對獨立的,無法像虛擬化一樣完全隔離。
三, MySQL多實例的生產應用場景
3.1 資金緊張型公司的選擇
若公司資金緊張,公司業務訪問量不太大,但又希望不同業務的數據庫服務各自盡量獨立地提供服務而互相不受影響,同時,還需要主從復制等技術提供備份或讀寫分離服務,那么多實例就再好不過了。例如:可以通過3台服務器部署9~15個實例,交叉做主從復制,數據備份及讀寫分離,這樣就可達到9~15台服務器每個只裝一個數據庫才有的效果。這里要強調的是,所謂的盡量獨立是相對的。
3.2 並發訪問不是特別大的業務
當公司業務訪問量不太大的時候,服務器的資源基本上都浪費了,這時就很適合多實例的應用,如果對SQL語句的優化做得比較好,MySQL多實例會是一個很值得使用的技術,即使並發很大,合理分配好系統資源,搭配好服務,也不會有太大問題。
3.3 門戶網站應用MySQL多實例場景
門戶網站通常都會使用多實例,因為配置硬件好的服務器,可節省IDC機櫃空間,同時,跑多實例也會減少硬件資源跑不滿的浪費。比如,百度公司的很多數據庫都是多實例,不過,一般是從庫多實例,例如某部門中使用的IBM服務器為48核CPU,內存96GB,一台服務器跑3~4個實例;此外,新浪網使用的也是多實例,內存48GB左右。
說明:
據調查,新浪網的數據庫單機1~4個數據庫實例的居多,其中又數1~2個的最多,因為大業務占用的機器比較多。服務器是DELL R510的居多,CPU是E5210,48GB內存,磁盤12×300G SAS,做RAID10,此為門戶網站的服務器配置參考,希望能給同學們的面試帶來一些啟迪。
另外,新浪網站安裝數據庫時,一般采用編譯安裝的方式,並且會在優化之后做成rpm包,以便統一使用。
四, MySQL多實例常見的配置方案
4.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
該方案的缺點是耦合度太高,一個配置文件,不好管理。工作開發和運維的統一原則為降低耦合度。
4.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數據庫的安裝和之前講解的單實例沒有任何區別,因此,同學們如果有前文單實例的安裝環境,那么可以直接略過5.1節的內容。
五,安裝並配置多實例MySQL數據庫
5.1 安裝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源碼包和二進制安裝包的名稱見下圖
(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方式的安裝就算成功了。
5.2 創建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個實例為佳。
5.3 創建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
[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
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
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
5.4 創建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
5.5 配置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
5.6 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/的下面。
5.7 初始化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
#以下省略若干...
5.8 啟動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多實例數據庫
6.1 配置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腳本可執行~
6.2 登陸MySQL測試
[root@localhost ~]# mysql -S /data/3306/mysql.sock #直接敲就進來了,而且身份還是root。但是多了-S /data/3306/mysql.sock,用於區別登陸不同的實例
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(); #查看當前的登陸用戶
+----------------+
| user() |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)
6.3 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
下面是重啟對應實例數據庫的命令
/data/3306/mysql stop
/data/3307/mysql start
6.4 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等命令強制殺死數據庫,這會引起數據庫無法啟動等故障的發生。
6.5 如何再增加一個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最下面有錯誤日志路徑地址。
6.6 多實例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主從復制介紹
MySQL數據庫的主從復制方案,與使用scp/rsync等命令進行的文件級別復制類似,都是數據的遠程傳輸,只不過MySQL的主從復制是其自帶的功能,無需借助第三方工具,而且,MySQL的主從復制並不是數據庫磁盤上的文件直接拷貝,而是通過邏輯的binlog日志復制到要同步的服務器本地,然后由本地的線程讀取日志里面的SQL語句,重新應用到MySQL數據庫中。
7.1 概述
- MySQL數據庫支持單向,雙向,鏈式級聯,環狀等不同業務場景的復制。在復制過程中,一台服務器充當主服務器(Master),接收來自用戶的內容更新,而一個或多個其他的服務器充當從服務器(Slave),接收來自主服務器binlog文件的日志內容,解析出SQL,重新更新到從服務器,使得主從服務器數據達到一致。
- 如果設置了鏈式級聯復制,那么,從服務器(Slave)本身除了充當從服務器外,也會同時充當其下面從服務器的主服務器。鏈式級聯復制類似A-->B-->C的復制形式。
下圖為單向主從復制架構邏輯圖,此架構只能在Master端進行數據寫入
下圖為雙向主主復制邏輯架構圖,此架構可以在Master1端或Master2端進行數據寫入,或者兩端同時寫入數據(需要特殊設置)
下圖為線性級聯單向雙主復制邏輯架構圖,此架構只能在Master1端進行數據寫入,工作場景中,Master1和master2作為主主互備,Slave1作為從庫,中間的Master2需要做特殊的設置。
下圖為環狀級聯單向多主同步邏輯架構圖,任意一個點都可以寫入數據,此架構比較復雜,屬於極端環境下的“成品”,一般場景慎用
在當前的生產工作中,MySQL主從復制都是異步的復制方式,既不是嚴格實時的數據同步,但是正常情況下給用戶的體驗是真實的。
7.2 MySQL主從復制的企業應用場景
MySQL主從復制集群功能使得MySQL數據庫支持大規模高並發讀寫成為可能,同時有效地保護了物理服務器宕機場景的數據備份。
應用場景1:從服務器作為主服務器的實時數據備份
- 主從服務器架構的設置可以大大加強MySQL數據庫架構的健壯性。例如:當主服務器出現問題時,我們可以人工或設置自動切換到從服務器繼續提供服務,此時從服務器的數據與宕機時的主數據庫幾乎是一致的。
- 這類似NFS存儲數據通過inotify + rsync同步到備份的NFS服務器,只不過MySQL的復制方案是其自帶的工具。
- 利用MySQL的復制功能進行數據備份時,在硬件故障,軟件故障的場景下,該數據備份是有效的,但對於人為地執行drop,delete等語句刪除數據的情況,從庫的備份功能就沒用了,因為從服務器也會執行刪除的語句。
應用場景2:主從服務器實現讀寫分離,從服務器實現負載均衡
- 主從服務器架構可通過程序(PHP,java等)或代理軟件(mysql-proxy,Amoeba)實現對用戶(客戶端)的請求讀寫分離,即讓從服務器僅僅處理用戶的select查詢請求,降低用戶查詢響應時間,以及同時讀寫在主服務器上帶來的訪問壓力。對於更新的數據(例如:update,insert,delete語句),則仍然交給主服務器處理,確保主服務器和從服務器保持實時同步。
- 百度,淘寶,新浪等絕大多數的網站都是用戶瀏覽頁面多於用戶發布內容,因此通過在從服務器上接收只讀請求,就可以很好地減輕主庫的讀壓力,且從服務器可以很容易地擴展為多台,使用LVS做負載均衡效果就非常棒了,這就是傳說中的數據庫讀寫分離架構。邏輯架構圖如下所示:
應用場景3:把多個從服務器根據業務重要性進行拆分訪問
可以把幾個不同的從服務器,根據公司的業務進行拆分。例如:有為外部用戶提供查詢服務的從服務器,有內部DBA用來數據備份的從服務器,還有為公司內部人員提供訪問的后台,腳本,日志分析及供開發人員查詢使用的從服務器。這樣的拆分除了減輕主服務器的壓力外,還可以使數據庫對外部用戶瀏覽,內部用戶業務處理及DBA人員的備份等互不影響。
7.3 實現MySQL主從讀寫分離的方案
(1)通過程序實現讀寫分離(性能和效率最佳,推薦)
PHP和Java程序都可以通過設置多個連接文件輕松地實現對數據庫的讀寫分離,即當語句關鍵字為select時,就去連接讀庫的連接文件,若為update,insert,delete時,則連接寫庫的連接文件。
通過程序實現讀寫分離的缺點就是需要開發人員對程序進行改造,使其對下層不透明,但這種方式更容易開發和實現,適合互聯網業務場景。
根據業務重要性拆分從庫方案
(2)通過開源的軟件實現讀寫分離
MySQL-proxy,Amoeba等代理軟件也可以實現讀寫分離功能,這些軟件的穩定性和功能一般,不建議生產使用。絕大多數公司常用的還是在應用端發程序實現讀寫分離。
(3)大型門戶獨立開發DAL層綜合軟件
百度,阿里等大型門戶都有開發牛人,會花大力氣開發適合自己業務的讀寫分離,負載均衡,監控報警,自動擴容,自動收縮等一系列功能的DAL層軟件。
7.4 MySQL主從復制原理介紹
- MySQL的主從復制是一個異步的復制過程(雖然一般情況下感覺是實時的),數據將從一個MySQL數據庫(我們稱之為Master)復制到另一個MySQL數據庫(我們稱之為Slave),在Master與Slave之間實現整個主從復制的過程是由三個線程參與完成的。其中有兩個線程(SQL線程和I/O線程)在Slave端,另外一個線程(I/O線程)在Master端。
- 要實現MySQL的主從復制,首先必須打開Master端的binlog記錄功能,否則就無法實現。因為整個復制過程實際上就是Slave從Master端獲取binlog日志,然后再在Slave上以相同順序執行獲取的binlog日志中所記錄的各種SQL操作。
- 要打開MySQL的binlog記錄功能,可通過在MySQL的配置文件my.cnf中的mysqld模塊([mysqld]標識后的參數部分)增加“log-bin”參數選項來實現,具體信息如下。
[mysqld]
log-bin=/data/3306/mysql-bin
提示:
有些同學把log-bin放在了配置文件結尾,而不是[mysqld]標識后,從而導致配置復制不成功。
7.5 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的復制原理邏輯圖
特別說明:
當企業面試MySQL主從復制原理時,不管是面試還是筆試,都要盡量畫圖表達,而不是口頭講或文字描述,面試時可以找黑板或拿出紙來給面試官詳細講解。
下面針對MySQL主從復制原理的重點進行小結:
- 主從復制是異步的邏輯的SQL語句級的復制
- 復制時,主庫有一個I/O線程,從庫有兩個線程,即I/O和SQL線程
- 實現主從復制的必要條件是主庫要開啟記錄binlog功能
- 作為復制的所有MySQL節點的server-id都不能相同。
- binlog文件只記錄對數據庫有更改的SQL語句(來自主數據庫內容的變更),不記錄任何查詢(如select,show)語句。
八,MySQL主從復制實踐
8.1 主從復制實踐准備
8.1.1 主從復制數據庫實戰環境准備
MySQL主從復制實踐對環境的要求比較簡單,可以是單機單數據庫多實例的環境,也可以是兩台服務器,每個機器一個獨立數據庫的環境。本文以單機數據庫多實例的環境為例講解。實例端口信息查看如下:
[root@localhost ~]# ss -antup | grep 330
tcp LISTEN 0 128 *:3307 *:* users:(("mysqld",3910,11))
tcp LISTEN 0 128 *:3306 *:* users:(("mysqld",2450,11))
提示:
這里把3306實例作為主庫,3307實例作為從庫,如果根據前面的內容配置了MySQL多實例環境,直接開啟多實例環境使用即可。
8.1.2 定義主從復制需要的服務器角色
這里的主從復制技術是針對前面的內容以單機數據庫多實例環境來講的。一般情況下,小企業在做常規的主從復制時,主從服務器多數在不同的機器上,並且監聽的端口均為默認的3306.雖然不在同一個機器上,但是步驟和過程卻是一樣的。
同學們在掌握了但數據庫多實例的同步方法后,可以自己適當擴展,完成異機相同端口之間的主從復制。
8.1.3 數據庫中英文名稱約定
8.2 在主庫Master上執行操作配置
8.2.1 設置server-id值並開啟binlog功能參數
根據之前介紹的MySQL主從復制原理我們知道,要實現主從復制,關鍵是要開啟binlog日志功能,所以,首先來打開主庫的binlog日志參數。
1)修改主庫的配置文件。執行vi /data/3306/my.cnf,編輯多實例3006的my.cnf配置文件,按如下內容修改兩個參數:
[mysqld]
server-id = 1 #用於同步的每台機器或實例server-id都不能相同
log-bin = /data/3306/mysql-bin #binlog日志的位置
提示:
上面的兩個參數要放在my.cnf中的[mysqld]模塊下,否則會出錯。
不同實例間server-id的值不可以重復
要先在my.cnf配置文件中查找相關參數,並按要求修改。若發現不存在,再添加參數,切記,參數不能重復。
修改my.cnf配置后,需要重啟動數據庫,命令為:/data/3306/mysql restart ,注意要確認真正重啟了。
2)檢查配置參數后的結果,如下:
root@localhost ~]# egrep "server-id|log-bin" /data/3306/my.cnf
server-id = 1
log-bin=/data/3306/mysql-bin #log-bin后面也可以不帶等號內容,MySQL會使用默認日志
3)重啟主庫MySQL服務,命令如下:
[root@localhost ~]# /data/3306/mysql restart
Restarting MySQL...
Stoping MySQL...
Starting MySQL....
4)登陸數據庫,檢查參數的更改情況,如下:
[root@localhost ~]# mysql -uroot -p123123 -S /data/3306/mysql.sock #登陸3306實例
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.5.22-log 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 variables like 'server_id'; #查看MySQL的系統變量(like類似於grep過濾)
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id | 1 | #配置的server_id為1
+---------------+-------+
1 row in set (0.00 sec)
mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | ON | #binlog功能已開啟
+---------------+-------+
1 row in set (0.00 sec)
mysql>
#這樣,binlog功能就開啟了。
8.2.2 在主庫上建立用於主從復制的賬號
根據主從復制的原理,從庫要想和主庫同步,必須有一個可以連接主庫的賬號,並且這個賬號是主庫上創建的,權限是允許主庫的從庫連接並同步數據。
1)登陸MySQL3306實例主數據庫,命令如下:
[root@localhost ~]# mysql -uroot -p123123 -S /data/3306/mysql.sock
2)建立用於從庫復制的賬號yunjisuan,命令如下:
mysql> grant replication slave on *.* to 'yunjisuan'@'192.168.0.%' identified by 'yunjisuan123';
Query OK, 0 rows affected (0.00 sec)
#語句說明:
1)replication slave為mysql同步的必須權限,此處不要授權all權限
2)*.* 表示所有庫所有表,也可以指定具體的庫和表進行復制。例如yunjisuan.test中,yunjisuan為庫名,test為表名
3)'yunjisuan'@'192.168.0.%' yunjisuan為同步賬號。192.168.0.%為授權主機網段,使用了%表示允許整個192.168.0.0網段可以用yunjisuan這個用戶訪問數據庫
4)identified by 'yunjisuan123'; yunjisuan123為密碼,實際環境下設置的復雜些為好
創建完賬號並授權后,需要刷新權限,使授權的權限生效
mysql> flush privileges; #刷新權限
Query OK, 0 rows affected (0.00 sec)
3)檢查主庫創建的yunjisuan復制賬號命令及結果如下:
mysql> select user,host from mysql.user;
+-----------+-------------+
| user | host |
+-----------+-------------+
| root | 127.0.0.1 |
| yunjisuan | 192.168.0.% | #出現這行表示復制賬號已經配置好了
| root | ::1 |
| | localhost |
| root | localhost |
+-----------+-------------+
5 rows in set (0.00 sec)
#說明:
MySQL里的授權用戶是以數據表格的形式存儲在mysql這個庫的user表里。
mysql> select user,host from mysql.user where user='yunjisuan'; #where是SQL查詢語句的條件
+-----------+-------------+
| user | host |
+-----------+-------------+
| yunjisuan | 192.168.0.% |
+-----------+-------------+
1 row in set (0.00 sec)
mysql> show grants for yunjisuan@'192.168.0.%'; #查看賬號的授權情況
+--------------------------------------------------------------------------------------------------------------------------------+
| Grants for yunjisuan@192.168.0.% |
+--------------------------------------------------------------------------------------------------------------------------------+
| GRANT REPLICATION SLAVE ON *.* TO 'yunjisuan'@'192.168.0.%' IDENTIFIED BY PASSWORD '*A2CC7FA422EF5A7CB098FEA7732C1F78CDC32F67' | #結果顯示授權正確
+--------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
8.2.3 實現對主數據庫鎖表只讀
1)對主數據庫鎖表只讀(當前窗口不要關掉)的命令如下:
mysql> flush table with read lock;
Query OK, 0 rows affected (0.00 sec)
提示:
在引擎不同的情況下,這個鎖表命令的時間會受下面參數的控制。鎖表時,如果超過設置時間不操作會自動解鎖。
默認情況下自動解鎖的時長參數值如下:
mysql> show variables like '%timeout%';
+----------------------------+----------+
| Variable_name | Value |
+----------------------------+----------+
| connect_timeout | 10 |
| delayed_insert_timeout | 300 |
| innodb_lock_wait_timeout | 120 |
| innodb_rollback_on_timeout | OFF |
| interactive_timeout | 28800 | #自動解鎖時間受本參數影響
| lock_wait_timeout | 31536000 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| slave_net_timeout | 3600 |
| wait_timeout | 28800 | #自動解鎖時間受本參數影響
+----------------------------+----------+
10 rows in set (0.00 sec)
#提示:有關這兩個參數,請同學們自行測試
2)鎖表后查看主庫狀態。可通過當前binlog日志文件名和二進制binlog日志偏移量來查看,結果如下:
注意,show master status;命令顯示的信息要記錄在案,后面的從庫導入全備后,繼續和主庫復制時就是要從這個位置開始。
mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 | 345 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
或者新開一個命令行窗口,用如下命令查看鎖表后的主庫binlog位置點信息:
[root@localhost ~]# mysql -uroot -p123123 -S /data/3306/mysql.sock -e "show master status"
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 | 533 | | |
+------------------+----------+--------------+------------------+
3)鎖表后,一定要單開一個新的SSH窗口,導出數據庫的所有數據,如果數據量很大(50GB以上),並且允許停機,可以停庫直接打包數據文件進行遷移,那樣更快。
[root@localhost ~]# mkdir -p /server/backup
[root@localhost ~]# mysqldump -uroot -p123123 -S /data/3306/mysql.sock --events -A -B | gzip >/server/backup/mysql_bak.$(date +%F).sql.gz
#注意:-A表示備份所有庫;-B表示增加use DB和 drop 等(導庫時會直接覆蓋原有的)
[root@localhost ~]# ll /server/backup/mysql_bak.2017-07-21.sql.gz
-rw-r--r--. 1 root root 137344 Jul 21 10:17 /server/backup/mysql_bak.2017-07-21.sql.gz
#為了確保導出數據期間,數據庫沒有數據插入,導庫完畢可以再次檢查主庫狀態信息,結果如下:
[root@localhost ~]# mysql -uroot -p123123 -S /data/3306/mysql.sock -e "show master status"
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 | 533 | | |
+------------------+----------+--------------+------------------+
提示:若無特殊情況,binlog文件及位置點和鎖表后導出數據前是一致的,即沒有變化。
#導出數據完畢后,解鎖主庫,恢復可寫,命令如下.因為主庫還要對外提供服務,不能一直鎖定不讓用戶訪問。
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)
#可能會有同學因為鎖表后的binlog位置問題犯迷糊,實際上做從庫前,無論主庫更新了多少數據,最后從庫都可以從上面show master status的位置很快趕上主庫的進度。
8.2.4 把主庫導出的MySQL數據遷移到從庫
下面主要講解單數據庫多實例的主從配置,也就是說,mysqldump備份的3306實例的數據和要恢復的3307實例在一台機器上,因此無需異地復制拷貝。想查看主庫導出的數據,如下:
[root@localhost ~]# ll /server/backup/mysql_bak.2017-07-21.sql.gz
-rw-r--r--. 1 root root 137344 Jul 21 10:17 /server/backup/mysql_bak.2017-07-21.sql.gz
8.3 在MySQL從庫上執行的操作過程
8.3.1 設置server-id值並關閉binlog功能參數
- 數據庫的server-id一般在一套主從復制體系內是唯一的,這里從庫的server-id要和主庫及其他從庫的不同,並且要注釋掉從庫的binlog參數配置,如果從庫不做級聯復制,並且不作為備份用,就不要開啟binlog,開啟了反而會增加從庫磁盤I/O等的壓力。
- 但是,有以下兩種情況需要打開從庫的binlog記錄功能,記錄數據庫更新的SQL語句:
- 級聯同步A-->B-->C中間的B時,就要開啟binlog記錄功能。
- 在從庫做數據庫備份,數據庫備份必須要有全備和binlog日志,才是完整的備份。
(1)修改配置文件,配置從庫1的相關參數
執行vi /data/3307/my.cnf,編輯my.cnf配置文件,按如下內容修改兩個參數:
[mysqld]
server-id = 3 #調整等號后的數值,和任何一個數據庫實例都不同
提示:
上面兩參數要放在my.cnf中的[mysqld]模塊下,否則會出錯。
server-id的值不能和任何MySQL實例重復。
要先在文件中查找相關參數按要求修改。若發現不存在,再添加參數,切記,參數不能重復。
修改my.cnf配置后需要重啟數據庫,命令為:/data/3307/mysql restart,注意要確認真正重啟了。
(2)檢查配置參數后的結果
命令如下:
[root@localhost ~]# egrep "server-id|log-bin" /data/3307/my.cnf
server-id = 3
(3)重啟3307的從數據庫
命令如下:
[root@localhost ~]# /data/3307/mysql restart
Restarting MySQL...
Stoping MySQL...
Starting MySQL....
[root@localhost ~]# ss -antup | grep 3307
tcp LISTEN 0 128 *:3307 *:* users:(("mysqld",5659,11))
(4)登陸數據庫檢查參數的改變情況
命令如下:
[root@localhost ~]# mysql -uroot -p123123 -S /data/3307/mysql.sock
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 variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | OFF |
+---------------+-------+
1 row in set (0.00 sec)
mysql> show variables like 'server_id';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id | 3 |
+---------------+-------+
1 row in set (0.00 sec)
mysql>
8.3.2 把從主庫mysqldump導出的數據恢復到從庫
操作命令如下:
[root@localhost ~]# cd /server/backup/
[root@localhost backup]# ls -l
total 136
-rw-r--r--. 1 root root 137344 Jul 21 10:17 mysql_bak.2017-07-21.sql.gz
[root@localhost backup]# gzip -d mysql_bak.2017-07-21.sql.gz
[root@localhost backup]# ll
total 496
-rw-r--r--. 1 root root 506730 Jul 21 10:17 mysql_bak.2017-07-21.sql
[root@localhost backup]# mysql -uroot -p123123 -S /data/3307/mysql.sock <mysql_bak.2017-07-21.sql #這是把數據還原到3307實例的命令
#提示:
如果備份時使用了-A參數,則在還原數據到3307實例時,登陸3307實例的密碼也會和3306主庫的一致,因為3307實例的授權表MySQL也被覆蓋了。
8.3.3 登陸3307從庫,配置復制參數
(1)MySQL從庫連接主庫的配置信息如下:
CHANGE MASTER TO
MASTER_HOST='192.168.0.200', #這里是主庫的IP
MASTER_PORT=3306, #這里是主庫的端口,從庫端口可以和主庫不同
MASTER_USER='yunjisuan', #這里是主庫上建立的用於復制的用戶yunjisuan
MASTER_PASSWORD='yunjisuan123', #這里是yunjisuan用戶的密碼
MASTER_LOG_FILE='mysql-bin.000001', #這里是show master status時查看到的二進制日志文件名稱,注意不能多空格
MASTER_LOG_POS=533; #這里是show master status時查看到的二進制日志偏移量,注意不能多空格
#提示:字符串用單引號括起來,數值不用引號,注意內容前后不能有空格。
(2)登陸數據庫后,去掉上述語句中的注釋,執行如下:
mysql> CHANGE MASTER TO MASTER_HOST='192.168.0.200',MASTER_PORT=3306,MASTER_USER='yunjisuan',MASTER_PASSWORD='yunjisuan123',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=533;
#提示:這個步驟的參數一定不能錯,否則,數據庫復制配置會失敗
上述操作的原理實際上是把用戶密碼等信息寫入從庫新的master.info文件中
[root@localhost backup]# ll /data/3307/data/master.info
-rw-rw----. 1 mysql mysql 90 Jul 21 11:31 /data/3307/data/master.info
[root@localhost backup]# cat /data/3307/data/master.info
18
mysql-bin.000001 #這里是show master status時查看的二進制日志文件名稱
533 #這里是show master status時查看的二進制日志偏移量
192.168.0.200 #這里是主庫的IP
yunjisuan #這里是主庫上建立的用於復制的用戶yunjisuan
yunjisuan123 #這里是yunjisuan用戶的密碼
3306 #這里是主庫的端口
60
0...以下省略若干...
8.4 啟動從庫同步開關,測試主從復制配置情況
(1)啟動從庫主從復制開關,並查看復制狀態
相關語句如下:
[root@localhost backup]# mysql -uroot -p123123 -S /data/3307/mysql.sock -e "start slave"
[root@localhost backup]# mysql -uroot -p123123 -S /data/3307/mysql.sock -e "show slave status\G"
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.0.200
Master_User: yunjisuan
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 533
Relay_Log_File: relay-bin.000002
Relay_Log_Pos: 253
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB: mysql
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 533
Relay_Log_Space: 403
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
主從同步是否成功,最關鍵的為下面的3項狀態參數:
[root@localhost backup]# mysql -uroot -p123123 -S /data/3307/mysql.sock -e "show slave status\G" | egrep "IO_Running|SQL_Running|Seconds_Behind_Master"
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Seconds_Behind_Master: 0
- [x] :Slave_IO_Running: Yes,這個時I/O線程狀態,I/O線程負責從從庫到主庫讀取binlog日志,並寫入從庫的中繼日志,狀態為Yes表示I/O線程工作正常。
- [x] :Slave_SQL_Running: Yes,這個是SQL線程狀態,SQL線程負責讀取中繼日志(relay-log)中的數據並轉換為SQL語句應用到從數據庫中,狀態為Yes表示I/O線程工作正常。
- [x] :Seconds_Behind_Master:0,這個是復制過程中從庫比主庫延遲的秒數,這個參數極度重要,但企業里更准確地判斷主從延遲的方法為:在主庫寫時間戳,然后從庫讀取時間戳,和當前數據庫時間進行比較,從而認定是否延遲。
(2)測試主從復制結果
在主庫上寫入數據,然后觀察從庫的數據狀況。
[root@localhost backup]# mysql -uroot -p123123 -S /data/3306/mysql.sock -e "create database benet"
[root@localhost backup]# mysql -uroot -p123123 -S /data/3307/mysql.sock -e "show databases"
+--------------------+
| Database |
+--------------------+
| information_schema |
| benet |
| mysql |
| performance_schema |
| test |
+--------------------+
[root@localhost backup]# mysql -uroot -p123123 -S /data/3306/mysql.sock -e "create database yunjisuan"
[root@localhost backup]# mysql -uroot -p123123 -S /data/3307/mysql.sock -e "show databases"
+--------------------+
| Database |
+--------------------+
| information_schema |
| benet |
| mysql |
| performance_schema |
| test |
| yunjisuan |
+--------------------+
[root@localhost backup]# mysql -uroot -p123123 -S /data/3306/mysql.sock -e "drop database yunjisuan"
[root@localhost backup]# mysql -uroot -p123123 -S /data/3307/mysql.sock -e "show databases"
+--------------------+
| Database |
+--------------------+
| information_schema |
| benet |
| mysql |
| performance_schema |
| test |
+--------------------+
#根據測試可以判斷,主從庫是同步的。
8.5 MySQL主從復制配置步驟小結
MySQL主從復制配置完整步驟如下:
- 准備兩台數據庫環境或單台多實例環境,確定能正常啟動和登陸
- 配置my.cnf文件:主庫配置log-bin和server-id參數;從庫配置server-id,該值不能和主庫及其他從庫一樣,一般不開啟從庫log-bin功能。注意,配置參數后要重啟才能生效。
- 登陸主庫,增加從庫連接主庫同步的賬戶,例如:yunjisuan,並授權replication slave同步的權限。
- 登陸主庫,整庫鎖表flush table with read lock(窗口關閉后即失效,超時參數設置的時間到了,鎖表也失效),然后show master status查看binlog的位置狀態。
- 新開窗口,在Linux命令行備份導出原有的數據庫數據,並拷貝到從庫所在的服務器目錄。如果數據庫數據量很大,並且允許停機,可以停機打包,而不用mysqldump。
- 導出主庫數據后,執行unlock tables解鎖主庫。
- 把主庫導出的數據恢復到從庫
- 根據主庫的show master status查看到的binlog的位置狀態,在從庫執行change master to....語句。
- 從庫開啟復制開關,即執行start slave;。
- 從庫show slave status\G,檢查同步狀態,並在主庫進行更新測試。
8.6 MySQL主從復制線程狀態說明及用途
8.6.1 MySQL主從復制主庫I/O線程狀態說明
(1)登陸主數據庫查看MySQL線程的同步狀態
mysql> show processlist\G
*************************** 1. row ***************************
Id: 1
User: root
Host: localhost
db: NULL
Command: Query
Time: 0
State: NULL
Info: show processlist
*************************** 2. row ***************************
Id: 5
User: yunjisuan
Host: 192.168.0.200:42008
db: NULL
Command: Binlog Dump
Time: 267
State: Master has sent all binlog to slave; waiting for binlog to be updated
Info: NULL
2 rows in set (0.00 sec)
#提示:上述狀態的意思是線程已經從binlog日志讀取所有更新,並已經發送到了從數據庫服務器。線程目前為空閑狀態,等待由主服務器上二進制日志中的新事件更新。
下圖中列出了主服務器binlog Dump線程中State列的最常見狀態。如果你沒有在主服務器上看見任何binlog Dump線程,則說明復制沒有運行,二進制binlog日志由各種事件組成,事件通常會為更新添加信息。
(2)登陸從數據庫查看MySQL線程工作狀態
從庫有兩個線程,即I/O和SQL線程。從庫I/O線程的狀態如下:
mysql> show processlist\G
*************************** 1. row ***************************
Id: 3
User: root
Host: localhost
db: NULL
Command: Query
Time: 0
State: NULL
Info: show processlist
*************************** 2. row ***************************
Id: 8
User: system user
Host:
db: NULL
Command: Connect
Time: 659
State: Waiting for master to send event
Info: NULL
*************************** 3. row ***************************
Id: 9
User: system user
Host:
db: NULL
Command: Connect
Time: 511
State: Slave has read all relay log; waiting for the slave I/O thread to update it
Info: NULL
3 rows in set (0.00 sec)
下圖列出了從服務器的I/O線程的State列的最常見的狀態。該狀態也出現在Slave_IO_State列,由SHOW SLAVE STATUS顯示。
下圖列出了從服務器的SQL線程的State列的最常見狀態
8.6.2 查看MySQL線程同步狀態的用途
- 通過MySQL線程同步狀態可以看到同步是否正常進行,故障的位置是什么,另外還可查看數據庫同步是否完成,可用於主庫宕機切換數據庫或人工數據庫主從切換遷移等。
- 例如:主庫宕機,要選擇最快的從庫將其提升為主庫,就需要查看主從庫的線程狀態,如果主從復制在正常情況下進行角色切換,也需要查看主從庫的線程狀態,根據復制狀態確定更新是否完成。
8.7 MySQL主從復制更多應用技巧實踐
8.7.1 工作中MySQL從庫停止復制故障案例
模擬重現故障的能力是運維人員最重要的能力。下面就來次模擬操作。先在從庫創建一個庫,然后去主庫創建同名的庫來模擬數據沖突,命令如下:
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.0.200
Master_User: yunjisuan
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000003
Read_Master_Log_Pos: 544
Relay_Log_File: relay-bin.000010
Relay_Log_Pos: 336
Relay_Master_Log_File: mysql-bin.000003
Slave_IO_Running: Yes
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB: mysql
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 1007
Last_Error: Error 'Can't create database 'yunjisuan'; database exists' on query. Default database: 'yunjisuan'. Query: 'create database yunjisuan'
Skip_Counter: 0
Exec_Master_Log_Pos: 451
Relay_Log_Space: 810
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 1007
Last_SQL_Error: Error 'Can't create database 'yunjisuan'; database exists' on query. Default database: 'yunjisuan'. Query: 'create database yunjisuan'
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
1 row in set (0.00 sec)
對於該沖突,解決辦法如下
辦法一:關閉從同步,調動sql_slave指針
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> set global sql_slave_skip_counter=1; #將sql線程同步指針向下移動一個,如果多次不同步,可以重復操作
Query OK, 0 rows affected (0.00 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
對於普通的互聯網業務,上述的移動指針的操作帶來的問題不是很大。當然,要在確認不影響公司業務的前提下。
若是在企業場景下,對當前業務來說,解決主從同步比主從不一致更重要,如果主從數據一致也是很重要的,那就再找個時間恢復這個從庫。
是主從數據不一致更重要,還是保持主從同步持續狀態更重要,要根據業務選擇。這樣Slave就會與Master同步了,主要關鍵點如下:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Seconds_Behind_Master: 0 #0表示已經同步狀態
#提示:set global sql_slave_skip_counter=n; #n取值>0,忽略執行N個更新。
辦法二:根據可以忽略的錯誤號事先在配置文件中配置,跳過指定的不影響業務數據的錯誤,例如:
[root@localhost ~]# grep slave-skip /data/3306/my.cnf
slave-skip-errors = 1032,1062
#提示:類似由於入庫重復導致的失敗可以忽略,其他情況是不是可以忽略需要根據不同公司的具體業務來評估。
其他可能引起復制故障的原因:
- MySQL自身的原因及人為重復插入數據。
- 不同的數據庫版本會引起不同步,低版本到高版本可以,但是高版本不能往低版本同步。
- MySQL的運行錯誤或程序bug
- binlog記錄模式,例如:row level模式就比默認的語句模式要好。
8.7.2 讓MySQL從庫記錄binlog日志的方法
從庫需要記錄binlog的應用場景:當前的從庫還要作為其他從庫的主庫,例如級聯復制或雙主互為主從場景的情況下。下面介紹從庫記錄binlog日志的方法。
在從庫的my.cnf中加入如下參數,然后重啟服務生效即可。
log-slave-updates #必須要有這個參數
log-bin = /data/3307/mysql-bin
expire_logs_days = 7 #相當於find /data/3307/ -type f -name "mysql-bin.000*" -mtime +7 | xargs rm -f
8.7.3 MySQL主從復制集群架構的數據備份策略
- 有主從復制了,還需要做定時全量加增量備份么?答案是肯定的!
因為,如果主庫有語句級誤操作(例如:drop database yunjisuan;),從庫也會執行drop database yunjisuan;,這樣MySQL主從庫就都刪除了該數據。 - 把從庫作為數據庫備份服務器時,備份策略如下:
高並發業務場景備份時,可以選擇在一台從庫上備份(Slave5),把從庫作為數據庫備份服務器時需要在從庫開啟binlog功能,其邏輯圖如下所示:
步驟如下:
1)選擇一個不對外提供服務的從庫,這樣可以確保和主庫更新最接近,專門用於做數據備份。
2)開啟從庫的binlog功能
備份時可以選擇只停止SQL線程,停止應用SQL語句到數據庫,I/O線程保留工作狀態,執行命令為stop slave sql_thread;,備份方式可以采取mysqldump邏輯備份或直接物理備份,例如:使用cp,tar(針對/data目錄)工具或xtrabackup(第三方的物理備份軟件)進行備份,則邏輯備份和物理備份的選擇,一般是根據總的備份數據量的多少進行選擇的,數據量低於30G,建議選擇mysqldump邏輯備份方法,安全穩定,最后把全備和binlog數據發送到備份服務器上留存。
8.7.4 MySQL主從復制延遲問題的原因及解決方案
問題一:主庫的從庫太多,導致復制延遲
從庫數量以3~5個為宜,要復制的從節點數量過多,會導致復制延遲。
問題二:從庫硬件比主庫差,導致復制延遲。
查看Master和Slave的系統配置,可能會因為機器配置不當,包括磁盤I/O,CPU,內存等各方面因素造成復制的延遲。這一般發生在高並發大數據量寫入場景中。
問題三:慢SQL語句太多
假如一條SQL語句執行時間是20秒,那么從執行完畢到從庫上能查到數據至少需要20秒,這樣就延遲20秒了。
一般要把SQL語句的優化作為常規工作,不斷的進行監控和優化,如果單個SQL的寫入時間長,可以修改后分多次寫入。通過查看慢查詢日志或show full processlist命令,找出執行時間長的查詢語句或大的事務。
問題四:主從復制的設計問題
例如,主從復制單線程,如果主庫寫並發太大,來不及傳送到從庫,就會導致延遲。
更高版本的MySQL可以支持多線程復制,門戶網站則會自己開發多線程同步功能。
問題五:主從庫之間的網絡延遲
主從庫的網卡,網線,連接的交換機等網絡設備都可能成為復制的瓶頸,導致復制延遲,另外,跨公網主從復制很容易導致主從復制延遲。
問題六:主庫讀寫壓力大,導致復制延遲。
主庫硬件要搞好一點,架構的前端要加buffer及緩存層。
8.7.5 通過read-only參數讓從庫只讀訪問
read-only參數選項可以讓從服務器只允許來自從服務器線程或具有SUPER權限的數據庫用戶進行更新,確保從服務器不接受來自用戶端的非法用戶更新。
read-only參數允許數據庫更新的條件為:
- 具有SUPER權限的用戶可以更新,不受read-only參數影響,例如:管理員root。
- 來自從服務器線程可以更新,不受read-only參數影響,例如:前文的yunjisuan用戶。
- 再生產環境中,可以在從庫Slave中使用read-only參數,確保從庫數據不被非法更新。
read-only參數的配置方法如下:
方法一:直接帶 --read-only參數啟動或重啟數據庫,
使用killall mysqld
或mysqladmin -uroot -p123123 -S /data/3307/mysql.sock shutdown
mysqld_safe --defaults-file=/data/3307/my.cnf --read-only &
方法二:在my.cnf里[mysqld]模塊下加read-only參數重啟數據庫,配置如下:
[mysqld]
read-only
九,本節重點回顧
- MySQL多實例的實現原理及實戰部署
- MySQL主從復制的原理(面試常問)
- MySQL主從復制的實踐
- MySQL主從復制故障解決思路
- MySQL主從復制延遲原因及解決思路
- MySQL主從復制集群,從庫備份的思想和思路