在這一章節裡, 我們來了解下如何在 Mysql 中進行用戶授權及主從復制
這裡先來了解下 Mysql 主從復制的優點:
1、 如果主服務器出現問題, 可以快速切換到從服務器提供的服務
2、 可以在從服務器上執行查詢操作, 降低主服務器的訪問壓力
3、 可以在從服務器上執行備份, 以避免備份期間影響主服務器的服務
注意一般只有更新不頻繁的數據或者對實時性要求不高的數據可以通過從服務器查詢, 實時性要求高的數據仍然需要從主數據庫獲得
在這裡我們首先得完成用戶授權, 目的是為了給從服務器有足夠的權限來遠程登入到主服務器的 Mysql
在這裡我假設
主服務器的 IP 為: 192.168.10.1
從服務器的 IP 為: 192.168.10.2
Mysql grant 用戶授權
查看 Mysql 的用戶表
復制代碼 代碼如下:
msyql> mysql -uroot -p123123;
msyql> select user, host, password from mysql.user;
結果如下:
復制代碼 代碼如下:+------------------+-----------+-------------------------------------------+
| user | host | password |
+------------------+-----------+-------------------------------------------+
| root | localhost | *E56A114692FE0DE073F9A1DD68A00EEB9703F3F1 |
| root | 127.0.0.1 | *E56A114692FE0DE073F9A1DD68A00EEB9703F3F1 |
+------------------+-----------+-------------------------------------------+
從如上表中看以看出 root 用戶只能從本機登入 Mysql, 也就是來自 localhost 或者 127.0.0.1
現在來通過 grant 命令來添加授權用戶
復制代碼 代碼如下:
msyql> ? grant //查看 grant 的詳細用法
msyql> grant all on *.* to [email protected] identified by "123456"; // *.* = 所有的數據庫.所有的表
//或者
msyql> grant replication slave on *.* to 'user2'@'192.168.10.%' identified by "123456"; // %代表通配符
通過了 grant 命令給予了來自 192.168.10.2 的用戶 user1 權限, 允許其遠程登錄, 如下:
復制代碼 代碼如下:
+------------------+--------------+-------------------------------------------+
| user | host | password |
+------------------+--------------+-------------------------------------------+
| root | localhost | *E56A114692FE0DE073F9A1DD68A00EEB9703F3F1 |
| root | 127.0.0.1 | *E56A114692FE0DE073F9A1DD68A00EEB9703F3F1 |
| user1 | 192.168.10.2 | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
| user2 | 192.168.10.% | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
+------------------+--------------+-------------------------------------------+
此時就可以在 192.168.10.2 的機器上訪問 10.1 的 Mysql 了, 如下:
復制代碼 代碼如下:
msyql> mysql -uuser1 -p123456 -h192.168.10.1;
Mysql bin-log 日志
開啟 bin-log 二進制日志, 它保存了所有增刪改的操作, 以便於數據恢復或同步
修改主服務器 mysql 配置文件:
復制代碼 代碼如下:shawn@Shawn:~$ sudo vi /etc/mysql/my.cnf;
/********** my.cnf **********/
[mysqld]
#開啟慢查詢日志, 記錄查詢過長的 sql 語句,以便於優化
log_slow_queries = /var/log/mysql/mysql-slow.log
#開啟 bin-log 日志
log-bin = /var/log/msyql/mysql-bin.log
添加完成後重啟 Mysql 服務
復制代碼 代碼如下:
shawn@Shawn:~$ sudo /etc/init.d/mysql restart
現在你可以通過如下命令來查看 bin-log 日志是否成功開啟
復制代碼 代碼如下:
mysql> show variables like "%log_%";
| log_bin | ON |
| log_slow_queries | ON |
如果顯示為 ON, 那麼就可以在 /var/log/mysql/ 文件夾看到 mysql-bin.000001 二進制文件
關於 bin-log 日志的相關操作:
復制代碼 代碼如下:
mysql> flush logs;
此時就會多一個最新的 bin-log 日志
復制代碼 代碼如下:
mysql> show master status;
查看最後一個 bin-log 日志, 如下:
復制代碼 代碼如下:
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000002 | 107 | | |
+------------------+----------+--------------+------------------+
mysql> show master logs;
查看所有 bin-log 日志, 如下:
復制代碼 代碼如下:
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 4340 |
| mysql-bin.000002 | 107 |
+------------------+-----------+
mysql> reset master;
清空所有 bin-log 日志
復制代碼 代碼如下:
shawn@Shawn:~$ mysqlbinlog /var/log/mysql/mysql-bin.000001 | more
查看 bin-log 日志內容
復制代碼 代碼如下:
#如果有字符集問題的話可以執行:
shawn@Shawn:~$ mysqlbinlog --no-defaults /var/log/mysql/mysql-bin.000001
shawn@Shawn:~$ mysqlbinlog /var/log/mysql/mysql-bin.000002 | mysql -uroot -p123123 test;
恢復 mysql-bin.000002 中所有的操作到 test 數據庫中
shawn@Shawn:~$ mysqlbinlog /var/log/mysql/mysql-bin.000002 --start-position="193" --stop-position="398" | mysql -uroot -p123123 test;
恢復 mysql-bin.000002 中指定的操作(position)到 test 數據庫中
Mysql 主從復制 - 數據同步
到這一步的時候首先確保 Mysql 用戶授權已經完成以及 Mysql bin-log 日志已經成功開啟
並確保每台服務器的 server-id 是唯一的
再次修改主服務器(192.168.10.1)的 mysql 配置文件:
復制代碼 代碼如下:
shawn@Shawn:~$ sudo vi /etc/mysql/my.cnf;
/********** my.cnf **********/
#取消 server-id 注釋符號
server-id = 1
/****************************/
#重啟 Mysql 服務
shawn@Shawn:~$ sudo /etc/init.d/mysql restart
到這裡, 主服務器的配置已經完成, 很簡單
這次我們主要做的是讓從服務器同步主服務器的數據, 同步的是將來所有對主服務做的增刪改操作, 但是現有主服務器中的大量數據得先手動同步到從服務器, 操作如下:
復制代碼 代碼如下:
#清空一下主服務器的 bin-log 日志, (可選: 保險操作, 防止主從 bin-log 日志混亂)
mysql> reset master;
#然後備份導出主服務器中現有的 test 數據庫
shawn@Shawn:~$ mysqldump -uroot -p123123 test -l -F > /tmp/test.sql;
-F = flush logs, 生成新的日志文件, 包括 bin-log 日志
-l = lock 數據庫, 防止在導出的時候被寫入數據, 完成後自動解鎖
#完成後把文件傳輸給從服務器
shawn@Shawn:~$ scp /tmp/test.sql 192.168.10.2:/tmp/
#然後再查詢確保一下從服務器已經成功授過權
mysql> show grants for [email protected]\G
*************************** 1. row ***************************
Grants for [email protected]:
GRANT ALL PRIVILEGES ON *.* TO 'user1'@'192.168.10.2'
IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9'
完成後, 現在我們到從服務器 (192.168.10.2) 導入現有的數據:
復制代碼 代碼如下:
#清空一下從服務器的 bin-log 日志, (可選: 保險操作)
mysql> reset master;
#然後導入主服務器中現有的數據
shawn@Shawn:~$ mysqldump -uroot -p123123 test -v -f < /tmp/test.sql;
-v = 查看導入的詳細信息
-f = 是當中間遇到錯誤時, 可以 skip 過去, 繼續執行下面的語句
當然你也可以用 source 命令導入
好了, 目前為止主服務器(192.168.10.1)和從服務器(192.168.10.2)現有的數據已經成功手動同步
接下來修改從服務器(192.168.10.2)的 mysql 配置文件:
復制代碼 代碼如下:
shawn@Shawn:~$ sudo vi /etc/mysql/my.cnf;
/********** my.cnf **********/
#取消 server-id 注釋符號, 並修改值
server-id = 2
#取消 master-host 注釋符號, 並修改值
master-host = 192.168.10.1
#取消 master-user 注釋符號, 並修改值
master-user = user1
#取消 master-password 注釋符號, 並修改值
master-password = 123456
#取消 master-port 注釋符號, 並修改值, 主服務器默認端口號為: 3306
master-port = 3306
/****************************/
#重啟 Mysql 服務
shawn@Shawn:~$ sudo /etc/init.d/mysql restart
配置文件修改完成, 此時在從服務器中登入自己的 Mysql, 而不是遠程登入主服務器(192.168.10.1)
復制代碼 代碼如下:
#在從服務器中登入自身的 Mysql
msyql> mysql -uroot -p123123;
#查看是否已經取得同步
msyql> show slave status\G
*************************** 1. row ***************************
Connect_Retry: 60
Master_Log_FIle: mysql-bin.000002
Read_Master_Log_Pos: 106
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Slave_IO_Running 如果是 Yes 的話代表成功從主服務器中同步到 bin-log 日志
Slave_SQL_Running 如果是 Yes 的話代表成功執行 bin-log 日志中的 SQL 語句
此時的 Master_Log_FIle 和 Read_Master_Log_Pos 的值應該對應主服務器中的 show master status 命令的值
Connect_Retry 中的 60 代表每 60 秒就去主服務器同步 bin-log 日志
OK, 如果你看到的是那兩個關鍵的 Yes, 那你就可以去測試了, 在主服務器插入新的數據, 再去從服務器查看, 不出意外的話, 你會興奮一下, 數據已經同步了
這裡再說一下其他經常用到的命令:
復制代碼 代碼如下:
#啟動復制線程
msyql> start slave
#停止復制線程
msyql> stop slave
#動態改變到主服務器的配置
msyql> change master to
#查看從數據庫運行進程
msyql> show processlist
這裡也同時說一下操作中的常見錯誤:
問題: 從數據庫無法同步
Slave_SQL_Running 值為 NO, 或 Seconds_Bebind_Master 值為 Null
原因:
一、 程序有可能在 slave 上進行了寫操作
二、 也有可能是 slave 機器重啟後, 事務回滾造成的
解決方法一:
復制代碼 代碼如下:
msyql> stop slave;
msyql> set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
msyql> start slave;
解決方法二:
復制代碼 代碼如下:
msyql> stop slave;
#查看主服務器上當前的 bin-log 日志名和偏移量
msyql> show master status;
#獲取到如下內容:
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000005 | 286 | | |
+------------------+----------+--------------+------------------+
#然後到從服務器上執行手動同步
msyql> change master to
-> master_host="192.168.10.1"
-> master_user="user1"
-> master_password="123456"
-> master_post=3306
-> master_log_file="mysql-bin.000005"
-> master_log_pos=286;
msyql> start slave;
再次通過 show slave status 查看:
如果 Slave_SQL_Running 的值變為 Yes, Seconds_Bebind_Master 的值為 0 時, 即正常
好了, 如上是我自己在操作中所總結的一些內容, 如有更好的建議, 歡迎留言一起探討
順便說一下, 我使用的是 Ubuntu 12.04