天天看點

mysql 主主_MySQL(主主)架構方案

主主架構:就是反向的再部署一遍主從,定義不同的id,進行bin_log去進行備份。

在企業中,資料庫高可用一直是企業的重中之重,中小企業很多都是使用mysql主從方案,一主多從,讀寫分離等,但是單主存在單點故障,從庫切換成主庫需要作改動。是以,如果是雙主或者多主,就會增加mysql入口,增加高可用。不過多主需要考慮自增長ID問題,這個需要特别設定配置檔案,比如雙主,可以使用奇偶,總之,主之間設定自增長ID互相不沖突就能完美解決自增長ID沖突問題。

主從同步複制原理複制分成三步:1. master将改變記錄到二進制日志(binary log)中(這些記錄叫做二進制日志事件,binary log events);2. slave将master的binary log events拷貝到它的中繼日志(relay log);3. slave重做中繼日志中的事件,将改變反映它自己的資料。

主從架構圖:

mysql 主主_MySQL(主主)架構方案

第一部分就是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) 來強化資料庫的主備一緻性,故障恢複,以及容錯能力。

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上去同步資料,這樣可能會造成一定程度的同步延時;

mysql 主主_MySQL(主主)架構方案

主主環境(這裡隻介紹2台主的配置方案):

1.CentOS 6.8 64位 2台:masterA(192.168.10.11),masterB(192.168.10.12)

2.官方Mysql5.6版本搭建過程不做介紹,采用二進制免編譯檔案安裝。安裝辦法:https://blog.51cto.com/13451715/2088719

此處直接寫配置檔案:添加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 #定義serverid為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]

特别參數說明

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

添加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]

配置主從同步

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;

主主上執行:show master status;

mysql 主主_MySQL(主主)架構方案
mysql 主主_MySQL(主主)架構方案

配置同步資訊: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

測試主從同步

在masterA上建立一個資料庫測試同步效果

show databases;

create database test01;

到masterB檢視是否已經同步建立資料庫

show databases; #檢視有沒有test01的庫開啟MySQL5.6的GTID功能

masterA和masterB分别執行如下指令:

stop slave;

change master to MASTER_AUTO_POSITION=1;

start slave;

遇到的問題

Last_IO_Errno: 1236

Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Could not open log file'

後面修改主從同步相關 參數,确認原因是my.cnf增加了如下參數:

log-bin = mysql-bin

relay-log = mysql-bin

從正常主主同步時的二進制日志檔案顯示,有2套二進制日志。是以推斷上面2個參數導緻不能産生2套二進制檔案,故導緻二進制檔案錯亂和丢失。