一,Mysql複製概述mysql
Mysql內建的複製功能是構建大型,高性能應用程序的基礎。將Mysql的數據分佈到多個系統上去,這種分佈的機制,是經過將Mysql的某一臺主機的數據複製到其它主機(slaves)上,並從新執行一遍來實現的。複製過程當中一個服務器充當主服務器,而一個或多個其它服務器充當從服務器。主服務器將更新寫入二進制日誌文件,並維護文件的一個索引以跟蹤日誌循環。這些日誌能夠記錄發送到從服務器的更新。當一個從服務器鏈接主服務器時,它通知主服務器從服務器在日誌中讀取的最後一次成功更新的位置。從服務器接收從那時起發生的任何更新,而後封鎖並等待主服務器通知新的更新。linux
1.複製能解決的問題sql
數據分佈(多個地區的數據分發)bash
負載均衡(讀寫分離)服務器
備份session
高可用和故障切換的核心功能架構
測試mysql升級負載均衡
2.複製的原理異步
mysql複製的原理現階段都是同樣的,master將操做記錄到bin-log中,slave的一個線程去master讀取bin-log,並將他們保存到relay-log中,slave的另一個線程去重放relay-log中的操做來實現和master數據同步。ide
3.複製的歷史
mysql-3.2 開始支持基於命令的複製,也就是statement-based replication。mysql-5.1 開始支持基於行的複製和混合複製,也就是row-based replication和mixed-based relication,mysql-5.5 開始支持semi-synchronous的複製,也叫半同步複製,目的在於事務環境下保持主從一致,mysql-5.6 開始支持延時複製。
下面是複製的基本原理:
二,配置主從複製
爲了演示方便,實驗使用通用的二進制包來安裝mysql:
mysql版本:mysql-5.5.33-linux2.6-x86_64
OS版本:Centos 6.4 x86:64
首先來安裝master服務器
[root@localhost ~]# useradd -r -u 120 mysql [root@localhost ~]# tar zxvf mysql-5.5.33-linux2.6-x86_64.tar.gz -C /usr/local/ [root@localhost local]# ln -s mysql-5.5.33-linux2.6-x86_64 mysql [root@localhost local]# cd mysql [root@localhost mysql]# mkdir /mydata/data -p [root@localhost mysql]# chown -R root.mysql ./* [root@localhost mysql]# ./scripts/mysql_install_db --user=mysql --datadir=/mydata/data [root@localhost mysql]# cp support-files/my-large.cnf /etc/my.cnf [root@localhost mysql]# cp support-files/mysql.server /etc/rc.d/init.d/mysqld [root@localhost mysql]# chmod +x /etc/init.d/mysqld [root@localhost mysql]# chkconfig --add mysqld [root@localhost mysql]# chkconfig mysqld on [root@localhost mysql]# vi /etc/my.cnf # 在mysqld中添加以下倆行 datadir=/mydata/data innodb_file_per_table=1 [root@localhost mysql]# service mysqld start Starting MySQL...... SUCCESS!
在從服務器上執行上面相同的操做
在master服務器上啓用二進制日誌,設置server-id(必須保證和從服務器不一樣)
[root@localhost mysql]# vi /etc/my.cnf log-bin = /mydata/data/master-bin log-bin-index = /mydata/data/master-bin.index server-id = 1
建立具體複製權限的用戶
[root@localhost ~]# mysql Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1 Server version: 5.5.33-log MySQL Community Server (GPL) Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> grant replication slave,replication client on *.* to 'repl'@'192.168.30.%' identified by '123456'; mysql> flush privileges; Query OK, 0 rows affected (0.00 sec) [root@localhost ~]# service mysqld restart Shutting down MySQL.. SUCCESS! Starting MySQL... SUCCESS!
登陸從服務器
[root@localhost mysql]# vi /etc/my.cnf # 開啓中繼日誌 relay-log=/mydata/data/relay-log relay-log-index=/mydata/data/relay-log.index server-id=2 # 關閉二進制日誌 #log-bin=mysql-bin [root@localhost ~]# service mysqld restart Shutting down MySQL. SUCCESS! Starting MySQL... SUCCESS!
鏈接至主服務器,並開始複製
# 查看主服務器正在使用的binlog和當前的position mysql> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000002 | 107 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec) # 在從服務器鏈接主服務器 mysql> change master to master_host='192.168.30.115' -> master_port=3306 -> master_log_file='mysql-bin.000002' -> master_user='repl' -> master_password='123456' -> master_log_pos=107; Query OK, 0 rows affected (0.49 sec) mysql> start slave; Query OK, 0 rows affected (0.00 sec) mysql> show slave status\G; *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.30.115 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000002 Read_Master_Log_Pos: 107 Relay_Log_File: relay-log.000002 Relay_Log_Pos: 253 Relay_Master_Log_File: mysql-bin.000002 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: 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: 107 Relay_Log_Space: 403 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 1 row in set (0.00 sec)
以上信息發現
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
說明主從服務器配置成功了。
三,配置半同步複製
登陸主服務器
# 加載半同步複製模塊 mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so'; Query OK, 0 rows affected (0.00 sec) # 開啓半同步複製功能 mysql> set global rpl_semi_sync_master_enabled=1; Query OK, 0 rows affected (0.00 sec) # 設置主服務器等待從服務器多長時間,開始轉爲異步複製 mysql> set global rpl_semi_sync_master_timeout=1000; Query OK, 0 rows affected (0.00 sec)
登陸從服務器
mysql> install plugin rpl_semi_sync_slave soname'semisync_slave.so'; Query OK, 0 rows affected (0.00 sec) mysql> set global rpl_semi_sync_slave_enabled=1; Query OK, 0 rows affected (0.00 sec) mysql> stop slave IO_THREAD; Query OK, 0 rows affected (0.07 sec) mysql> start slave IO_THREAD; Query OK, 0 rows affected (0.00 sec)
在Master和Slave的my.cnf中編輯
# On Master [mysqld] rpl_semi_sync_master_enabled=1 rpl_semi_sync_master_timeout=1000 # 1 second # On Slave [mysqld] rpl_semi_sync_slave_enabled=1
# 也可經過設置全局變量的方式來設置,以下: set global rpl_semi_sync_master_enabled=1 # 取消加載插件 mysql> UNINSTALL PLUGIN rpl_semi_sync_master;
查看從服務器上的semi_sync是否開啓:
mysql> show global status like 'rpl_semi%'; +--------------------------------------------+-------+ | Variable_name | Value | +--------------------------------------------+-------+ | Rpl_semi_sync_master_clients | 1 | | Rpl_semi_sync_master_net_avg_wait_time | 0 | | Rpl_semi_sync_master_net_wait_time | 0 | | Rpl_semi_sync_master_net_waits | 0 | | Rpl_semi_sync_master_no_times | 0 | | Rpl_semi_sync_master_no_tx | 0 | | Rpl_semi_sync_master_status | ON | | Rpl_semi_sync_master_timefunc_failures | 0 | | Rpl_semi_sync_master_tx_avg_wait_time | 0 | | Rpl_semi_sync_master_tx_wait_time | 0 | | Rpl_semi_sync_master_tx_waits | 0 | | Rpl_semi_sync_master_wait_pos_backtraverse | 0 | | Rpl_semi_sync_master_wait_sessions | 0 | | Rpl_semi_sync_master_yes_tx | 0 | +--------------------------------------------+-------+ 14 rows in set (0.00 sec) # 注意clients 變爲1 ,證實主從半同步複製鏈接成功
在主-從架構上,建議使用的配置:
主服務器:
sync_binlog=1 # 主服務器崩潰,任何一個事務提交以後就當即寫入到磁盤中的二進制文件
innodb_flush_logs_at_trx_commit=1 #任何一個事物提交以後就當即寫入到磁盤中的日誌文件
從服務器:
skip_slave_start=1 #重啓從服務器時不自動開啓slave進程
read_only=1 #設置從服務器爲只讀模式
四,配置基於SSL主從複製
配置Master爲CA服務器
[root@localhost ~]# cd /etc/pki/CA [root@localhost CA]# (umask 077;openssl genrsa 2048 > private/cakey.pem) [root@localhost CA]# openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 3650 [root@localhost CA]# mkdir certs crl newcerts [root@localhost CA]# touch index.txt [root@localhost CA]# echo 01 > serial
在主服務器上爲mysql準備私鑰和證書
[root@localhost ~]# mkdir /usr/local/mysql/ssl [root@localhost ~]# cd /usr/local/mysql/ssl/ [root@localhost ssl]# (umask 077;openssl genrsa 1024 > mysql.key) # 這裏生成的證書請求要去CA的一致 [root@localhost ssl]# openssl req -new -key mysql.key -out mysql.csr [root@localhost ssl]# openssl ca -in mysql.csr -out mysql.crt [root@localhost ssl]# cp /etc/pki/CA/cacert.pem /usr/local/mysql/ssl/ [root@localhost ssl]# chown -R mysql.mysql /usr/local/mysql/ssl/
在從服務器上:
[root@localhost ~]# mkdir /usr/local/mysql/ssl [root@localhost ~]# chown -R mysql.mysql /usr/loca/mysql/ssl [root@localhost ~]# cd /usr/local/mysql/ssl/ [root@localhost ssl]# (umask 077;openssl genrsa 1024 > mysql.key) # 這裏填寫也要與CA一致 root@localhost ssl]# openssl req -new -key mysql.key -out mysql.csr # 把證書申請傳到CA服務器上 [root@localhost ssl]# scp mysql.csr root@192.168.30.115:/root/
在master爲slave簽署證書
[root@localhost ~]# openssl ca -in mysql.csr -out mysql.crt [root@localhost ~]# scp ./mysql.crt root@192.168.30.116:/usr/local/mysql/ssl [root@localhost ~]# scp /etc/pki/CA/cacert.pem root@192.168.30.116:/usr/local/mysql/ssl/ #在從服務器,設置ssl屬主屬組爲mysql [root@localhost ~]# chown -R mysql.mysql /usr/local/mysql/ssl/
在主從服務器上都開啓ssl功能:
[root@localhost ~]# vi /etc/my.cnf # 添加以下幾行 ssl ssl-ca=/usr/local/mysql/ssl/cacert.pem ssl-cert=/usr/local/mysql/ssl/mysql.crt ssl-key=/usr/local/mysql/ssl/mysql.key [root@localhost ~]# service mysqld restart Shutting down MySQL. SUCCESS! Starting MySQL... SUCCESS! [root@localhost ssl]# mysql mysql> show variables like '%ssl%'; ERROR 2006 (HY000): MySQL server has gone away No connection. Trying to reconnect... Connection id: 3 Current database: *** NONE *** +---------------+---------------------------------+ | Variable_name | Value | +---------------+---------------------------------+ | have_openssl | YES | | have_ssl | YES | | ssl_ca | /usr/local/mysql/ssl/cacert.pem | | ssl_capath | | | ssl_cert | /usr/local/mysql/ssl/mysql.crt | | ssl_cipher | | | ssl_key | /usr/local/mysql/ssl/mysql.key | +---------------+---------------------------------+ 7 rows in set (0.00 sec)
以上信息顯示master服務器ssl功能已經開啓
在slave服務器執行上面一樣的操做,開啓ssl功能
在master服務器刪除原來的複製帳號,添加新的複製帳號
mysql> delete from user where User='repl'; mysql> grant replication client,replication slave on *.* to 'sslrepl'@'192.168.30.%' identified by '123456' require ssl; mysql> flush privileges;
在slave服務器鏈接master
mysql> stop slave; mysql> change master to master_host='192.168.30.115' -> master_port=3306 -> master_log_file='mysql-bin.000005' -> master_user='sslrepl' -> master_password='123456' -> master_log_pos=107 -> master_ssl=1 -> master_ssl_ca='/usr/local/mysql/ssl/cacert.pem' -> master_ssl_cert='/usr/local/mysql/ssl/mysql.crt' -> master_ssl_key='/usr/local/mysql/ssl/mysql.key'; mysql> start slave; mysql> show slave status\G; *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.30.115 Master_User: sslrepl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000005 Read_Master_Log_Pos: 107 Relay_Log_File: relay-log.000002 Relay_Log_Pos: 253 Relay_Master_Log_File: mysql-bin.000005 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: 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: 107 Relay_Log_Space: 403 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: Yes Master_SSL_CA_File: /usr/local/mysql/ssl/cacert.pem Master_SSL_CA_Path: /usr/local/mysql/ssl Master_SSL_Cert: /usr/local/mysql/ssl/mysql.crt Master_SSL_Cipher: Master_SSL_Key: /usr/local/mysql/ssl/mysql.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 1 row in set (0.00 sec) Slave_IO_Running: Yes Slave_SQL_Running: Yes Master_SSL_Allowed: Yes 三個都輸出爲yes 才代表配置成功
五,在slave主機測試
[root@localhost ~]# mysql -u sslrepl -h 192.168.30.115 -p123456 --ssl-ca=/usr/local/mysql/ssl/cacert.pem --ssl-cert=/usr/local/mysql/ssl/mysql.crt --ssl-key=/usr/local/mysql/ssl/mysql.key mysql> \s -------------- mysql Ver 14.14 Distrib 5.1.66, for redhat-linux-gnu (x86_64) using readline 5.1 Connection id: 6 Current database: Current user: sslrepl@192.168.30.116 SSL: Cipher in use is DHE-RSA-AES256-SHA Current pager: stdout Using outfile: '' Using delimiter: ; Server version: 5.5.33-log MySQL Community Server (GPL) Protocol version: 10 Connection: 192.168.30.115 via TCP/IP Server characterset: latin1 Db characterset: latin1 Client characterset: latin1 Conn. characterset: latin1 TCP port: 3306 Uptime: 24 min 25 sec Threads: 2 Questions: 23 Slow queries: 0 Opens: 33 Flush tables: 1 Open tables: 26 Queries per second avg: 0.015
信息:SSL: Cipher in use is DHE-RSA-AES256-SHA 代表鏈接是加密的
Mysql-5.5.33主從複製,半同步複製,以及基於ssl的複製已經配置完成