mysql中日志类型有慢查询日志,二进制日志,错误日志,默认情况下,系统只打开错误日志,因为开启日志会产生较大的IO性能消耗。
一般情况下,生成系统中很少打开二进制日志(bin log),bin log日志的优化策略:
mysql> show variables like ‘%binlog%‘;
+-----------------------------------------+----------------------+
| Variable_name | Value |
+-----------------------------------------+----------------------+
| binlog_cache_size | 32768 |
| binlog_checksum | CRC32 |
| binlog_direct_non_transactional_updates | OFF |
| binlog_format | ROW |
| binlog_max_flush_queue_time | 0 |
| binlog_order_commits | ON |
| binlog_row_image | FULL |
| binlog_rows_query_log_events | OFF |
| binlog_stmt_cache_size | 32768 |
| binlogging_impossible_mode | IGNORE_ERROR |
| innodb_api_enable_binlog | OFF |
| innodb_locks_unsafe_for_binlog | OFF |
| max_binlog_cache_size | 18446744073709547520 |
| max_binlog_size | 1073741824 |
| max_binlog_stmt_cache_size | 18446744073709547520 |
| sync_binlog | 0 |
+-----------------------------------------+----------------------+
binlog_cache_size:在事务过程中,用来保存二进制SQL语句的缓存大小。二进制日志缓存使用的前提条件是服务器端使用了支持事务的引擎以及开启了bin log功能。
该参数为每个客户端都分配binlog_cache_size大小的缓存,如果用户频繁使用多语句事务的话,可以增大binlog_cache_size大小,已获得更好的性能,如何判断binlog_cache_size
设置的是否合理呢?通过如下两个状态可以判断:
mysql> show status like ‘binlog%‘;
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Binlog_cache_disk_use | 1 |
| Binlog_cache_use | 33 |
+----------------------------+-------+
max_binlog_size :binlog大小的最大值,一般为512M或1G,但不能超过1G,该大小不能严格控制binlog日志大小,如果在binlog大小临界点的时候执行了一个大事务,为了保证事务完整性,不能做日志切换,只能将该事务的所有sql记录当前日志中。其实mysql的binlog日志记录的是带来数据改变的DML,DDL操作
sync_binlog:该参数用来控制以何种方式将binlog cache中的记录同步(fsync)到磁盘。以下是它的参数值的说明;
sync_binlog=0: 表示当事务提交后,不立即将binlog cache中的记录同步到磁盘,具体何时同步,让文件系统自行决定,或者cache满了之后才同步。这种方式性能最好,都是风险也最大,一旦系统宕机,binlog cache中所有的记录都会丢失,如果将sync_binlog值设为1的话,最安全,因为即使系统宕机,也只丢失一个事务的操作记录,都是性能最差,事务每提交一次就会将binlog_cache中的记录同步到磁盘。
sync_binlog=n: 表示事务多少次提交后才将binlog cache中的记录同步到磁盘
mysql的主从同步就是slave端通过IO线程将master端产生的日志同步到slave端的中继日志,然后通过SQL线程将中继日志在slave端重演。所以master端的日志量大小,直接影响了salve端同步的性能,通常情况下,master端产生binlog日志量是无法避免的,但是可以通过设置参数有选择性地同步哪些数据库或表产生的binlog日志来减少binlog日志同步量。
binlog_do_db:设置哪些数据库需要记录binlog(master端)
binlog_ignore_db:设置哪些数据库不需要记录binlog(master端)
replicate_do_db:设置哪些数据库需要同步binlog,多个数据库用逗号”,“隔开
replicate_ignore_db:设置哪些数据库不需要同步binlog,多个数据库用逗号”,“隔开
replicate_do_table:设置哪些表需要同步binlog
replicate_ignore_table:设置哪些表不需要同步binlog
replicate_wild_do_table:设置哪些表需要同步binlog,与replicate_do_table的区别是可以使用通配符的方式来指定表
replicate_wild_ignore_table:设置哪些表不需要同步binlog,与replicate_ignore_table的区别是可以使用通配符的方式来指定表
如果在master端设置了上面两个参数。会减少master端binlog日志的记录量,降低master端日志IO量,减少同步到slave端时的网络通信量,进而降低lave端IO线程同步日志量和SQL线程应用relay log量。但是需要注意的是,mysql判断是否复制某个event不是根据产生该event的query中指定的db名来记录的,而是根据执行该query时所在的db(即using dbname)是否是binlog_do_db指定的db,若是,则记录,否则不记录。考虑如下场景:
有三个数据库:A,B,C,其中binlog_do_db=B,C
应用登录时默认db是A,现执行如下query:update B.t1 set c1 = xxx;这种情况下,mysql是不记录binlog的,由于对B库下的t1表的update操作不记录binlog,所以无法同步到slave端,进而会导致master与slave数据不一致。
如果所在db等于binlog_do_db,此时修改了不需要同步的db下的表也会记录binlog日志,即该db下所有改变db数据的query都会记录binlog
即应用登录db是B,执行query:update A.t1 set c1=xxx;此时也会记录binlog日志。由于binlog_do_db中没有A库,所以slave端不会有A库,从而导致slave端无法找到A库而报错。
如果在slave端设置后面六个参数,无论master该复制或不该复制的event都会被同步到slave端,这样带来的负面影响是IO,网络的压力,和slave端IO线程写入relay log的压力,但是可以减少slave端SQL线程应用relay log的日志量,由于设置了replicate_do_db,replicate_ignore_db会过滤相应的日志,所以可以规避默认db是否等于binlog_do_db问题。