1. binlog 日志
MySQL的二进制日志可以说是MySQL最重要的日志了,它以事件de形式记录了所有的DDL和DML(除了数据查询语句)语句, 记录内容还包含语句所执行的消耗的时间。 binlog是 Server 层 的日志
binlog日志 主要作用:
- 恢复数据
- 主从复制
binlog日志 两类文件:
二进制日志索引文件 ,文件名后缀为.index,二进制日志文件 ,文件名后缀为.00000*,记录数据库所有的DDL和DML
开启
配置开启
[mysqld]
log_bin=mysql-bin
server-id=721657
- log_bin=mysql-bin
mysql会根据这个配置自动设置log_bin为on状态,自动设置log_bin_index、log_bin_basename文件 - server-id=721657
如果是5.7及以上版本 加入了很多集群相关的代码,如果没有该配置,重启mysql服务会报错。该配置 指定 当前mysql的唯一id标识,不能和其他集群中机器重名的字符串。
查看是否开启
show variables like '%log_bin%';
+---------------------------------+--------------------------------+
| Variable_name | Value |
+---------------------------------+--------------------------------+
| log_bin | ON |
| log_bin_basename | /var/lib/mysql/mysql-bin |
| log_bin_index | /var/lib/mysql/mysql-bin.index |
| log_bin_trust_function_creators | OFF |
| log_bin_use_v1_row_events | OFF |
| sql_log_bin | ON |
+---------------------------------+--------------------------------+
binlog的三种模式
Statement (默认模式)
每一条会修改数据的sql 都会记录在binlog中。
不需要记录每一行的变化,减少了binlog日志量,节约了IO,提高性能。
slave可与master上要保持一致会有很多问题.
Row (重量模式)
不记录sql语句上下文相关信息,仅保存哪条记录 被修改。
rowlevel的日志内容会非常清楚的记录下每一行数据修改的细节。 而且不会出现某些特定情况下的存储过程,或function, 以及trigger的调用和触发无法被正确复制的问题。
可能会产生大量的日志内容, 比如一条update语句,修改多条记录,则binlog中每一条修改都会有记录,这样造成binlog日志量会很大, 特别是当执行alter table之类的语句的时候,由于表结构修改,每条记录都发生改变,那么该表每一条记录都会记录到日志中。
Mixed (自动模式, 推荐使用)
是以上两种level的混合使用。 一般的语句修改使用statment格式保存binlog, 如一些函数,statement无法完成主从复制的操作,则采用row格式保存binlog, MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志形式。
binlog日志详解
查看 当前 binlog 状态信息
show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 410713 | | | |
+------------------+----------+--------------+------------------+-------------------+
mysql-bin.000001 是 当前 正在被mysql写入的 二进制日志文件名。 410713 这个数值 表示的就是binlog的当前位置 。每次执行dml操作,position都会改变。
查看 binlog 内容
查看某个binlog日志内容,常用有两种方式
文本的方式(cat、less、more) 查看 mysql-bin.000001的内容是一堆乱码, mysql给我们提供了一个用于查看binlog日志的工具,叫做mysqlbinlog, mysqlbinlog mysql-bin.000001
- 方式二: show binlog events 查看binlog日志
show binlog events [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count];
选项解析:
IN 'log_name' 指定要查询的binlog文件名(不指定就是第一个binlog文件)
FROM pos 指定从哪个pos起始点开始查起(不指定就是从整个文件首个pos点开始算)
LIMIT [offset,] 偏移量(不指定就是0)
row_count 查询总条数(不指定就是所有行)
show binlog events in 'mysql-bin.000002' from 534620 limit 2,10
show binlog events in 'mysql-bin.000003'\G
*************************** 1. row ***************************
Log_name: mysql-bin.000003 ----> 查询的binlog日志文件名
Pos: 4 ----> pos起始点:
Event_type: Format_desc ----> 事件类型
Server_id: 1 ----> 标识是由哪台服务器执行的
End_log_pos: 120 ----> pos结束点:120(即:下行的pos起始点)
Info: use `sdf`; INSERT INTO `wtt` VALUES (1,'tom') ---> 执行的sql语句
*************************** 2. row ***************************
binlog文件操作
show master status;
show master logs;
flush logs;
该操作会新建一个 日志文件,并指定为当前文件。 mysql 重启一次,会自动执行此命令,所以也会自动生成一个新的binlog文件 在mysqldump备份数据时加 -F 选项,在备份完成后 也会自动执行此命令。
purge master logs before '2017-03-30 00:20:00';
mysql> purge master logs to 'mysql-bin.000009';
set global expire_logs_days=7;
show variables like 'expire_logs_days';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| expire_logs_days | 0 |
+------------------+-------+
reset master;
在生产环境中,这个操作是非常危险的
[mysqld]
binlog_format=MIXED
expire_logs_days=7
max_binlog_size 100m
binlog-do-db=wtt
binlog-ignore-db=test
数据恢复
本质: 让 binlog记录的操作 再 执行一遍。
mysqlbinlog mysql-bin.0000xx | mysql -u用户名 -p密码 [数据库名]
mysqlbinlog 常用命令参数:
--start-position=953 起始pos点
--stop-position=1437 结束pos点
--start-datetime="2017-6-20 13:18:54" 起始时间点
--stop-datetime="2017-6-20 13:21:53" 结束时间点
--database=wtt 指定只恢复 wtt 数据库
mysqlbinlog 不常用命令参数:
-u --user=name 连接到远程主机的用户名
-p --password[=name] 连接到远程主机的密码
-h --host=name 从远程主机上获取binlog日志
--read-from-remote-server 从某个MySQL服务器上读取binlog日志
mysqlbinlog --stop-position=759 --database=wtt mysql-bin.000007 | mysql -uroot -p123456 -v wtt
mysqlbinlog --start-position=759 --stop-position=880 --database=wtt mysql-bin.000007 | mysql -uroot -p123456 wtt
mysqlbinlog --start-datetime="2017-6-20 13:18:54" --stop-datetime="2013-16-20 14:21:53" --database=wtt mysql-bin.000007 | mysql -uroot -p123456 -v juzidb
当要某个数据库被删除了,要恢复数据库 这个级别时,mysql -uroot -p123456 后面 无需带 数据库名称, 当要恢复某个数据库的 数据表or记录时, mysql -uroot -p123456 后面 需带 数据库名称,
mysql 的 -v 说明: -V是查看版本的, -v 主要用在脚本、命令中可以用来简化代码
- 若要同时显示语句本身:-v
- 若要增加查询结果行数:-vv
- 若要增加执行时间:-vvv
上面的-v完全是就可以省略的。
2. 主从复制
简单来说,就是保证主SQL(Master)和从SQL(Slave)的数据是一致性的, 向Master插入数据后,Slave会自动从Master把修改的数据同步过来(避免不了的是会有一定的延迟), 通过这种方式来保证数据的一致性,就是主从复制。
注意:
- 主从服务器操作系统版本和位数一致,
- Master和Slave数据库的版本要一致,
Master和Slave的 server_id 必须唯一
原理
主要基于MySQL二进制日志,主要包括三个线程(2个I/O线程,1个SQL线程)
- MySQL将数据变化记录到二进制日志中;
- Slave将MySQL的二进制日志拷贝到Slave的中继日志中;
- Slave将中继日志中的事件再做一次,将数据变化,反应到自身(Slave)的数据库
只复制服务器中的一部分数据,有两种复制过滤:
- 在Master上过滤二进制日志中的事件
- 在Slave上过滤中继日志中的事件。
- 基于语句的复制, 对应 binlog的 默认模式;
- 基于行的复制, 对应 binlog的 重量模式;
- 默认采用 基于语句的复制, 对应 binlog的 智能模式;
实践
配置 master
[mysqld]
server_id=100
binlog-ignore-db=mysql
log-bin=edu-mysql-slave1-bin
binlog_cache_size=1M
binlog_format=mixed
expire_logs_days=7
slave_skip_errors=1062
relay_log=edu-mysql-relay-bin
log_slave_updates=1
read_only=1
配置完成后重启mysql
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
flush privileges;
配置 slave
[mysqld]
server_id=101
binlog-ignore-db=mysql
log-bin=edu-mysql-slave1-bin
binlog_cache_size=1M
binlog_format=mixed
expire_logs_days=7
slave_skip_errors=1062
relay_log=edu-mysql-relay-bin
log_slave_updates=1
read_only=1
建立连接
保证 带同步的数据库 中数据一致。
show master status\G
change master to master_host='192.168.100.70', master_user='slave', \
master_password='123456', master_port=3306, \
master_log_file='aaa.000001', master_log_pos=721657, \
master_connect_retry=30;
master_host=’192.168.100.70′
master_user=’slave’
master_password=’123456′
master_port=3306
master_log_file=’edu-mysql-bin.000001′
master_log_pos=120
master_connect_retry=30
show slave status;
start slave;
show slave status;
3. 完整、差异、增量备份
4. 查看 锁
show status like 'Table%';
show OPEN TABLES where In_use > 0;
show processlist
select trx_state, trx_started, trx_mysql_thread_id, trx_query from information_schema.innodb_trx;
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
|