前言
1:重做日志(redo log)
2:回滚日志(undo log)
3:二进制日志(binlog)
4:错误日志(errorlog)
5:慢查询日志(slow query log)
6:一般查询日志(general log)
7:中继日志(relay log)。
其中重做日志和回滚日志与事务 *** 作息息相关,二进制日志也与事务 *** 作有一定的关系,这三种日志,对理解MySQL中的事务 *** 作有着重要的意义。
一、重做日志(redo log)
作用:
确保事务的持久性。redo日志记录事务执行后的状态,用来恢复未写入data file的已成功事务更新的数据。防止在发生故障的时间点,尚有脏页未写入磁盘,在重启mysql服务的时候,根据redo log进行重做,从而达到事务的持久性这一特性。
内容:
物理格式的日志,记录的是物理数据页面的修改的信息,其redo log是顺序写入redo log file的物理文件中去的。
什么时候产生:
事务开始之后就产生redo log,redo log的落盘并不是随着事务的提交才写入的,而是在事务的执行过程中,便开始写入redo log文件中。
什么时候释放:
当对应事务的脏页写入到磁盘之后,redo log的使命也就完成了,重做日志占用的空间就可以重用(被覆盖)。
对应的物理文件:
默认情况下,对应的物理文件位于数据库的data目录下的ib_logfile1&ib_logfile2
innodb_log_group_home_dir 指定日志文件组所在的路径,默认./ ,表示在数据库的数据目录下。
innodb_log_files_in_group 指定重做日志文件组中文件的数量,默认2
关于文件的大小和数量,由以下两个参数配置:
innodb_log_file_size 重做日志文件的大小。
innodb_mirrored_log_groups 指定了日志镜像文件组的数量,默认1
其他:
很重要一点,redo log是什么时候写盘的?前面说了是在事物开始之后逐步写盘的。
之所以说重做日志是在事务开始之后逐步写入重做日志文件,而不一定是事务提交才写入重做日志缓存,原因就是,重做日志有一个缓存区Innodb_log_buffer,Innodb_log_buffer的默认大小为8M(这里设置的16M),Innodb存储引擎先将重做日志写入innodb_log_buffer中。
然后会通过以下三种方式将innodb日志缓冲区的日志刷新到磁盘
Master Thread 每秒一次执行刷新Innodb_log_buffer到重做日志文件。
每个事务提交时会将重做日志刷新到重做日志文件。
当重做日志缓存可用空间 少于一半时,重做日志缓存被刷新到重做日志文件
由此可以看出,重做日志通过不止一种方式写入到磁盘,尤其是对于第一种方式,Innodb_log_buffer到重做日志文件是Master Thread线程的定时任务。
因此重做日志的写盘,并不一定是随着事务的提交才写入重做日志文件的,而是随着事务的开始,逐步开始的。
另外引用《MySQL技术内幕 Innodb 存储引擎》(page37)上的原话:
即使某个事务还没有提交,Innodb存储引擎仍然每秒会将重做日志缓存刷新到重做日志文件。
这一点是必须要知道的,因为这可以很好地解释再大的事务的提交(commit)的时间也是很短暂的。
二、回滚日志(undo log)
作用:
保证数据的原子性,保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC),也即非锁定读
内容:
逻辑格式的日志,在执行undo的时候,仅仅是将数据从逻辑上恢复至事务之前的状态,而不是从物理页面上 *** 作实现的,这一点是不同于redo log的。
什么时候产生:
事务开始之前,将当前是的版本生成undo log,undo 也会产生 redo 来保证undo log的可靠性
什么时候释放:
当事务提交之后,undo log并不能立马被删除,而是放入待清理的链表,由purge线程判断是否由其他事务在使用undo段中表的上一个事务之前的版本信息,决定是否可以清理undo log的日志空间。
对应的物理文件:
MySQL5.6之前,undo表空间位于共享表空间的回滚段中,共享表空间的默认的名称是ibdata,位于数据文件目录中。
MySQL5.6之后,undo表空间可以配置成独立的文件,但是提前需要在配置文件中配置,完成数据库初始化后生效且不可改变undo log文件的个数
如果初始化数据库之前没有进行相关配置,那么就无法配置成独立的表空间了。
关于MySQL5.7之后的独立undo 表空间配置参数如下:
innodb_undo_directory = /data/undospace/ –undo独立表空间的存放目录 innodb_undo_logs = 128 –回滚段为128KB innodb_undo_tablespaces = 4 –指定有4个undo log文件
如果undo使用的共享表空间,这个共享表空间中又不仅仅是存储了undo的信息,共享表空间的默认为与MySQL的数据目录下面,其属性由参数innodb_data_file_path配置。
其他:
undo是在事务开始之前保存的被修改数据的一个版本,产生undo日志的时候,同样会伴随类似于保护事务持久化机制的redolog的产生。
默认情况下undo文件是保持在共享表空间的,也即ibdatafile文件中,当数据库中发生一些大的事务性 *** 作的时候,要生成大量的undo信息,全部保存在共享表空间中的。
因此共享表空间可能会变的很大,默认情况下,也就是undo 日志使用共享表空间的时候,被“撑大”的共享表空间是不会也不能自动收缩的。
因此,mysql5.7之后的“独立undo 表空间”的配置就显得很有必要了。
三、二进制日志(binlog):
作用:
用于复制,在主从复制中,从库利用主库上的binlog进行重播,实现主从同步。
用于数据库的基于时间点的还原。
内容:
逻辑格式的日志,可以简单认为就是执行过的事务中的sql语句。
但又不完全是sql语句这么简单,而是包括了执行的sql语句(增删改)反向的信息,也就意味着delete对应着delete本身和其反向的insert;update对应着update执行前后的版本的信息;insert对应着delete和insert本身的信息。
在使用mysqlbinlog解析binlog之后一些都会真相大白。
因此可以基于binlog做到类似于oracle的闪回功能,其实都是依赖于binlog中的日志记录。
什么时候产生:
事务提交的时候,一次性将事务中的sql语句(一个事物可能对应多个sql语句)按照一定的格式记录到binlog中。
这里与redo log很明显的差异就是redo log并不一定是在事务提交的时候刷新到磁盘,redo log是在事务开始之后就开始逐步写入磁盘。
因此对于事务的提交,即便是较大的事务,提交(commit)都是很快的,但是在开启了bin_log的情况下,对于较大事务的提交,可能会变得比较慢一些。
这是因为binlog是在事务提交的时候一次性写入的造成的,这些可以通过测试验证。
什么时候释放:
binlog的默认是保持时间由参数expire_logs_days配置,也就是说对于非活动的日志文件,在生成时间超过expire_logs_days配置的天数之后,会被自动删除。
对应的物理文件:
配置文件的路径为log_bin_basename,binlog日志文件按照指定大小,当日志文件达到指定的最大的大小之后,进行滚动更新,生成新的日志文件。
对于每个binlog日志文件,通过一个统一的index文件来组织。
其他:
二进制日志的作用之一是还原数据库的,这与redo log很类似,很多人混淆过,但是两者有本质的不同
作用不同:redo log是保证事务的持久性的,是事务层面的,binlog作为还原的功能,是数据库层面的(当然也可以精确到事务层面的),虽然都有还原的意思,但是其保护数据的层次是不一样的。
内容不同:redo log是物理日志,是数据页面的修改之后的物理记录,binlog是逻辑日志,可以简单认为记录的就是sql语句
另外,两者日志产生的时间,可以释放的时间,在可释放的情况下清理机制,都是完全不同的。
恢复数据时候的效率,基于物理日志的redo log恢复数据的效率要高于语句逻辑日志的binlog
关于事务提交时,redo log和binlog的写入顺序,为了保证主从复制时候的主从一致(当然也包括使用binlog进行基于时间点还原的情况),是要严格一致的,MySQL通过两阶段提交过程来完成事务的一致性的,也即redo log和binlog的一致性的,理论上是先写redo log,再写binlog,两个日志都提交成功(刷入磁盘),事务才算真正的完成。
四、错误日志
错误日志记录着mysqld启动和停止,以及服务器在运行过程中发生的错误的相关信息。在默认情况下,系统记录错误日志的功能是关闭的,错误信息被输出到标准错误输出。
指定日志路径两种方法:
编辑my.cnf 写入 log-error=[path]
通过命令参数错误日志 mysqld_safe –user=mysql –log-error=[path] &
显示错误日志的命令(如下图所示)
五、普通查询日志 general query log
记录了服务器接收到的每一个查询或是命令,无论这些查询或是命令是否正确甚至是否包含语法错误,general log 都会将其记录下来 ,记录的格式为 {Time ,Id ,Command,Argument }。也正因为mysql服务器需要不断地记录日志,开启General log会产生不小的系统开销。 因此,Mysql默认是把General log关闭的。
查看日志的存放方式:show variables like ‘log_output’
如果设置mysql>set global log_output=’table’ 的话,则日志结果会记录到名为gengera_log的表中,这表的默认引擎都是CSV
如果设置表数据到文件set global log_output=file
设置general log的日志文件路径:
set global general_log_file=’/tmp/general.log’
开启general log: set global general_log=on
关闭general log: set global general_log=off
然后在用:show global variables like ‘general_log’
六、慢查询日志
慢日志记录执行时间过长和没有使用索引的查询语句,报错select、update、delete以及insert语句,慢日志只会记录执行成功的语句。
1. 查看慢查询时间:
show variables like “long_query_time”默认10s
2. 查看慢查询配置情况:
show status like “%slow_queries%”
3. 查看慢查询日志路径:
show variables like “%slow%”
4. 开启慢日志
查看已经开启:
获取mysql有关的帮助信息,直接在mysql提示符下输入help即可获得有关在mysql客户端相关的帮助信息。这个方式与Oracle SQL*plus下的help 是类似的。
mysql>help
For information about MySQL products and services, visit:
http://www.mysql.com/
For developer information, including the MySQL Reference Manual, visit:
http://dev.mysql.com/
To buy MySQL Enterprise support, training, or other products, visit:
https://shop.mysql.com/
List of all MySQL commands:
Note that all text commands must be first on line and end with ''
? (\?) Synonym for `help'.
clear (\c) Clear the current input statement. --清除当前输入的语句
connect (\r) Reconnect to the server. Optional arguments are db and host. --重新连接,通常用于被剔除或异常断开后重新连接,SQL*plus下也有这样一个connect命令
delimiter (\d) Set statement delimiter. --设置命令终止符,缺省为;,比如我们可以设定为/来表示语句结束
edit (\e) Edit command with $EDITOR. --编辑缓冲区的上一条SQL语句到文件,缺省调用vi,文件会放在/tmp路径下
ego (\G) Send command to mysql server, display result vertically. --控制结果显示为垂直显示
exit (\q) Exit mysql. Same as quit. --退出mysql
go(\g) Send command to mysql server. --发送命令到mysql服务
help (\h) Display this help.
nopager (\n) Disable pager, print to stdout.--关闭页设置,打印到标准输出
notee (\t) Don't write into outfile. --关闭输出到文件
pager (\P) Set PAGER [to_pager]. Print the query results via PAGER. --设置pager方式,可以设置为调用more,less等等,主要是用于分页显示
print (\p) Print current command.
prompt(\R) Change your mysql prompt. --改变mysql的提示符
quit (\q) Quit mysql.
rehash(\#) Rebuild completion hash. --自动补齐相关对象名字
source(\.) Execute an SQL script file. Takes a file name as an argument. --执行脚本文件
status(\s) Get status information from the server.--获得状态信息
system(\!) Execute a system shell command.--执行系统命令
tee (\T) Set outfile [to_outfile]. Append everything into given outfile.-- *** 作结果输出到文件
use (\u) Use another database. Takes database name as argument. --切换数据库
charset (\C) Switch to another charset. Might be needed for processing binlog with multi-byte charsets. --设置字符集
warnings (\W) Show warnings after every statement. --打印警告信息
nowarning (\w) Don't show warnings after every statement.
--上面的所有命令,扩号内的为快捷 *** 作,即只需要输入“\”+ 字母即可执行
For server side help, type 'help contents'--注意这里的描述help contents将获得服务器端的相关帮助信息
--演示部分,演示常用命令
--connect命令
mysql>connect chardb localhost
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Connection id:5
Current database: chardb
--设置分页,在多余一个页面显示时会不停的翻滚,用该命令可以设置分页,设置为调用系统命令
mysql>pager more --设置为more方式
PAGER set to 'more'
mysql>select table_name,table_type,engine from information_schema.tables --该查询会超出一屏显示后按空格键会自动翻滚到下一屏
mysql>pager tail -5 --设置输出尾部5行
PAGER set to 'tail -5'
mysql>select table_name,table_type,engine from information_schema.tables
| setup_timers | BASE TABLE | PERFORMANCE_SCHEMA |
| threads | BASE TABLE | PERFORMANCE_SCHEMA |
| animals | BASE TABLE | InnoDB |
| shop | BASE TABLE | InnoDB |
+----------------------------------------------+-------------+--------------------+
92 rows in set (0.02 sec)
mysql>pager --查看当前的pager设置
PAGER set to 'tail -5'
mysql>nopager --切换到标准(缺省)pager方式
PAGER set to stdout
--tee命令,输出日志文件
mysql>tee /tmp/query.log--开启输出到文件,相当与SQL*plus下的spool
Logging to file '/tmp/query.log'
mysql>select table_name,table_type,engine from information_schema.tables
+----------------------------------------------+-------------+--------------------+
| table_name | table_type | engine |
+----------------------------------------------+-------------+--------------------+
| CHARACTER_SETS | SYSTEM VIEW | MEMORY |
| COLLATIONS | SYSTEM VIEW | MEMORY |
.............
mysql>notee --关闭输出到文件,相当于SQL*Plus下的spool off
Outfile disabled.
mysql>system tail /tmp/query.log--查看输出的日志文件
| setup_consumers | BASE TABLE | PERFORMANCE_SCHEMA |
| setup_instruments| BASE TABLE | PERFORMANCE_SCHEMA |
| setup_timers | BASE TABLE | PERFORMANCE_SCHEMA |
| threads | BASE TABLE | PERFORMANCE_SCHEMA |
| animals | BASE TABLE | InnoDB |
| shop | BASE TABLE | InnoDB |
+----------------------------------------------+-------------+--------------------+
92 rows in set (0.02 sec)
--改变mysql提示符
mysql>prompt SessionA>
PROMPT set to 'SessionA>'
--恢复到缺省提示符
SessionA>prompt
Returning to default PROMPT of mysql>
--执行sql脚本文件
mysql>system more query.sql --注意,此时为当前目录
use chardb
select * from tb_isam
mysql>source query.sql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
+------+-------+
| id | value |
+------+-------+
|1 | a |
|2 | b |
|3 | c |
|4 | f |
+------+-------+
4 rows in set (0.00 sec)
--获取状态信息
mysql>status
--------------
mysql Ver 14.14 Distrib 5.5.37, for Linux (x86_64) using readline 5.1
Connection id: 6
Current database: chardb
Current user: root@localhost
SSL:Not in use
Current pager: less
Using outfile: ''
Using delimiter:
Server version: 5.5.37-log MySQL Community Server (GPL)
Protocol version: 10
Connection: Localhost via UNIX socket
Server characterset:latin1
Db characterset:utf8
Client characterset:latin1
Conn. characterset:latin1
UNIX socket:/var/lib/mysql/mysql.sock
Uptime: 3 hours 10 min 59 sec
Threads: 1 Questions: 97 Slow queries: 0 Opens: 313 Flush tables: 1 Open tables: 51 Queries per second avg: 0.008
--------------
--修改客户端字符集
在学习SQL语句之前,首先需要区分几个概念,我们常说的数据库是指数据库软件,例如MySQL、Oracle、SQL Server等,而本文提到的数据库是指数据库软件中的一个个用于存储数据的容器。
在MySQL中,数据库称为database,数据表称为table,一个数据库软件中有多个数据库(databases),每个数据库中又可以有多个数据表(tables),最终,数据是存储在数据表中。
数据库和数据表之间的关系可以用下面这个图来表示,对于一个数据库来说,有多个数据表。
在正式开始写SQL语句之前,需要说明两点。
这里通过MySQL Workbench来写SQL代码,在Workbench中,执行一条SQL语句的方式有两种。
了解了这之后,接下来介绍一些常见的命令,分两部分:数据库常用命令和数据表常用命令。
1、查看有哪些数据库
2、创建数据库
创建一个名为Testdb的数据库。
3、创建数据库并指定编码格式
有些时候,为了防止中文乱码,创建数据库的时候需要指定编码格式。
4、使用某个数据库
使用mydb这个数据库,或者进入mydb这个数据库。
5、删除数据库
删除Testdb这个数据库。
1、查看有哪些数据表
进入某个数据库之后,想查看有哪些数据表,SQL语句为:
mydb是一个新建的数据库,所以自然是没有数据表。
2、创建数据表
建表SQL语句格式为:
说明: 每个字段以逗号分隔,最后一个字段不加逗号。
例如,给定一个学员信息表,如下表所示。
根据以上表格,建表SQL语句如下。
以上语句中,primary key表示主键,意思是这个字段作为记录的唯一标识,就像每个人的身份z号,都是唯一确定的。
3、查看表结构
查看表结构的SQL命令为:
执行该命令会显示表stuinfo的基本结构,例如有哪些字段,每个字段是什么类型,谁是主键等。
4、修改数据表
修改数据表通过drop子句进行,比如,建完表后,想增加一个字段,SQL语句的格式为:
想在指定位置增加一个字段,例如,在某个字段后增加一个字段,SQL语句的格式为:
如果在某个字段之前增加字段,用before即可。
例如,在字段age后增加一个字段major(专业),SQL语句为:
执行这个命令,再通过describe查看表结构,会发现表中多了一个字段major。
如果要删除major这个字段,通过drop子句,SQL语句为:
5、重命名表
重命名表通过alter+rename来实现,SQL语句格式为:
这里为了不影响之前创建的表,我们创建一个新表,SQL语句如下。
以上创建一个名为stuInfoTest的表,现在想将它的名称改成stuinfotest1,SQL语句为:
6、删除数据表
删除数据表通过drop进行,SQL语句格式为:
例如,删除数据表stuinfotest1,SQL语句为:
7、插入记录
此时的表stuinfo是空的,没有数据,我们要向表中插入记录。
插入记录通过insert into进行,SQL语句格式为:
例如,向表stuinfo插入一条记录,SQL语句为:
注意:上方是一条SQL语句,为了可读性换行,记住一条SQL语句默认以分号结尾。
如果需要一次性插入多条记录,SQL语句格式为:
例如,向表stuinfo再插入两条记录,SQL语句为:
注意:如果设置了主键,插入记录的主键字段是不能重复的,也就是不能插入重复的记录。
作业:大家可以按照上述方法将上面的学员信息表中的所有记录都插入表stuinfo中。
8、查询记录
有了数据之后,就可以查询记录了,查询记录通过select子句进行。
例如,想查询表stuinfo中的所有记录,SQL语句为:
执行之后,就可以看到表stuinfo中的所有记录了。
如果想查询符合某个条件的记录,就要用到where子句了,SQL格式为:
例如,想查询stuid为20161001的记录,SQL语句为:
9、删除记录
删除记录通过delete子句进行,SQL语句格式为:
例如,想删除stuid为20161002的记录,SQL语句为:
10、修改记录
修改记录通过update子句进行,update就是更新的意思,SQL语句格式为:
例如,想将学号(stuid)为20161001的记录的姓名(stuname)更新为Jack,SQL语句为:
以上,就是MySQL中的基本SQL语句。
零基础如何学习数据分析?查看下方专栏。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)