關於主從配置的好處和壞處我這裏就不詳細解說了,自己百度下就一大堆,我這就直入主題了
MySQL數據庫複製操作大致可以分成三個步驟:
- 主服務器將數據的改變記錄到二進制日誌(binary log)中。
- 從服務器將主服務器的binary log events 複製到它的中繼日誌(relay log)中。
- 從服務器重做中繼日誌中的事件,將數據的改變與從服務器保持同步
首先,主服務器會記錄二進制日誌,每個事務更新數據完成之前,主服務器將這些操作的信息記錄在二進制日誌裏面在事件寫入二進制日誌完成後主服務器通知存儲引擎提交事務。
準備: 瞭解binlog日誌,MySQL用戶-權限
1. 創建複製賬號
mysql服務器配置複製不難,但是因爲場景不同可能會存在一定的差異化,總的來說分爲一下幾步:
- 在服務器上創建複製賬號。
- 通知備庫連接到主庫並從主庫複製數據。
對於主從複製,在本質上就是通過與從數據庫複製與主數據庫的binlog日誌文件,通過重做實現的同步; 但是一定要注意儘量保證主從服務器上安裝了相同的版本的數據庫,設定主從的服務器ip地址爲192.168.153.129從服務器的ip地址是192.168.153.131。
然後再主服務器上設置一個複製使用的賬號,並授予replication slave權限。我們可以根據ip創建賬號爲127
/*
創建賬號sql:
create user 'username'@'localhost' identified by 'password';
授權
grant [權限] on *.* to 'username'@'localhost' identified by 'password';
*/
mysql> create user 'repl_131'@'%' identified by 'repl_131';
Query OK, 0 rows affected (0.04 sec)
mysql> select user,host from mysql.user;
mysql> grant replication slave on *.* to 'repl_131'@'%' identified by 'repl_131';
Query OK, 0 rows affected, 1 warning (0.00 sec)
對於MySQL的主從複製來說最重要的主要就是binlog日誌,所以我們就需要開啓binlog日誌,並設置server-id的值。需要重啓服務器之後才生效
二進制日誌,也就是我們常說的binlog。二進制日誌記錄了MySQL所有修改數據庫的操作,然後以二進制的形式記錄日誌在日誌文件中,其中還包括沒調語句所執行的時間和消耗的資源,以及相關的事務信息。默認情況下二進制日誌功能是沒有開啓的,啓動可以配置log-bin[=file_name]開啓,
mysql> show global variables like '%log_bin%';
+---------------------------------+----------------------------------+
| Variable_name | Value |
+---------------------------------+----------------------------------+
| log_bin | ON |
| log_bin_basename | /www/server/data/mysql-bin |
| log_bin_index | /www/server/data/mysql-bin.index |
| log_bin_trust_function_creators | OFF |
| log_bin_use_v1_row_events | OFF |
+---------------------------------+----------------------------------+
5 rows in set (0.03 sec)
作用就是
- 增量備份(不是所有數據備份,而是最近的寫操作)
- 用於MySQL主從複製
解釋爲什麼每次修改配置文件都用find...因爲記不住
[root@localhost panel]# vi /etc/my.cnf
主要就是下配置文件中添加如下配置
[mysqld]
log-bin=mysql-bin
server-id=1
2 binlog數據恢復操作
查看MySQL的日誌文件, 這是查詢主服務器上當前的二進制日誌名和偏移值。這個操作的母的是爲了在從數據庫啓動以後,從這個點進行數據庫的恢復。
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000009 | 708 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
對於binlog來說mysql-bin.xxx就是binlog的節點日誌文件,而mysql-bin.index這是日誌文件的所以會記錄的是所有日誌文件的地址
[root@localhost data]# more mysql-bin.index
./mysql-bin.000006
./mysql-bin.000007
./mysql-bin.000008
./mysql-bin.000009
我們可以看看binlog日誌中的信息
-- 查看二進制日誌信息
Mysqlbinlog filename
show binlog events in 'filename'\G;
查看binlog的信息,先設置mysqlbinlog爲系統環境變量
[root@localhost data]# vi ~/.bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin:/www/server/mysql/bin
export PATH
[root@localhost data]# source ~/.bash_profile
[root@localhost data]# cd /www/server/data
[root@localhost data]# mysqlbinlog ./mysql-bin.000009
日誌中由 #at xxx 頭, #at xxx ~~ /!/ 體兩部分組成
-- 查看所有二進制文件信息
show binary logs;
-- 查看最新二進制文件
show master status;
-- 刷新日誌
flush logs;
-- 清空所有的日誌文件
reset master
添加一下測試的數據操作
CREATE DATABASE bin DEFAULT CHARACTER SET utf8;
use bin;
CREATE TABLE `t` (
`id` int(10) ,
`name` varchar(20)
) ;
INSERT INTO t VALUES(1, 'sixstar');
INSERT INTO t VALUES(2, 'shineyork');
INSERT INTO t VALUES(3, 'xxx');
這個時候我們可以看看這個binlog日誌中的信息
mysql> show binlog events in 'mysql-bin.000001';
+------------------+------+----------------+-----------+-------------+-----------------------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+------+----------------+-----------+-------------+-----------------------------------------------------------------------+
| mysql-bin.000001 | 4 | Format_desc | 1 | 123 | Server ver: 5.7.27-log, Binlog ver: 4 |
| mysql-bin.000001 | 123 | Previous_gtids | 1 | 154 | |
| mysql-bin.000001 | 154 | Anonymous_Gtid | 1 | 219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000001 | 219 | Query | 1 | 310 | create database bin |
| mysql-bin.000001 | 310 | Anonymous_Gtid | 1 | 375 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000001 | 375 | Query | 1 | 505 | use `bin`; CREATE TABLE `t` (
`id` int(10) ,
`name` varchar(20)
) |
| mysql-bin.000001 | 505 | Anonymous_Gtid | 1 | 570 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000001 | 570 | Query | 1 | 647 | BEGIN |
| mysql-bin.000001 | 647 | Query | 1 | 753 | use `bin`; INSERT INTO t VALUES(1, 'sixstar') |
| mysql-bin.000001 | 753 | Xid | 1 | 784 | COMMIT /* xid=2369 */ |
| mysql-bin.000001 | 784 | Anonymous_Gtid | 1 | 849 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000001 | 849 | Query | 1 | 926 | BEGIN |
| mysql-bin.000001 | 926 | Query | 1 | 1034 | use `bin`; INSERT INTO t VALUES(2, 'shineyork') |
| mysql-bin.000001 | 1034 | Xid | 1 | 1065 | COMMIT /* xid=2370 */ |
| mysql-bin.000001 | 1065 | Anonymous_Gtid | 1 | 1130 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysql-bin.000001 | 1130 | Query | 1 | 1207 | BEGIN |
| mysql-bin.000001 | 1207 | Query | 1 | 1309 | use `bin`; INSERT INTO t VALUES(3, 'xxx') |
| mysql-bin.000001 | 1309 | Xid | 1 | 1340 | COMMIT /* xid=2371 */ |
+------------------+------+----------------+-----------+-------------+-----------------------------------------------------------------------+
18 rows in set (0.00 sec)
接下來做一個操作就是對於t表中的數據進行刪除所有的數據(這是模擬某些不小心的同學做的操作);
mysql> delete from `t` where id > 1;
Query OK, 2 rows affected (0.02 sec)
mysql> select * from t;
+------+---------+
| id | name |
+------+---------+
| 1 | sixstar |
+------+---------+
1 row in set (0.00 sec)
現在來做恢復;根據數據情況找到數據的節點位置, 發現是從849開始到1340結束
[root@localhost data]# mysqlbinlog mysql-bin.000001 --start-position 849 --stop-position 1340 | mysql -u root -p
Enter password:
3. 配置從節點
注意:對於使用虛擬機的同學--注意克隆之後的系統你需要稍微修改一下系統的ip 地址
[root@localhost ~]# vi /etc/sysconfig/network-scripts/ifcfg-ens33
IPADDR=192.168.153.131
NETMASK=255.255.255.0
GATEWAY=192.168.153.2
[root@localhost ~]# systemctl restart network
注意還順便也修改一下寶塔的nginx服務地址 -- 然後暫時就ok了把...
在進行配置之前,回顧一下過程
要先明確配置的架構Master-slave
1. 配置主節點 1.1 配置賬號 1.2 開啓binlog日誌 2. 配置從節點 2.1 配置同步日誌 2.2 指定主節點的ip, 端口, 用戶.. 2.3 啓動從節點
3.1 配置同步日誌
修改配置
[root@localhost ~]# find / -name my.cnf
/etc/my.cnf
[root@localhost ~]# vi /etc/my.cnf
[root@localhost ~]# find / -name mysqld
/etc/rc.d/init.d/mysqld
/www/server/mysql/bin/mysqld
[root@localhost ~]# /etc/rc.d/init.d/mysqld restart
Shutting down MySQL.. SUCCESS!
Starting MySQL. SUCCESS!
在配置文件中添加
# 配置從節點
server-id = 2
relay_log = /www/server/data/mysql-relay-bin
relay_log-index = /www/server/data/mysql-relay-bin.index
log_slave_updates = 1
read_only = 1
參數介紹: server_id:這是服務id系統會自動命名的,但如果機器名邊畫畫肯能回答導致問題。可以講你主庫和備庫上的log-bin設置爲相同的值。 relay_log:指定中繼日誌的位置和命名
3.2 指定主節點的ip,端口,用戶
mysql> change master to master_host='192.168.153.129',master_port=3306,master_user='127',master_password='127',master_log_file='mysql-bin.000001',master_log_pos=0;
Query OK, 0 rows affected, 2 warnings (0.02 sec)
3.3 啓動從節點
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
mysql> show slave status \G;
對於我們來說其中的信息主要是關注
Slave_IO_Running: Connecting
Slave_SQL_Running: Yes
reset slave all 清楚slave信息
測試的方法就是在主服務器中,添加一些數據測試觀察從服務其中的數據變化情況。
進入slave服務器,運行:
mysql> show slave status\G
.......
Relay_Log_File: localhost-relay-bin.000535
Relay_Log_Pos: 21795072
Relay_Master_Log_File: localhost-bin.000094
Slave_IO_Running: Yes
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB:
......
解決辦法一、
Slave_SQL_Running: No
1.程序可能在slave上進行了寫操作
2.也可能是slave機器重起後,事務回滾造成的.
一般是事務回滾造成的:
解決辦法:
mysql> stop slave ;
mysql> set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
mysql> start slave ;
解決辦法二、
首先停掉Slave服務:slave stop
到主服務器上查看主機狀態:
記錄File和Position對應的值
進入master
mysql> show master status;
+----------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+----------------------+----------+--------------+------------------+
| localhost-bin.000094 | 33622483 | | |
+----------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
然後到slave服務器上執行手動同步:
mysql> change master to
> master_host='master_ip',
> master_user='user',
> master_password='pwd',
> master_port=3306,
> master_log_file=localhost-bin.000094',
> master_log_pos=33622483 ;
1 row in set (0.00 sec)
mysql> start slave ;
1 row in set (0.00 sec)
mysql> show slave status\G
*************************** 1. row ***************************
........
Master_Log_File: localhost-bin.000094
Read_Master_Log_Pos: 33768775
Relay_Log_File: localhost-relay-bin.000537
Relay_Log_Pos: 1094034
Relay_Master_Log_File: localhost-bin.000094
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
手動同步需要停止master的寫操作!