未解决Unable to use slave's temporary directory /tmp - Can't create/write to file '/tmp/SQL_LOAD-' (Err

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: <div id="header" style="background-color:rgb(0,78,97); font-family:Verdana,'Lucida Grande','Lucida Sans Unicode',Tahoma,Arial,sans-serif; line-height:19px"> <div id="logo" style="padding:10px"><a
MySQL
 

Bug #62055 Race condition in check_temp_dir() from multiple mysqld instances
Submitted: 2 Aug 2011 10:24 Modified: 19 Dec 2011 1:29
Reporter: Yoshinori Matsunobu (OCA) Email Updates:
Status: Closed Impact on me: None 
Category: MySQL Server: Replication Severity: S3 (Non-critical)
Version: 5.1.59, 5.5.15 OS: Any
Assigned to:   Target Version:  
Triage: Needs Triage: D3 (Medium)

[2 Aug 2011 10:24] Yoshinori Matsunobu
Description:
In check_temp_dir(), mysqld creates a temporary file and removes it immediately, without protecting any mutex/lockfile/etc. 
--------------
  /*
    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= mysql_file_create(key_file_misc,
                             tmp_file, CREATE_MODE,
                             O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
                             MYF(MY_WME))) < 0)
  DBUG_RETURN(1);

  /*
    Clean up.
   */
  mysql_file_close(fd, MYF(0));
--------------

check_temp_dir() is called at initializing SQL thread. 
  if (check_temp_dir(rli->slave_patternload_file))
The filename is fixed to SQL_LOAD-.

A problem might happen when multiple mysqld instances on the same host start SQL thread at the same time. SQL thread might abort with the following error.

110802 00:00:00 [ERROR] Slave SQL: Unable to use slave's temporary directory /tmp - Can't create/write to file '/tmp/SQL_LOAD-' (Errcode: 17), Error_code: 1

Setting tmpdir separately from each mysqld instance is certainly a workaround for this issue, but this should be a problem anyway.

How to repeat:
See above
[2 Aug 2011 11:09] Valeriy Kravchuk
Thank you for the problem report. Verified by code review.
[19 Dec 2011 1:29] Jon Stephens
Documented fix in the 5.6.5 changelog as follows:

      A race condition could occur when running multiple instances of mysqld on
      a single machine, when more than slave thread was started at the same
      time, and each such thread tried to use the same temporary file.

Closed.
[19 Dec 2011 1:29] Jon Stephens
Thank you for your bug report. This issue has been committed to our source repository of that product and will be incorporated into the next release.

If necessary, you can access the source repository and build the latest available version, including the bug fix. More information about accessing the source trees is available at

    http://dev.mysql.com/doc/en/installing-source.html
 
  

2016-03-09 10:22:28 15680 [Note] Event Scheduler: Loaded 0 events
2016-03-09 10:22:28 15680 [Note] /usr/local/mysql/bin/mysqld: ready for connections.
Version: '5.6.10-log'  socket: '/tmp/mysql.sock'  port: 3306  MySQL Community Server (GPL)
2016-03-09 10:22:28 15680 [Note] Slave SQL thread initialized, starting replication in log 'mysql-bin.000001' at position 151, relay log './t1-relay-bin.000001' position: 4
2016-03-09 10:22:28 15680 [ERROR] Slave SQL: Unable to use slave's temporary directory /tmp                                                          | - Can't read dir of '/tmp                                                          |/' (Errcode: 2 - No such file or directory), Error_code: 12


Unable to use slave's temporary directory /tmp - Can't create/write to file '/tmp/SQL_LOAD-' (Errcode: 17)

这个错误时在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

 

参考:
http://www.cnblogs.com/lit10050528/p/4155325.html

总结不要使用 5.6.10 5.1.59, 5.5.15 版本 
使用主从切换的时候,会遇到这个问题。


 
 
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
17天前
|
SQL
启动mysq异常The server quit without updating PID file [FAILED]sql/data/***.pi根本解决方案
启动mysq异常The server quit without updating PID file [FAILED]sql/data/***.pi根本解决方案
15 0
|
SQL Web App开发 关系型数据库
mysql解决Value ‘0000-00-00 00:00:00’ can not be represented as java.sql.Timestamp
  同步发布:http://www.yuanrengu.com/index.php/mysqlsolvetimestamp.html   在使用mysql时,如果数据库中的字段类型是timestamp,默认为0000-00-00,会发生异常:Value ‘0000-00-00 00:00:00’ can not be represented as java.
2826 0
|
SQL Java 关系型数据库
java.sql.SQLException: Value &#39;0000-00-00 00:00:00&#39; can not be represented as java.sql.Timestamp
详细错误信息: org.springframework.dao.TransientDataAccessResourceException: ### Error querying database.
876 0
|
7天前
|
SQL 人工智能 算法
【SQL server】玩转SQL server数据库:第二章 关系数据库
【SQL server】玩转SQL server数据库:第二章 关系数据库
44 10
|
1月前
|
SQL 数据库 数据安全/隐私保护
Sql Server数据库Sa密码如何修改
Sql Server数据库Sa密码如何修改
|
2月前
|
SQL 算法 数据库
【数据库SQL server】关系数据库标准语言SQL之数据查询
【数据库SQL server】关系数据库标准语言SQL之数据查询
95 0
|
2月前
|
SQL 算法 数据库
【数据库SQL server】关系数据库标准语言SQL之视图
【数据库SQL server】关系数据库标准语言SQL之视图
73 0
|
7天前
|
SQL 算法 数据库
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(二)数据查询
【SQL server】玩转SQL server数据库:第三章 关系数据库标准语言SQL(二)数据查询
61 6
|
7天前
|
SQL 存储 数据挖掘
数据库数据恢复—RAID5上层Sql Server数据库数据恢复案例
服务器数据恢复环境: 一台安装windows server操作系统的服务器。一组由8块硬盘组建的RAID5,划分LUN供这台服务器使用。 在windows服务器内装有SqlServer数据库。存储空间LUN划分了两个逻辑分区。 服务器故障&初检: 由于未知原因,Sql Server数据库文件丢失,丢失数据涉及到3个库,表的数量有3000左右。数据库文件丢失原因还没有查清楚,也不能确定数据存储位置。 数据库文件丢失后服务器仍处于开机状态,所幸没有大量数据写入。 将raid5中所有磁盘编号后取出,经过硬件工程师检测,没有发现明显的硬件故障。以只读方式将所有磁盘进行扇区级的全盘镜像,镜像完成后将所
数据库数据恢复—RAID5上层Sql Server数据库数据恢复案例
|
11天前
|
SQL 安全 Java
SQL server 2017安装教程
SQL server 2017安装教程
14 1