原文出自:https://abcops.cn/mysql-replicate/
什么是MySQL主從復(fù)制
MySQL 主從復(fù)制通常是用來建立一個(gè)和主數(shù)據(jù)庫完全一樣的數(shù)據(jù)庫環(huán)境,被稱為從數(shù)據(jù)庫,MySQL 主從復(fù)制默認(rèn)采用異步復(fù)制方式,這樣從節(jié)點(diǎn)不用一直訪問主服務(wù)器來更新自己的數(shù)據(jù),數(shù)據(jù)的更新可以在遠(yuǎn)程連接上進(jìn)行,從節(jié)點(diǎn)可以復(fù)制主數(shù)據(jù)庫中的所有數(shù)據(jù)庫或者特定的數(shù)據(jù)庫,或者特定的表。
在主從復(fù)制的過程中,一個(gè)服務(wù)器充當(dāng)一個(gè)主數(shù)據(jù)庫,而另外一臺(tái)服務(wù)器充當(dāng)從服務(wù)器,此時(shí)主服務(wù)器講本機(jī)的操作信息記錄至一個(gè)特定的二進(jìn)制文件中。
MySQL主從復(fù)制應(yīng)用場景
- 數(shù)據(jù)備份:主從服務(wù)器架構(gòu)的設(shè)置,可以大大加強(qiáng)MySQL數(shù)據(jù)庫架構(gòu)的健壯性。例如:當(dāng)主服務(wù)器出現(xiàn)問題時(shí),我們可以人工或設(shè)置自動(dòng)切換到從服務(wù)器繼續(xù)提供服務(wù),此時(shí)從服務(wù)器的數(shù)據(jù)和宕機(jī)時(shí)的主數(shù)據(jù)庫幾乎是一致的。
- 負(fù)載均衡:主從服務(wù)器架構(gòu)可通過程序(PHP、Java等)或代理軟件(mysql-proxy、Amoeba)實(shí)現(xiàn)對用戶(客戶端)的請求讀寫分離,即讓從服務(wù)器僅僅處理用戶的select查詢請求,降低用戶查詢響應(yīng)時(shí)間及讀寫同時(shí)在主服務(wù)器上帶來的訪問壓力。對于更新的數(shù)據(jù)(例如update、insert、delete語句)仍然交給主服務(wù)器處理,確保主服務(wù)器和從服務(wù)器保持實(shí)時(shí)同步。
- 橫向擴(kuò)展:將工作負(fù)載分發(fā)的多個(gè)Slave節(jié)點(diǎn)上,從而提高系統(tǒng)性能。在這個(gè)使用場景下,所有的寫(write)和更新(update)操作都在Master節(jié)點(diǎn)上完成;所有的讀( read)操作都在Slave節(jié)點(diǎn)上完成。通過增加更多的Slave節(jié)點(diǎn),便能提高系統(tǒng)的讀取速度。
MySQL主從復(fù)制架構(gòu)及原理
MySQl主從復(fù)制的前提
1)主服務(wù)器一定要打開二進(jìn)制日志bin-log
2)至少是兩臺(tái)服務(wù)器(或者多個(gè)實(shí)例)
3)主庫創(chuàng)建主從復(fù)制賬號
4)從庫必須要有relay-log(中繼日志)設(shè)置,存放主庫返回的二進(jìn)制日志
5)在復(fù)制過程中涉及到的線程
從庫會(huì)開啟一個(gè)IO thread(線程),負(fù)責(zé)連接主庫,請求binlog,接收binlog并寫入relay-log。
從庫會(huì)開啟一個(gè)SQL thread(線程),負(fù)責(zé)執(zhí)行relay-log中的事件。
主庫會(huì)開啟一個(gè)dump thrad(線程),負(fù)責(zé)響應(yīng)從IO thread的請求。
主從復(fù)制架構(gòu)圖:

主從復(fù)制原理
1)Master將數(shù)據(jù)改變記錄到二進(jìn)制日志(binary-log)中,也就是配置文件my.cnf中l(wèi)og-bin指定的文件。
2)在Slave服務(wù)器上執(zhí)行 start slave 命令開啟主從復(fù)制開關(guān),開始進(jìn)行主從復(fù)制。此時(shí),Slave服務(wù)器的IO線程會(huì)通過在master上已經(jīng)授權(quán)的復(fù)制用戶請求連接master服務(wù)器,并請求從服務(wù)器執(zhí)行binlog日志文件的指定位置。
3)Master服務(wù)器接收到Slave服務(wù)器的IO線程請求之后,主節(jié)點(diǎn)會(huì)創(chuàng)建一個(gè)log dump 線程,用于發(fā)送bin-log的內(nèi)容。在讀取bin-log中的操作時(shí),此線程會(huì)對主節(jié)點(diǎn)上的bin-log加鎖,當(dāng)讀取完成,甚至在發(fā)動(dòng)給從節(jié)點(diǎn)之前,鎖會(huì)被釋放。
4)當(dāng)Slave服務(wù)器的IO線程獲取到Master服務(wù)器上log-dump線程返回的binlog日志內(nèi)容和日志文件位置后,會(huì)將binlog日志內(nèi)容依次寫入到Slave自身的Relay Log (中繼日志) 文件 (MySQL-relay-bin.xxx) 的最末端,并將新的binlog文件名和位置記錄到master-info中,以便下一次讀取master新binlog日志時(shí)能告訴master服務(wù)器從新binlog日志的指定文件及位置開始讀取新的binlog日志內(nèi)容。
5)Slave再通過本地SQL線程會(huì)實(shí)時(shí)檢測本地Relay Log中IO線程新增的日志內(nèi)容,然后及時(shí)把Relay LOG文件中的內(nèi)容通過mysqlbinlog工具轉(zhuǎn)換成SQL語句,并在自身Slave服務(wù)器上按解析SQL語句的位置順序執(zhí)行SQL語句,并在Relay-log.info中記錄當(dāng)前應(yīng)用中繼日志的文件名和位置點(diǎn),而從達(dá)到數(shù)據(jù)一致
小結(jié):由于主從復(fù)制是通過網(wǎng)絡(luò)來傳輸bin-log日志來達(dá)成一致,一般都會(huì)有網(wǎng)了延遲,也可以說是異步。
MySQL binlog日志三種模式
ROW Level
ROW Level記錄的方式是行,即如果批量修改數(shù)據(jù),記錄的不是批量修改的SQL語句事件,而是每條記錄被更改的SQL語句,因此,ROW模式的binlog日志文件會(huì)變的很“重”

優(yōu)點(diǎn):row level的binlog日志內(nèi)容會(huì)非常清楚的記錄下每一行數(shù)據(jù)被修改的細(xì)節(jié)。而且不會(huì)出現(xiàn)某些特定情況下存儲(chǔ)過程或function,以及trigger的調(diào)用和觸發(fā)器無法被正確復(fù)制的問題。
缺點(diǎn):row level下,所有執(zhí)行的語句當(dāng)記錄到日志中的時(shí)候,都以每行記錄的修改來記錄,這樣可能會(huì)產(chǎn)生大量的日志內(nèi)容,產(chǎn)生的binlog日志量是驚人的。批量修改幾百萬條數(shù)據(jù),那么記錄幾百萬行……
Statement Level
記錄每一條修改數(shù)據(jù)的SQL語句(批量修改時(shí),記錄的不是單條SQL語句,而是批量修改的SQL語句事件)。看上面的圖很好理解row level和statement level兩種模式的區(qū)別。
優(yōu)點(diǎn):statement模式記錄的更改的SQ語句事件,并非每條更改記錄,所以大大減少了binlog日志量,節(jié)約磁盤IO,提高性能。
缺點(diǎn):statement level下對一些特殊功能的復(fù)制效果不是很好,比如:函數(shù)、存儲(chǔ)過程的復(fù)制。由于row level是基于每一行的變化來記錄的,所以不會(huì)出現(xiàn)類似問題
Mixed
實(shí)際上就是前兩種模式的結(jié)合。在Mixed模式下,MySQL會(huì)根據(jù)執(zhí)行的每一條具體的sql語句來區(qū)分對待記錄的日志形式,也就是在Statement和Row之間選擇一種。如果sql語句確實(shí)就是update或者delete等修改數(shù)據(jù)的語句,那么還是會(huì)記錄所有行的變更
企業(yè)場景如何選擇binlog的模式
1、 如果生產(chǎn)中使用MySQL的特殊功能相對少(存儲(chǔ)過程、觸發(fā)器、函數(shù))。選擇默認(rèn)的語句模式,Statement Level。
2、 如果生產(chǎn)中使用MySQL的特殊功能較多的,可以選擇Mixed模式。
3、 如果生產(chǎn)中使用MySQL的特殊功能較多,又希望數(shù)據(jù)最大化一致,此時(shí)最好Row level模式;但是要注意,該模式的binlog非?!俺林亍?。
查看binlog模式
mysql> show global variables like "%binlog_format%";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW |
+---------------+-------+
1 row in set (0.00 sec)
配置binlog模式
cat /etc/my.cnf | grep binlog
log-bin = /usr/local/mysql/binlogs/mysql-bin
max_binlog_size = 100M
binlog_expire_logs_seconds = 604800
binlog_cache_size=1048576
binlog_format='ROW' #行模式
#binlog_format='STATEMENT' #SQL語句模式
#binlog_format='MIXED' #混合模式
binlog_stmt_cache_size=1048576
sync_binlog=100
不重啟,使配置在msyql中生效
SET global binlog_format='STATEMENT';
主從復(fù)制配置搭建
| IP地址 | 配置 | 系統(tǒng)版本 | 狀態(tài) | 數(shù)據(jù)庫版本 |
|---|---|---|---|---|
| 192.168.31.215 | 2c/4G | CentOS 7.6.1810 | Master | mysql-8.0.17 |
| 192.168.31.216 | 2c/4G | CentOS 7.6.1810 | Slave | mysql-8.0.17 |
MySQL8二進(jìn)制安裝
下載MySQL8.0二進(jìn)制版本:wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.17-linux-glibc2.12-x86_64.tar.xz
1) 安裝依賴
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
yum clean all && yum makecache
yum install libaio.x86_64 libaio-devel.x86_64 -y
2)創(chuàng)建用戶組
groupadd mysql
useradd -r -g mysql -s /bin/false mysql
tar xf mysql-8.0.17-linux-glibc2.12-x86_64.tar.xz -C /usr/local/
cd /usr/local/
mv mysql-8.0.17-linux-glibc2.12-x86_64 mysql
3)設(shè)置基礎(chǔ)環(huán)境
mkdir mysql/mysql-files
chown mysql.mysql mysql/mysql-files/
echo 'export PATH=$PATH:/usr/local/mysql/bin' > /etc/profile.d/mysql.sh
source /etc/profile
mkdir -p /usr/local/mysql/{data,run,log}
chown -Rf mysql.mysql /usr/local/mysql/{data,run,log}
4)添加啟動(dòng)腳本
cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
chmod +x /etc/init.d/mysqld
chkconfig --add mysqld
5)my.cnf配置
cat /etc/my.cnf
[client]
port = 3306
socket = /usr/local/mysql/run/mysql.sock
[mysqld]
local_infile = 1
secure_file_priv = /tmp
log_timestamps=SYSTEM
default-time_zone = '+8:00'
port = 3306
wait_timeout = 28800
socket = /usr/local/mysql/run/mysql.sock
pid_file = /usr/local/mysql/run/mysql.pid
datadir = /usr/local/mysql/data
basedir = /usr/local/mysql
default_storage_engine = InnoDB
default_authentication_plugin=mysql_native_password
max_allowed_packet = 512M
max_connections = 65536
open_files_limit = 65536
log_bin_trust_function_creators=1
skip-name-resolve
lower_case_table_names=1
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'
innodb_read_io_threads = 16
innodb_io_capacity = 2000
innodb_buffer_pool_size = 8192M
innodb_log_file_size = 128M
innodb_file_per_table = 1
innodb_flush_log_at_trx_commit = 0
key_buffer_size = 512M
log-error = /usr/local/mysql/log/mysql_error.log
6)初始化數(shù)據(jù)庫
bin/mysqld --initialize --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/usr/local/mysql/log/mysql_error.log --open-files-limit=65536 --pid-file=/usr/local/mysql/run/mysql.pid --socket=/usr/local/mysql/run/mysql.sock --port=3306
查看密碼:
cat log/mysql_error.log | grep password
2019-09-29T16:27:15.074787+08:00 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: uqpIwWffn7=E #記住此密碼
7)加密連接
bin/mysql_ssl_rsa_setup
Generating a 2048 bit RSA private key
...........................................................+++
..........................................................+++
writing new private key to 'ca-key.pem'
-----
Generating a 2048 bit RSA private key
...........................................+++
................................................................+++
writing new private key to 'server-key.pem'
-----
Generating a 2048 bit RSA private key
............................................+++
.........................................+++
writing new private key to 'client-key.pem'
-----
8)修改root密碼
/etc/init.d/mysqld restart
Shutting down MySQL.. [ OK ]
Starting MySQL... [ OK ]
#連接數(shù)據(jù)庫,輸入剛才在日志中的密碼
mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.17
#修改root密碼采用mysql_native_password加密方式
mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password by '123456';
Query OK, 0 rows affected (0.01 sec)
#修改root密碼采用caching_sha2_password加密方式(與上面的二選一即可)
mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password by '123456';
Query OK, 0 rows affected (0.01 sec)
mysql> use mysql;
Database changed
#查看密碼所采用的加密方式,在plugin列
mysql> select host, user, authentication_string, plugin from user;
+-----------+------------------+------------------------------------------------------------------------+-----------------------+
| host | user | authentication_string | plugin |
+-----------+------------------+------------------------------------------------------------------------+-----------------------+
| localhost | mysql.infoschema | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | caching_sha2_password |
| localhost | mysql.session | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | caching_sha2_password |
| localhost | mysql.sys | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | caching_sha2_password |
| localhost | root | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | mysql_native_password |
+-----------+------------------+------------------------------------------------------------------------+-----------------------+
4 rows in set (0.00 sec)
9)數(shù)據(jù)庫加固
mysql_secure_installation
Enter password for user root: #輸入root密碼
Change the password for root ? ((Press y|Y for Yes, any other key for No) : No #是否修改root密碼
Remove anonymous users? (Press y|Y for Yes, any other key for No) : Y #是否刪除匿名用戶
Disallow root login remotely? (Press y|Y for Yes, any other key for No) : Y #是否允許root遠(yuǎn)程登錄
Remove test database and access to it? (Press y|Y for Yes, any other key for No) : Y #是否刪除測試數(shù)據(jù)庫
Reload privilege tables now? (Press y|Y for Yes, any other key for No) : Y #是否重新刷新權(quán)限表
主從復(fù)制配置
Master
添加主從配置及優(yōu)化參數(shù)至my.cnf文件
cat >> /etc/my.cnf << EOF
server-id = 1 #一個(gè)網(wǎng)絡(luò)內(nèi)server-id不能相同
log-bin = /usr/local/mysql/binlogs/mysql-bin #binlog日志位置
max_binlog_size = 100M
binlog_expire_logs_seconds = 604800
binlog_cache_size=1048576
binlog_format='STATEMENT'
binlog_stmt_cache_size=1048576
log_queries_not_using_indexes=ON
sync_binlog=100
innodb_flush_log_at_trx_commit=2
skip_name_resolve = 0 #跳過域名解析參數(shù)
EOF
mkdir -p /usr/local/mysql/binlogs
chown -Rf mysql.mysql binlogs/
/etc/init.d/mysqld restart
Shutting down MySQL.. [ OK ]
Starting MySQL... [ OK ]
Slave
添加主從配置及優(yōu)化參數(shù)至my.cnf文件
cat >> /etc/my.cnf << EOF
server-id = 2 #一個(gè)網(wǎng)絡(luò)內(nèi)server-id不能相同
max_binlog_size = 100M
binlog_expire_logs_seconds = 604800
binlog_cache_size=1048576
binlog_format='STATEMENT'
binlog_stmt_cache_size=1048576
log_queries_not_using_indexes=ON
sync_binlog=100
innodb_flush_log_at_trx_commit=2
skip_name_resolve = 0 #跳過域名解析參數(shù)
read_only = 1 #從庫只讀 (非root用戶)
EOF
/etc/init.d/mysqld restart
Shutting down MySQL... [ OK ]
Starting MySQL... [ OK ]
在Master主庫上創(chuàng)建用戶
#創(chuàng)建專屬在備庫上能夠登錄的用戶
mysql> create user 'db_repl'@'192.168.31.216' identified with mysql_native_password by '123456';
Query OK, 0 rows affected (0.00 sec)
#授權(quán)改用戶為slave
mysql> grant replication slave on *.* to 'db_repl'@'192.168.31.216';
Query OK, 0 rows affected (0.00 sec)
#刷新授權(quán)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
#獲取主節(jié)點(diǎn)當(dāng)前binary log文件名稱及位置
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 | 155 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
在Slave備庫上設(shè)置主節(jié)點(diǎn)參數(shù)
mysql> change master to
master_host='192.168.31.215',
master_user='db_repl',
master_password='123456',
master_log_file='mysql-bin.000002',
master_log_pos=155;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
在備庫查看同步狀態(tài)

在Slave備庫上開啟主從同步
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
再次查看同步狀態(tài)
已經(jīng)在備庫上開啟同步,所以IO線程和SQL線程都為YES

測試主從復(fù)制
在Master主庫上進(jìn)行創(chuàng)建,插入操作
#創(chuàng)建測試數(shù)據(jù)庫
mysql> create database db_mysql;
Query OK, 1 row affected (0.00 sec)
mysql> use db_mysql;
Database changed
mysql> CREATE TABLE `event_log` (
`dbname` varchar(128) NOT NULL DEFAULT '',
`eventname` varchar(128) NOT NULL DEFAULT '',
`starttime` datetime NOT NULL DEFAULT '1979-01-01 00:00:00',
`endtime` datetime DEFAULT NULL,
`issuccess` int(11) DEFAULT NULL,
`duration` int(11) DEFAULT NULL,
`errormessage` varchar(512) DEFAULT NULL,
`randno` int(11) DEFAULT NULL,
PRIMARY KEY (`dbname`,`eventname`,`starttime`),
KEY `idx_event_log_endtime` (`endtime`),
KEY `idx_event_log_starttime_randno` (`starttime`,`randno`),
KEY `idx_eventlog_stt_scs` (`starttime`,`issuccess`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected, 4 warnings (0.04 sec)
mysql> show tables;
+--------------------+
| Tables_in_db_mysql |
+--------------------+
| event_log |
+--------------------+
1 row in set (0.00 sec)
在Slave備庫上進(jìn)行查看是否同步
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| db_mysql |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.01 sec)
mysql> use db_mysql;
Database changed
mysql> show tables;
+--------------------+
| Tables_in_db_mysql |
+--------------------+
| event_log |
+--------------------+
1 row in set (0.01 sec)
二進(jìn)制日志管理說明
1)查看二進(jìn)制日志位置
mysql> show variables like '%log_bin%';
+---------------------------------+------------------------------------------+
| Variable_name | Value |
+---------------------------------+------------------------------------------+
| log_bin | ON |
| log_bin_basename | /usr/local/mysql/binlogs/mysql-bin |
| log_bin_index | /usr/local/mysql/binlogs/mysql-bin.index |
| log_bin_trust_function_creators | ON |
| log_bin_use_v1_row_events | OFF |
| sql_log_bin | ON |
+---------------------------------+------------------------------------------+
6 rows in set (0.01 sec)
2)查看二進(jìn)制日志名稱/查看都有哪些二進(jìn)制日志
mysql> show binary logs;
+------------------+-----------+-----------+
| Log_name | File_size | Encrypted |
+------------------+-----------+-----------+
| mysql-bin.000001 | 178 | No |
| mysql-bin.000002 | 1140 | No |
+------------------+-----------+-----------+
2 rows in set (0.00 sec)
3)查看當(dāng)前使用的binlog二進(jìn)制日志
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 | 1140 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
4)查看二進(jìn)制日志格式
mysql> show variables like '%format%';
+---------------------------------+-----------+
| Variable_name | Value |
+---------------------------------+-----------+
| binlog_format | STATEMENT |
| default_week_format | 0 |
| information_schema_stats_expiry | 86400 |
| innodb_default_row_format | dynamic |
+---------------------------------+-----------+
4 rows in set (0.00 sec)
MySQL主從復(fù)制常見問題
從庫binlog落后主庫binlog?
從庫記錄的主庫已經(jīng)傳送binlog事件的坐標(biāo),一般在繁忙及數(shù)據(jù)量大的情況下備庫會(huì)落后于主庫。
落后太遠(yuǎn)的原因:
硬件條件:機(jī)器磁盤IO性能不足
網(wǎng)絡(luò)原因:假如兩臺(tái)設(shè)備采用分布式架構(gòu),通過公網(wǎng)傳輸binlog日志。或者內(nèi)容帶寬速率過小
主庫存放二進(jìn)制日志的存儲(chǔ)性能太低,建議binlog日志存儲(chǔ)在SSD中
主庫 dump-log 線程太繁忙,這種情況主要發(fā)生在一主多從的架構(gòu)中
從庫IO線程太忙
人為控制(delay節(jié)點(diǎn)、延時(shí)節(jié)點(diǎn))
主庫 update,從庫遲遲沒有更新
特殊情況:日志已經(jīng)傳過來了,數(shù)據(jù)并沒有同步
一般情況:
1)沒有開啟SQL線程或者SQL線程故障
2)傳的東西有問題(你要做的事情,我提前已經(jīng)做了,不想重復(fù)做了,然后他就死了)
3)SQL線程繁忙
4)人為控制【delay(從庫)、延時(shí)節(jié)點(diǎn),一般生產(chǎn)設(shè)置3-6小時(shí)之間,可以保證過去3-6小時(shí)之間的誤操作,可以避免】
主從復(fù)制延時(shí)配置(從庫配置)
1)停止從庫復(fù)制
mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)
2)配置從庫延時(shí)
修改延時(shí)參數(shù)master_delay,單位為秒s,配置從庫復(fù)制主庫延遲60s
mysql> change master to master_delay = 60;
Query OK, 0 rows affected (0.01 sec)
3)啟動(dòng)從庫復(fù)制
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
4)查看配置是否生效
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.31.215
Master_User: db_repl
Master_Port: 3306
Connect_Retry: 60 #連接延遲60秒
從庫安全配置(其他用戶只讀)
修改my.cnf配置文件,添加只讀參數(shù)
tail -2 /etc/my.cnf
read_only = 1 #控制普通用戶在從庫只讀
innodb_read_only = 1 #控制root用戶在從庫只讀
添加完成后,重啟數(shù)據(jù)庫
service mysqld restart
Shutting down MySQL... [ OK ]
Starting MySQL... [ OK ]
查看只讀狀態(tài)
mysql> show variables like '%read_only%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_read_only | ON | #root用戶只讀
| read_only | ON | #普通用戶只讀
| super_read_only | OFF |
| transaction_read_only | OFF |
+-----------------------+-------+
4 rows in set (0.01 sec)
主從復(fù)制故障及解決(跳過錯(cuò)誤)
1)在mysql中配置
#臨時(shí)停止同步
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)
#將同步指針向下移動(dòng)一個(gè),如果多次不同步,可以重復(fù)操作
mysql> set global sql_slave_skip_counter=1;
Query OK, 0 rows affected (0.00 sec)
#啟動(dòng)同步,但是報(bào)錯(cuò)如下,是因?yàn)槲覀冮_啟了root只讀,在my.cnf中把root只讀給關(guān)閉掉,然后重啟mysql,再進(jìn)來開啟同步
mysql> start slave;
ERROR 1036 (HY000): Table 'slave_master_info' is read only
tail -2 /etc/my.cnf
read_only = 1
#innodb_read_only = 1 #注釋掉root只讀
/etc/init.d/mysqld restart #重啟mysqld
Shutting down MySQL.. [ OK ]
Starting MySQL... [ OK ]
mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)
在mysql中可以跳過某些錯(cuò)誤,但是最好的解決辦法,重新搭建主從復(fù)制
延時(shí)節(jié)點(diǎn)概念
此操作通過 show slave status\G; 命令看到
Last_SQL_Errno: 0
Last_SQL_Error:
原因:
1、主庫做操作的對象,在從庫不存在
2、主庫做操作的對象屬性不一致。
3、主庫做操作的對象,從庫已經(jīng)存在
備庫I/O及SQL線程狀態(tài)問題

Slave_IO_Running:I/O線程正在運(yùn)行狀態(tài)為 Yes,未運(yùn)行為 No,正在運(yùn)行但尚未連接到服務(wù)器為 Connecting
Slave_SQL_Running:SQL線程正在運(yùn)行狀態(tài)為 Yes,未運(yùn)行為 No

主服務(wù)器日志坐標(biāo):
Master_Log_File 和 Read_Master_Log_Pos 標(biāo)識主服務(wù)器二進(jìn)制日志中 dump-log 線程已經(jīng)傳輸?shù)淖罱录淖鴺?biāo)。
如果Master_Log_File和Read_Master_Log_Pos 的值遠(yuǎn)遠(yuǎn)落后于主服務(wù)器上的那些值,這表示主服務(wù)器與從屬服務(wù)器之間事件的網(wǎng)絡(luò)傳輸可能存在延遲
MySQL讀寫分離
原本我也是想著在主從復(fù)制的基礎(chǔ)之上把讀寫分離給做出來,但是考慮再三后覺得沒必要,原因如下:
MySQL主從復(fù)制本來就不是高可用架構(gòu),現(xiàn)在是兩臺(tái)機(jī)器跑MySQL主從架構(gòu),如果增加了讀寫分離,就需要多一臺(tái)機(jī)器再做讀寫分離的代理機(jī),這個(gè)時(shí)候的架
構(gòu)就如下圖:

1)此架構(gòu)中共有三臺(tái)機(jī)器(都是單點(diǎn)),如果任何一臺(tái)設(shè)備故障,則整個(gè)程序無法執(zhí)行查詢操作或?qū)懭氩僮鳌?br> 2)原本是主從是兩臺(tái)設(shè)備,在程序中可以寫死為讀在Slave,寫在Master,但是加了一個(gè)MySQL Proxy后,程序里連接數(shù)據(jù)庫地址要指向代理機(jī),假如代理機(jī)掛掉后,整個(gè)集群則無法可用。或者M(jìn)aster節(jié)點(diǎn)掛掉后,則無法進(jìn)行寫入操作,Slave節(jié)點(diǎn)掛掉后則無法進(jìn)行讀操作
3)簡單的主從架構(gòu),當(dāng)Master故障后,一時(shí)半會(huì)恢復(fù)不了業(yè)務(wù)的情況下,建議將Slave節(jié)點(diǎn)從復(fù)制集群中擇出來跑單機(jī),然后將IP地址換位Master地址即可。
這個(gè)時(shí)候可能會(huì)有同學(xué)說,為什么不用MySQL的雙主模式,雙主模式就可以達(dá)到高可用,但是雙主模式在數(shù)據(jù)量大的情況下,很難保證數(shù)據(jù)的一致性
參考文獻(xiàn)
感謝各位:
www.cnblogs.com/clsn/p/8087678.html
https://blog.csdn.net/zyhlwzy/article/details/80569422
https://blog.51cto.com/zhangxinqi/2178407