開發人員學Linux(6):CentOS7編譯安裝MySQL5.17.8多實例及主從複製

1.前言
上一篇講述瞭如何在CentOS7下編譯安裝Nginx-1.12.0並如何配置反向代理,本篇將講述如何編譯安裝MySQL5.7.18並配置多實例。
2.準備
2.1下載MySQL5.7.18源碼
注意最新版本的MySQL需要Boost才能編譯安裝,在MySQL提供的下載中有不帶boost的源碼,還有帶boost的源碼,如果下載不帶boost的源碼還需要再去下載boost源碼,爲省事起見,建議下載帶boost的源碼,下載地址:https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-boost-5.7.18.tar.gz (可直接使用wget下載)
注:可以打開網頁來下載,網頁地址爲:https://dev.mysql.com/downloads/mysql/,當前最新版本爲5.7.18,在“Select Operating System:”處選擇“Source Code”,然後在圖中選擇“Generic Linux (Architecture Independent), Compressed TAR Archive Includes Boost Headers 5.7.18 58.8M (mysql-boost-5.7.18.tar.gz)”,如下圖所示:

wKiom1k9VIrCGCVTAAIJkrL6OUE334.png-wh_50

wKiom1k9VIyz_Sh0AAH6-nz1kjk478.png-wh_50
 
2.2安裝epel
EPEL的全稱叫 Extra Packages for Enterprise linux 。EPEL是由 Fedora 社區打造,爲 RHEL 及衍生髮行版如 CentOS、Scientific Linux 等提供高質量軟件包的項目。裝上了 EPEL之後,就相當於添加了一個第三方源。
在編譯MySQL過程中需要一些依賴插件,安裝epel後可直接通過yum install 來安裝。
執行命令:

yum install epel-release –y

2.3安裝cmake
不同於nginx使用make來編譯和安裝,MySQL使用CMake來編譯和安裝,安裝命令:

yum install cmake –y


爲將來方便還可以把相關的也一併安裝了:

yum install autoconf automake libtool


2.4安裝可能依賴庫

yum install -y krb5 krb5-devel libidn libidn-devel openssl openssl-devel -y
yum install libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devdel -y
yum install zlib zlib-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel -y
yum install ncurses ncurses-devel curl curl-devel e2fsprogs e2fsprogs-devel -y
yum install perl-Data_dumper python-devel -y

3.編譯及安裝
3.1解壓文件
假定mysql-boost-5.7.18.tar.gz文件位於/root/目錄下(不管是通過wget直接下載的還是通過下載工具上傳的),首先解壓文件:

tar zxvf /root/mysql-boost-5.7.18.tar.gz
cd /root/mysql-5.7.18

3.2配置、編譯及安裝
首先進行參數配置,命令如下:

cmake \
-DWITH_BOOST=boost \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql-5.7.18 \
-DMYSQL_DATADIR=/usr/local/mysql-5.7.18/data \
-DWITH_MYISAM_STORAGE_ENGINE=1 \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_FEDERATED_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITH_EXAMPLE_STORAGE_ENGINE=1 \
-DWITH_PARTITION_STORAGE_ENGINE=1 \
-DWITH_MEMORY_STORAGE_ENGINE=1 \
-DWITH_READLINE=1 \
-DENABLED_LOCAL_INFILE=1 \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DEXTRA_CHARSETS=gbk,gb2312,utf8,ascii \
-DMYSQL_USER=mysql \
-DWITH_ZLIB=bundled \
-DWITH_READLINE=1 \
-DWITH_FAST_MUTEXES=1 \
-DWITH_EMBEDDED_SERVER=1 \
-DWITH_DEBUG=0 \
-DWITH_SSL=system

這裏要說明幾點:
(1)當命令或參數過長時,爲了便於直觀顯示,可以在其後加上”\”,當然”\”與正常命令之間需要有空格;
(2) -DWITH_BOOST=boost 指定boost類庫的位置;
(3) -DCMAKE_INSTALL_PREFIX=/usr/local/mysql-5.7.18 指定安裝位置;
在上述配置過程中可能會有出錯信息,根據出錯信息調整響應參數或者安裝缺失的類庫,直到提示可以安裝爲止。
然後執行make進行編譯,編譯過程中沒有錯誤的再執行make install安裝,由於源代碼體積有點大,編譯耗費的時間比較長,在本人2G內存、4核的虛擬機上編譯時間超過半小時以上。
安裝成功之後,在/usr/local/mysql-5.7.18下就是安裝後的文件目錄。

4.數據庫初始化
4.1創建my.cnf文件
my.cnf文件是MySQL的配置文件,在MySQL啓動過程中會讀取裏面的配置信息。
在本篇中不滿足於單實例的配置,本篇將利用3306和3307兩個端口創建兩個實例。
首先創建文件夾:

mkdir –p /usr/local/mysql-5.7.18/data/3306/data
mkdir –p /usr/local/mysql-5.7.18/data/3307/data

/usr/local/mysql-5.7.18/data/3306文件夾用於存放監聽3306端口實例的相關配置信息、執行腳本和數據,/usr/local/mysql-5.7.18/data/3307文件夾用於存放監聽3307端口實例的相關配置信息、執行腳本和數據。
因爲mysql數據庫將以nginx這個用戶來運行,因此首先需要創建這個賬戶:

useradd mysql -s /sbin/nologin –M


分別在/usr/local/mysql-5.7.18/data/3306和/usr/local/mysql-5.7.18/data/3307創建my.cnf文件,可以使用vim創建並粘貼內容。
/usr/local/mysql-5.7.18/data/3306/my.cnf的內容:

[client]
port        = 3306
socket        = /usr/local/mysql-5.7.18/data/3306/mysql.sock
[mysqld_safe]
log-error        = /usr/local/mysql-5.7.18/data/3306/mysql.err
pid-file        = /usr/local/mysql-5.7.18/data/3306/mysql.pid
[mysqld]
#
# * Basic Settings
#
server-id   = 1
log-bin= /usr/local/mysql-5.7.18/data/3306/mysql-bin
user        = mysql
pid-file    = /usr/local/mysql-5.7.18/data/3306/mysql.pid
socket        = /usr/local/mysql-5.7.18/data/3306/mysql.sock
port        = 3306
basedir        = /usr/local/mysql-5.7.18
datadir        = /usr/local/mysql-5.7.18/data/3306/data
tmpdir        = /tmp
open_files_limit=1024
external-locking = false
character-set-server=utf8
default-storage-engine=MyISAM
bind-address        = 0.0.0.0
max_allowed_packet    = 8M
thread_stack        = 192K
thread_cache_size       = 8
max_connections        = 800
max_connect_errors    = 300
#table_cache            = 64
#thread_concurrency     = 10
query_cache_limit    = 1M
query_cache_size        = 2M
join_buffer_size=1M
sort_buffer_size=1M
long_query_time = 1
relay-log = /usr/local/mysql-5.7.18/data/3306/relay-bin
relay-log-info-file =/usr/local/mysql-5.7.18/data/3306/relay-log.info
binlog_cache_size = 1M
max_binlog_cache_size = 1M
max_binlog_size = 2M
key_buffer_size=16M
read_buffer_size = 1M
read_rnd_buffer_size = 1M
bulk_insert_buffer_size = 1M
lower_case_table_names = 1
skip-name-resolve
slave-skip-errors =1032,1062
replicate-ignore-db = mysql
#innodb_additional_mem_pool_size = 4M
innodb_buffer_pool_size = 32M
innodb_data_file_path = ibdata1:12M:autoextend
#innodb_file_io_threads = 4
innodb_thread_concurrency = 8
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 2M
innodb_log_file_size = 4M
#innodb_log_files_in_groups = 3
innodb_max_dirty_pages_pct = 90
innodb_lock_wait_timeout = 120
innodb_file_per_table = 0
[mysqldump]
quick
quote-names
max_allowed_packet    = 16M

/usr/local/mysql-5.7.18/data/3307/my.cnf的內容:

[client]
port        = 3307
socket        = /usr/local/mysql-5.7.18/data/3307/mysql.sock
[mysqld_safe]
log-error        = /usr/local/mysql-5.7.18/data/3307/mysql.err
pid-file        = /usr/local/mysql-5.7.18/data/3307/mysql.pid
[mysqld]
#
# * Basic Settings
#
server-id   = 2
user        = mysql
pid-file    = /usr/local/mysql-5.7.18/data/3307/mysql.pid
socket        = /usr/local/mysql-5.7.18/data/3307/mysql.sock
port        = 3307
basedir        = /usr/local/mysql-5.7.18
datadir        = /usr/local/mysql-5.7.18/data/3307/data
tmpdir        = /tmp
open_files_limit=1024
external-locking = false
character-set-server=utf8
default-storage-engine=MyISAM
bind-address        = 0.0.0.0
max_allowed_packet    = 8M
thread_stack        = 192K
thread_cache_size       = 8
max_connections        = 800
max_connect_errors    = 300
#table_cache            = 64
#thread_concurrency     = 10
query_cache_limit    = 1M
query_cache_size        = 2M
join_buffer_size=1M
sort_buffer_size=1M
long_query_time = 1
relay-log = /usr/local/mysql-5.7.18/data/3307/relay-bin
relay-log-info-file =/usr/local/mysql-5.7.18/data/3307/relay-log.info
binlog_cache_size = 1M
max_binlog_cache_size = 1M
max_binlog_size = 2M
key_buffer_size=16M
read_buffer_size = 1M
read_rnd_buffer_size = 1M
bulk_insert_buffer_size = 1M
lower_case_table_names = 1
skip-name-resolve
slave-skip-errors =1032,1062
replicate-ignore-db = mysql
#innodb_additional_mem_pool_size = 4M
innodb_buffer_pool_size = 32M
innodb_data_file_path = ibdata1:12M:autoextend
#innodb_file_io_threads = 4
innodb_thread_concurrency = 8
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 2M
innodb_log_file_size = 4M
#innodb_log_files_in_groups = 3
innodb_max_dirty_pages_pct = 90
innodb_lock_wait_timeout = 120
innodb_file_per_table = 0
[mysqldump]
quick
quote-names
max_allowed_packet    = 16M

注:在3306及3307配置中都提到了mysql.err這個文件,這個文件是用來記錄MySQL啓動過程的錯誤信息的,不過悲催的是如果這個文件不存在,那麼是會啓動出錯的,可又沒有地方可以查看錯誤,因此需要提前創建好文件並設置權限。

touch /usr/local/mysql-5.7.18/data/3306/mysql.err
touch /usr/local/mysql-5.7.18/data/3307/mysql.err
chmod 766 /usr/local/mysql-5.7.18/data/3306/mysql.err
chmod 766 /usr/local/mysql-5.7.18/data/3307/mysql.err

注:如果嫌每次輸入完整的文件路徑麻煩可以切換到程序的安裝目錄,甚至還可以創建軟鏈接,所謂的軟鏈接有點類似於Windows下的快捷方式,如ln –s /usr/local/mysql-5.7.18 /usr/local/mysql就是創建了mysql-5.7.18的軟鏈接,甚至如果你喜歡,還可以在用戶根目錄下創建軟鏈接,如:ln –s /usr/local/mysql-5.7.18 /root /mysql。
通過命令查看,如下圖所示是在SSH客戶端中的效果:
wKiom1k9VU-A87sxAAB4fOhGxo0207.png-wh_50 
上面mysql,nginx及tomcat都是創建的軟鏈接(文件屬性的第一個字符是”l”表明是軟鏈接),其對應的真實路徑分別爲當前路徑下的mysql-5.7.18、nginx-1.12.0及apache-tomcat-8.5.15目錄。
4.2創建MySQL的啓動文件
分別在/usr/local/mysql-5.7.18/data/3306和/usr/local/mysql-5.7.18/data/3307創建mysql文件。可用vim來創建文件,這個文件是用來啓動MySQL實例的,所以在創建完成不要忘記chmod 755設置。
/usr/local/mysql-5.7.18/data/3306/mysql

#!/bin/sh
port=3306
mysql_user="root"
mysql_pwd="mypassword"
cmd_path="/usr/local/mysql-5.7.18/bin"
mysql_sock="/usr/local/mysql-5.7.18/data/${port}/mysql.sock"
#startup function
function_start_mysql()
{
    if [ ! -e "$mysql_sock" ];then
      printf "Starting MySQL...\n"
      /bin/sh ${cmd_path}/mysqld_safe --defaults-file=/usr/local/mysql-5.7.18/data/${port}/my.cnf 2>&1 > /dev/null &
    else
      printf "MySQL is running...\n"
      exit
    fi
}
#stop function
function_stop_mysql()
{
    if [ ! -e "$mysql_sock" ];then
       printf "MySQL is stopped...\n"
       exit
    else
       printf "Stoping MySQL...\n"
       ${cmd_path}/mysqladmin -u ${mysql_user} -p${mysql_pwd} -S /usr/local/mysql-5.7.18/data/${port}/mysql.sock shutdown
   fi
}
#restart function
function_restart_mysql()
{
    printf "Restarting MySQL...\n"
    function_stop_mysql
    sleep 2
    function_start_mysql
}
case $1 in
start)
    function_start_mysql
;;
stop)
    function_stop_mysql
;;
restart)
    function_restart_mysql
;;
*)
    printf "Usage: /usr/local/mysql-5.7.18/data/${port}/mysql {start|stop|restart}\n"
esac

/usr/local/mysql-5.7.18/data/3307/mysql文件內容:

#!/bin/sh
port=3307
mysql_user="root"
mysql_pwd="mypassword"
cmd_path="/usr/local/mysql-5.7.18/bin"
mysql_sock="/usr/local/mysql-5.7.18/data/${port}/mysql.sock"
#startup function
function_start_mysql()
{
    if [ ! -e "$mysql_sock" ];then
      printf "Starting MySQL...\n"
      /bin/sh ${cmd_path}/mysqld_safe --defaults-file=/usr/local/mysql-5.7.18/data/${port}/my.cnf 2>&1 > /dev/null &
    else
      printf "MySQL is running...\n"
      exit
    fi
}
#stop function
function_stop_mysql()
{
    if [ ! -e "$mysql_sock" ];then
       printf "MySQL is stopped...\n"
       exit
    else
       printf "Stoping MySQL...\n"
       ${cmd_path}/mysqladmin -u ${mysql_user} -p${mysql_pwd} -S /usr/local/mysql-5.7.18/data/${port}/mysql.sock shutdown
   fi
}
#restart function
function_restart_mysql()
{
    printf "Restarting MySQL...\n"
    function_stop_mysql
    sleep 2
    function_start_mysql
}
case $1 in
start)
    function_start_mysql
;;
stop)
    function_stop_mysql
;;
restart)
    function_restart_mysql
;;
*)
    printf "Usage: /usr/local/mysql-5.7.18/data/${port}/mysql {start|stop|restart}\n"
esac

注意:
上述啓動文件中關閉實例沒有采用kill進程的辦法,而是使用mysqladmin shutdown的方法,這個方法需要root級別用戶的賬號和密碼,因此需要控制這個文件的查看和編輯權限。
需要給兩個文件設置執行權限。

chmod 755 /usr/local/mysql-5.7.18/data/3306/mysql
chmod 755 /usr/local/mysql-5.7.18/data/3307/mysql

此外,因爲MySQL的兩個實例均以MySQL用戶運行,爲保證有足夠的權限,設置/usr/local/mysql-5.7.18/文件夾的用戶和用戶組屬性:

chown –R mysql:mysql /usr/local/mysql-5.7.18


4.3執行初始化
網上有很多例子講解MySQL初始化都是利用MySQL安裝目錄下的bin目錄中的mysql_install_db來執行,但是這個官方不建議的,官方建議使用mysqld來初始化。
下面的腳本可以執行但不建議使用(且本人發現執行後不知道root用戶默認密碼):

/usr/local/mysql-5.7.18/bin/mysql_install_db \
--basedir=/usr/local/mysql-5.7.18 \
--datadir=/usr/local/mysql-5.7.18/data/3306/data \
--user=mysql
/usr/local/mysql-5.7.18/bin/mysql_install_db \
--basedir=/usr/local/mysql-5.7.18 \
--datadir=/usr/local/mysql-5.7.18/data/3307/data \
--user=mysql

下面的腳本是官方建議的:

/usr/local/mysql-5.7.18/bin/mysqld --initialize \
--basedir=/usr/local/mysql-5.7.18 \
--datadir=/usr/local/mysql-5.7.18/data/3306/data \
--user=mysql
/usr/local/mysql-5.7.18/bin/mysqld --initialize \
--basedir=/usr/local/mysql-5.7.18 \
--datadir=/usr/local/mysql-5.7.18/data/3307/data \
--user=mysql

上面的腳本如果執行成功,最後一句裏有root用戶的初始密碼,在本人執行上述兩條命令時得到結果如下:
wKiom1k9VZyTZl_xAAFK0GH521E708.png-wh_50 
其中關鍵的兩句(每個實例初始化都有類似一句):

2017-06-09T13:45:09.590690Z 1 [Note] A temporary password is generated for root@localhost: Gdl<nv>R7&+w
2017-06-09T13:46:48.721250Z 1 [Note] A temporary password is generated for root@localhost: Z>B#5IfIFAfj

上述密碼是隨機的,請記住一會登錄系統後更改臨時密碼。
4.4啓動MySQL實例和登錄
4.4.1啓動實例
啓動3306端口實例:

/usr/local/mysql-5.7.18/data/3306/mysql start


啓動3307端口實例;

/usr/local/mysql-5.7.18/data/3307/mysql start


這是可以查看實例是否啓動成功,如果啓動成功相應的端口就會處於監聽狀態。

[root@localhost ~]# /usr/local/mysql-5.7.18/data/3306/mysql start
Starting MySQL...
[root@localhost ~]# /usr/local/mysql-5.7.18/data/3307/mysql start
Starting MySQL...
[root@localhost ~]# netstat -lntp | grep 330
tcp        0      0 0.0.0.0:3307            0.0.0.0:*               LISTEN      4480/mysqld         
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      3817/mysqld

     
從執行結果來看,3306和3307兩個端口對應的MySQL實例均已啓動。
如果啓動不成功,可以通過相應的錯誤日誌來排除錯誤,如下就是用tail來查看錯誤日誌:

[root@localhost ~]# tail /usr/local/mysql-5.7.18/data/3306/mysql.err
2017-06-10T14:41:51.366238Z 0 [Warning] 'db' entry 'sys mysql.sys@localhost' ignored in --skip-name-resolve mode.
2017-06-10T14:41:51.366625Z 0 [Warning] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode.
2017-06-10T14:41:51.371787Z 0 [Warning] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode.
2017-06-10T14:41:51.416687Z 0 [Note] Event Scheduler: Loaded 0 events
2017-06-10T14:41:51.416855Z 0 [Note] /usr/local/mysql-5.7.18/bin/mysqld: ready for connections.
Version: '5.7.18-log'  socket: '/usr/local/mysql-5.7.18/data/3306/mysql.sock'  port: 3306  Source distribution
2017-06-10T14:41:51.416862Z 0 [Note] Executing 'SELECT * FROM INFORMATION_SCHEMA.TABLES;' to get a list of tables using the deprecated partition engine. You may use the startup option '--disable-partition-engine-check' to skip this check. 
2017-06-10T14:41:51.416864Z 0 [Note] Beginning of list of non-natively partitioned tables
2017-06-10T14:41:51.473660Z 0 [Note] End of list of non-natively partitioned tables
2017-06-10T14:42:07.539386Z 3 [Note] Start binlog_dump to master_thread_id(3) slave_server(2), pos(mysql-bin.000001, 2654)

4.4.2登錄實例
如果是單實例可以通過mysql –u user –p來登錄,但這裏有了兩個實例,所以登錄方式有些區別。
登錄到3306端口對應的實例:

cd /usr/local/mysql-5.7.18
./bin/mysql -u root -p -S ./data/3306/mysql.sock

登錄到3307端口對應的實例:

cd /usr/local/mysql-5.7.18
./bin/mysql -u root -p -S ./data/3307/mysql.sock

以下是登錄3306實例的過程:

[root@localhost ~]# cd /usr/local/mysql-5.7.18
[root@localhost mysql-5.7.18]# ./bin/mysql -u root -p -S ./data/3306/mysql.sock
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.18

在此過程中需要輸入root的密碼,root的密碼在初始化階段時系統隨機生成了,可見“執行初始化”一節中描述:

2017-06-09T13:45:09.590690Z 1 [Note] A temporary password is generated for root@localhost: Gdl<nv>R7&+w
2017-06-09T13:46:48.721250Z 1 [Note] A temporary password is generated for root@localhost: Z>B#5IfIFAfj

其中Gdl<nv>R7&+w和Z>B#5IfIFAfj分別是3306和3307實例對應的隨機密碼,初次登錄過程中需要輸入。

登錄成功後,如果再執行其它語句時會得到如下提示:

ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.


因爲我們沒有改系統爲root賬戶生成的隨機密碼,在此之前是不能進行任何操作的,可以通過如下命令更改:

mysql> SET PASSWORD = PASSWORD('your_password'); 
Query OK, 0 rows affected (0.03 sec)

在實際執行過程中請將your_password更改爲自己的密碼。改完之後記得改3306和3307兩個啓動文件中的用戶密碼哦,否則stop命令不會生效的。
至此,MySQL數據庫已完成初始化和初步配置。在實際過程中由於root用戶的權限過大、且默認情況下只能在服務器上登錄,爲了安全一般會創建其它較小權限的用戶,在這裏爲了演示方便省卻了這個操作。
5.設置MySQL主從同步
主從同步,也稱master-slave,是開發過程中常見的提高程序性能的辦法。通常情況下在主數據庫服務器寫入數據,查詢數據的時候是在從服務器,主從服務器之間通過同步機制來保持一致,雖然主從數據庫的一致性是存在一定時間差的,但因爲這個時間差很小所以在一些對時間不是非常敏感的業務場景下被認爲是實時一致的。在大多數主流數據庫中都是可以通過配置來實現主從同步、讀寫分離的。
這裏就以剛剛配置起來的兩個數據實例來演示如何實現主從同步的,步驟有如下:
(1)主數據庫實例設置server-id和開啓bin-log;
(2)主數據庫實例創建用於同步的賬號;
(3)從數據庫實例設置server-id;
(4)從數據庫實例配置同步參數;
(5)從數據庫實例啓動同步開關。
5.1主數據庫實例設置server-id和開啓bin-log
其實在上面的3306的配置文件裏已經配置了server-id和bin-log,就在/usr/local/mysql-5.7.18/data/3306/my.cnf文件的[mysqld]節點處:

[mysqld]
#
# * Basic Settings
#
server-id   = 1
log-bin= /usr/local/mysql-5.7.18/data/3306/mysql-bin

另外還需要注意的是在這個my.cnf配置文件中還有一句:

replicate-ignore-db = mysql


它的意思是在進行主從同步時忽略mysql這個庫,因爲mysql庫主要存放賬號及授權信息的,不同數據庫實例賬號和授權信息不同的可能性極大,因此沒有必要同步這個庫。
通過如下命令可以快速查看是否已經正確配置:

[root@localhost ~]# egrep "server-id|log-bin" /usr/local/mysql-5.7.18/data/3306/my.cnf
server-id   = 1
log-bin         = /usr/local/mysql-5.7.18/data/3306/mysql-bin

在數據庫中也可以查看:

mysql> show variables like "server_id";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 1     |
+---------------+-------+
1 row in set (0.00 sec)
mysql> show variables like "log_bin";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | ON    |
+---------------+-------+
1 row in set (0.00 sec)

同時,這裏也查看一下主數據庫的狀態:

mysql> show master status \G;
*************************** 1. row ***************************
             File: mysql-bin.000003
         Position: 154
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: 
1 row in set (0.00 sec)
ERROR: 
No query specified

這裏:File和Position的值是兩個很重要的參數,這是從數據庫下次同步時的起始位置。
5.2主數據庫實例創建用於同步的賬號
在主數據庫創建一個replication賬號用於從主庫同步數據到從庫,創建replication賬號的語句如下:
grant replication slave on *.* to 'replication'@'%' identified by 'your_password';flush privileges;
在實際執行時請將your_password改爲自己的密碼,執行這個SQL語句後就會在mysql庫中的user表中創建一個名爲replication的用戶,可以通過SQL語句查看:

mysql> show grants for "replication"@"%";
+-----------------------------------------------------+
| Grants for replication@%                            |
+-----------------------------------------------------+
| GRANT REPLICATION SLAVE ON *.* TO 'replication'@'%' |
+-----------------------------------------------------+
1 row in set (0.00 sec)

5.3從數據庫實例設置server-id
同樣,其實在上面的3307的配置文件裏已經配置了server-id和bin-log,就在/usr/local/mysql-5.7.18/data/3307/my.cnf文件的[mysqld]節點處:

[mysqld]
#
# * Basic Settings
#
server-id   = 2

注意:在一個主從關係羣中server-id是唯一的,另外在由於從數據庫不向其它庫同步數據,因此沒有開啓bin-log。這裏也通過egrep查看一下:

[root@localhost ~]# egrep "server-id|log-bin" /usr/local/mysql-5.7.18/data/3307/my.cnf
server-id   = 1

5.4從數據庫實例配置同步參數
登錄3307端口對應的實例:

cd /usr/local/mysql-5.7.18
./bin/mysql -S ./data/3307/mysql.sock

然後執行以下語句:

CHANGE MASTER TO \
MASTER_HOST='127.0.0.1', \
MASTER_PORT=3306, \
MASTER_USER='replication', \
MASTER_PASSWORD='your_password', \
MASTER_LOG_FILE='mysql-bin.000003', \
MASTER_LOG_POS=154;

說明:
MASTER_HOST爲主服務器IP或主機名;
MASTER_PORT爲主服務器端口;
MASTER_USER爲主服務器上用於同步的數據庫賬戶名;
MASTER_PASSWORD爲主服務器上用於同步的數據庫賬戶對應的密碼;
MASTER_LOG_FILE爲當前bin-log日誌文件名;
MASTER_LOG_POS爲當前偏移量;
其中MASTER_LOG_FILE和MASTER_LOG_POS可以在主數據庫上執行” show master status \G;”SQL語句來獲得,見本文“主數據庫實例設置server-id和開啓bin-log”一節。
5.5從數據庫實例啓動同步開關
登錄從數據庫執行”start slave”即可。
在本篇中由於連個數據庫都是剛剛初始化的,所以數據都是一致的。在實際情況中,需要先將兩個數據庫實例中的除mysql庫之外的數據一致後纔可啓動同步,否則兩個庫中的就會不一致。
這裏我們來檢查一下效果:
在主庫中創建一個數據庫,如下:

mysql> create database zhoufoxcn;
Query OK, 1 row affected (0.00 sec)
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| zhoufoxcn          |
+--------------------+
5 rows in set (0.01 sec)

然後在從庫中查看數據庫的情況:

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| zhoufoxcn          |
+--------------------+
5 rows in set (0.00 sec)

可見主庫的數據被自動同步到從庫了,這時再在主庫中刪除zhoufoxcn這個庫,可以看到從庫中也自動刪掉了。

這時在主庫查看狀態:

mysql> show master status \G;
*************************** 1. row ***************************
             File: mysql-bin.000003
         Position: 488
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: 
1 row in set (0.00 sec)
ERROR: 
No query specified

在從庫查看狀態:

mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 127.0.0.1
                  Master_User: replication
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 488
               Relay_Log_File: relay-bin.000008
                Relay_Log_Pos: 701
        Relay_Master_Log_File: mysql-bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: mysql
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 488
              Relay_Log_Space: 1115
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: da584607-4d19-11e7-8903-080027f376f5
             Master_Info_File: /usr/local/mysql-5.7.18/data/3307/data/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
1 row in set (0.00 sec)
ERROR: 
No query specified

可以看出通過配置,兩臺數據庫能夠自動同步數據了。

6.總結
本篇主要講述瞭如何從MySQL官方網站下載源代碼通過編譯和安裝,然後配置成多個實例運行,在最後還講解了如何配置MySQL數據庫主從同步。在實際情況中,可能有人在用MariaDB了,這是原MySQL開發人員在Oracle收購了Sun之後(Sun收購了MySQL),擔心Oracle不再繼續開源MySQL而開發的一套開源數據系統,它們有很多相似性,在本篇沒有涉及。另外,本篇沒有涉及的還有通過mysqld_multi.server來設置將MySQL隨系統啓動。

聲明:本文首發於本人個人微信訂閱號:zhoujinqiaoIT,其後會同時在本人的CSDN、51CTO及oschina三處博客發佈,本人會負責在此四處答疑。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章