mysql 5.7多源複製(用於生產庫多主庫合併到一個查詢從庫)

  目前咱們使用的是主從+分庫分表的系統架構,主庫有N個分庫,從庫爲多個slave作負載均衡,因此數據庫端的架構是下面這樣的:html

 

  由於差很少有一年半沒有專門搞技術爲主了,順帶回顧下。mysql

  這就涉及到多個主庫數據同步到不分庫分表的從庫共查詢和管理類系統使用。在mysql 5.6以及以前的版本中,沒有原生的解決方法,除非使用mariadb分支,在mysql 5.7以後支持多源複製,除了使用原生的多源複製以外,還有一個選擇,就是使用案例開源的otter/canal。若是隻是N個庫合併到一個庫的,咱們使用mysql原生的複製,由於不管從穩定性仍是運維成本、系統要求的角度,mysql複製都合理的多。對於須要特殊處理比較多的或者目標庫爲oracle的,咱們使用otter/canal。文本講述mysql多源的搭建。下一文中,咱們會講述完整的otter環境搭建並進行簡單的性能測試。redis

  首先安裝mysql 5.7,推薦使用percona server,相關參數優化推薦等請參考mysql安裝以及配置參數優化。spring

  由於環境限制,兩個主節點在同一臺機器,從節點另一臺機器。sql

172.28.1.97 3307 主1
172.28.1.97 3308 主2
10.20.24.89 3308 從數據庫

  同時172.28.1.97 3308 主2有三個database,ta_1,ta_2,ta_base,均同步到從庫的ta庫。tomcat

  和mysql一主一從複製相比,多源複製加入了一個叫作Channel的概念, 每個Channel都是一個獨立的Slave,都有一個IO_THREAD和SQL_THREAD。原理和普通複製同樣。咱們只須要對每個Master執行Change Master 語句,只須要在每一個語句最後使用For Channel來進行區分。多源複製和正常主從其餘的配置都同樣,基本上主庫開下binlog、server-id不同就能夠了,只有下列額外限制:服務器

  • master-info-repository必須爲TABLE
  • relay-log-info-repository必須爲TABLE
  • 以FOR CHANNEL 'CHANNEL_NAME'區分不一樣的master。

  首先參考mysql單機版安裝mysql 5.7安裝與參數優化,下列爲slave直接相關的參數,在/etc/my.cnf中額外或者修改下列參數:架構

master-info-repository=TABLE
relay-log-info-repository=TABLE
# replicate-rewrite-db 多庫同步到單庫,庫名重寫,其餘的replicate-*會在replicate-rewrite-db評估後執行,多個映射的話,配置文件中包含多行便可,這個設計好傻,爲啥不逗號或者分號分隔呢。若是同時有多個replicate*過濾器,先評估數據庫級別的、而後表級別的;先評估do,後評估ignore(也就是在白名單或者不在黑名單的模式)。好比,主庫多個分庫合併到從庫一個庫
replicate-rewrite-db=ta_base->ta
replicate-rewrite-db=ta_1->ta
replicate-rewrite-db=ta_2->ta
sync_relay_log=1
relay_log_recovery=1
slave-parallel-type=LOGICAL_CLOCK
slave-parallel-workers=16 #具體值多少合適須要性能測試獲得,通常cpu數量便可
server-id = 2
replicate-do-db # 若是隻要同步某些庫
replicate-ignore-db #若是隻須要不一樣步某些庫
slave-skip-errors=ddl_exist_errors + 1022 #建議不要同步ddl(1007,1008,1050,1051,1054,1060,1061,1068,1094,1146,1022)
log_slave_updates=ON(GTID模式必須開始log_slave_updates,對性能有必定影響,Mysql 5.7以後從節點能夠不開啓binlog)
skip-slave-start=false #默認false,也就是server重啓的時候會自動啓動slave,不建議修改

啓動mysql服務器。oracle

MySQL [(none)]> SET GLOBAL master_info_repository = 'TABLE';
Query OK, 0 rows affected (0.00 sec)

MySQL [(none)]> SET GLOBAL relay_log_info_repository = 'TABLE';
Query OK, 0 rows affected (0.00 sec)

-- 注:不一樣於設置全局變量,全部這些經過change master修改的信息都有存儲在performance_schema的replication相關表中,重啓後不會失效,複製鏈接信息存儲在performance_schema庫的replication_connection_configuration表中,IO線程當前狀態在replication_connection_status。SQL線程的配置和狀態分別在replication_applier_configuration和replication_applier_status表。
全部這些經過change/replication修改的信息都有存儲在performance_schema的replication相關表中,重啓後會失效,必定要同時保存到配置文件中
MySQL [(none)]> CHANGE MASTER TO MASTER_HOST='172.18.1.97',MASTER_PORT=3307,MASTER_USER='repl', MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=1834 FOR CHANNEL 'Master_3307';
Query OK, 0 rows affected, 2 warnings (0.03 sec)

MySQL [(none)]> CHANGE MASTER TO MASTER_HOST='172.18.1.97',MASTER_PORT=3308,MASTER_USER='repl', MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000002',MASTER_LOG_POS=7484 FOR CHANNEL 'Master_3308';
Query OK, 0 rows affected, 2 warnings (0.01 sec)

MySQL [(none)]> start slave for channel 'Master_3307';
Query OK, 0 rows affected (0.00 sec)

MySQL [(none)]> start slave for channel 'Master_3308';
Query OK, 0 rows affected (0.01 sec)

MySQL [(none)]> show slave status for channel 'Master_3307'\G;
*************************** 1. row ***************************
               Slave_IO_State: Connecting to master
                  Master_Host: 172.18.1.97
                  Master_User: repl
                  Master_Port: 3307
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 1834
               Relay_Log_File: slave-relay-bin-master_3307.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Connecting
            Slave_SQL_Running: Yes
              Replicate_Do_DB: ta
          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: 1834
              Relay_Log_Space: 154
              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: 2003
                Last_IO_Error: error connecting to master 'repl@172.18.1.97:3307' - retry-time: 60  retries: 1
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 0
                  Master_UUID: 
             Master_Info_File: mysql.slave_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: 180703 08:23:54
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: (ta_base,ta),(ta_1,ta),(ta_2,ta)
                 Channel_Name: master_3307
           Master_TLS_Version: 
1 row in set (0.00 sec)

ERROR: No query specified

MySQL [(none)]> show slave status for channel 'Master_3308'\G;
*************************** 1. row ***************************
               Slave_IO_State: Connecting to master
                  Master_Host: 172.18.1.97
                  Master_User: repl
                  Master_Port: 3308
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000002
          Read_Master_Log_Pos: 7484
               Relay_Log_File: slave-relay-bin-master_3308.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: mysql-bin.000002
             Slave_IO_Running: Connecting
            Slave_SQL_Running: Yes
              Replicate_Do_DB: ta
          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: 7484
              Relay_Log_Space: 154
              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: 2003
                Last_IO_Error: error connecting to master 'repl@172.18.1.97:3308' - retry-time: 60  retries: 1  #這裏是由於後來網斷了,前面忘了截圖下來
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 0
                  Master_UUID: 
             Master_Info_File: mysql.slave_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: 180703 08:23:58
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: (ta_base,ta),(ta_1,ta),(ta_2,ta)
                 Channel_Name: master_3308
           Master_TLS_Version: 
1 row in set (0.00 sec)

ERROR: No query specified

MySQL [(none)]> exit
Bye

其餘注意點

  • mysql僅支持實例級別設置計數器的步長,經過auto_increment_increment參數控制,這樣分庫分表的時候,自增表的auto_increment就須要區分開從1仍是2開始。
  • 在mysql 8.0以前,global參數在重啓以後就會失效,因此對於能夠動態修改的全局參數,須要同時修改my.cnf配置文件確保重啓後保持一致。
  • 若是主庫是雙節點,還須要有個監控程序監控主庫,便於宕機後自動切換到另一個節點,具體實現根據基於日誌點位、GTID的不一樣而不一樣(有需求可留站內信,可提供同時監控並自動重啓rabbitmq、es、tomcat、spring boot、mysql複製、redis、zk、otter manager的守護程序)。

參考

https://blog.csdn.net/qustdjx/article/details/26937325/http://yoshinorimatsunobu.blogspot.com/2013/10/making-full-table-scan-10x-faster-in.htmlhttps://www.cnblogs.com/zhoujinyi/p/5704567.htmlMySQL 5.7並行複製實現原理與調優https://www.oschina.net/translate/showdown-mysql-8-vs-postgresql-10https://aws.amazon.com/cn/about-aws/whats-new/2017/12/amazon-aurora-with-mysql-compatibility-speeds-query-processing-with-hash-join-and-batched-scans/https://blog.csdn.net/chenhaifeng2016/article/details/77530569

相關文章
相關標籤/搜索