mysql的複製和mysql的讀寫分離歷來就不是一個簡單的話題,今天筆者就詳細來記錄一下我學習的mysql。
mysql日至類型有:二進制日誌,事務日誌,錯誤日誌,通常查詢日誌,中繼日誌,慢查詢日誌。
二進制日誌通常放在數據目錄,通常文件名叫mysql-bin.xxxx,當數據大到咱們設定的最大大小的時候就會滾動,還有相似flush ,logs,服務器重啓都會引發滾動,在mysql下刪除日誌通常咱們不實用rm來刪除,而是在mysql命令下使用PURGE來清除
二進制記錄的格式有基於語句的,有基於行的,有混合的。除了mysql-bin-xxx外還有一些mysql-bin-index的文件,這是msyql二進制日誌文件的縮影
文件。想查看當前mysql使用的二進制文件咱們在mysql>下使用SHOW MASTER STATUS;
SHOW查看mysql二進制日誌中的相關內容,mysql> SHOW BINLOG EVENTS IN "file";
查看當前mysql上存在二進制日誌文件的列表。mysql> SHOW BINARY LOGS;
一個日誌通常會記錄:產生時間(timestamp); 位置(position) 時間自己(offset),
二進制日誌記錄日誌並不完善,因此若是不備份數據庫,僅僅靠二進制文件恢復數據可能不完善。因此最好的辦法就是把數據庫備份一邊
因爲主服務器容許並行執行,例如擁有多顆CPU就能同時執行多個寫操做,可是向二進制日誌中寫入的話只容許一個一個寫入,因此向從服務器傳輸的時候也只能一個一個傳輸,因此從服務器會比主管服務器慢,甚至有可能慢不少。
若是MYSQL的複製是同步的話,用戶就須要等待主服務器上的二進制文件徹底傳輸到從服務器的時候才能執行下一個操做,而這時不科學的,因此MYSQL上的複製都是異步的,半同步就是隻要數據發送到從服務器的tcp/ip的緩存中就OK了,可是對於MYSQL來講這個不實用,由於mysql還須要將他們保存到中繼日誌中去,一個一個去讀的。因此半同步和異步是差很少的,因此mysql通常使用異步。mysql和drbd最大的不一樣就是mysql支持一主多從。前端
看下圖一,就是mysql的基本原理圖node
在一主多從的模式下,只要有一個從服務器返回以及保存成功的信息,咱們就再也不去管其餘的從服務器,這種方式咱們叫作半同步。
mysql在5.5以前是不支持半同步的,
從服務器的全部數據都是從主服務器上覆制過來的,由於從服務器是備份用的,因此咱們須要保存和主服務器如出一轍的數據,若是從服務器的數據和主服務器的數據不同,咱們就失去了從服務器的意義,因此咱們不允許從服務器寫操做和向主服務器傳送東西。
熱備份很複雜,並且容易產生數據不一致的狀況,有了從服務器咱們能夠在從服務器上中止Mysql的服務,而後進行冷備份,這樣安全多了。
從服務器不須要二進制日誌,沒什麼做用,還拖延從服務器的速度
mysql還有多級輔助
爲了讓咱們的讀寫速度加快,咱們能夠給他們分配任務,只在主服務器上寫,只在從服務器上讀。可是那麼多從服務器呢,咱們在在那個上邊讀呢,簡單,負載均衡器。在前邊找一個MYsql路由,若是咱們想發起Mysql讀寫的時候,我i們須要聯繫這個Mysql代理,它能夠判斷咱們執行是什麼操做,讀的話就聯繫從服務器,寫的話就聯繫主服務器,這就叫作Mysql的讀寫分離。若是咱們的讀操做很是多,那樣咱們怎麼能儘量的讓咱們的讀速度變快呢,咱們怎麼才能知道個人讀操做是那個從服務器響應咱們呢?簡單,添加一個LVS就好了。在前端添加一個directory就好了mysql
若是directory壞掉了怎麼辦?MYSQL代理壞掉怎麼辦?好辦,都作成高可用,以下圖三爲了加快速度,咱們能夠加上個共享緩存,不管那個服務器的查詢均可以暫時緩存到memcnche,之後不管那個服務器查詢先到 memcnche查詢。
爲了增長咱們的讀寫速度咱們添加了不少的從服務器,可是這麼多從服務器難道每次咱們都要從主服務器啓動一個線程把日誌從二進制日誌發送到從服務器的中繼日誌麼?這就會產生大量的IO,那樣速度還會快麼?基於這樣的狀況,就產生了多級複製的辦法
多級複製,就是從從服務器中選出一個專門負責中轉主服務器的日誌發總給別的從服務器。
PHP不須要和Mysql發生關係,發生關係的是PHP語言開發的程序。
咱們可讓開發語言,咱們在配置時候本身來解決讀寫的程序,只不過開發程序比較麻煩。
若是既不想讓前端程序變得複雜,又不想提供讀寫分離,這就是主主模式,可是咱們並不建議使用。
如圖四,黑線表明咱們開始的時候的順序,產生的數據,咱們保存在二進制日誌裏,二進制日誌經過傳送到另外一個服務器中的中繼日誌中,中繼日誌在經過本地服務器讀出保存在數據庫,並儲存在二進制日誌中,而後開始紅線的部分,和這樣同樣的進程,複製到第一個進程中。可是這樣你們發現沒有,這樣會陷入一個循環中,尷尬,那咱們須要作的就是給進程添加一個編號,這樣咱們再也不本地運行相同ID的server,這樣就不會再二進制日誌中發送了。
雙主模型,其實沒法實現平均負載寫操做的,由於兩個節點上的數據必須如出一轍,否則會出錯的。雙主模型還容易產生爽膚數據不一致致使崩潰的狀況。
對於MYSQL來講一個主服務器能夠帶多個從服務器,可是一個從不能帶多個主,若是各個主服務器都寫入不一樣的數據,從服務器徹底複製過來會到時數據不一致或者衝突之類的。
配置MySQL複製基本步驟:
簡單的下載解壓就不說了,咱們直接從配置開始把。
一,先配置主服務器
複製配置文件到/etc/my.cof
複製腳本到/etc/rc.d/in.d/mysqld
chkconfig -add mysqld
vim /etc/my.cnf
咱們全部的和複製有關的配置都在mysqld這裏邊
咱們須要把log-bin=master-bin這一項啓動起來
二、選擇一個唯一server-id =1
server-id = {0-2^32}
innodb_file_per_table = 1
datedir = /mydata/data
而後service mysqld start
而後把該文件配置到從服務器上去
三、建立具備複製權限的用戶
REPLICATION SLAVE
REPLICATION CLIENT
2、配置從服務器
一、啓用中繼日誌
添加relay-log = relay-log
添加relay-log-index = relay-log.index
二、選擇一個唯一的server-id = (必定不能等於主服務器)
server-id = {0-2^32}
三、鏈接至主服務器,並開始複製數據;
mysql> CHANGER MASTER TO MASTER_HOST='',MASTER_PORT='',MASTER_LOG_FILE='',MASTER_LOG_FIEL_POS='',MASTER_USER='',MASTER_PASSWORD='';
mysql>SHOW SLAVE STATUS\G(查看當前狀態
)
mysql> START SLAVE;(啓動服務)
mysql> START SLAVE IO_Thread; (YES爲正常)
mysql> START SLAVE SQL_Thread; (YES爲正常)
複製線程:
master: dump
slave: IO_Thread, SQL_Thread
怎麼把從服務器設置成只讀
在配置文件中添加
read-only = YES 重啓服務有效
可是對於擁有管理員身份的人無效
sync-binlog = ON
在主服務器上設定,用於事務安全;
全部的從服務器上的信息都會被保存在/mydata/daya/node2.magedu.com.err下邊
如何讓mysql實現半同步呢,這須要一個插件
這個插件在 /usr/local/mysql/lib/plugin裏邊有兩個文件 semisync_slave.so 和semisync_maste.so。一主一從
設置半同步步驟:
在Master和Slave的mysql命令行運行以下代碼:
# On Master
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;
mysql> SET GLOBAL rpl_semi_sync_master_timeout = 1000;
設置是否啓用和超時時間
# On Slave
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;
mysql> STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;
在Master和Slave的my.cnf中編輯:
# On Master
[mysqld]
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=1000 # 1 second
# On Slave
[mysqld]
rpl_semi_sync_slave_enabled=1
# 也可經過設置全局變量的方式來設置,以下:
set global rpl_semi_sync_master_enabled=1
# 取消加載插件
mysql> UNINSTALL PLUGIN rpl_semi_sync_master;
設置主-主複製:
一、在兩臺服務器上各自創建一個具備複製權限的用戶;
二、修改配置文件:
# 主服務器上
[mysqld]
server-id = 10
log-bin = mysql-bin
relay-log = relay-mysql
relay-log-index = relay-mysql.index
auto-increment-increment = 2
auto-increment-offset = 1
# 從服務器上
[mysqld]
server-id = 20
log-bin = mysql-bin
relay-log = relay-mysql
relay-log-index = relay-mysql.index
auto-increment-increment = 2
auto-increment-offset = 2
三、若是此時兩臺服務器均爲新創建,且無其它寫入操做,各服務器只需記錄當前本身二進制日誌文件及事件位置,以之做爲另外的服務器複製起始位置便可
server1|mysql> SHOW MASTER STATUS\G
************************** 1. row ***************************
File: mysql-bin.000001
Position: 710
Binlog_Do_DB:
Binlog_Ignore_DB:
1 row in set (0.00 sec)
server2|mysql> SHOW MASTER STATUS\G
mysql> SHOW MASTER STATUS\G
*************************** 1. row ***************************
File: mysql-bin.000003
Position: 811
Binlog_Do_DB:
Binlog_Ignore_DB:
1 row in set (0.00 sec)
四、各服務器接下來指定對另外一臺服務器爲本身的主服務器便可:
server1|mysql> CHANGE MASTER TO ...,MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=811
server2|mysql> CHANGE MASTER TO ...,MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=710
sql