如何提升複製的性能mysql
MySQL從庫上經過SHOW PROCESSLIST能夠看到有且僅有一個SQL線程在解析中繼日誌Relay Log並應用,例如:sql
mysql> show processlist \G; *************************** 1. row *************************** Id: 5 User: root Host: 192.168.211.1:63440 db: ssm Command: Sleep Time: 2185 State: Info: NULL *************************** 2. row *************************** Id: 6 User: root Host: 192.168.211.1:63488 db: ssm Command: Sleep Time: 2190 State: Info: NULL *************************** 3. row *************************** Id: 15 User: root Host: localhost db: NULL Command: Query Time: 0 State: init Info: show processlist *************************** 4. row *************************** Id: 16 User: system user Host: db: NULL Command: Connect Time: 2 State: Waiting for master to send event Info: NULL *************************** 5. row *************************** Id: 17 User: system user Host: db: NULL Command: Connect Time: 2 State: Slave has read all relay log; waiting for the slave I/O thread to update it Info: NULL
那麼寫入壓力特別大的場景下,考慮到主庫是多線程併發在寫入(應用服務器併發鏈接寫入),而從庫僅僅只有一個SQL線程在應用日誌,就容易出現從庫追不上主庫的狀況,能夠在從庫上經過SHOW SLAVE STATUS來查看從庫落後主庫的時間:數據庫
mysql> show slave status \G; *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.211.136 Master_User: root Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000007 Read_Master_Log_Pos: 1271 Relay_Log_File: mysqld-relay-bin.000011 Relay_Log_Pos: 283 Relay_Master_Log_File: mysql-bin.000007 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: 1271 Relay_Log_Space: 620 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: 136 Master_UUID: cb248a05-3538-11eb-8893-005056253f37 Master_Info_File: /var/lib/mysql/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it 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 1 row in set (0.00 sec)
其中 Seconds_Behind_Master 顯示了預估從庫落後主庫的秒數,不是特別精準,只是一個預估值。安全
從庫的數據落後主庫的問題,固然能夠經過提升從庫配置的硬件來解決。但更推薦經過架構設計來解決這個問題,經過減小從庫須要作的寫入操做或者在從庫上實現多線程寫入操做都可以解決。服務器
經過拆分減小一個從庫上須要數據同步的表來解決。首先考慮配置一主多從的架構,而後在不一樣的從庫上,經過設置不一樣 replicate-do-db、replicate-do-table、replicate-ignore-db、replicate-ignore-table或replicate-wild-do-table參數,使得不一樣的從庫複製不一樣的庫/表,減小每一個從庫上須要寫入的數據。
例如,假設主庫爲M1,從庫爲S一、S二、S3,其中設置從庫S1僅須要複製databaseA,而從庫S2僅須要複製databaseB,從庫S3僅須要複製databaseC,那麼每一個從庫只須要執行本身須要複製的庫/表相關的SQL就能夠了,以下圖所示。網絡
這時,因爲主庫M1須要給S一、S二、S3三個從庫(或者更多從庫)都發送完整的Binlog日誌,I/O 和網絡壓力較大,再改進一下架構:配置 MySQL 多級主從架構減輕主庫壓力,以下圖所示。多線程
經過多級主從的方式,提升從庫的複製性能,同時儘可能下降對主庫的影響。架構
注意:BLACKHOLE引擎就是一個「黑洞」引擎,在建立表的時候,選擇BLACKHOLE引擎,那麼寫入表的數據不會真實地寫入磁盤,僅僅記錄Binlog日誌,極大下降了磁盤的I/O。併發
方案一的優勢在於可以自由拆分從庫,方便地把熱點數據分散開來;缺點在於維護起來不夠簡潔,而且因爲從庫S一、S二、S3上都沒有主庫完整的數據,在主庫M1出現意外宕機的狀況,應用處理較爲麻煩。須要提早和應用溝通好異常的處理解決方案。性能
MySQL 5.6提供了基於 Schema的多線程複製,容許從庫並行更新。例如,主庫上存在 2個Schema,即ssm和replication。
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | replication | | ssm | +--------------------+ 5 rows in set (0.00 sec)
MySQL 5.6的從庫在同步主庫時,經過設置參數 slave_parallel_workers爲 2,讓MySQL從庫在複製時啓動兩個SQL線程。參數設置前:
mysql> show variables like '%slave_parallel_workers%'; +------------------------+-------+ | Variable_name | Value | +------------------------+-------+ | slave_parallel_workers | 0 | +------------------------+-------+ 1 row in set (0.00 sec) mysql> select version(); +-----------+ | version() | +-----------+ | 5.6.50 | +-----------+ 1 row in set (0.00 sec)
mysql> show processlist \G; *************************** 1. row *************************** Id: 5 User: root Host: 192.168.211.1:63440 db: ssm Command: Sleep Time: 3480 State: Info: NULL *************************** 2. row *************************** Id: 6 User: root Host: 192.168.211.1:63488 db: ssm Command: Sleep Time: 3485 State: Info: NULL *************************** 3. row *************************** Id: 15 User: root Host: localhost db: NULL Command: Query Time: 0 State: init Info: show processlist *************************** 4. row *************************** Id: 16 User: system user Host: db: NULL Command: Connect Time: 1297 State: Waiting for master to send event Info: NULL *************************** 5. row *************************** Id: 17 User: system user Host: db: NULL Command: Connect Time: 1297 State: Slave has read all relay log; waiting for the slave I/O thread to update it Info: NULL 5 rows in set (0.00 sec)
設置參數後以下:注意須要先stop slave,再start slave纔有效果
mysql> set global slave_parallel_workers=2; Query OK, 0 rows affected (0.00 sec) mysql> stop slave; Query OK, 0 rows affected (0.00 sec) mysql> start slave; Query OK, 0 rows affected, 1 warning (0.01 sec) mysql> show processlist \G; *************************** 1. row *************************** Id: 5 User: root Host: 192.168.211.1:63440 db: ssm Command: Sleep Time: 3603 State: Info: NULL *************************** 2. row *************************** Id: 6 User: root Host: 192.168.211.1:63488 db: ssm Command: Sleep Time: 3608 State: Info: NULL *************************** 3. row *************************** Id: 15 User: root Host: localhost db: NULL Command: Query Time: 0 State: init Info: show processlist *************************** 4. row *************************** Id: 18 User: system user Host: db: NULL Command: Connect Time: 2 State: Waiting for master to send event Info: NULL *************************** 5. row *************************** Id: 19 User: system user Host: db: NULL Command: Connect Time: 2 State: Slave has read all relay log; waiting for the slave I/O thread to update it Info: NULL *************************** 6. row *************************** Id: 20 User: system user Host: db: NULL Command: Connect Time: 2 State: Waiting for an event from Coordinator Info: NULL *************************** 7. row *************************** Id: 21 User: system user Host: db: NULL Command: Connect Time: 2 State: Waiting for an event from Coordinator Info: NULL 7 rows in set (0.00 sec)
經過設置slave_parallel_workers 參數,讓ssm和replication兩個Schema擁有本身獨立的SQL線程,這樣也大大提升了從庫的複製速度。
複製是MySQL數據庫中常常使用的一個功能,它能夠有效地保證主數據庫的數據安全,並減輕主數據庫的備份壓力,以及分擔主數據庫的一部分查詢壓力。
-------學自《深刻淺出MySQL》