IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    MySQL 的临时目录

    Xupeng发表于 2012-02-04 07:18:00
    love 0

    MySQL 服务器设置的 binlog 单文件最大为 1GB,偶然发现会有十几 GB 大小的 binlog 文件,从产生的时间上看像是某个 cron job 使用了超大的 transaction,为了找出“罪魁祸首”,我需要分析一下 binlog。

    在使用 mysqlbinlog 将 binary log 转换为文本文件时,发现根分区很快就被塞满了,使用 lsof 发现 mysqlbinlog 在往 /tmp 下写临时文件:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    # lsof -p 17423
    COMMAND     PID USER   FD   TYPE DEVICE    SIZE/OFF      NODE NAME
    mysqlbinl 17423 root    1w   REG   0,19   791765366   3186036 /mfs/user/xupeng/tmp/bigbinlogs/bigbinlog.sql
    mysqlbinl 17423 root    2u   CHR  136,7         0t0        10 /dev/pts/7
    mysqlbinl 17423 root    3r   REG   0,19 13863171331   3172073 /mfs/user/xupeng/tmp/bigbinlogs/log.000323
    mysqlbinl 17423 root    4u   REG    8,1   612122624 135332782 /tmp/tmp.rWTNda (deleted)
    mysqlbinl 17423 root    5u   REG    8,1     2490368 135332784 /tmp/tmp.spKjTA (deleted)
    
    …

    看 mysqlbinlog 的 Man page,发现并没有参数可以指定临时目录,翻了一下 mysqlbinlog (client/mysqlbinlog.cc) 的代码,看到了下面的代码:

    1
    2
    3
    4
    5
    6
    7
    8
    
      MY_TMPDIR tmpdir;
      tmpdir.list= 0;
      if (!dirname_for_local_load)
      {
        if (init_tmpdir(&tmpdir, 0))
          exit(1);
        dirname_for_local_load= my_strdup(my_tmpdir(&tmpdir), MY_WME);
      }
    

    init_tmpdir 定义在 mysys/mf_tempdir.c 中:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    my_bool init_tmpdir(MY_TMPDIR *tmpdir, const char *pathlist)
    {
      char *end, *copy;
      char buff[FN_REFLEN];
      DBUG_ENTER("init_tmpdir");
      DBUG_PRINT("enter", ("pathlist: %s", pathlist ? pathlist : "NULL"));
    
      pthread_mutex_init(&tmpdir->mutex, MY_MUTEX_INIT_FAST);
      if (my_init_dynamic_array(&tmpdir->full_list, sizeof(char*), 1, 5))
        goto err;
      if (!pathlist || !pathlist[0])
      {
        /* Get default temporary directory */
        pathlist=getenv("TMPDIR");  /* Use this if possible */
    #if defined( __WIN__) || defined(__NETWARE__)
        if (!pathlist)
          pathlist=getenv("TEMP");
        if (!pathlist)
          pathlist=getenv("TMP");
    #endif
        if (!pathlist || !pathlist[0])
          pathlist=(char*) P_tmpdir;
      }
    ...
    

    可以看到,在没有指定 pathlist 时,会使用 TMPDIR 这个环境变量指定的目录作为临时目录,如果 TMPDIR 这个环境变量也不存在,在 Windows 下会接着查找 TEMP 和 TMP 这两个环境变量,从环境变量查找临时目录失败,会使用 P_tmpdir 作为默认临时目录,在 Linux 上 P_tmpdir 是 /tmp (定义在 stdio.h 中)。

    所以在运行 mysqlbinlog 之前设置 TMPDIR 这个环境变量就好了。

    MySQL server 和 客户端工具都使用这个临时目录查找策略,怪不得使用 mysqlbinlog tmp directory 作为关键词没有搜到需要的结果,而使用 mysql tmp directory 作为关键词,第一条搜索结果就是 Where MySQL Stores Temporary Files,选择正确的关键词很重要啊。



沪ICP备19023445号-2号
友情链接