记得在09年系统架构师大会上一个51.com的DBA秀了一个mysql的小“魔术”,其大概过程是不更改数据库表中的数据,只是执行了一下flush table表中的数据就全部改变。

之前没研究过mysql,一时也不明就里。

这两天对mysql很感兴趣,想起了去年这位老兄的“魔术”。今天就做了个测试重现了一下这个场景。[@more@]

测试过程如下:

mysql> select * from test;

+------+

| name |

+------+

| 1 |

| 2 |

| 3 |

| 4 |

| 5 |

+------+

5 rows in set (0.00 sec)

mysql> select * from test;

+------+

| name |

+------+

| 1 |

| 2 |

| 3 |

| 4 |

| 5 |

+------+

5 rows in set (0.00 sec)

mysql> flush tables;

Query OK, 0 rows affected (0.00 sec)

mysql> select * from test;

+------------------------------+

| name |

+------------------------------+

| 热烈祝贺宇宙大爆炸一万万周年 |

| 忽忽变了变了 |

+------------------------------+

2 rows in set (0.00 sec)

mysql>

测试中使用的表是MyIsam引擎。

只是执行flush table并没有update,delete,insert的操作说明这个现象也就是跟缓存之类的有关。

先看看flush table是做了什么。

mysql参考手册中解释:

关闭打开的表,并迫使所有正在使用的表关闭。这也会刷新查询缓存。和RESET QUERY CACHE语句一样,FLUSH TABLES还会取消来自查询缓存的所有查询结果。

呵呵 下面来分析一下这个“魔术”是怎么产生的。

首先我们会想到query cache,其实这很容易理解。

本次测试中query cache参数如下:

mysql> show variables like 'q%';

+------------------------------+----------+

| Variable_name | Value |

+------------------------------+----------+

| query_alloc_block_size | 8192 |

| query_cache_limit | 1048576 |

| query_cache_min_res_unit | 4096 |

| query_cache_size | 34603008 |

| query_cache_type | ON |

| query_cache_wlock_invalidate | OFF |

| query_prealloc_size | 8192 |

+------------------------------+----------+

7 rows in set (0.00 sec)

mysql中的query cache的功能是缓存查询结果,在下次查询是如果查询语句相同会直接从缓存中提取结果,而不是从数据表中查询。

当然并非是所有的查询都会被缓存,要满足一定条件:结果集超过query_cache_limit的大小不缓存,procedure中的结果不缓存,子查询中的外联结果集不缓存。。

本次测试不存在这些问题。

所有过程如下:

先插入数据:

mysql> insert into test values("热烈祝贺宇宙大爆炸一万万周年");

Query OK, 1 row affected (0.00 sec)

mysql> insert into test values("忽忽变了变了");

Query OK, 1 row affected (0.00 sec)

然后把数据文件copy到其他位置

root@qadb:/var/lib/mysql/test# cp -a test.* /root/test

删除表中的数据

mysql> delete from test;

Query OK, 3 rows affected (0.00 sec)

插入新数据

mysql> insert into fuleqing values('1');

Query OK, 1 row affected (0.00 sec)

mysql> insert into fuleqing values('2');

Query OK, 1 row affected (0.00 sec)

mysql> insert into fuleqing values('3');

Query OK, 1 row affected (0.00 sec)

mysql> insert into fuleqing values('4');

Query OK, 1 row affected (0.00 sec)

mysql> insert into fuleqing values('5');

Query OK, 1 row affected (0.00 sec)

最后把之前备份的数据文件覆盖现在的数据文件

root@qadb:/var/lib/mysql/test# cp -a /root/test.* .

现在在之客户端执行select ,flush,select这个”魔术“就可以了

到这里大家应该都看明白了吧,如果我们使用DDL语句更改数据则相关的query cache则会相应的失效,再次使用会从数据表中读取。但如果使用直接数据文件覆盖的话至少目前mysql的MyIsam引擎并不知道数据发生了变化,相应的query cache并不会失效。第一次select的结果其实是从cache里取的旧数据,直到flush后query cache被清空,然后再select才是从新的数据文件读取。

下面我再做一个小”魔术“,不使用query cache

mysql> select sql_no_cache * from test;

+------+

| name |

+------+

| 1 |

| 2 |

| 3 |

| 4 |

| 5 |

+------+

5 rows in set (0.00 sec)

mysql> select sql_no_cache * from test;

+------+

| name |

+------+

| 1 |

| 2 |

| 3 |

| 4 |

| 5 |

+------+

5 rows in set (0.00 sec)

mysql> flush tables;

Query OK, 0 rows affected (0.00 sec)

mysql> select sql_no_cache * from test;

+------------------------------+

| name |

+------------------------------+

| 热烈祝贺宇宙大爆炸一万万周年 |

| 忽忽变了变了 |

+------------------------------+

2 rows in set (0.00 sec)

mysql>

一般到这里大家会产生点疑问,都不从cache里取数据了为什么也会出现这个现象呢?

如果我们还是按照之前的操作,用备份的数据文件覆盖是不行的。

大家可以看到有两种情况,如果备份的数据比当前的数据多,只显示新数据文件中的部分数据。如果备份的数据比当前的数据少,查询即报错。

mysql> select sql_no_cache * from test;

ERROR 1194 (HY000): Table 'test' is marked as crashed and should be repaired

这些跟mysql的故障侦测机制有关,我没有深入的研究。等以后有时间再看

在出现上面这些情况时做一下flush table或者repair一下都可以恢复正常,但是重现不了我们这次的”魔术“

说一下我操作的过程:

插入数据->备份表的数据文件

delete旧数据

insert新数据

这个过程跟前一个场景相同.之后就不一样了

删除当前数据文件

root@qadb:/var/lib/mysql/test# rm test.*

copy回备份数据文件

root@qadb:/var/lib/mysql/test# cp -a /root/temp/test.* .

现在前面的客户端又可以执行select,flush,select这个"魔术"了

这次又是为什么呢?

首先声明这次的测试只有在linux/unix中才能实现,windows不可以

我们知道mysql是通过os来操作数据文件的,这就要跟linux/unix对文件的处理有关.

一个比较经典的问题,在windows中当一个文件被使用的时候,另一个进程可以删除这个文件吗?这个我们都知道不行。

但在linux/unix中呢?是可以的。之前读取文件的进程在文件被另一个进程删除后会报错吗?也不会。

这个文件这时候其实并没有真正意义上删除。在linux/unix中只有所有操作该文件的进程/线程都退出,该文件才会真正的被释放。

分析本次的select,flush,select的操作如下:

虽然另一个进程删除了数据文件并copy进新的数据文件但由于之前表是open的,mysql后台线程一直在使用旧数据文件,该文件并未真正删除。此时select的数据仍是旧数据。

flush 关闭表,使用旧数据文件的线程退出,旧数据文件被真实释放;

再次select 表open这时读取新的数据文件。此时select的数据为新数据。

总结:

第一次的”魔术“是由于mysql的query cache造成的有趣现象;

第二次的”魔术“是由于linux/unix操作系统本身对文件的并发处理机制造成的有趣现象;

如果有兴趣大家可以再研究研究有没有其他的可能。

mysql 魔术设置_09年系统架构师大会中一个mysql小魔术的分析相关推荐

  1. 2011系统架构师大会分享-自动化运维中的关系管理

    问过一些技术方向的朋友,在他们眼中运维是做怎么样的事情?其中大部份人回答说:搬机器.装系统.收报警.写各种各样维护清理的shell脚本等等.运维真的只是做这些事情? 不同的公司.不同规模的集群,运维所 ...

  2. 系统架构师大会推荐的10本云计算图书

    本文讲的是系统架构师大会推荐的10本云计算图书 [IT168 资讯]2010年系统架构师大会于8月28日在北京落下帷幕."云计算"成为此次大会的一大焦点,IT168企业级编辑部总编 ...

  3. 引领架构创新之路第八届系统架构师大会撼世来袭

    作为国内最受欢迎的架构师盛会,2016年第八届中国系统架构师大会(SACC2016)即将于10月27-29日在北京盛大召开.本届大会以"架构创新之路"为主题,安排两大主场和24个专 ...

  4. 在Linux系统的命令行中为MySQL创建用户的方法

    这篇文章主要介绍了在Linux系统的命令行中为MySQL创建用户的方法,包括对所建用户的权限管理,需要的朋友可以参考下 要访问一个MySQL服务器,你需要使用一个用户帐号登录其中方可进行.每个MySQ ...

  5. mysql的相关技术说明_MySQL 系统架构 说明

    说明:本文转自 简朝阳(MySQL ACE)的 <MySQL性能调优与架构设计> 一.逻辑模块组成 总的来说,MySQL 可以看成是二层架构,第一层我们通常叫做SQL Layer,在MyS ...

  6. 2015年的系统架构师大会随感

    引言: 由itpub等几家媒体主办的2015系统架构师大会,历时三天,笔者参加各个场次,予以文字,略作纪录. 每一年的大会都会选择在京城西环的云南饭店,今年亦不例外:依然是人来人往,各色人等,穿梭其间 ...

  7. mysql 手动配置服务器_Win7系统下手动配置Apache+PHP+MySQL环境WEB服务器 -电脑资料...

    本来想学学php,于是就想搭建web服务器和sql环境,结果浪费掉了不少时间, 大致的总结下,也算是长个记性. 使用的安装包分别是httpd-2.2.22-win32-x86-no_ssl .msi, ...

  8. Windows10系统的Linux子系统中安装MySQL数据库心得

    后端开发童鞋们, 自己开发机用的是Windows系统电脑(台式机或笔记本), 而开发的程序和使用的数据库等要运行在Linux服务器上, 这种情况有木有? 提前声明: 本文并不讨论操作系统的比较, 以及 ...

  9. ai系统架构_人工智能中的模糊逻辑系统架构

    ai系统架构 The Fuzzy Logic System is a system which uses Fuzzy logic for reasoning. Fuzzy Logic is a ver ...

最新文章

  1. ios searchBar 的代理方法 集合
  2. wamp(ajax)
  3. 关于SparkMLlib的基础数据结构Spark-MLlib-Basics
  4. eclipse 重构_Eclipse对类固醇的重构
  5. 人工智能与大数据的完美结合 1
  6. 敏捷开发团队管理系列之二:程序与测试团队I
  7. Linux有哪些目录命令,linux最常用的20个命令有哪些
  8. linux删除更新的系统内核,Linux系统如何删除旧内核
  9. [codeup 2143] 迷瘴
  10. qq空间把android改成iphone,qq空间利用代码修改iPhone6 Plus详细方法 qq空间修改手机型号教程...
  11. Selenium加速执行方法
  12. C#Winform拓展控件之Panel
  13. java生成短网址_http 长网址、短网址(短网址生成API)
  14. ADV-234-字符串跳步
  15. 从罗马帝国精英军团/秦帝国军制谈iOS/Android
  16. 图书馆图书上架_泉城书房济南市平阴县图书馆锦东分馆图书上架了!
  17. Es6箭头函数详细用法
  18. 【云原生 | 44】Docker搭建Registry私有仓库之管理访问权限
  19. 【Linux】动态链接库 cannot find -lxxx问题总结
  20. Echarts清空图表:There is a chart instance already initialized on the dom.

热门文章

  1. (BY框架)多产品多外协工序合同(加工协议书)预览
  2. Seo:秒排建站(三)主机推荐补充讲解
  3. django 加 celery 异步任务配置到成功运行
  4. css怪异盒子模型,CSS3弹性盒---怪异盒
  5. 51单片机之智能小车(避障、跟随、循迹)
  6. Vanilla是什么
  7. gitlab 完整部署实例
  8. Python绘制温度变化曲线
  9. js format 设置日期格式 将Fri Dec 12 2014 08:00:00 GMT+0800改为2014-12-12 8:00:00
  10. 场效应管(FET)总结: