目前大部份的應該程式,都需要架設資料庫,所以說資料庫是應用程式的核心組件。這篇文章主要是教大家如何安裝與設置主從式(Master Slave)機制的架構,而不是探討這個機制可以應用在甚麼情境的應用程式下。
資料庫在擴展上最常使用的技術就是複製(Replication)技術,這個技術主要是以資料複製的方式把一個MySQL裹資料完整的複製到另一個MySQL節點上。因為大部分的資料庫應用程式都是SELECT為主,所以最常用到的就是讀寫分離的「主從式架構」。
MySQL的主(Master)節點負責「讀寫」,寫資料會透過Binlog Relay機制,以非同步模式複製Binlog到每一台從(Slave)節點執行。而從(Slave)節點只提供讀功能,不提供寫入功能,為了分散SELECT的運算。這種架構在實作時,必須自行在程式上實作「讀寫分離」的機制,即是需要程式邏輯上將SELECT Query 查詢分散到Slave節點執行。如果不想由程式上實作,也可以使用一些Proxy的軟體進行分配工作,如HAProxy。
廢話不多說,以下是安裝與設置流程:
伺服器 A:
作業系統:CentOS 7
資料庫:MySQL 5.7
IP:192.168.1.10
伺服器 B:
作業系統:CentOS 7
資料庫:MySQL 5.7
IP:192.168.1.11
步驟一:
安裝與設置「伺服器 A」
- 下載MySQL的Yum Repository RPM(可從官方網站下載其它版本 https://dev.mysql.com/downloads/repo/yum/)
$ wget http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm
- 安裝MySQL的Yum Repository RPM
$ sudo yum localinstall mysql57-community-release-el7-7.noarch.rpm
- 安裝MySQL
$ sudo yum install mysql-community-server
- 修改MySQL的設置文檔my.cnf
$ sudo vi /etc/my.cnf [mysqld] # 在最後加入以下參數 server-id=1 log-bin=mysql-bin binlog-do-db=exampledb
- 啓動MySQL服務
$ sudo systemctl start mysqld.service
- 查看MySQL初始啓動時,默認的root密碼
$ cat /var/log/mysqld.log | grep 'temporary password' 2018-04-19T15:12:10.337245Z 1 [Note] A temporary password is generated for root@localhost: xxxxxxxxxxx
- 提供MySQL的安裝過程中的安全性,使用mysql_secure_installation
$ mysql_secure_installation Securing the MySQL server deployment. Enter password for user root: The existing password for the user account root has expired. Please set a new password. New password: Re-enter new password: The 'validate_password' plugin is installed on the server. The subsequent steps will run with the existing configuration of the plugin. Using existing password for root. Estimated strength of the password: 100 Change the password for root ? ((Press y|Y for Yes, any other key for No) : y New password: Re-enter new password: Estimated strength of the password: 100 Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : Y By default, a MySQL installation has an anonymous user, allowing anyone to log into MySQL without having to have a user account created for them. This is intended only for testing, and to make the installation go a bit smoother. You should remove them before moving into a production environment. Remove anonymous users? (Press y|Y for Yes, any other key for No) : Y Success. Normally, root should only be allowed to connect from 'localhost'. This ensures that someone cannot guess at the root password from the network. Disallow root login remotely? (Press y|Y for Yes, any other key for No) : Y Success. By default, MySQL comes with a database named 'test' that anyone can access. This is also intended only for testing, and should be removed before moving into a production environment. Remove test database and access to it? (Press y|Y for Yes, any other key for No) : Y - Dropping test database... Success. - Removing privileges on test database... Success. Reloading the privilege tables will ensure that all changes made so far will take effect immediately. Reload privilege tables now? (Press y|Y for Yes, any other key for No) : Y Success.
- 使用root用戶登入MySQL
$ mysql -u root -p
- 新增與授權一個可以有覆製能力的用戶「replication」
mysql> grant replication slave on *.* to 'replication'@'%' identified by 'password'; mysql> flush privileges; mysql> exit
- 如防火牆沒有讓端口3306放行,需要為防火牆設置
$ sudo firewall-cmd --add-service=mysql --permanent $ sudo firewall-cmd --reload
步驟二:
安裝與設置「伺服器 B」
- 與「伺服器 A – 1」相同
- 與「伺服器 A – 2」相同
- 與「伺服器 A – 3」相同
- 修改MySQL的設置文檔my.cnf
$ sudo vi /etc/my.cnf [mysqld] # 在最後加入以下參數 server-id=2
- 與「伺服器 A – 5」相同
- 與「伺服器 A – 6」相同
- 與「伺服器 A – 7」相同
- 與「伺服器 A – 8」相同
- 設置需要同步的主(Master)節點資料庫
mysql> change master to -> master_host='192.168.1.11', -> master_user='replication', -> master_password='password';
- 啓動開始進行同步
start slave;
步驟三:
兩台伺服器已經設置完,可以進行測試
- 使用root用戶登入伺服器 A的MySQL
- MySQL新增一個exampledb資料庫和test資料表
mysql> create database exampledb; mysql> use exampledb; mysql> create table test (number int);
- 在伺服器 A上的資料表test新增一筆記錄
mysql> insert into test values (1);
- 使用root用戶登入伺服器 B的MySQL
- 在伺服器 B上的查詢資料表test
mysql> select * from test;
- 如果查詢到結果如下代表設置成功
+--------+ | number | +--------+ | 1 | +--------+
鏈結到這頁!
Matser
show master status;
slave
CHANGE MASTER TO
MASTER_LOG_FILE=’xxx’,
MASTER_LOG_POS=xxx;
您好,我照了上面方法做後
第二台slave機器,進入 mydql -u root -p
之後下 select * from test; 指令
會報錯:ERROR 1046 (3D000): No database selected
請問是因為什麼原因嗎?
目前查看
Slave_IO_Running: Connecting
Slave_SQL_Running: Yes
你好,
我想你是因為沒有執行「use exampledb;」選取資料庫操作,所以報錯訊息為No database selected,告訴你沒有選取到資料庫。
目前因為我只有一台主機,因此皆安裝於同一台,指利用不同的port來區分。
主的為3306,從的為3307,我自主的資料庫下create,insert在從的皆會立即複製完成。
但是我要在從的資料庫下insert 資料,該資料庫竟然會讓我輸入,但是主的資料會造成不一致。
請問是哪裡有問題?
你好,
請問你想實現「主從」或是「主主」架構呢?按照你的說法,你應該是希望兩個資料庫都可以insert操作,兩個資料庫互相同步,這種情況應該屬於「主主」架構,你可以參閱另一篇文章來設置。
https://blog.vvtitan.com/2018/04/mysql-5-7-master-master-replication-%e4%b8%bb%e4%b8%bb%e8%a4%87%e8%a3%bd-%e5%ae%89%e8%a3%9d%e8%88%87%e8%a8%ad%e7%bd%ae/
如果你是想實現「主從」架構,不應該在從資料庫執行insert操作,這樣會導致無法同步的情況。
感謝您的回答,我想施作「主從」架構,但要如何防止從的資料庫內做insert的動作,所以才會做這個測試。謝謝!!
如果不讓從的資料庫做insert的動作,有很多種方式,例如在存取權限上不允許寫入操作,而程式碼上亦控制不會指向從資料庫作insert操作。