1. 程式人生 > 實用技巧 >第6章:主從複製(多例項資料庫完成主從同步)

第6章:主從複製(多例項資料庫完成主從同步)

1.什麼是MySQL主從讀寫分離?

  主庫上的讀資料和寫資料分成了主庫上寫資料,從庫上讀資料,減輕了主庫的壓力。

2.MySQL主從同步其實是非同步同步,先 看看主從同步的原理。

簡單介紹一下這個圖,實現主從同步其實是由三個執行緒完成的  

  • 主庫和從庫進行對接需要的是Io執行緒
  • SQL執行緒主要是監控relay-log日誌,並執行其新增的日誌內容
  • bin-log dump執行緒主要是主管log-bin日誌

   1.slave請求與Master建立連線,請求報文中包括

    MASTER_HOST=’192.168.2.200’

    MASTER_USER=’rep’

    MASTER_PASSWORD=’rep’

    MASTER_LOG_FILE=’ mysql-bin.000014’

    MASTER_LOG_POS=333’

   2.主庫IO執行緒收到請求會將資訊傳送給bin-log dump 執行緒

   3.bin-log dump執行緒就會根據資訊將對應的log-bin日誌傳回給Master的IO執行緒,由Master的IO執行緒傳給salve 的IO執行緒。

   4.salve 中的IO執行緒就會將傳來的資訊寫入中繼日誌(relay-log)中.

   5.並且將節點寫入Master info檔案中作為記錄

   6.SQL監控著中繼日誌,只要有新資料,就會重新執行新加的SQL語句。

   7.SQL執行緒將資料寫入到從庫的資料檔案中。

安裝環境

  • [root@localhost ~]# yum install ncurses-devel -y
    [root@localhost ~]# yum install libaio-devel -y
    

安裝資料庫(這裡用cmake安裝MySQL5.5版本)

(https://www.cnblogs.com/hanjiali/p/13941511.html中有詳細MySQL部署過程,這裡就不作過多的介紹,直接操作)

相關資料包在

連結:https://pan.baidu.com/s/1yPYaLIB9M-k5c_U2yxaJ3A
提取碼:2vbi

  •    24  yum install ncurses-devel -y
       25  yum install libaio-devel -y
       26  mkdir /tools/
       27  cd /tools/
       28  rz
       29  yum install -y lrzsz
       30  rz
       31  tar xf cmake-2.8.6.tar.gz -C /usr/src/
       32  cd /usr/src/cmake-2.8.6/
       33   ./configure && gmake && gmake install
     
       
      
       37  cd /tools/
       38  tar xf mysql-5.5.22.tar.gz -C /usr/src/
       39  cd /usr/src/mysql-5.5.22/
       40  cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH_EXTRA_CHARSETS=all -DSYSCONFDIR=/etc && make && make install
       41  echo "PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile
       42   . /etc/profile
       43  /bin/cp -p /usr/src/mysql-5.5.22/support-files/my-medium.cnf /etc/my.cnf
       44  /bin/cp -p /usr/src/mysql-5.5.22/support-files/mysql.server /etc/init.d/mysqld
       45  chmod +x /etc/init.d/mysqld 
       46  chkconfig --add mysqld
       47  chkconfig mysqld on
       48  useradd -M -s /sbin/nologin mysql
       49  /usr/local/mysql/scripts/mysql_install_db  --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data/ --user=mysql
       50  /etc/init.d/mysqld start
       51  netstat -anptu|grep 3306
       52  mysqladmin -uroot  password "123123"

    [root@localhost ~]# groupadd mysql
    groupadd:“mysql”組已存在
    [root@localhost ~]# useradd -s /sbin/nologin -g mysql -M mysql
    useradd:使用者“mysql”已存在

    [root@localhost ~]# pkill mysqld
    [root@localhost ~]# ps -ef|grep mysql
    root 38106 18999 0 18:37 pts/0 00:00:00 grep --color=auto mysql

建立多例項的資料檔案目錄

  • [root@localhost ~]# mkdir -p /data/{3306,3307}/data
    [root@localhost ~]# tree /data
    /data
    ├── 3306
    │ └── data
    └── 3307
        └── data
    

指令碼配置檔案進行解壓

  • [root@localhost tools]# unzip data.zip 
    Archive:  data.zip
       creating: data/
       creating: data/3306/
      inflating: data/3306/my.cnf        
      inflating: data/3306/mysql         
       creating: data/3307/
      inflating: data/3307/my.cnf        
      inflating: data/3307/mysql          
    [root@localhost tools]# cp data/3306/my.cnf /data/3306/
    [root@localhost tools]# cp data/3307/my.cnf /data/3307/
    [root@localhost tools]# tree /data/
    /data/
    ├── 3306
    │ ├── data
    │ └── my.cnf
    └── 3307
        ├── data
        └── my.cnf
    
    4 directories, 2 files
    

將啟動檔案複製到/data下

  • [root@localhost tools]# cp data/3306/mysql /data/3306/
    [root@localhost tools]# cp data/3307/mysql /data/3307/
    
    [root@localhost tools]# tree /data
    /data
    ├── 3306
    │ ├── data
    │ ├── my.cnf
    │ └── mysql
    └── 3307
        ├── data
        ├── my.cnf
        └── mysql
  • 進入3306和3307的my.conf 將配置檔案的制動位置改為basedir = /usr/local/mysql/

使用者授權

  • [root@localhost ~]# chown -R mysql.mysql /data
    
    [root@localhost ~]# find /data/ -type f -name "mysql"|xargs ls -l
    -rw-r--r-- 1 mysql mysql 1307 11月 17 18:11 /data/3306/mysql
    -rw-r--r-- 1 mysql mysql 1307 11月 17 18:11 /data/3307/mysql
    

初始化資料庫 建立基礎的資料檔案(出現兩個ok則成功)

  • [root@localhost ~]# cd /usr/local/mysql/
    [root@localhost mysql]# ls
    bin      data  include         lib  mysql-test  scripts  sql-bench
    COPYING  docs  INSTALL-BINARY  man  README      share    support-files
    [root@localhost mysql]# cd scripts/
    [root@localhost scripts]# ls
    mysql_install_db

    [root@localhost scripts]# ./mysql_install_db --basedir=/usr/local/mysql --datadir=/data/3306/data --user=mysql
    Installing MySQL system tables...
    OK
    Filling help tables...
    OK

    [root@localhost scripts]# ./mysql_install_db --basedir=/usr/local/mysql --datadir=/data/3307/data --user=mysql
    Installing MySQL system tables...
    OK
    Filling help tables...
    OK

      

初始化成功後可以檢視一下自己的資料庫

  • root@localhost scripts]# tree /data/
    /data/
    ├── 3306
    │ ├── data
    │ │ ├── mysql
    │ │ │ ├── columns_priv.frm
    │ │ │ ├── columns_priv.MYD
    │ │ │ ├── columns_priv.MYI
    │ │ │ ├── db.frm
    │ │ │ ├── db.MYD
    │ │ │ ├── db.MYI
    │ │ │ ├── event.frm
    │ │ │ ├── event.MYD
    │ │ │ ├── event.MYI
    │ │ │ ├── func.frm
    │ │ │ ├── func.MYD
    │ │ │ ├── func.MYI
    │ │ │ ├── general_log.CSM
    │ │ │ ├── general_log.CSV
    │ │ │ ├── general_log.frm
    │ │ │ ├── help_category.frm
    │ │ │ ├── help_category.MYD
    │ │ │ ├── help_category.MYI
    │ │ │ ├── help_keyword.frm
    │ │ │ ├── help_keyword.MYD
    │ │ │ ├── help_keyword.MYI
    │ │ │ ├── help_relation.frm
    │ │ │ ├── help_relation.MYD
    │ │ │ ├── help_relation.MYI
    │ │ │ ├── help_topic.frm
    │ │ │ ├── help_topic.MYD
    │ │ │ ├── help_topic.MYI
    │ │ │ ├── host.frm
    │ │ │ ├── host.MYD
    │ │ │ ├── host.MYI
    │ │ │ ├── ndb_binlog_index.frm
    │ │ │ ├── ndb_binlog_index.MYD
    │ │ │ ├── ndb_binlog_index.MYI
    │ │ │ ├── plugin.frm
    │ │ │ ├── plugin.MYD
    │ │ │ ├── plugin.MYI
    │ │ │ ├── proc.frm
    │ │ │ ├── proc.MYD
    │ │ │ ├── proc.MYI
    │ │ │ ├── procs_priv.frm
    │ │ │ ├── procs_priv.MYD
    │ │ │ ├── procs_priv.MYI
    │ │ │ ├── proxies_priv.frm
    │ │ │ ├── proxies_priv.MYD
    │ │ │ ├── proxies_priv.MYI
    │ │ │ ├── servers.frm
    │ │ │ ├── servers.MYD
    │ │ │ ├── servers.MYI
    │ │ │ ├── slow_log.CSM
    │ │ │ ├── slow_log.CSV
    │ │ │ ├── slow_log.frm
    │ │ │ ├── tables_priv.frm
    │ │ │ ├── tables_priv.MYD
    │ │ │ ├── tables_priv.MYI
    │ │ │ ├── time_zone.frm
    │ │ │ ├── time_zone_leap_second.frm
    │ │ │ ├── time_zone_leap_second.MYD
    │ │ │ ├── time_zone_leap_second.MYI
    │ │ │ ├── time_zone.MYD
    │ │ │ ├── time_zone.MYI
    │ │ │ ├── time_zone_name.frm
    │ │ │ ├── time_zone_name.MYD
    │ │ │ ├── time_zone_name.MYI
    │ │ │ ├── time_zone_transition.frm
    │ │ │ ├── time_zone_transition.MYD
    │ │ │ ├── time_zone_transition.MYI
    │ │ │ ├── time_zone_transition_type.frm
    │ │ │ ├── time_zone_transition_type.MYD
    │ │ │ ├── time_zone_transition_type.MYI
    │ │ │ ├── user.frm
    │ │ │ ├── user.MYD
    │ │ │ └── user.MYI
    │ │ ├── mysql-bin.000001
    │ │ ├── mysql-bin.000002
    │ │ ├── mysql-bin.index
    │ │ ├── performance_schema
    │ │ │ ├── cond_instances.frm
    │ │ │ ├── db.opt
    │ │ │ ├── events_waits_current.frm
    │ │ │ ├── events_waits_history.frm
    │ │ │ ├── events_waits_history_long.frm
    │ │ │ ├── events_waits_summary_by_instance.frm
    │ │ │ ├── events_waits_summary_by_thread_by_event_name.frm
    │ │ │ ├── events_waits_summary_global_by_event_name.frm
    │ │ │ ├── file_instances.frm
    │ │ │ ├── file_summary_by_event_name.frm
    │ │ │ ├── file_summary_by_instance.frm
    │ │ │ ├── mutex_instances.frm
    │ │ │ ├── performance_timers.frm
    │ │ │ ├── rwlock_instances.frm
    │ │ │ ├── setup_consumers.frm
    │ │ │ ├── setup_instruments.frm
    │ │ │ ├── setup_timers.frm
    │ │ │ └── threads.frm
    │ │ └── test
    │ ├── my.cnf
    │ └── mysql
    └── 3307
        ├── data
        │ ├── mysql
        │ │ ├── columns_priv.frm
        │ │ ├── columns_priv.MYD
        │ │ ├── columns_priv.MYI
        │ │ ├── db.frm
        │ │ ├── db.MYD
        │ │ ├── db.MYI
        │ │ ├── event.frm
        │ │ ├── event.MYD
        │ │ ├── event.MYI
        │ │ ├── func.frm
        │ │ ├── func.MYD
        │ │ ├── func.MYI
        │ │ ├── general_log.CSM
        │ │ ├── general_log.CSV
        │ │ ├── general_log.frm
        │ │ ├── help_category.frm
        │ │ ├── help_category.MYD
        │ │ ├── help_category.MYI
        │ │ ├── help_keyword.frm
        │ │ ├── help_keyword.MYD
        │ │ ├── help_keyword.MYI
        │ │ ├── help_relation.frm
        │ │ ├── help_relation.MYD
        │ │ ├── help_relation.MYI
        │ │ ├── help_topic.frm
        │ │ ├── help_topic.MYD
        │ │ ├── help_topic.MYI
        │ │ ├── host.frm
        │ │ ├── host.MYD
        │ │ ├── host.MYI
        │ │ ├── ndb_binlog_index.frm
        │ │ ├── ndb_binlog_index.MYD
        │ │ ├── ndb_binlog_index.MYI
        │ │ ├── plugin.frm
        │ │ ├── plugin.MYD
        │ │ ├── plugin.MYI
        │ │ ├── proc.frm
        │ │ ├── proc.MYD
        │ │ ├── proc.MYI
        │ │ ├── procs_priv.frm
        │ │ ├── procs_priv.MYD
        │ │ ├── procs_priv.MYI
        │ │ ├── proxies_priv.frm
        │ │ ├── proxies_priv.MYD
        │ │ ├── proxies_priv.MYI
        │ │ ├── servers.frm
        │ │ ├── servers.MYD
        │ │ ├── servers.MYI
        │ │ ├── slow_log.CSM
        │ │ ├── slow_log.CSV
        │ │ ├── slow_log.frm
        │ │ ├── tables_priv.frm
        │ │ ├── tables_priv.MYD
        │ │ ├── tables_priv.MYI
        │ │ ├── time_zone.frm
        │ │ ├── time_zone_leap_second.frm
        │ │ ├── time_zone_leap_second.MYD
        │ │ ├── time_zone_leap_second.MYI
        │ │ ├── time_zone.MYD
        │ │ ├── time_zone.MYI
        │ │ ├── time_zone_name.frm
        │ │ ├── time_zone_name.MYD
        │ │ ├── time_zone_name.MYI
        │ │ ├── time_zone_transition.frm
        │ │ ├── time_zone_transition.MYD
        │ │ ├── time_zone_transition.MYI
        │ │ ├── time_zone_transition_type.frm
        │ │ ├── time_zone_transition_type.MYD
        │ │ ├── time_zone_transition_type.MYI
        │ │ ├── user.frm
        │ │ ├── user.MYD
        │ │ └── user.MYI
        │ ├── mysql-bin.000001
        │ ├── mysql-bin.000002
        │ ├── mysql-bin.index
        │ ├── performance_schema
        │ │ ├── cond_instances.frm
        │ │ ├── db.opt
        │ │ ├── events_waits_current.frm
        │ │ ├── events_waits_history.frm
        │ │ ├── events_waits_history_long.frm
        │ │ ├── events_waits_summary_by_instance.frm
        │ │ ├── events_waits_summary_by_thread_by_event_name.frm
        │ │ ├── events_waits_summary_global_by_event_name.frm
        │ │ ├── file_instances.frm
        │ │ ├── file_summary_by_event_name.frm
        │ │ ├── file_summary_by_instance.frm
        │ │ ├── mutex_instances.frm
        │ │ ├── performance_timers.frm
        │ │ ├── rwlock_instances.frm
        │ │ ├── setup_consumers.frm
        │ │ ├── setup_instruments.frm
        │ │ ├── setup_timers.frm
        │ │ └── threads.frm
        │ └── test
        ├── my.cnf
        └── mysql
    
    10 directories, 190 files
    

啟動資料庫時報錯

  • 解決辦法是進入/data3306/mysql將路徑改為:CmdPath="/usr/local/mysql/bin"

  • [root@localhost 3307]# /data/3306/mysql start
    MySQL is running...
    [root@localhost 3307]# /data/3307/mysql start
    Starting MySQL...
    
    [root@localhost 3307]# netstat -lntup|grep 330[6,7]
    tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 49691/mysqld 
    tcp 0 0 0.0.0.0:3307 0.0.0.0:* LISTEN 50607/mysqld
    

      配置成功

多例項環境進行主從複製(主從同步)

環境搭建

  • 3306------>master
  • 3307------>slave

將master中的開啟並且確定server-id不同

  •   server-id的值使用伺服器IP地址的後8位,避免不同機器的id重複
    [root@localhost ~]# egrep "log-bin = /data/3306/mysql-bin|server-id" /data/330{6,7}/my.cnf 
    /data/3306/my.cnf:log-bin = /data/3306/mysql-bin
    /data/3306/my.cnf:server-id = 1
    /data/3307/my.cnf:server-id = 3  

如果生效直接會在/data/3306/下生成日誌檔案

或者 執行如下命令,進行檢視

  • [root@localhost 3306]# mysql -uroot -p123123 -P3306 -e "show variables like 'log_bin';"
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | log_bin | ON |

在主的資料庫中新增用於從庫的賬號rep

  • mysql> grant replication slave on *.* to 'rep'@'192.168.2.%' identified by '123123';
    Query OK, 0 rows affected (0.00 sec)
  • 重新整理資料庫
    mysql> flush privileges;
    Query OK, 0 rows affected (0.00 sec)
    

通常來說在備份時要進行鎖資料庫(這裡可以不用鎖,現在只是演示,不是必做)

  • mysql> flush table with read lock;
    Query OK, 0 rows affected (0.00 sec)
    

    鎖住之後重新開個視窗

  • [root@localhost ~]# mysqldump -uroot -p123123 -P3306 -A -B --events --master-data=2 >/opt/rep.sql
    

    進入vim /opt/rep.sql檢視是否有節點

  • 對主資料庫進行解鎖,提供服務
    mysql> unlock tables;
    Query OK, 0 rows affected (0.00 sec)
    

      

  • 主庫3306配置完畢,現在配置從庫3307,將目標指向從庫的3306
  • mysql> CHANGE MASTER TO MASTER_HOST='192.168.2.200',  MASTER_USER='rep',  MASTER_PASSWORD='rep', MASTER_LOG_FILE='mysql-bin.000014', MASTER_LOG_POS=333;
    Query OK, 0 rows affected (0.00 sec) 

  • 報錯:
  • 解決方式:停止slave ,然後執行,最後在開啟服務。

  • 檢測是否成功,當主庫給傳送日誌,則master.info會不停的進行更新

  • 重啟從庫
  • mysql> stop slave;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> start slave;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> show slave status\G;
    *************************** 1. row ***************************
                   Slave_IO_State: Connecting to master
                      Master_Host: 192.168.2.200
                      Master_User: rep
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000014
              Read_Master_Log_Pos: 333
                   Relay_Log_File: localhost-relay-bin.000002
                    Relay_Log_Pos: 4
            Relay_Master_Log_File: mysql-bin.000014
                 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: 333
                  Relay_Log_Space: 107
                  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: NULL
    Master_SSL_Verify_Server_Cert: No
                    Last_IO_Errno: 1130
                    Last_IO_Error: error connecting to master '[email protected]:3306' - retry-time: 60  retries: 86400
                   Last_SQL_Errno: 0
                   Last_SQL_Error: 
      Replicate_Ignore_Server_Ids: 
                 Master_Server_Id: 0
    1 row in set (0.00 sec)
    

     兩個yes,則說明搭建成功 

  • 測試
  • 在主庫中建立一個表,在從庫中看是否也得到了更新。