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