《老男孩Linux運維》筆記
MySQL-Documentation
概述
MySQL介紹
MySQL屬于傳統關系型數據庫產品,它開放式的架構使得用戶選擇性很強,同時社區開發與維護人數眾多。
MySQL是一種關系型數據庫管理系統,關系型數據庫的特點是將數據保存在不同的表中,再將這些表放入不同的數據庫中,而不是將所有數據統一放在一個大倉庫里,這樣的設計增加了MySQL的讀取速度,而且靈活性和可管理型也得到了很大提高。
訪問和管理MySQL數據庫的最常用標準化語言為SQL結構化查詢語言。
MariaDB介紹
自從甲骨文公司收購了MySQL之后,為了避免Oracle將MySQL閉源,MySQL社區采用分支的方式來避開這個風險。MariaDB就這樣誕生了。
MariaDB是一個向后兼容,可能在以后替代MySQL的數據庫產品。
MySQL多實例介紹
什么是MySQL多實例
MySQL多實例就是在一臺服務器上同時開啟多個不同的服務器端口(如3306, 3307),同時運行多個MySQL服務進程,這些服務進程通過不同的socket監聽不同的服務器端口來提供服務。
這些MySQL多實例公用一套MySQL安裝程序,使用不同的 my.cnf(也可以相同)和數據文件。在提供服務時,多實例MySQL在邏輯上看起來是各自獨立的,他們根據配置文件的對應設定值,獲得服務器相應數量的硬件資源。
其實很多網絡服務都是可以配置多實例的,如 Nginx,Apache,Mongodb,Redis等。
MySQL多實例的作用與問題
MySQL多實例作用:
- 有效利用服務器資源;
- 節約服務器資源;
MySQL多實例有它的好處,也有其弊端。比如,會存在資源互相搶占的問題
MySQL多實例的應用場景
- 資金緊張型公司的選擇;
- 并發訪問不是特別大的業務;
- 門戶網站應用MySQL多實例場景;
MySQL多實例常見的配置方案
單一配置文件、單一啟動程序的多實例部署方案
單一配置文件、單一啟動程序實施方案。
vim /etc/my.cnf
[mysqld_multi]
mysqld = /bin/mysqld_safe
mysqladmin = /bin/mysqladmin
user = mysql
[mysqld1]
socket = /dir/path/mysql.sock
port = 3306
pid-file = /dir/path/mysql.pid
datedir = /dir/path/mysql
user = mysql
[mysql2]
socket = /path/mysql.sock
port = 3307
pid-file = /path/mysql.pid
datedir = /path/mysql
user = mysql
啟動命令:
mysqld_multi --config-file=/path/my.cnf start 1,2
不建議使用單一配置文件和單一啟動程序部署多實例方案
安裝并配置多實例MySQL數據庫
安裝MySQL多實例
安裝MySQL依賴包
yum install -y ncurses-devel libaio-devel
安裝MySQL
- 源碼安裝:
useradd -s /sbin/nologin -M mysql
wget mysql源碼包
tar mysql壓縮包
cd mysql-xxx
./configure
make&&make install
- rpm包安裝:
wget http://repo.mysql.com/xxx 選擇匹配的版本
rpm -ivh mysql.xxx.rpm
yum install mysql-server
創建MySQL多實例的數據文件目錄
mkdir -p /var/mysql/{3306,3307,3308}/db
創建MySQL多實例的配置文件
MySQL數據庫默認為用戶提供了多個配置文件模板,用戶可以根據服務器硬件配置的大小來選擇。
vi /var/mysql/3306/my06.cnf
vi /var/mysql/3307/my07.cnf
vi /var/mysql/3308/my08.cnf
為了讓MySQL多實例之間彼此獨立,要為每一個實例建立一個 my.cnf 配置文件和一個啟動文件MySQL,讓它們分別對應自己的數據文件目錄 db。
3306實例 | 3307實例 | 3308實例 |
---|---|---|
[ client ] port = 3306 socket = /var/mysql/3306/mysql.sock [ mysql ] no-auto-rehash [ mysqld ] user = mysql port = 3306 socket = /var/mysql/3306/mysql.sock basedir = /bin/mysql datadir = /var/mysql/3306/db 以及其他優化信息 [ mysql_safe ] pid-file = /var/mysql/3306/mysql.pid log-error = /var/log/mysql/mysql06.log |
[ client ] port = 3307 socket = /var/mysql/3307/mysql.sock [ mysql ] no-auto-rehash [ mysqld ] user = mysql port = 3307 socket = /var/mysql/3307/mysql.sock basedir = /bin/mysql datadir = /var/mysql/3307/db 以及其他優化信息 [ mysqld_safe ] pid-file = /var/mysql/3307/mysql.pid log-error = /var/log/mysql/mysql07.log |
[ client ] port = 3308 socket = /var/mysql/3308/mysql.sock [ mysql ] no-auto-rehash [ mysqld ] user = mysql port = 3308 socket = /var/mysql/3308/mysql.sock basedir = /bin/mysql datadir = /var/mysql/3308/db 以及其他優化信息 [ mysqld_safe ] pid-file = /var/mysql/3308/mysql.pid log-error = /var/log/mysql/mysql08.log |
創建MySQL多實例的啟動程序
創建MySQL啟動文件
vim /var/mysql/3306/mysql.sh
vim /var/mysql/3307/mysql.sh
vim /var/mysql/3308/mysql.sh
這幾個啟動MySQL實例的腳本自己根據需要來寫。
在多實例啟動文件中,啟動MySQL不同實例服務,所執行的命令實質是有區別的。
mysqld_sage --defaulte-files=/var/mysql/3306/my06.cnf >/dev/null 2>&1
mysqladmin -u root -p passwd -S /var/mysql/3306/mysql.sock shutdown
配置MySQL多實例文件權限
建議權限:700
MySQL相關命令加入全局路徑的配置
配置MySQL全局路徑
which mysql
echo 'export PATH=/path/xxx/mysql/bin:$PATH' >> /etc/profile
echo $PATH 查看
或者使用軟連接的方法
ln -s /path/xxx/mysql/bin/* /usr/local/sbin/
務必把MySQL命令路徑放在PATH路徑中其他路徑的前面,否則,可能會導致使用的 mysql 命令不是同一個,進而產生錯誤。
啟動MySQL多實例數據庫
/var/mysql/3306/mysql.sh start
/var/mysql/3307/mysql.sh start
/var/mysql/3308/mysql.sh start
如果發現沒有顯示MySQL對應實施的端口,請稍等幾秒在檢查,MySQL服務的啟動比Web服務慢一些;
請查看錯誤日志
配置及管理MySQL多實例數據庫
服務的開機自啟動很關鍵!把MySQL多實例的啟動命令加入 /etc/rc.local,實現開機自啟動。
echo "/var/mysql/3306/mysql.sh start
echo "/var/mysql/3307/mysql.sh start
echo "/var/mysql/3308/mysql.sh start
socket connect
mysql -S /var/mysql/3306/mysql.sock
MySQL安全配置:
mysqladmin -uroot -S /var/mysql/3306/mysql.sock -ppasswd #設置密碼
mysql -uroot -S /var/mysql/3306/mysql.sock -p
禁止使用 kill -9
等命令強制殺死數據庫,這會引起數據庫無法啟動等故障發生。
MySQL主從復制介紹
MySQL的主從復制并不是數據庫磁盤上的文件直接拷貝,而是通過邏輯的 binlog 日志復制到要同步的服務器本地,然后由本地的線程讀取日志里面的 SQL 語句,重新應用到MySQL數據庫匯總。
MySQL數據庫支持單向、雙向、鏈式級聯、環狀等不同業務場景的復制。
在復制過程中,一臺服務器充當 主服務器(Master), 接收來自用戶的內容更新;
而一個或多個的其他服務器充當從服務器(Slave),接收來自主服務器 binlog 文件的日志內容,解析出SQL,重新更新到從服務器,使得主從服務器數據達到一致;
如果設置了鏈式級聯,那么,從服務器(Slave)本身除了充當從服務器外,也會同時充當其下面從服務器的主服務器。鏈式級聯復制類似 A-->B-->C
的復制形式。
MySQL主從復制都是異步的復制方式,既不是嚴格實時的數據同步,但是正常情況下給用戶的體驗是實時的。
MySQL主從復制的企業應用場景
MySQL主從復制集群功能使得MySQL數據庫支持大規模高并發讀寫成為可能,同時有效保護了物理服務器宕機場景的數據備份。
應用場景1:從服務器作為主服務器的實時數據備份
主從服務器架構的設置可以大大加強MySQL數據庫架構的健壯性。當主服務器出現問題時,可設置自動切換到從服務器繼續提供服務,此時從服務器的數據與宕機時的主數據庫幾乎是一模一樣的。
這類似 NFS 儲存數據通過 inotify+rsync 同步到備份的 NFS服務器,只不過MySQL的復制方案是其自帶的工具。
利用MySQL的復制功能進行數據備份時,在硬件故障、軟件故障的場景下,該數據備份是有效的;但是對于人為地執行 drop , delete
等語句刪除數據的情況,從庫的備份功能就沒用了,因為從服務器也會執行刪除的語句。
應用場景2:主從服務器實現讀寫分離,從服務器實現負載均衡
主從服務器架構可通過程序(PHP,Java等)或代理軟件實現對用戶(客戶端)的請求讀寫分離。即讓重復服務器僅僅處理用戶的 select
查詢請求,降低用戶查詢響應時間,以及同事讀寫在主服務器上帶來的訪問壓力; 對于更新的數據,如update, insert, delete
等,仍交給主服務器處理。確保主服務器和從服務器保持實時同步。
百度、淘寶等絕大多數網站都是用戶瀏覽頁面多余用戶發布內容,因此通過在從服務器上接受 只讀請求,就可以很好地減輕主庫的 讀壓力,且從服務器可以很容易地擴展為多臺,使用LVS做負載均衡效果就非常幫棒了。
這就是傳說中的數據庫讀寫分離架構
應用場景3:把多個從服務器根據業務重要性進行拆分訪問
可以把幾個不同的從服務器,根據公司的業務進行拆分。如:
用來做查詢服務的從服務器;
用來做數據備份的從服務器;
為公司人員提供訪問的從服務器;
為開發人員使用的從服務器;
這樣的拆分減輕了主服務器的壓力外,還可以是數據庫各個業務互不影響。
實現MySQL主從讀寫分離的方案
1. 通過程序實現讀寫分離(推薦)
PHP和Java等程序都可以通過設置多個連接文件輕松地實現對數據庫的讀寫分離,即當語句關鍵字為 select
時,就去連接 讀庫 的連接文件,若為 update, insert, delete
時,則連接寫庫的連接文件。
2. 通過開源軟件實現讀寫分離
3. 大型門戶獨立開發 DAL 層綜合軟件
像百度、阿里等大型門戶都會自己開發適合自己業務的讀寫分離、負載均衡、監控報警、自動擴容等一系列功能的DAL層軟件。
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功能
vim /etc/my.cnf
[ mysqld ]
log-bin = /path/mysql-bin
注意是放在 [mysqld]里,不要放錯位置了!
MySQL主從復制原理過程詳解
- 在Slave服務器上執行
start slave
命令開啟主從復制開關,開始,開始進行主從復制; - Slave服務器的I/O線程會通過在Master上已經授權的復制用戶權限請求連接Master服務器,并請求從指定 binlog 日志文件的指定位置(日志文件名和位置就是在配置主從復制服務時執行 change master 命令指定的),之后開始發送 binlog 日志內容。
- Master服務器接收到來自Slave服務器的I/O線程請求后,其上負責復制的I/O線程會根據Slave服務器的I/O線程請求的信息分批讀取指定 binlog 日志文件指定位置之后的 binlog 日志信息,然后返回給 Slave 端的I/O線程。返回的信息中除了 binlog 日志內容外,還有在Master服務器端記錄的新的 binlog 文件名稱,以及在新的 binlog 中的下一個指定更新位置。
- 當Slave服務器的I/O線程獲取到Master服務器上I/O線程發送的日志內容、日志文件及位置點后,會將 binlog 日志內容依次寫到Slave端自身的 Relay Log(中繼文件)的最末端,并將新的 binlog 文件名和位置記錄到 master-info 文件中,以便下一次讀取Master端新 binlog 日志時能夠告訴Master服務器從新binlog 日志的指定文件及位置開始請求新的 binlog 日志內容;
- Slave服務器端的SQL線程會實時監測本地的 Relay Log 中 I/O線程新增加的日志內容,然后及時地把Relay Log文件中的內容解析成SQL語句,并在自身Slave服務器上按解析SQL語句的位置順序執行應用這些SQL語句,并在relay-log.info中記錄當前應用中繼日志的文件名和位置點。
小結:
- 主從復制是異步邏輯的SQL語句級的復制;
- 復制時,主庫有一個I/O線程,從庫有兩個線程,即I/O和SQL線程;
- 實現主從復制的必要條件是主庫要開啟記錄的 binlog 功能;
- 作為復制的所有MySQL節點的server-id都不能相同;
- binlog文件只記錄對數據庫有更改的SQL語句,不記錄任何查詢語句。
MySQL主從復制實踐
主從復制實踐
MySQL主從復制實踐對環境要求較簡單,可以是單機單數據庫多實例(3306,3307,3308)的環境;也可以是多臺服務器,每個服務器一個獨立數據庫的環境。
建議使用多服務器實現數據庫主從功能!
單機數據庫多實例
1. 主從復制數據庫單機多實例環境準備
使用前面配置的 3306,3307,3308三個實例
2. 定義主從復制需要的服務器角色
主庫及從庫名稱、IP、Port信息:
Master,ip:3306;
Slave1,ip:3307;
Slave2,ip:3308;
3. 在主庫Master上執行操作配置
設置server-id并開啟binlog功能參數
vim ./3306/my.cnf
[mysqld]
server-id = 1
log-bin = /path/3306/mysql-bin
提示:
- 這兩個參數一定要放置于[mysqld]模塊下,否則會出錯;
- server-id建議使用服務器ip最后一個點分十進制數,目的是避免不同機器或實例 ID 重復;
- 參數不能重復;
- 修改參數后重啟數據庫。
4. 在主庫上建立用于主從復制的賬號
登錄主庫3306:
mysql -uroot -ppasswd -S /path/3306/mysql.sock
件利用與從庫復制的賬號:
grant replication slave on *.* to 'rep'@'192.168.0.%' identified by 'passwd';
#登錄之后
flush privilege;
#grant 權限1,權限2,…權限n on 數據庫名.表名稱 to 用戶名@用戶地址 identified by ‘連接口令’;
# 192.168.0.%代表此網段
select user,host form mysql.user where user='rep';
5. 實現對主數據庫鎖表只讀
對主數據庫鎖表只讀:
flush table with read lock;
在引擎不同的情況下,這個鎖表命令的時間會受下面參數的控制。鎖表時,如果超過設置時間不操作會自動解鎖。
鎖表后查看主庫狀態:
mysql> show master status;
鎖表后導出數據庫:
mysqldump -uusername -ppasswd -S /path/mysql.sock xxxxx
導出數據完畢后,解鎖主庫,恢復可寫:
mysql> unlock tables;
6. 把主庫導出的數據遷移到從庫
這里常用的命令有 scp
,rsync
等,將備份的數據往異地拷貝。
在MySQL從庫上執行的操作
1. 設置server-id并關閉binlog功能參數
數據庫的server-id一般在一套主從復制體系內是唯一的,這里從庫的 server-id 要與主庫及其他從庫不同,并且要注釋掉從庫的 binlog 參數配置。如果從庫不做級聯復制,并且不作為備份用,就不要開啟 binlog,開啟了反而會增加從庫磁盤I/O等的壓力。
這兩種情況需要打開從庫 binlog 記錄功能,記錄數據庫更新的SQL語句:
級聯同步 A-->B-->C中B時,需要開啟;
在從庫做數據備份,數據庫備份必須要有全備和binlog日志,才是完整的備份。
vim /path/3307/my.cnf
[mysqld]
server-id = 2
2. 把主庫的數據導入從庫
mysql -uusername -ppasswd -S /path/mysql.sock < mysql_bak.sql
3. 登錄從庫,配置復制信息
從庫連接主庫配置信息:
mysql> CHANGE MASTER TO
MASTER_HOST='192.168.1.1',
MASTER_PORT='3306',
MASTER_USER='rep',
MASTER_PASSWORD='passwd',
MASTER_LOG_FILE='mysql-bin.log',
MASTER_LOG_POS=342;
#字符串用單引號' '括起來,數值不用引號,注意內容前后無空格,參數不能出錯。
上述操作的原理實際上是把用戶密碼等信息寫入從庫新的 master.info 文件中。
啟動從庫同步開關,測試主從復制配置
1. 啟動從庫主從復制,并查看狀態
mysql -uroot -ppasswd -S /path/mysql.sock -e "start slave;"
#等同于 mysql> start slave;
主從復制是否成功的3項關鍵參數:
- Slave_IO_Running:Yes,這個是I/O線程狀態。I/O線程復制從從庫到主庫讀取binlog日志,并寫入從庫的中繼日志;
- Slave_SQL_Running:Yes,這個是SQL線程狀態。SQL線程負責讀取中繼日志(relay-log)中的數據并轉換為SQL語句應用到從數據庫中;
- Seconds_Behind_Master:0,這個是復制過程中從庫比主庫延遲的秒數,這個參數很重要。
測試主從復制:
在主庫上隨便新建數據,然后觀察從庫的數據狀況。
MySQL主從復制配置小結
- 環境實例準備;
- 配置my.cnf文件;
- 登錄主庫并配置;
- 導出數據;
- 從庫配置;
- 從庫數據恢復;
- 從庫開啟復制;
- 檢查同步狀態。
MySQL主從復制應用技巧
工作中MySQL從庫停止復制故障
模擬重現故障的能力是運維人員最重要的能力。
先在從庫創建一個庫,然后去主庫創建一個同名的庫來模擬數據沖突。
然后運行 show slave status
查看報錯信息。
讓從庫記錄binlog日志的方法
從庫需要記錄binlog的應用場景:當前從庫還要作為其他從庫的主庫,如級聯或互為主從的情況。
vim /path/my.cnf
[mysqld]
log-slave-updates
log-bin = /path/mysql-bin
MySQL主從復制集群架構的數據備份策略
有了主從復制,還需要做定時 全量 + 增量 備份嗎?答案是肯定的!
因為,如果主庫有誤操作(如:drop),從庫也會執行,這樣主從庫都沒有了該數據。
把從庫作為數據庫備份服務器時,備份策略如下:
MySQL主從復制延遲問題的原因及解決方案
1. 主庫的從庫太多,導致復制延遲
從庫數量盡量不要超過五個,要復制的節點數量過多,會導致復制延遲;
2. 從庫硬件比主庫差,導致復制延遲
查看主從系統配置,可能是因為配置不當;
3. 慢SQL語句過多
加入一條SQL語句執行時間是20s,那么從執行完畢到從庫上能查到數據至少需要20s,這樣就延遲了20s;
一般要把SQL語句的優化作為常規工作,不斷地進行監控和優化。如果單個SQL的寫入時間長,可以修改后分多次寫入;
通過查看慢查詢日志或show full processlist
命令,找出執行時間長的慢查詢語句或大的事務。
4. 主從復制的設計問題
如,主從復制單線程,如果主庫寫并發太大,來不及傳送到從庫,就會導致延遲;
5. 主從庫之間的網絡問題
主從庫之間的網卡、線路、連接設備等都有可能稱為復制的瓶頸,導致延遲;
6. 主庫讀寫壓力大,導致復制延遲
主機硬件搞好一點,增加buffer。
通過read-only參數讓從庫只讀訪問
read-only參數可以讓從服務器只允許來自從服務器線程或具有SUPER權限的數據庫用戶進行更新,確保從服務器不接受來自用戶端的非法用戶更新。
方法一:直接帶 --read-only 參數啟動或重啟數據庫
mysql xxxxx --read-only
方法二:vim /path/my.cnf
[mysqld]
read-only
MySQL主從復制讀寫分離集群
讀寫分離賬戶設置
主從庫,賬戶權限,訪問IP等······
#Master
GRANT SELECT, INSERT, 權限 ON 'database'.'table' TO 'user'@'ip' identified by 'passwd';
#Slave
GRANT SELECT ON 'database'.'table' TO 'user'@'ip' identified by 'passwd';
flush privilege;
重點
- MySQL多實例的實現原理和實戰部署;
- MySQL主從復制的原理;
- MySQL主從復制的實踐;
- MySQL主從復制故障解決思路;
- MySQL主從復制延遲原因及解決思路;
- MySQL主從復制集群,從庫備份的思想和思路;
- MySQL主從復制讀寫分離授權訪問用戶方案;