主從同步
原理
Master,記錄數據更改操作
啟用binlog日志
設置binlog日志格式
設置server_id
Slave運行兩個線程
Slave_IO
//復制master主機binlog日志文件里的sql到本機的relay-log文建立
Slave_SQL
//執行本機relay-log文件里的sql語句,重現Master的數據操作
配置主從同步
確保從庫上必須有主庫上的數據
配置主服務器
reset master; //重置binlog日志
vim /etc/my.cnf
[mysqld]
.. ..
log_bin=dbsvr1-bin //啟用binlog日志
server_id=10 //指定服務器ID號(不可和從服務器重復)
binlog_format=mixed //指定日志格式
systemctl restart mysqld
mysql> grant replication slave on *.* to '用戶名'@'從服務器ip' identified by '密碼';
//授權備份用戶
mysql>show master status\G; //查看master狀態
.. ..
File: dbsvr1-bin.000004 //日志文件名
Position: 334 //偏移位置
Binlog_Do_DB:
Binlog_Ignore_DB:
Execute
.. ..
配置從服務器
vim /etc/my.cnf
[mysqld]
.. ..
server_id=20 //指定服務器ID號(不可和主服務器重復)
//以下為可選項
og_bin=dbsvr2-bin //啟用binlog日志
sync-binlog=1 //允許日志同步
read_only=1 //只讀模式,同步及SUPER權限用戶例外
systemctl restart mysqld
mysql>change master to master_host='主服務器ip',
-> master_user='用戶名',
-> master_password='123456',
-> master_log_file='dbsvr1-bin.000004', //監控的日志文件
-> master_log_pos=334; //主服務器上的偏移位置
mysql>change master to master_host='主服務器ip', \
master_user='用戶名’, \
master_password='123456', \
master_log_file='dbsvr1-bin.000004', \
master_log_pos=334;
mysql>change master to master_host='192.168.4.51', \
master_user='repluser', \
master_password='123456', \
master_log_file='master51.000005', \
master_log_pos=154;
mysql> start slave; //啟動復制
//以上信息會自動保存到/var/lib/mysql/master.info中,以后在change更改master信息時,需要先stop slave
查看slave狀態
show slave status\G;
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.4.10
Master_User: replicater
.. ..
Slave_IO_Running:Yes //IO線程已運行
Slave_SQL_Running:Yes //SQL線程已運行
//確保這兩個選項為YES
相關文件
master.info //連接主服務器信息
relay-log,info //中繼日志信息
主機名-relay-bin.xxxxx //中繼日志
主機名-relay-bin.index //中繼日志索引文件
主服務器mysql配置選項
針對所有從服務器生效
vim /etc/my.cnf
binlog_do_db=數據庫名
//配置記錄哪些庫的binlog日志(哪些庫可以同步)
binlog_ignore_db=數據庫名
//配置不記錄哪些庫的binlog日志(不同步哪些庫)
從服務器mysql配置選項
只針對當前服務器生效
vim /etc/my.cnf
log_slave_updates
//級聯更新,默認情況下主從從結構不會級聯更新
relay_log=dbsvr2-relay-bin //指定中繼日志文件名
replicate_do_db=庫名
//僅復制指定庫,其他庫被忽略,此選項可設置多條
replicate_ignore_db=庫名 //不復制哪些庫,和do_db不可共存
復制模式
異步復制
//主庫在執行完客戶端提交的事務后立即將結果返給客戶端,並不關心從庫是否已經接收並處理
同步模式
//當主庫執行完一個事務,所有的從庫都執行了該事務才返回給客戶端
半同步模式
//主庫在執行完客戶端提交的事務后不會立即返回給客戶端,而是等待至少一個從庫接收並寫到relay log中猜返回給客戶端
show variables like "have_dynamic_loading";
//查看是否允許動態加載模塊,默認允許
命令行加載插件,用戶需具有super權限
臨時設置,重啟失效
主庫
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
從庫
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
查看
mysql> select plugin_name,plugin_status from information_schema.plugins where plugin_name like '%semi%';
安裝完插件后半同步默認時關閉的
主庫
mysql> set global rpl_semi_sync_master_enable=1;
從庫
mysql> set global rpl_semi_sync_slave_enabled=1;
查看
mysql> show variables lik "rpl_semi_sync_%_enabled";
永久啟用半同步復制
vim /etc/my.cnf
[mysqld]
.. ..
主庫
plugin-load=rpl_semi_sync_master=semisync_master.so
rpl_semi_sync_master_enabled=1
從庫
plugin-load=rpl_semi_sync_slave=semisync_slave.so
rpl_semi_sync_slave_enabled=1
systemctl restart mysqld
mysql讀寫分離
多台MySQL服務器分別提供讀、寫服務,均衡流量,通過主從復制保持數據一致性.由MySQL代理面向客戶端
收到SQL寫請求時,交給服務器A處理,收到SQL讀請求時,交給服務器B處理,具體區分策略由服務設置
結構
至少一組主從服務器,一台代理服務器訪問mysql數據庫
安裝maxscale
rpm -ivh maxscale-2.1.2-1.rhel.7.x86_64.rpm
修改配置文件
vim /etc/maxscale.cnf
[server1] //定義數據庫服務器主機名,有幾個主機寫幾個server
type=server
address=192.168.4.10 //master主機ip地址
port=3306
protocol=MySQLBackend
[server2] //定義數據庫服務器
type=server
address=192.168.4.20 //slave主機ip地址
port=3306
protocol=MySQLBackend
[MySQL Monitor] //定義要監視的數據庫服務器,監控插件
type=monitor
module=mysqlmon
servers=server1, server2
//定義的主從數據庫服務器主機名(逗號后面要有空格)
user=scalemon //用戶名
passwd=111111 //密碼
monitor_interval=10000
將[Read-Only]注釋
[Read-Write Service] //定義實現讀寫分離的數據庫服務器,路由插件
type=service
router=readwritesplit
servers=server1, server2
//定義的主從數據庫服務器主機名(逗號后面要有空格)
user=maxscale //用戶名
passwd=111111 //密碼
max_slave_connections=100%
[Read-Write Listener] //監聽讀寫
type=listener
service=Read-Write Service
protocol=MySQLClient
port=4006
[MaxAdmin Listener]
type=listener
service=MaxAdmin Service
protocol=maxscaled
socket=default
port=4099
//路由插件決定如何把客戶端的請求轉發給后端數據庫服務器,讀寫分離和負載均衡的功能就是由這個模塊實現的
//監控插件對各個數據庫服務器進行監控,例如發現某個數據庫服務器響應很慢,那么就不向其轉發請求了
在主從服務器上授權用戶
mysql> grant replication slave, replication client on *.* to scalemon@'%' identified by “111111”;
//創建監控用戶
mysql> grant select on mysql.* to maxscale@'%' identified by “111111”;
//創建路由用戶
mysql> grant all on *.* to student@'%' identified by “111111”;
//創建訪問數據用戶
//授權的時候地址要么是%要么是絕對IP地址,網段范圍無法識別,無法授權
啟動 maxscale
maxscale --config=/etc/maxscale.cnf
netstat -utnalp | grep maxscale
tcp 0 0 192.168.1.110:58960 192.168.1.101:3306
ESTABLISHED 19081/maxscale
tcp 0 0 192.168.1.110:43508 192.168.1.111:3306
ESTABLISHED 19081/maxscale
tcp6 0 0 :::4006 :::* LISTEN 19081/maxscale
//查看端口
mysql -h代理服務器ip -P4006 -ustudent -p111111
mysql>select @@hostname; //查看當前訪問的主機名
mysql調優
調優所有參數單位為毫秒
提高MySQ 系統的性能,響應速度
替換有問題的硬件(CPU/磁盤/內存等)
服務程序的運行參數調整
對 SQL 查詢進行優化
並發及連接控制
max_connections //允許的最大並發連接數
connect_timeout //等待建立連接的超時秒數,默認10秒,只在登錄時有效
wait_timeout //等待關閉連接的不活動超時秒數,默28800秒(8小時)
show variables like "%關鍵字%"\G; //查看sql系統變量
show global status lik "max_used_connections";
//查看當前已使用的連接數
show variables like "max_connections";
//查看默認最大連接數,使用的最大連接數要<=最大連接數的85%為理想比例
緩存參數控制
key_buffer-size //用於MyISAM引擎的關鍵索引緩存大小
sort_buffer_size //為每個要排序的線程分配此大小的緩存空間
read_buffer_size //為順序讀取表記錄保留的緩存大小
thread_cache_size //允許保存在緩存中被重用的線程數量
table_open_cache //為所有線程緩存的打開的表的數量
key_buffer-size指定索引緩沖區的大小,只對MyISAM表起作用,它決定索引處理的速度
Key_reads和Key_read_requests做比例計算,數值較低時,可加大此緩存值
sort_buffer_size增大此值可提高order by和group by的速度
read_buffer_size此緩存值影響SQL查詢的相應速度
thread_cache_size當客戶端斷開之后,服務器處理此客戶的線程將會緩存起來以響應下一個客戶而不是銷毀(前提是緩存數未達上限)
即可以重新利用保存在緩存中線程的數量,當斷開連接時如果緩存中還有空間,那么客戶端的線程將被放到緩存中,如果線程重新被請求,那么請求將從緩存中讀取,如果緩存中是空的或者是新的請求,那么這個線程將被重新創建,如果有很多新的線程,增加這個值可以改善系統性能
table_open_cache如果opend_tables大於此值,會拉低性能,將此值設置成max_connections的數
優化SQL查詢
vim /etc/my.cnf
[mysqld]
.. ..
slow_query_log=1 //啟用慢查詢
slow_query_log_file=mysql-slow.log //指定慢查詢日志文件
long_query_time=5 //超過此秒數的查詢才會被記錄
log_queries_not_using_indexes=1 //記錄沒有使用索引查詢語句
mysqldumpslow /var/lib/mysql/mysql-slow.log
//查看慢查詢日志
show variables like 'query_cache%';
//查看查詢緩存大小
show variables like 'qcache%';
//查看查詢緩存統計
調優思路總結
升級硬件 //CPU 內存硬盤
加大網絡帶寬 //付費加大帶寬
調整mysql服務運行參數 //並發連接數,連接超時時間,重復使用的,線程數...
調整與查詢相關的參數 //查詢緩存,索引緩存...
啟用慢查詢日志 //slow-query-log
網絡架構不合理 //調整網絡架構
Mycat
基於Java的分布式數據庫系統中間層
提供JDBC的鏈接方式,支持MySQL,Orale,SqlServer,Mongodb等,支持讀寫分離和高可用,實現數據分片
基於阿里巴巴Cobar進行研發的開源軟件,適用於數據大量寫入的需求
Mycat提供10中分片規則
sharding-by-intfile //枚舉法
rule1 //固定分片
auto-sharding-long //范圍約定
mod-long //求模法
sharding-by-date //日期列分區法
sharding-by-pattern //通配取模
sharding-by-prefixpattern //ASCII碼求模通配
sharding-by-substring //編程指定
sharding-by-stringhash //字符串拆分hash解析
sharding-by-murmur //一致性hash
Mycat工作原理
當Mycat收到一個SQL時,會先解析這個SQL涉及到的表,然后看此表的定義,如果有分片規則,則獲取到SQL里分片字段的值,並匹配分片函數,得到SQL對應的分片列表.然后將SQL發往這些分片去執行,最后收集和處理所有分片返回的數據,輸出到客戶端
Mycat部署
拓撲結構
拓撲名稱 |
主機名 |
角色 |
數據庫名 |
IP |
hostA |
client |
客戶端 |
無 |
192.168.4.254/24 |
hostB |
Mycat |
Mycat服務器 |
無 |
192.168.4.56/24 |
hostC |
c1 |
數據庫服務器 |
db1 |
192.168.4.55/24 |
hostD |
c2 |
數據庫服務器 |
db2 |
192.168.4.54/24 |
1.裝包
1.1安裝JDK
因為Mycat是基於java開發的,所以需要安裝JDK
rpm -qa | grep -i jdk //檢查是否已經安裝JDK
java-1.8.0-openjdk-1.8.0.65-3.b17.el7.x86_64
java-1.8.0-openjdk-headless-1.8.0.65-3.b17.el7.x86_64
1.2安裝Mycat服務軟件包
tar -zxf Mycat-server-1.4-beta-20150604171601-linux.tar.gz
//免安裝,解壓即可用
mv mycat/ /usr/local/
2.修改配置文件
2.1目錄結構說明
bin //包含Mycat命令
catlet //擴展功能
conf //配置文件
lib //Mycat使用的jar包
log //啟動日志和運行日志
其中包含
wrapper.log //啟動日志,啟動有問題看這個log
mycat.log //記錄sql腳本執行后的具體報錯內容
2.2重要配置文件說明
server.xml //設置鏈接Mycat服務的賬號,密碼
schema.xml //配置Mycat使用的真實數據庫和表
rule.xml //定義Mycat分片規則
2.3配置標簽說明
<user>...</user>
//定義鏈接Mycat服務時使用的用戶名密碼及邏輯庫名字
<datanode>...</datanode>
//指定數據節點,物理庫的主機名和存儲分片數據和數據庫名
<datahost>...</datahost>
//指定數據庫服務器的IP地址以及連接數據庫使用的授權用戶及密碼
3.修改配置文件
3.1配置賬號密碼
vim /usr/local/mycat/conf/server.xml
<user name="test">
//鏈接mycat服務時使用的用戶名cat
<property name="password">test</property>
//使用test鏈接mycat的密碼
<property name="schemas">TESTDB</property>
//都好分離多個邏輯庫
<property name="readOnly">true</property>
//開啟只讀權限
</user>
3.2定義分片信息
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
//邏輯庫名,要和server.xml中定義的一致
<table name="travelrecord" dataNode="dn1,dn2" rule="auto-sharding-long" />
//定義分片的表
<table name="company" primaryKey="ID" type="global" dataNode="dn1,dn2" />
<table name="goods" primaryKey="ID" type="global" dataNode="dn1,dn2" />
<table name="hotnews" primaryKey="ID" dataNode="dn1,dn2" rule="mod-long"/>
<table name="employee" primaryKey="ID" dataNode="dn1,dn2" rule="sharding-by-intfile" />
<table name="customer" primaryKey="ID" dataNode="dn1,dn2" rule="sharding-by-intfile" />
</schema>
<dataNode Name="dn1" dataHost="c1" database="db1" />
//定義分片使用的庫,所在的物理主機,真正存儲數據庫的db1庫在物理機c1上
<dataNode Name="dn2" dataHost="c2" database="db2" />
//指定c1名稱主機對應的ip地址
<dataHost name="c1" mxCon="1000" minCon="10" balance="0" writeYtpe="0" dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="192.168.4.55:3306" user="admin" password="123456">
//訪問數據庫時,mycat鏈接數據庫使用的用戶名和密碼
</writeHost>
</dataHost>
//指定c2名稱主機對應的ip地址
<dataHost name="c2" mxCon="1000" minCon="10" balance="0" writeYtpe="0" dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM2" url="192.168.4.54:3306" user="admin" password="123456">
//訪問數據庫時,mycat鏈接數據庫使用的用戶名和密碼
</writeHost>
</dataHost>
3.3修改數據庫配置信息(所有主機)
vim /etc/my.cnf
[mysqld]
.. ..
lower_case_table_name=1
//表名區分大小寫字母
//重啟mysqld
systemctl restart mysqld
//授權mycat鏈接數據庫的用戶
MySQL> grant all on *.* to admin@"%" identified by "123456";
4.啟動服務
vim /usr/local/mycat/conf/wrapper.conf
# Java Application
//第五行添加
wrapper.java.command=java
//查看java的安裝目錄
which java
/usr/bin/java
//添加java的程序路徑到PATH下
echo "export PATH=/usr/local/mycat/bin" >> /etc/profile
//查看mycat幫助
mycat --help
//啟動mycat
mycat start
//檢查mycat啟動
ss -anput | grep :8066
5.在客戶端鏈接mycat
mysql -h Mycat服務器IP -P端口 -u用戶名 -p密碼
mysql> show databases;
MHA集群管理
MySQL高可用環境下故障切換和主動提升的高可用軟件
在MySQL高可用方面是一個相對成熟的解決方案,比MySQL MMM更可靠
MHA能在30秒內自動完成數據庫的故障切換操作,切換過程中,也能最大程度上保證數據的一致性
工作原理
MHA Manager會定時探測集群中的master節點,當master出現故障時,它可以自動將最新數據的slave提升為新的master,然后將所有其他的 slave重新指向新的 master,整個故障轉移過程對應用程序完全透明
拓撲環境
Master數據庫服務器 //192.168.4.51
備用master數據庫服務器 //192.168.4.52
slave服務器 //192.168.4.53
slave服務器 //192.168.4.54
slave服務器 //192.168.4.55
Mha_manager服務器 //192.168.4.56
VIP(Virtual IP)地址 //192.168.4.100
搭建流程
1.搭建一主多從
1.1主服務器(包含備用主服務器)
vim /etc/my.cnf
[mysqld]
.. ..
plugin-load =“rpl_semi_sync_master = semisync_master.so; rpl_semi_sync_slave = semisync_slave.so”
rpl-semi-sync-master-enabled = 1
rpl-semi-sync-slave-enabled = 1
//開啟半同步復制模式
server_id=51
//server_id不可和其他sql服務器重復
log_bin=master52 //登錄名
binlog_format=mixed //binlog日志格式
mysql> set global relay_log_purge=off;
//不自動刪除本機的中繼日志文件(所有節點)
mysql> grant replication slave on *.* to repluser@"%" identified by"123456";
//添加主從同步授權用戶(所有節點)
mysql> show master status;
//查看master狀態
1.2備用服務器(包含備用主服務器)
vim /etc/my.cnf
[mysqld]
.. ..
server_id=52
//server_id不可和其他sql服務器重復
mysql> change master to master_host =“192.168.4.51”, \
master_user =“repluser”, \
master_password =“123456”, \
master_log_file =“master51.000001”, \
master_log_pos = 441;
//根據實際情況創建從服務器
//確保除主服務器外,其他服務器(包括備用主服務器)都是主服務器的從服務器
//Slave_IO_Running和Slave_SQL_Running確保為YES
1.3ssh root免密鑰登錄
所有的主從服務器之間都需要設置ssh免密鑰登錄
ssh keygen
ssh-copy-ip root@192.168.4.51
1.4安裝依賴軟件包
1.4.1所有節點安裝
yum -y install perl-DBD-mysql
unzip mha-soft-student.zip
cd mha-soft-student.zip
rpm -ivh mha4mysql-node-0.56-0.el6.noarch.rpm
1.4.2管理機安裝
yum -y install perl-ExtUtils-* perl-CPAN-*
tar -zxf mha4mysql-manager-0.56.tar.gz
cd mha4mysql-manager-0.56
perl Makefile.pl
make
make install
1.5配置管理機環境
1.5.1指定命令所在的路徑
cd mha4mysql-manager-0.56
mkdir /root/bin
cp bin/* /root/bin/
//將MHA manager的命令放入$PATH路徑的/root/bin下,方便使用
1.5.2修改配置文件
mkdir /etc/mha_manager/
cd mha4mysql-manager-0.56/samples/conf/
cp app1.cnf /etc/mha_manager/
//將配置文件范例拷貝到配置目錄
cp /etc/mha_manager/app1.cnf /etc/mha_manager/app1.cnf.bak
//備份
vim /etc/mha_manager/app1.cnf
manager_workdir=/etc/mha_manager
//MHA manager配置文件目錄
manager_log=/etc/mha_manager/manager.log
//日志目錄
master_ip_failover_script=/etc/mha_manager/master_ip_failover
//主庫地址更換腳本目錄
user=root
password=123456
//登錄數據庫用戶名密碼
repl_user=repluser
repl_password=123456
//主從數據庫設置的密碼
ssh_user=root
ssh_port=22
//ssh用戶名密碼
//有幾個數據庫就寫幾個server
[server1]
hostname=192.168.4.51
candidate_master=1 //主庫
[server2]
candidate_master=1
hostname=192.168.4.52
[server3]
hostname=192.168.4.53
no_master=1 //從庫(不參與主庫)
1.5.3修改VIP文件(主庫地址更換腳本)
cd mha-soft-student
cp master_ip_failover /etc/mha_manager/
//將范本拷貝到配置目錄
//此范本為達內寫好的范本,更改VIP地址后可以直接使用
//此文件要有可執行權限
cd mha4mysql-manager-0.56/samples/scripts
cp master_ip_failover /etc/mha_manager/
//此范本為MHA自帶范本,可用性未知
//在35行添加(更改)
my $vip = '192.168.4.100/24'; # Virtual IP
my $key = "1";
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";
2.測試
2.1測試配置文件
vim /etc/mha_manager/app1.cnf
#master_ip_failover_script=/etc/mha_manager/master_ip_failover
//將主庫地址更換腳本注釋
//測試會調用配置文件,此行不注釋會將數據庫的VIP地址更換
2.2.1測試SSH聯通性
masterha_check_ssh --conf=/etc/mha_manager/app1.cnf
.... All SSH connection tests passed successfully.
2.2.2測試主從庫聯通性
masterha_check_repl --conf=/etc/mha_manager/app1.cnf
.....MySQL Replication Health is OK.
3.啟動服務
3.1啟動配置文件
vim /etc/mha_manager/app1.cnf
master_ip_failover_script=/etc/mha_manager/master_ip_failover
//取消注釋
3.2把VIP地址手動綁定到當前主庫上
ifconfig eth0:1 192.168.4.100/24
ifconfig eth0:1
//ifconfig eth0:1 down
//VIP地址的作用,客戶端訪問只需訪問VIP地址,而不需要管集群服務器的地址
3.3啟動服務
masterha_manager --conf=/etc/mha_manager/app1.cnf --remove_dead_master_conf --ignore_last_failover
--remove_dead_master_conf
//不在app1.cnf文件里刪除宕機的主庫的信息
//主庫down后,會將其的配置信息從配置文件中刪除
--ignore_last_failover
//每次failover切換后會在管理目錄生成文件app1.failover.complete,下次在切換的時候會發現有這個文件導致切換不成功,需要手動清理掉
//ignore_last_failover忽略此文件
masterha_check_status --conf=/etc/mha_manager/app1.cnf
//manager端新開一個終端檢查MHA的狀態
4.總結
MHA集群中的所有主機必須是主庫的從庫(集群中不能有獨立服務器)
所有主機之間SSH要免密鑰登錄
服務起來后,manager會監視主服務器的運行情況,當主服務器宕掉后(模擬停止mysql服務),manager會將VIP地址從宕機的主服務器上刪除,並在備用主服務器上啟用VIP地址,從服務器會自動選擇備用的主服務器.配置文件中會刪除宕機的配置,防止再宕機恢復之前備用主服務器再次宕機而導致服務器集群崩潰.
宕機發生后,MHA manager會停止監控.
主服務器恢復后,需要將主服務器的配置重新寫入MHA配置文件中,主服務器要變成從服務器指向現在運行的備用主服務器,並重新啟動manager監控