• Unable to use slave's temporary directory /tmp


    这个错误时在Mysql主从配置产生的,最后找到这个Mysql的一个bug

    http://bugs.mysql.com/bug.php?id=62055

    bug的主要原因是:打开文件的函数中指定打开模式时,如果O_CREAT和O_EXCL同时指定,那么当文件存在时会导致打开文件出错,这个使用方法本来也没有什么错误,但是当使用Mysql主从备份机制,在一台服务器上安装多个mysqld实例时,就会出问题,代码在Mysql源码中/sql/slave.cc文件中,Mysql5.1.68是在2904行

    /*
      Check the temporary directory used by commands like
      LOAD DATA INFILE.
     */
    static 
    int check_temp_dir(char* tmp_file)
    {
      int fd;
      MY_DIR *dirp;
      char tmp_dir[FN_REFLEN];
      size_t tmp_dir_size;
    
      DBUG_ENTER("check_temp_dir");
    
      /*
        Get the directory from the temporary file.
      */
      dirname_part(tmp_dir, tmp_file, &tmp_dir_size);
    
      /*
        Check if the directory exists.
       */
      if (!(dirp=my_dir(tmp_dir,MYF(MY_WME))))
        DBUG_RETURN(1);
      my_dirend(dirp);
    
      /*
        Check permissions to create a file.
       */
      if ((fd= my_create(tmp_file, CREATE_MODE,
                         O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
                         MYF(MY_WME))) < 0)
      DBUG_RETURN(1);
    
      /*
        Clean up.
       */
      my_close(fd, MYF(0));
      my_delete(tmp_file, MYF(0));
    
      DBUG_RETURN(0);
    }

    上面红色的是调用了一个函数打开文件,my_create,在这个函数中第三个参数传递了O_EXCL,但是并没有O_CREAT,下面继续看my_create函数,它在/mysys/my_create.c文件中定义

    File my_create(const char *FileName, int CreateFlags, int access_flags,
               myf MyFlags)
    {
      int fd, rc;
      DBUG_ENTER("my_create");
      DBUG_PRINT("my",("Name: '%s' CreateFlags: %d  AccessFlags: %d  MyFlags: %d",
               FileName, CreateFlags, access_flags, MyFlags));
    
    #if !defined(NO_OPEN_3)
      fd = open((char *) FileName, access_flags | O_CREAT,
            CreateFlags ? CreateFlags : my_umask);
    #elif defined(VMS)
      fd = open((char *) FileName, access_flags | O_CREAT, 0,
            "ctx=stm","ctx=bin");
    #elif defined(__WIN__)
      fd= my_sopen((char *) FileName, access_flags | O_CREAT | O_BINARY,
               SH_DENYNO, MY_S_IREAD | MY_S_IWRITE);
    #else
      fd = open(FileName, access_flags);
    #endif
    
      if ((MyFlags & MY_SYNC_DIR) && (fd >=0) &&
          my_sync_dir_by_file(FileName, MyFlags))
      {
        my_close(fd, MyFlags);
        fd= -1;
      }
    
      rc= my_register_filename(fd, FileName, FILE_BY_CREATE,
                               EE_CANTCREATEFILE, MyFlags);
      /*
        my_register_filename() may fail on some platforms even if the call to
        *open() above succeeds. In this case, don't leave the stale file because
        callers assume the file to not exist if my_create() fails, so they don't
        do any cleanups.
      */
      if (unlikely(fd >= 0 && rc < 0))
      {
        int tmp= my_errno;
        my_delete(FileName, MyFlags);
        my_errno= tmp;
      }
      
      DBUG_RETURN(rc);
    } /* my_create */

    红色的字体部分代码是为了实现跨平台,其中默认是蓝色字体代码,可以明显的看到,这时将O_CREAT添加进来了,此时就造成了O_CREAT和O_EXCL同时使用了。

    在POSIX关于open函数的文档中可以看到,当O_CREAT和O_EXCL同时使用时,如果文件存在就会失败。

    http://linux.die.net/man/3/open

  • 相关阅读:
    Python_base_局部变量和全局变量
    Python_base_id()函数
    登录的测试点
    Http协议
    python_base_while循环、for循环
    <10>Golang基础进阶——函数
    <7>Golang基础进阶——流程控制
    Could not connect to SFTP server at "sftp://x.x.x.x:22/"
    <5>Golang基础进阶——类型别名
    <4>Golang基础进阶——字符串应用
  • 原文地址:https://www.cnblogs.com/lit10050528/p/4155325.html
Copyright © 2020-2023  润新知