全库逻辑备份:
- flush table with read lock,只能进行select语句,不能执行DML,以及DDL语句。适用于不支持事务的表进行备份。
- 使用mysql自带的逻辑备份工具mysqldump,使用参数-single transaction来建立一个视图进行备份,由于mvcc的支持,可以对技术进行更新操作
- 注意:set global readonly = true和FTWRL都可以使整个库处于只读状态,但是两者之间还是有差异的 主要有两点区别:
- set global readonly = true这个参数还可能有其他意义,比如再主从架构之中用来做主从库的判断
- 异常处理机制有区别,FTWRL再mysql客户端连接异常中断之后全局锁会释放,但是设置参数的方式依然会使整个库处于只读状态,不会释放锁。
表级锁:
- 添加表级锁的语法:lock tables ... read/write,可以通过语句unlock tables手动释放锁。这种加锁方式和FTWRL类似,再客户端异常断开之后,会自动释放锁。
- 元数据锁,这是一种特殊的表级锁,不许要进行显示加锁,当访问一张表的时候会自动加锁,当对这张表中的数据进行增删改查的时候,会加读锁,在对一张表增加字段时会加写锁。注意:
- 读锁之间不相互冲突,意思就是两个线程可以同时对一张表进行增删改查操作
- 读锁和写锁之间,写锁之间互相冲突。若两个两个线程需要同时对一张表增加字段,就需要进行排队等候了
- 增加一个字段可能使整个库挂掉,分析下面这个实例: sessionA和sessionB都可以正常申请到读锁,进行读操作,但是由于sessionA 和 session B的事务没有结束,导致session C在申请写锁的时候申请不到写锁资源,进入阻塞状态,于此同时,session D申请读锁也会失败。mysql自带有重试机制,当select查询不到时会自动开启以一个新的session进行查询请求,这样服务端线程会爆满
- 我们如何个一个表增加一个字段并且不会影响后面的线程请求呢? 首先我们可以从占用所资源的一方来解决,也就是先前的长事务,在mysql中infomation_schema库的innodb_trix这个表中查看目前正在运行的事务,若有事务占用你将要申请表的锁资源的时候,kill这个长事务,元数据所会自动进行释放,因此你就会申请到这个表的写锁了。但是若有一个表数据量不大,但是查询频率很高,上面这种方式就不能解决了,因为即使你杀死一个线程之后马上会另一个线程及进行请求,所以你可以通过使用alter table里面设置等待时间,在等待时间之内申请到了就进行增加字段,若没有申请到就先进行放弃,避免影响后面的查询,之后等待程序员或者DBA手动重试或者命令来增加字段。 以上有两种方式,既可以设置等待时间,也可以不设置。