Mysql主從配置
大型網站爲了軟解大量的併發訪問,除了在網站實現分佈式負載均衡,遠遠不夠。到了數據業務層、數據訪問層,如果還是傳統的數據結構,或者只是單單靠一臺服務器扛,如此多的數據庫連接操作,數據庫必然會崩潰,數據丟失的話,後果更是不堪設想。這時候,我們會考慮如何減少數據庫的聯接,一方面採用優秀的代碼框架,進行代碼的優化,採用優秀的數據緩存技術如:memcached,如果資金豐厚的話,必然會想到假設服務器羣,來分擔主數據庫的壓力。今天總結一下利用MySQL主從配置,實現讀寫分離,減輕數據庫壓力.
這裏我們一本地虛擬機爲例來配置主從. mysql和mariadb是一樣的配置的.我這裏一mariadb爲實際案例. 配置的時候兩臺虛擬機使用的是內網地址.
MySQL 主從複製(也稱 A/B 複製) 的原理
- Master將數據改變記錄到二進制日誌(binary log)中,也就是配置文件log-bin指定的文件,
這些記錄叫做二進制日誌事件(binary log events); - Slave 通過 I/O 線程讀取 Master 中的 binary log events 並寫入到它的中繼日誌(relay log);
- Slave 重做中繼日誌中的事件, 把中繼日誌中的事件信息一條一條的在本地執行一次,完
成數據在本地的存儲, 從而實現將改變反映到它自己的數據(數據重放)。
主從配置需要注意的點
- 主從服務器操作系統版本和位數一致;
- Master 和 Slave 數據庫的版本要一致;
- Master 和 Slave 數據庫中的數據要一致;
- Master 開啓二進制日誌, Master 和 Slave 的 server_id 在局域網內必須唯一;
主從配置的簡要步驟
- 安裝數據庫;
- 修改數據庫配置文件, 指明 server_id, - 開啓二進制日誌(log-bin);
- 啓動數據庫, 查看當前是哪個日誌, position 號是多少;
- 登錄數據庫, 授權數據複製用戶(IP 地址爲從機 IP 地址, 如果是雙向主從, 這裏的還需要授權本機的 IP 地址, 此時自己的 IP 地址就是從 IP 地址);
- 備份數據庫(記得加鎖和解鎖);
- 傳送備份數據到 Slave 上;
- 啓動數據庫;
Slave 上的配置
- 安裝數據庫;
- 修改數據庫配置文件, 指明 server_id(如果是搭建雙向主從的話, 也要開啓二進制
日誌 log-bin); - 啓動數據庫, 還原備份;
- 查看當前是哪個日誌, position 號是多少(單向主從此步不需要, 雙向主從需要);
- 指定 Master 的地址、 用戶、 密碼等信息;
- 開啓同步, 查看狀態。
1、 Linux Centos 7.5 虛擬機部署環境
主機(Server1): 192.168.26.22 OS:CentOS 7.5
從機(Server1): 192.168.26.23 OS:CentOS 7.5
修改IP方式
vi /etc/sysconfig/network-scripts/ifcfg-ens33
修改網絡配置
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static # 修改
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33
UUID=9f5b3186-f784-4857-8c4e-2b394a3d9672
DEVICE=ens33
ONBOOT=yes # 修改
GATEWAY=192.168.26.2 # Vmware 工具欄編輯項,選擇虛擬網絡編輯器,Nat 模式,單擊 Nat 設置 獲取網關 192.168.26.2
IPADDR=192.168.26.23 # 對外訪問IP
NETMASK=255.255.255.0 # 一樣
DNS1=192.168.26.2
按esc、組合鍵shrit + : ,wq 保存退出
重啓網絡
service network restart
至此,服務器已經搭建好了
2、 創建數據庫和表
主機創建 wtf 數據庫 以及 user 表
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`u_id` int(11) NOT NULL AUTO_INCREMENT,
`address` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`apartment` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`create_time` datetime(0) NULL DEFAULT NULL,
`password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`phone_number` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`role` int(11) NULL DEFAULT NULL,
`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`u_id`) USING BTREE
) ENGINE = MyISAM AUTO_INCREMENT = 0 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
主機創建 wtf2 數據庫 以及 user 表,SQL 同上
3、 主數據庫的配置
3.1 主數據庫配置(非 Docker 安裝 )
首先使用命令
cd /etc
然後在執行
ls my.cnf
在使用編輯器vi打開my.cnf文件
vi my.cnf 按 i 進入編輯模式
ESC :set number 打印行號
[root@localhost etc]# vi my.cnf
[mysqld]
1 [mysqld]
2 datadir=/var/lib/mysql
3 socket=/var/lib/mysql/mysql.sock
4 # Disabling symbolic-links is recommended to prevent assorted security risks
5 symbolic-links=0
6 # Settings user and group are ignored when systemd is used.
7 # If you need to run mysqld under a different user or group,
8 # customize your systemd unit file for mariadb according to the
9 # instructions in http://fedoraproject.org/wiki/Systemd
10
11 server-id=200
12
13 innodb_flush_log_at_trx_commit=2
14
15 sync_binlog=1
16
17 log-bin=mysql-bin-200
18
19 binlog-do-db=wtf
20
21 [mysqld_safe]
22 log-error=/var/log/mariadb/mariadb.log
23 pid-file=/var/run/mariadb/mariadb.pid
24
25 #
26 # include all files from the config directory
27 #
28 !includedir /etc/my.cnf.d
幾條配置文件的含義如下:
設置主服務 的ID (id可以自己隨便設置但是要保證和slave的id不一樣)
server-id=200
innodb_flush_log_at_trx_commit=2 #(參數的含義如下)
- 0:如果innodb_flush_log_at_trx_commit的值爲0,log buffer每秒就會被刷寫日誌文件到磁盤,提交事務的時候不做任何操作(執行是由mysql的master thread線程來執行的。
-主線程中每秒會將重做日誌緩衝寫入磁盤的重做日誌文件(REDO LOG)中。不論事務是否已經提交)默認的日誌文件是ib_logfile0,ib_logfile1 - 1:當設爲默認值1的時候,每次提交事務的時候,都會將log buffer刷寫到日誌。
- 2:如果設爲2,每次提交事務都會寫日誌,但並不會執行刷的操作。每秒定時會刷到日誌文件。要注意的是,並不能保證100%每秒一定都會刷到磁盤,這要取決於進程的調度。
- 每次事務提交的時候將數據寫入事務日誌,而這裏的寫入僅是調用了文件系統的寫入操作,而文件系統是有 緩存的,所以這個寫入並不能保證數據已經寫入到物理磁盤
- 默認值1是爲了保證完整的ACID。當然,你可以將這個配置項設爲1以外的值來換取更高的性能,但是在系統崩潰的時候,你將會丟失1秒的數據。
- 設爲0的話,mysqld進程崩潰的時候,就會丟失最後1秒的事務。設爲2,只有在操作系統崩潰或者斷電的時候纔會丟失最後1秒的數據。InnoDB在做恢復的時候會忽略這個值。
總結
設爲1當然是最安全的,但性能頁是最差的(相對其他兩個參數而言,但不是不能接受)。如果對數據一致性和完整性要求不高,完全可以設爲2,如果只最求性能,例如高併發寫的日誌服務器,設爲0來獲得更高性能
開啓binlog 志同步功能
sync_binlog=1
binlog 日誌文件名
log-bin=mysql-bin-200
這個表示只同步某個庫 (如果沒有此項,表示同步所有的庫)
binlog-do-db=wtf
上面的配置寫好之後按鍵盤ESC鍵在按shift+:輸入wq.保存退出.
重啓我們的主機數據庫看自己的數據庫是什麼選用不同的命令
systemctl restart mysql
3.2 Mysql 主配置 (Docker Mysql 容器安裝)
Docker 使用的是容器技術,其容器的配置與外界環境相隔離,按照 3.1 命令操作,其內部的Mysql Server_id 依然是 1,所以再進行主從配置配置時,報錯… ,說的話比較抽象。大致可以理解爲安裝的 Docker 容器中有各自的配置環境,與操作系統環境相隔離。
安裝詳情見 linux 模塊中的第三步,安裝 Mysql 8.0.12。
這裏在Linux 安裝 3 個 Mysql 數據庫,初始化密碼爲 root
192.168.26.22:3306 對外映射端口爲 3306
docker run -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:8.0.12 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
192.168.26.23:3306 對外映射端口爲 3306
docker run -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:8.0.12 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
192.168.26.23:3306 對外映射端口爲 3307
docker run -p 3307:3306 --name mysql1 -e MYSQL_ROOT_PASSWORD=root -d mysql:8.0.12 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
進入正在運行中的 Mysql 容器
docker start mysql # 啓動名稱爲 Mysql 的容器
docker exec -it mysql bash # 以 Bash 進入 Mysql 終端
apt-get update # 更新安裝源
apt-get install vim # 安裝 vim 命令,Docker 容器沒有提供常見命令
vim /etc/mysql/my.cnf # 修改容器中的配置文件
主從文件配置(my.cnf)
192.168.26.22:3306 主數據庫配置
server-id=1
innodb_flush_log_at_trx_commit=1
sync_binlog=1
log-bin=mysql-bin-22-3306
192.168.26.22:3306 -> 3306 從數據庫配置
server-id=2
innodb_flush_log_at_trx_commit=1
sync_binlog=1
log-bin=mysql-bin-23-3306
192.168.26.22:3306 -> 3307 從主數據庫配置
server-id=3
innodb_flush_log_at_trx_commit=1
sync_binlog=1
log-bin=mysql-bin-23-3307
這裏使用,mysql 爲 docker Mysql 的容器名稱,然後之前的操作
docker restart mysql
連續兩次
exit 推出容器,或者重新連接一個 Shell 表
重啓 mysql 容器
3.2 授權
進入 Mysql 主數據庫,進行賬號授權,只有獲取而二進制 log 日誌權利
docker exec -it mysql bash
如果不是 docker 安裝的 mysql 直接這一步
mysql -uroot -proot
說一下,登錄密碼依然是安裝鏡像的密碼,真奇怪
docker run -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:8.0.12 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
授權給用戶
再來給授權給從數據庫服務 192.168.26.0-255,用戶mark,密碼158262751
mysql> use mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> CREATE USER 'mark'@'192.168.26.%' IDENTIFIED WITH mysql_native_password BY '158262751';
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT REPLICATION SLAVE ON *.* TO 'mark'@'192.168.26.%';
Query OK, 0 rows affected, 1 warning (0.00 sec)
刷新授權表信息
mysql> flush privileges;
獲取主節點當前binary log文件名和位置(position)
mysql> SHOW MASTER STATUS;
+---------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000005 | 4990 | | | |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
4. 從數據庫配置
server-id=201
innodb_flush_log_at_trx_commit=2
sync_binlog=1
log-bin=mysql-bin-201
4.1 進入數據庫,進行操作,可以在Navicat 操作
如果配置了同步的數據庫,則在從機數據庫上面要有一個和主機配置的數據庫一樣的數據庫.
配置從機連接master
change master to master_host='192.168.26.22',master_user='mark' ,master_password='158262751', master_log_file='mysql-bin-22-3306.000001' ,master_log_pos=450;
參數說明:
- master_host: 主機的ip
- master_user : 主機授權的用戶.
- master_password : 主機授權時候填寫的密碼
- master_log_file : 主機show master status;中的File
- master_log_pos: 主機show master status;中的Position.
開啓主從,可以在Navicat 操作
start slave; # 開啓主從
stop slave; # 關閉
reset slava; # 重置設置
show master status; # 顯示主數據庫 log 狀態,主數據庫查看
查看主從連接狀態,可以在Navicat 操作
顯示不明顯
show slave status\G #
兩個連接成功就說明成功了,主從數據庫的數據庫和表應該保持一致,不一致的話,會有錯。
apt-get update
apt-get install vim
vim /etc/mysql/my.cnf
server-id=2
master-host=192.168.1.111
master-user=mstest
master-password=123456
master-port=3306
master-connect-retry=60