Mysql 主主互備搭建及原理簡介
在企業中,資料庫高可用一直是企業的重中之重,中小企業很多都是使用mysql主從方案,一主多從,讀寫分離等,但是單主存在單點故障,從庫切換成主庫需要作改動。因此,如果是雙主或者多主,就會增加mysql入口,增加高可用。不過多主需要考慮自增長ID問題,這個需要特別設定配置檔案,比如雙主,可以使用奇偶,總之,主之間設定自增長ID相互不衝突就能完美解決自增長ID衝突問題。
主從同步複製原理
在開始之前,我們先來了解主從同步複製原理。
複製分成三步:
1. master將改變記錄到二進位制日誌(binary log)中(這些記錄叫做二進位制日誌事件,binary log events);
2. slave將master的binary log events拷貝到它的中繼日誌(relay log);
3. slave重做中繼日誌中的事件,將改變反映它自己的資料。
下圖描述了這一過程:
該過程的第一部分就是master記錄二進位制日誌。在每個事務更新資料完成之前,master在二日誌記錄這些改變。MySQL將事務序列的寫入二進位制日誌,即使事務中的語句都是交叉執行的。在事件寫入二進位制日誌完成後,master通知儲存引擎提交事務。
下一步就是slave將master的binary log拷貝到它自己的中繼日誌。首先,slave開始一個工作執行緒——I/O執行緒。I/O執行緒在master上開啟一個普通的連線,然後開始binlog dump process。Binlog dump process從master的二進位制日誌中讀取事件,如果已經跟上master,它會睡眠並等待master產生新的事件。I/O執行緒將這些事件寫入中繼日誌。
SQL slave thread處理該過程的最後一步。SQL執行緒從中繼日誌讀取事件,更新slave的資料,使其與master中的資料一致。只要該執行緒與I/O執行緒保持一致,中繼日誌通常會位於OS的快取中,所以中繼日誌的開銷很小。
此外,在master中也有一個工作執行緒:和其它MySQL的連線一樣,slave在master中開啟一個連線也會使得master開始一個執行緒。
MySQL5.6以前的版本複製過程有一個很重要的限制——複製在slave上是序列化的,也就是說master上的並行更新操作不能在slave上並行操作。 MySQL5.6版本引數slave-parallel-workers=1 表示啟用多執行緒功能。
MySQL5.6開始,增加了一個新特性,是加入了全域性事務 ID (GTID) 來強化資料庫的主備一致性,故障恢復,以及容錯能力。
官方文件:http://dev.mysql.com/doc/refman/5.6/en/replication-gtids.html
MySQL雙主(主主)架構方案思路是:
1.兩臺mysql都可讀寫,互為主備,預設只使用一臺(masterA)負責資料的寫入,另一臺(masterB)備用;
2.masterA是masterB的主庫,masterB又是masterA的主庫,它們互為主從;
3.兩臺主庫之間做高可用,可以採用keepalived等方案(使用VIP對外提供服務);
4.所有提供服務的從伺服器與masterB進行主從同步(雙主多從);
5.建議採用高可用策略的時候,masterA或masterB均不因宕機恢復後而搶佔VIP(非搶佔模式);
這樣做可以在一定程度上保證主庫的高可用,在一臺主庫down掉之後,可以在極短的時間內切換到另一臺主庫上(儘可能減少主庫宕機對業務造成的影響),減少了主從同步給線上主庫帶來的壓力;
但是也有幾個不足的地方:
1.masterB可能會一直處於空閒狀態(可以用它當從庫,負責部分查詢);
2.主庫後面提供服務的從庫要等masterB先同步完了資料後才能去masterB上去同步資料,這樣可能會造成一定程度的同步延時;
架構的簡易圖如下:
主主環境(這裡只介紹2臺主的配置方案):
1.CentOS 7 64位 2臺:masterA(192.168.10.11),masterB(192.168.10.12)
2.官方Mysql5.6版本
3.安裝時請注意路徑的對應,最好使用同博主一樣的路徑.
搭建過程:
1.安裝MySQL服務(建議原始碼安裝)
1.1 yum安裝依賴包
yum -y install make gcc gcc-c++ ncurses-devel bison openssl-devel
1.2 新增MySQL所需要的使用者和組
groupadd -g 27 mysql
adduser -u 27 -g mysql -s /sbin/nologin mysql
1.3 下載MySQL原始碼包
mkdir -p /data/packages/src
cd /data/packages/
wget https://cmake.org/files/v3.3/cmake-3.3.2.tar.gz
wget http://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.34.tar.gz
(如果下載連線失效,百度一個其他的連線即可)
1.4 建立mysql資料目錄
mkdir -p /usr/local/mysql/data
1.5 解壓編譯安裝cmake、MySQL
cd /data/packages/src
tar -zxvf ../cmake-3.3.2.tar.gz
cd cmake-3.3.2/
./bootstrap
gmake
make install
將cmake加入到環境變數PATH.
export PATH=$PATH:${your_cmake_path}/bin
cd ../
tar xf mysql-5.6.34.tar.gz
cd mysql-5.6.34
cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DSYSCONFDIR=/etc \
-DWITH_SSL=bundled -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_MYISAM_STORAGE_ENGINE=1 \
-DMYSQL_TCP_PORT=3306 -DMYSQL_UNIX_ADDR=/tmp/mysql.sock \
-DMYSQL_DATADIR=/usr/local/mysql/data
make && make install
將cmake加入到環境變數PATH.
export PATH=$PATH:${your_mysql_path}/bin
1.6 新增開機啟動指令碼
cp support-files/mysql.server /etc/rc.d/init.d/mysqld
1.7 新增masterA配置檔案/etc/my.cnf
[client]
port = 3306
socket = /tmp/mysql.sock
[mysqld]
basedir = /usr/local/mysql
port = 3306
socket = /tmp/mysql.sock
datadir = /usr/local/mysql/data
pid-file = /usr/local/mysql/data/mysql.pid
log-error = /usr/local/mysql/data/mysql.err
server-id = 1
auto_increment_offset = 1
auto_increment_increment = 2 #奇數ID
log-bin = mysql-bin #開啟二進位制功能,MASTER主伺服器必須開啟此項
binlog-format=ROW
binlog-row-p_w_picpath=minimal
log-slave-updates=true
gtid-mode=on
enforce-gtid-consistency=true
master-info-repository=TABLE
relay-log-info-repository=TABLE
sync-master-info=1
slave-parallel-workers=0
sync_binlog=0
binlog-checksum=CRC32
master-verify-checksum=1
slave-sql-verify-checksum=1
binlog-rows-query-log_events=1
#expire_logs_days=5
max_binlog_size=1024M #binlog單檔案最大值
replicate-ignore-db = mysql #忽略不同步主從的資料庫
replicate-ignore-db = information_schema
replicate-ignore-db = performance_schema
replicate-ignore-db = test
replicate-ignore-db = zabbix
max_connections = 3000
max_connect_errors = 30
skip-character-set-client-handshake #忽略應用程式想要設定的其他字符集
init-connect='SET NAMES utf8' #連線時執行的SQL
character-set-server=utf8 #服務端預設字符集
wait_timeout=1800 #請求的最大連線時間
interactive_timeout=1800 #和上一引數同時修改才會生效
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES #sql模式
max_allowed_packet = 10M
bulk_insert_buffer_size = 8M
query_cache_type = 1
query_cache_size = 128M
query_cache_limit = 4M
key_buffer_size = 256M
read_buffer_size = 16K
skip-name-resolve
slow_query_log=1
long_query_time = 6
slow_query_log_file=slow-query.log
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 16M
[mysql]
no-auto-rehash
[myisamchk]
key_buffer_size = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M
[mysqlhotcopy]
interactive-timeout
[mysqldump]
quick
max_allowed_packet = 16M
[mysqld_safe]
1.8 特別引數說明
log-slave-updates = true #將複製事件寫入binlog,一臺伺服器既做主庫又做從庫此選項必須要開啟
#masterA自增長ID
auto_increment_offset = 1
auto_increment_increment = 2 #奇數ID
#masterB自增加ID
auto_increment_offset = 2
auto_increment_increment = 2 #偶數ID
1.9 新增masterB配置檔案/etc/my.cnf
[client]
port = 3306
socket = /tmp/mysql.sock
[mysqld]
basedir = /usr/local/mysql
port = 3306
socket = /tmp/mysql.sock
datadir = /usr/local/mysql/data
pid-file = /usr/local/mysql/data/mysql.pid
log-error = /usr/local/mysql/data/mysql.err
server-id = 2
auto_increment_offset = 2
auto_increment_increment = 2 #偶數ID
log-bin = mysql-bin #開啟二進位制功能,MASTER主伺服器必須開啟此項
binlog-format=ROW
binlog-row-p_w_picpath=minimal
log-slave-updates=true
gtid-mode=on
enforce-gtid-consistency=true
master-info-repository=TABLE
relay-log-info-repository=TABLE
sync-master-info=1
slave-parallel-workers=0
sync_binlog=0
binlog-checksum=CRC32
master-verify-checksum=1
slave-sql-verify-checksum=1
binlog-rows-query-log_events=1
#expire_logs_days=5
max_binlog_size=1024M #binlog單檔案最大值
replicate-ignore-db = mysql #忽略不同步主從的資料庫
replicate-ignore-db = information_schema
replicate-ignore-db = performance_schema
replicate-ignore-db = test
replicate-ignore-db = zabbix
max_connections = 3000
max_connect_errors = 30
skip-character-set-client-handshake #忽略應用程式想要設定的其他字符集
init-connect='SET NAMES utf8' #連線時執行的SQL
character-set-server=utf8 #服務端預設字符集
wait_timeout=1800 #請求的最大連線時間
interactive_timeout=1800 #和上一引數同時修改才會生效
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES #sql模式
max_allowed_packet = 10M
bulk_insert_buffer_size = 8M
query_cache_type = 1
query_cache_size = 128M
query_cache_limit = 4M
key_buffer_size = 256M
read_buffer_size = 16K
skip-name-resolve
slow_query_log=1
long_query_time = 6
slow_query_log_file=slow-query.log
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 16M
[mysql]
no-auto-rehash
[myisamchk]
key_buffer_size = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M
[mysqlhotcopy]
interactive-timeout
[mysqldump]
quick
max_allowed_packet = 16M
[mysqld_safe]
1.10 初始化MySQL
cd /usr/local/mysql
scripts/mysql_install_db --user=mysql
1.11 為啟動指令碼賦予可執行許可權並啟動MySQL
chmod +x /etc/rc.d/init.d/mysqld
/etc/init.d/mysqld start
如果出現Starting MySQL... ERROR! The server quit without updating PID file (/usr/local/mysql/data/mysql.pid).請註釋掉/etc/my.cnf中的binlog-row-p_w_picpath=minimal一行然後重新執行第十步:
cd /usr/local/mysql
scripts/mysql_install_db --user=mysql
2. 配置主從同步
2.1 新增主從同步賬戶
masterA上:
mysql> grant replication slave on *.* to 'repl'@'192.168.10.12' identified by '123456';
mysql> flush privileges;
masterB上:
mysql> grant replication slave on *.* to 'repl'@'192.168.10.11' identified by '123456';
mysql> flush privileges;
2.2 檢視主庫的狀態
masterA上:
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 120 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
masterB上
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 437 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
2.3 配置同步資訊:
masterA上:
mysql> change master to master_host='192.168.10.12',master_port=3306,master_user='repl',master_password='123456',master_log_file='mysql-bin.000003',master_log_pos=437;
mysql> start slave;
mysql> show slave status\G;
顯示有如下狀態則正常:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
masterB上:
#本人是測試環境,可以保證沒資料寫入,否則需要的步驟是:先masterA鎖表-->masterA備份資料-->masterA解鎖表 -->masterB匯入資料-->masterB設定主從-->檢視主從
mysql> change master to master_host='192.168.10.11',master_port=3306,master_user='repl',master_password='123456',master_log_file='mysql-bin.000003',master_log_pos=120;
start slave;
mysql> show slave status\G;
顯示有如下狀態則正常:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
3.測試主從同步
3.1 在masterA上建立一個數據庫測試同步效果
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
4 rows in set (0.00 sec)
mysql> create database test01;
Query OK, 1 row affected (0.00 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
| test01 |
+--------------------+
5 rows in set (0.00 sec)
mysql> quit
Bye
[[email protected] data]#
3.2 到masterB檢視是否已經同步建立資料庫
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
| test01 |
+--------------------+
5 rows in set (0.00 sec)
mysql> quit
Bye
[[email protected] data]#
4. 開啟MySQL5.6的GTID功能
masterA和masterB分別執行如下命令:
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
mysql> change master to MASTER_AUTO_POSITION=1;
Query OK, 0 rows affected (0.01 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
到此,mysql主主互備搭建完畢.感謝您的閱讀.
本文的搭建過程是博主親自驗證可行的.原文地址:https://www.cnblogs.com/ygqygq2/p/6045279.html.