如何提升复制的性能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》