MariaDB数据库并发控制和日志管理
---------------------------------------------------------------------------------------------------------------------------------------------
1、并发控制
(1)锁粒度:表级锁、行级锁
(2)读锁:共享锁,只读不可写,多个读取互不阻塞,意思是多台主机可以同时查看一张上了读锁的表
写锁:独占锁、排它锁,一个写锁会阻塞其它读和写锁,当A用户对表上写锁,其他用户对该表不能读,更不能写
(3)使用锁
LOCK TABLES tblname {READ | WRITE}:加锁
UNLOCK TABLES:解锁
FLUSH TABLES TBNAME:关闭正在打开的表,在备份前加全局读锁,如果不指定表明,全部数据库全部表格都将加入读锁,适用于温备分
SELECT...WHERE从句 FOR UPDATE:加写锁
SELECT...WHERE从句 LOCK IN SHARE MODE:加读锁
读锁示例
写锁示例
(4)实现
存储引擎:自行实现其锁策略和锁粒度
服务器级:实现了锁,表级锁;用户可显示请求
(5)分类
隐式锁:由存储引擎自动施加锁
显示锁:用户手动请求
(6)锁策略:在锁粒度及数据安全性寻求的平衡机制
2、事务
(1)事务Transactions:一组原子性的SQL语句,或一个独立动作单元
(2)事务日志:记录事务信息,实现undo,redo等故障恢复功能
(3)事务的ACID特性:
A:atomicity,原子性,整个事务中的所有操作要么全部成功执行,要么全部失败后回滚
C:consistency一致性,数据库总是从一个一致性状态转换为另一个一致性状态
I:isolation隔离性,一个事务所做出的操作在提交之前,不能被其它事务所见,隔离有多种隔离级别,实现并发
D:durability持久性,一旦事务提交,其所做的修改会永久保存于数据库中
3、事务生命周期
4、事务流程
(1)启动事务
BEGIN、BEGIN WORK\START TRANSACTION
(2)结束事务
COMMIT:提交,ROLLBACK:回滚
注:只有事务型存储引擎中的DML语句方能支持此类操作,即增删改操作
(3)自动提交:set autocommit={1|0},默认为1,为0时设为手动提交
建议:显式请求和提交事务,而不要使用“自动提交”功能
mysql和sql server默认设置是自动提交,oracle默认手动提交
网站查询结果是--autocommit, autocommit,表明选项和变量都有
(4)事务支持保存点:savepoint
SAVEPOINT identifier
ROLLBACK [WORK] TO [SAVEPOINT] identifier
RELEASE SAVEPOINT identifier
注意:savepoint保存点名称必须字母开头,不可以是纯数字
示例
提交后
事务保存点示例:先有以下结果产生
此时后悔了,想把数据表恢复到savepoint sp2处,也就是sp2点完菜,但未做sp3点,结果如图
5、事务隔离级别
(1)事务隔离级别:从上到下越来越严格
<1>READ UNCOMMITTED 可读取到未提交数据,产生脏读
<2>READ COMMITTED 可读取到提交数据,但未提交数据不可读,产生不可重复读,即可读取到多个提交数据,导致每次读取数据不一致
<3>REPEATABLE READ 可重复读,多次读取数据都一致,产生幻读,即读取过程中,即使有其它提交的事务修改数据,仍只能读取到未修改前的旧数据。此为MySQL默认设置,意思是修改记录过程中表格对其他用户产生行锁,事务完成提交后才对其他用户显示修改后的数据
<4>SERIALIZABILE 可串行化,未提交的读事务阻塞修改事务,或者未提交的修改事务阻塞读事务。导致并发性能差
(2)MVCC: 多版本并发控制,和事务级别相关
事务隔离级别 |
脏读可能性 |
不可重复读 可能性 |
幻读可能性 |
加锁读 |
读未提交(read-uncommitted) |
Y |
Y |
Y |
N |
不可重复读(read-committed) |
N |
Y |
Y |
N |
可重复读(repeatable-read) |
N |
N |
Y |
N |
串行化(serializable) |
N |
N |
N |
Y |
(3)指定事务隔离级别
SET tx_isolation=''
READ-UNCOMMITTED
READ-COMMITTED
REPEATABLE-READ
SERIALIZABLE
服务器选项中指定
vim /etc/my.cnf
[mysqld]
transaction-isolation=SERIALIZABLE
6、并发控制
(1)死锁:两个或多个事务在同一资源相互占用,并请求锁定对方占用的资源的状态
(2)事务日志的写入类型为“追加”,因此其操作为“顺序IO”;通常也被称为:预写式日志 write ahead logging,条件允许可以将事务日志独立放入一个硬盘分区中,使得事务日志的写入不用随便插入地方进行写入而是追加
日志文件: ib_logfile0, ib_logfile1,位于数据库存放目录下,可以更
7、解决阻塞(工作中慎用)
(1)show processlist \G
(2)看到数据库进程后确定结束阻塞的id号,比如5号,输入kill 5
8、日志
(1)当对一个表格删除大量数据后,它的日志文件不会缩小,此时需要优化表格,执行命令:optimize table TBLNAME,使得该表的日志文件容量缩小
(2)日志类型
<1>日志
附:慢查询profiling工具用法
<2>二进制日志,因为非常重要,内容又多,所以单独放一分类
<3>二进制日志的客户端命令工具
mysqlbinlog [OPTIONS] log_file...
--start-position= 指定开始位置的POS点
--stop-position= 指定结束位置的POS点
--start-datetime=
--stop-datetime=
时间格式,YYYY-MM-DD hh:mm:ss
--base64-output[=name]
示例:mysqlbinlog --start-position=1465 --stop-position=2123 mysql-bin.000001
<4>清除指定二进制日志
PURGE { BINARY | MASTER } LOGS
{ TO 'log_name' | BEFORE datetime_expr }
示例:
PURGE BINARY LOGS TO ‘mariadb-bin.000003’;删除3之前的日志
PURGE BINARY LOGS BEFORE '2017-01-23';
PURGE BINARY LOGS BEFORE '2017-03-22 09:25:30';
<5>删除所有二进制日志,index文件重新记数
RESET MASTER [TO #]; 日志文件从#开始记数,默认从1开始,一般是master第一次启动时执行,MariaDB10.1.6开始支持TO #
<6>切换日志文件:
FLUSH LOGS;