一.mysql日志:
mysql的日志种类有很多,常见的有二进制日志,一般查询日志,满查询日志,中继日志,事务日志等,具体信息可以通过 mysql> SHOW GLOBAL VARIABLES LIKE '%log%'; 查看,在我的机器上结果如下:
+-----------------------------------------+--------------------------------+ | Variable_name | Value | +-----------------------------------------+--------------------------------+ | back_log | 80 | | binlog_cache_size | 32768 | | binlog_checksum | CRC32 | | binlog_direct_non_transactional_updates | OFF | | binlog_error_action | IGNORE_ERROR | | binlog_format | MIXED | | binlog_gtid_simple_recovery | OFF | | 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 | | expire_logs_days | 0 | | general_log | OFF | | general_log_file | /var/lib/mysql/master.log | | innodb_api_enable_binlog | OFF | | innodb_flush_log_at_timeout | 1 | | innodb_flush_log_at_trx_commit | 1 | | innodb_locks_unsafe_for_binlog | OFF | | innodb_log_buffer_size | 8388608 | | innodb_log_compressed_pages | ON | | innodb_log_file_size | 50331648 | | innodb_log_files_in_group | 2 | | innodb_log_group_home_dir | ./ | | innodb_mirrored_log_groups | 1 | | innodb_online_alter_log_max_size | 134217728 | | innodb_undo_logs | 128 | | log_bin | ON | | log_bin_basename | /var/log/mysql/mysql-bin | | log_bin_index | /var/log/mysql/mysql-bin.index | | log_bin_trust_function_creators | OFF | | log_bin_use_v1_row_events | OFF | | log_error | /var/log/mysql/error.log | | log_output | FILE | | log_queries_not_using_indexes | OFF | | log_slave_updates | OFF | | log_slow_admin_statements | OFF | | log_slow_slave_statements | OFF | | log_throttle_queries_not_using_indexes | 0 | | log_warnings | 1 | | max_binlog_cache_size | 18446744073709547520 | | max_binlog_size | 104857600 | | max_binlog_stmt_cache_size | 18446744073709547520 | | max_relay_log_size | 0 | | relay_log | | | relay_log_basename | | | relay_log_index | | | relay_log_info_file | relay-log.info | | relay_log_info_repository | FILE | | relay_log_purge | ON | | relay_log_recovery | OFF | | relay_log_space_limit | 0 | | simplified_binlog_gtid_recovery | OFF | | slow_query_log | OFF | | slow_query_log_file | /var/lib/mysql/master-slow.log | | sql_log_bin | ON | | sql_log_off | OFF | | sync_binlog | 0 | | sync_relay_log | 10000 | | sync_relay_log_info | 10000 | +-----------------------------------------+--------------------------------+ 61 rows in set (0.00 sec)
其中binlog_format字段是指二进制日志的类型,分为3种:1、基于语句(statement) 2、基于行(row) 3、混合方式 。基于语句和基于行各有优劣,如果制定的是基于语句,那么如果sql语句中有类似date的指令,那么在备份的时候就会产生错误。而基于行的会造成日志文件过大。二进制日志会记录任何引起数据库变化和可能引起数据库变化的操作。顾名思义二进制日志的文件类型是二进制的,因此不能用打开ASCII文件的方式打开,用 file mysql-bin.000001 查看二进制日志的类型是 mysql-bin.000001:MySQL replication log 如果用cat,less等命令打开会是乱码,必须用 $mysqlbinlog mysql-bin.000001 查看,才会得到具体的日志信息,部分结果如下:
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; # at 4 #160411 8:13:40 server id 1 end_log_pos 120 CRC32 0xd41ad4d6 Start: binlog v 4, server v 5.6.28-1-log created 160411 8:13:40 at startup # Warning: this binlog is either in use or was not closed properly. ROLLBACK/*!*/; BINLOG ' NOwKVw8BAAAAdAAAAHgAAAABAAQANS42LjI4LTEtbG9nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAA07ApXEzgNAAgAEgAEBAQEEgAAXAAEGggAAAAICAgCAAAACgoKGRkAAdbU GtQ= '/*!*/; # at 120 #160411 9:47:59 server id 1 end_log_pos 221 CRC32 0x26bc23ca Query thread_id=7 exec_time=1 error_code=0 SET TIMESTAMP=1460339279/*!*/; SET @@session.pseudo_thread_id=7/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=1073741824/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; /*!C utf8 *//*!*/; SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=8/*!*/; SET @@session.lc_time_names=0/*!*/; SET @@session.collation_database=DEFAULT/*!*/; drop database article /*!*/; # at 221 #160411 9:49:41 server id 1 end_log_pos 324 CRC32 0x69a849f1 Query thread_id=9 exec_time=0 error_code=0 SET TIMESTAMP=1460339381/*!*/; create database article /*!*/; # at 324 #160411 9:50:10 server id 1 end_log_pos 461 CRC32 0x7b2ad848 Query thread_id=10 exec_time=0 error_code=0 use `article`/*!*/; SET TIMESTAMP=1460339410/*!*/; SET @@session.foreign_key_checks=0, @@session.unique_checks=0/*!*/; SET @@session.sql_mode=524288/*!*/; DROP TABLE IF EXISTS `at_admin` /* generated by server */ /*!*/;
这里面无非就是记录的一些sql脚本,但是mysql的二进制日志对于数据库的复制和及时点恢复至关重要,在生产环境中一定要将二进制日志和数据文件存放在两块不同的硬盘上,一旦数据文件所在的硬盘损坏就可以通过二进制日志备份还原,还有一个原因是二进制日志和数据库数据文件都会引起大量IO操作,如果两者放在同一块磁盘上那么io量就会变得非常大,引起系统性能下降。除了在终端使用mysqlbinlog查看二进制日志,还可以在mysql交互式模式中使用一系列命令查看和二进制日志相关的信息。
mysql>show binary logs; 查看系统当前有哪些二进制日志文件名
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 423 |
| mysql-bin.000002 | 2811 |
+------------------+-----------+
2 rows in set (0.00 sec)
mysql> show master status; 查看当前记录二进制日志文件的状态 +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000002 | 2811 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)
mysql> show binlog events in 'mysql-bin.000001'; 查看某个二进制日志文件的内容 G可选,可以让结果以垂直的方式显示 +------------------+-----+-------------+-----------+-------------+---------------------------------------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +------------------+-----+-------------+-----------+-------------+---------------------------------------------------------------------+ | mysql-bin.000001 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.28-1-log, Binlog ver: 4 | | mysql-bin.000001 | 120 | Query | 1 | 205 | BEGIN | | mysql-bin.000001 | 205 | Intvar | 1 | 237 | INSERT_ID=6 | | mysql-bin.000001 | 237 | Query | 1 | 369 | use `article`; insert into at_type (typename) values ('pt'),('ll') | | mysql-bin.000001 | 369 | Xid | 1 | 400 | COMMIT /* xid=24 */ | | mysql-bin.000001 | 400 | Stop | 1 | 423 | | +------------------+-----+-------------+-----------+-------------+---------------------------------------------------------------------+ 6 rows in set (0.00 sec)
expire_logs_days是指日志过期时间,一般要设定为0,如果设定为30,那么30天之后所有日志将被自动清空,而二进制日志对于数据库恢复是很重要的,不能清除。
general_log字段的值一般设为OFF关闭,如果开启普通查询日志,则用户的每一条查询语句都将被记录下来,这将产生大量磁盘IO,而凡是产生IO的地方都会影响系统系统。IOPS用来衡量一个IO设备每秒钟执行IO操作的次数,普通台式机机械硬盘的iops是100,SCSI硬盘的iops能达到200,而SSD的iops可能会达到500---1000不等,因此在生产环境中一个繁忙的数据库服务器一般都要使用SSD提高性能。二进制日志文件很有可能成为整个系统的瓶颈,因此最好把数据库的二进制日志文件单独放到一块SSD上,定期转移。
innodb_flush_log_at_trx_commit 有3个可选的值,0:每秒同步,并执行磁盘flush操作 1:每事务同步,并执行磁盘flush操作 2:每事务同步,但不执行磁盘flush操作,由操作系统选择空闲的时间将内存中的数据同步至磁盘。
二.mysql备份与恢复:
mysql的备份按是否可读写,分为3种,1.热备份:备份的同时读写不受影响. 2.温备份:备份的同时仅可以执行读操作 3.冷备份:也称离线备份,必须终止一切读写操作才能开始备份. 另一种划分方式是按照备份文件的类型分为物理备份和逻辑备份,物理备份都是直接备份数据文件,而逻辑备份会产生一堆sql脚本,速度慢而且可能会丢失浮点数精度,但是很方便采用文本处理工具对其处理.不同的数据库存储引擎支持的备份方法也不同,MyISAM存储引擎仅支持温备份,InnoDB引擎支持热备份和冷备份.
备份的工具也有很多,mysql自带的mysqldump可以进行逻辑备份,percona提供了遵循GPL协议的开源备份工具xtrabackup,功能十分强大,官网有详细的文档介绍,percona为了mysql提供了很多开源的技术支持,发布了很多mysql管理工具.直接用cp命令也可以备份,但是这样只能冷备份了,用逻辑卷lv可以实现几乎热备份的效果
下面介绍一下mysqldump 的使用,详细的使用方法可以man一下.在使用mysqldump进行逻辑备份前最好锁表,操作结束后
mysql > flush tables with read lock; mysql > flush logs
msyql > unlock tables;
再释放锁,或者直接加上--lock-alltables,--flush-logs执行日志滚动,--all-databases 备份所有库,--databases db1, db2,......备份制定的库,--master-data={0,1,2} ,这里水平所限,仅介绍mysqldump,xtrabackup这个强大的工具如何使用还是看官方文档吧.
一些example:
1. mysqldump -u root -p --lock-all-tables --flush-logs --master-data=2 --all-databases > ~/all.sql
Warning: Using unique option prefix all-tables instead of all-tablespaces is deprecated and will be removed in a future release. Please use the full name instead.
2. mysqldump -u root -p --lock-all-tables --flush-logs --master-data=2 --database article > ~/article.sql
第一步:备份数据库至~/article.sql,article.sql打开就是一堆sql 脚本,部分内容如下:
$ cat article.sql -- MySQL dump 10.13 Distrib 5.6.28, for debian-linux-gnu (x86_64) -- -- Host: localhost Database: article -- ------------------------------------------------------ -- Server version 5.6.28-1-log /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Position to start replication or point-in-time recovery from -- -- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000004', MASTER_LOG_POS=120; -- -- Current Database: `article` -- CREATE DATABASE /*!32312 IF NOT EXISTS*/ `article` /*!40100 DEFAULT CHARACTER SET latin1 */; USE `article`; -- -- Table structure for table `at_admin` -- DROP TABLE IF EXISTS `at_admin`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `at_admin` ( `id` int(5) NOT NULL AUTO_INCREMENT, `name` varchar(40) DEFAULT NULL, `passwd` varchar(40) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */;
第二步:模拟数据库损坏 mysql> drop databse article
第三部:恢复数据库:恢复之前一定要在当前会话中关闭数据库的二进制日志功能,因为他会把恢复过程记录进日志中
myslq > set sql_log_bin=0
mysql > source /home/grid/article.sql
或者
mysql > . /home/grid/article.sql
另一种恢复数据的方式是直接使用二进制日志:
#mysqlbinlog mysql-bin.000002 | mysql -u root -p
但这种方式似乎不能完全恢复所有的数据