今天遇到了一些关于处理数据库操作相关的事情,先做一些简要的总结:
昨天老大安排要测试一下数据库单表中可以插入多少条记录,为此做了个简单的网页来跑这个程序,昨天下班的时候忘记查看记录,为此导致在同一数据库的其他项目不能正确拉取数据库。错误的原因很简单,数据库所在的磁盘分区已满,数据库不满进行数据库操作。
在得到数据库所在磁盘分区已满的情况下,首先想到的是要将测试数据删除掉,我们采取的操作为清表操作,即truncate table document,但是过了一段时间却没有却发现“show processlist”该语句依然在“waiting for table”。此后kill了这条语句,依然发现“waiting for table”。而执行这两条语句期间“select count(*) from documents ”的结构没有变。此后一段时间一度想直接删除数据库相关的文件,经与运维的同事一讨论发现这是时分愚蠢的做法。
运维童鞋的提议是删除一些数据库所在磁盘分区的一些文件,然后再进行删除数据库的操作。分析了一下该分区下的文件,竟然发现一程序的日志文件竟然达到拉31G如此庞大,清空此文件之后即可进行数据库的操作。
究其原因,在数据库操作过程中,数据库中部分数据需要回写到磁盘中。在我操作的MySQL所在磁盘中,使用率已经为100%。所以才会出现在没用锁表情况下的“waiting for documents”的提示信息。
总结处理此类问题的方法:
1、 首先要查看mysql的慢日志记录,mysql的配置文件通常存放在/etc/my.cnf中,可以根据此文件找到mysql配置文件的位置;
2、 利用show processlist,查看当前语句的执行状态,关键是查看该语句是否被“Locked”;
3、 分析Locked的原因;
4、 查看MySQL所在磁盘分区的使用情况。
附此次操作中的学习的主要命令:
1、 杀掉MySQL中执行某些语句连接的方式,kill该连接的ID号,类似于杀死进程一样的方式;
2、 查看系统的分区情况:
3、查看分区下文件大小的命令
顺便也学习了一下关于MySQL锁的相关概念:
MySQL的锁并非像Linux中的P/V锁。如果在Linux中用sem_wait和sem_post进行P/V锁操作,如果此时发生死锁,没有其他可以选择的方式,只能由系统的守护来负责解锁操作。但是在MySQL中的锁,即使执行该操作的MySQL进程显示为“Locked”,并非是显示死锁,而是临时锁,而是等待前面正在执行的语句执行完毕,释放该表的时候,此锁就会解锁,继续执行该语句。MySQL就像对所有待执行的语句做了一个等待队列,在等待队列中的语句显示为“Locked”状态。